وسائل لوڈ ہو رہے ہیں... لوڈنگ...

ایک حکمت عملی ٹیمپلیٹ آپ کو ویب ساکٹ کے شعبے کو بغیر کسی رکاوٹ کے استعمال کرنے کی اجازت دیتا ہے

مصنف:گھاس, تخلیق: 2024-10-30 09:49:20, تازہ کاری: 2024-11-05 17:45:31

img

یہ ایف ایم زیڈ کی جانب سے تیار کردہ ایک ویب ساکٹ مارکیٹ ٹیمپلیٹ ہے، جس کی نقل اور محفوظ کردہ ٹیمپلیٹ کے طور پر کی جا سکتی ہے، اور نئی پالیسی میں اس ٹیمپلیٹ کو منتخب کرکے استعمال کیا جا سکتا ہے:https://www.fmz.com/strategy/470349

ویب ساکٹ کی ضرورت کیوں ہے؟

فی الحال ایف ایم زیڈ کی حکمت عملی بنیادی طور پر روایتی REST API کی لپیٹ پر مبنی ہے ، جس میں API کے ہر مرحلے پر ایک نیٹ ورک کنکشن قائم کیا جاتا ہے تاکہ مارکیٹ کے اعداد و شمار کو مشورے کے ذریعہ حاصل کیا جاسکے۔ یہ طریقہ آسان اور استعمال میں آسان ہے ، اور زیادہ تر ضروریات کے لئے ایسا کرنا بالکل کافی ہے۔

تاہم ، REST پروٹوکول میں تاخیر کا مسئلہ موجود ہے ، اور جب متعدد تجارتی جوڑوں ، متعدد تبادلے کی حکمت عملی کی ضرورت ہوتی ہے تو تاخیر کا مسئلہ بڑھا دیا جاتا ہے۔ اگرچہ پلیٹ فارم کے ساتھ Go فنکشن کو بیک وقت انجام دیا جاسکتا ہے ، لیکن تاخیر کا مسئلہ اب بھی موجود ہے ، جو نسبتا high اعلی تعدد کی حکمت عملی کی تجارت کی ضروریات کو پورا کرنا مشکل ہے ، اور بہت زیادہ تجارت کی ضرورت ہے ، اور روٹنگ فریکوئنسی بہت تیز ہے اور اس کے ساتھ ہی تجارتی پلیٹ فارم تک رسائی کی تعدد کی حد سے دوچار ہے۔

موجودہ تبادلے میں سرور کا بوجھ بھی بہت زیادہ ہے ، دونوں ویب ساکٹ پروٹوکول کو مکمل طور پر پیش کرتے ہیں اور API صارفین کو استعمال کرنے کی سفارش کرتے ہیں۔ REST پروٹوکول کے مقابلے میں ، ویب ساکٹ ایک مستقل دو طرفہ رابطے کا طریقہ فراہم کرتا ہے ، جس سے تبادلے کو گاہکوں کو حقیقی وقت میں ڈیٹا بھیجنے کی اجازت ملتی ہے ، کثرت سے درخواستوں اور ردعمل سے بچنے اور تاخیر کو بہت کم کرتا ہے۔ عام طور پر ، اگر REST API تک رسائی کی تاخیر 20ms کے ارد گرد ہے تو ، ویب ساکٹ کے پاس ڈیٹا بھیجنے میں تقریبا 2ms کی تاخیر ہوتی ہے۔ اور لنک ویب ساکٹ پروٹوکول پلیٹ فارم تک رسائی کی تعدد کی حد سے آزاد ہے ، جو بنیادی طور پر ایک بار میں درجنوں ٹرانزیکشنز کو سبسکرائب کرسکتا ہے۔

ویب ساکٹ مارکیٹ ٹیمپلیٹ کا تعارف

ایف ایم زیڈ کی کوٹیفیکیشن ٹریڈنگ پلیٹ فارم نے ابتدائی طور پر ویب ساکٹ پروٹوکول کی حمایت کی تھی اور اس کی کال کرنا نسبتا easy آسان تھا ، لیکن نئے صارفین کے لئے ، متعدد خریداریوں ، متعدد تبادلے کی خریداریوں کو سنبھالنا ، اور پوری حکمت عملی کے عمل میں موثر اور آسان طور پر شامل کرنا بہت پیچیدہ تھا۔ یہ عوامی ویب ساکٹ ریئل ٹائم مارکیٹ ڈیٹا ایکسلریٹر ٹیمپلیٹ ، اس تکلیف کو حل کرتا ہے ، بہت آسان استعمال ، مکمل طور پر موجودہ پیکیجڈ API کال کے ساتھ ہم آہنگ ہے ، اور آپ کی پالیسی کو تیز کرنے کے لئے براہ راست استعمال کرنے کے لئے آسان تبدیلیوں کے ساتھ زیادہ تر اصل REST پالیسیوں کی پالیسیوں کے لئے۔

اہم خصوصیات:

  • کثیر تبادلے کی حمایتاس پالیسی میں متعدد تبادلے جیسے بینان ، او کے ایکس ، بائی بٹ ، بٹ گیٹ اور دیگر کے لئے ویب ساکٹ کنکشن کی حمایت کی گئی ہے۔ صارفین اس ٹیمپلیٹ کے پیکیجنگ کے طریقہ کار کی نقل کرسکتے ہیں تاکہ وہ مزید تبادلے کی حمایت کرسکیں۔
  • حسب ضرورت سبسکرپشن: مخصوص مارکیٹ چینلز (جیسے گہرائی ، تجارت وغیرہ) کو سبسکرائب کرنے کی اجازت دیتا ہے اور فوری طور پر تجارتی حکمت عملی کے لئے موصول ہونے والے ڈیٹا کو موثر انداز میں پروسیس کرتا ہے۔
  • اعلی درجے کی غلطی: بلٹ میں غلطی سے باخبر رہنے اور ویب ساکٹ دوبارہ منسلک میکانیزم، ڈیٹا کے بہاؤ کی وشوسنییتا اور مستقل مزاجی کو یقینی بنانے کے لئے؛

عملدرآمد کے اصول کا ایک سادہ تعارف

نوٹ کریں کہ یہ حکمت عملی ٹائپ اسکرپٹ کا استعمال کرتی ہے ، جو اگر آپ صرف جاوا اسکرپٹ سے واقف ہیں تو تھوڑا سا اجنبی نظر آئے گا۔ ٹائپ اسکرپٹ نے جاوا اسکرپٹ کی بنیاد پر ٹائپ سسٹم اور زبان کی بھرپور خصوصیات متعارف کروائی ہیں ، جس میں کوانٹیمیٹڈ ٹرانزیکشنز جیسے پیچیدہ منطق کو سنبھالنے کی ضرورت ہے ، ٹائپ اسکرپٹ کا استعمال ممکنہ غلطیوں کو کم کرنے ، کوڈ کی پڑھنے اور برقرار رکھنے کی صلاحیت کو بڑھانے کے لئے آسان سیکھنے کی سفارش کی جاتی ہے۔

اس کے علاوہ یہ پالیسی ایف ایم زیڈ پلیٹ فارم کے متضاد میکانزم کا استعمال کرتی ہے، جس میں ذیلی دھارے __threadPostMessage فنکشن کے ذریعے مین تھریڈ کو پیغامات بھیج سکتے ہیں۔ یہ طریقہ متضاد ہے اور اس کا اطلاق ذیلی تھریڈ میں پیدا ہونے والے ڈیٹا کی تازہ کاری کی اطلاع دینے والے مین تھریڈ پر ہوتا ہے۔ __threadGetData اور __threadSetData فنکشن کے ذریعے مین تھریڈ اور ذیلی تھریڈ کے مابین ڈیٹا شیئر کیا جاسکتا ہے۔ اس طرح اس تھریڈ کو شیئر کی حیثیت تک رسائی اور ترمیم کی اجازت ملتی ہے۔ اگر آپ مزید تھریڈز سیکھنا چاہتے ہیں تو ، پلیٹ فارم کی دستاویزات کے ساتھ مل کر ، یہ حکمت عملی بھی ایک عمدہ سیکھنے کی مثال ہے۔

اس حکمت عملی کا بنیادی اصول یہ ہے کہ ویب ساکٹ کے ذریعہ مرکزی ڈیجیٹل کرنسی کے تبادلے کو مربوط کیا جائے تاکہ مارکیٹ کے اعداد و شمار (جیسے گہرائی کی معلومات اور ٹرانزیکشن کی معلومات) کو حقیقی وقت میں حاصل کیا جاسکے تاکہ مقداری تجارتی فیصلوں کے لئے اعداد و شمار کی حمایت کی جاسکے۔

1. ویب ساکٹ کنکشن کی ترتیبات

setupWebsocketایک فنکشن جو ویب ساکٹ کنکشن کو شروع کرنے اور مارکیٹ کے اعداد و شمار کو حاصل کرنے کے لئے استعمال کیا جاتا ہے۔ یہ ایک پیرامیٹر وصول کرتا ہے۔main_exchangesاس کے علاوہ ، یہ بھی کہا جاتا ہے کہ آپ کو اس کے بارے میں مزید جاننے کی ضرورت ہے۔

  • MyDialفنکشن: ویب ساکٹ کنکشن بناتا ہے ، کنکشن کا وقت ریکارڈ کرتا ہے ، اور جب کنکشن بند ہوجاتا ہے تو بند ہونے کا وقت آؤٹ پٹ کرتا ہے۔
  • updateSymbolsفنکشن: باقاعدگی سے چیک کریں کہ آیا کوئی نیا سبسکرپشن کی درخواست ہے اور اگر ضرورت ہو تو موجودہ ٹرانزیکشنز کی فہرست کو اپ ڈیٹ کریں۔

2. ڈیٹا پروسیسنگ

supportsاشیاء کی حمایت کی تبادلے اور ان کے عملدرآمد کے افعال (جیسے) کی وضاحتBinanceہر ایکسچینج کا پروسیسنگ فنکشن موصولہ پیغامات کو تجزیہ کرنے اور متعلقہ ڈیٹا نکالنے کا ذمہ دار ہے۔

  • processMsgفنکشن: تبادلے سے آنے والے پیغامات کو پروسیس کرنا ، مختلف اقسام کے اعداد و شمار (جیسے گہرائی میں تازہ کاری ، تجارت وغیرہ) کی نشاندہی کرنا ، اور ان کو یکساں واقعہ کے طور پر فارمیٹ کرنا۔

3. سبسکرپشن ڈیٹا

ہر کنکشن کے دوران، نظام موجودہ ٹرانزیکشن کے مطابق سبسکرپشن سے متعلق مارکیٹ ڈیٹا چینلز کا تجزیہ کرتا ہے۔

  • getFunctionفنکشن: ایکسچینج کے نام کے مطابق متعلقہ پروسیسنگ افعال حاصل کریں۔
  • this.wssPublicفنکشن: ویب ساکٹ کنکشن کو شروع کریں اور ڈیٹا وصول کرنا شروع کریں۔

تھریڈ مینجمنٹ

ہر تبادلے کے لئے ایک تھریڈ شروع کریں ، اعداد و شمار کو حقیقی وقت میں وصول کریں اور کال بیک فنکشن کے ذریعہ اعداد و شمار پر کارروائی کریں۔

  • threadMarketفنکشن: ذیلی دھاگوں میں ڈیٹا وصول کریں ، تازہ ترین گہرائی اور ٹرانزیکشن کی معلومات کو تجزیہ اور اسٹور کریں۔

5. ڈیٹا حاصل کرنے کا طریقہ دوبارہ لکھنا

ہر تبادلے کے لئے گہرائی اور تجارتی معلومات حاصل کرنے کے طریقوں کو دوبارہ لکھنا ، حقیقی وقت میں تازہ ترین اعداد و شمار کو ترجیح دینا۔

ٹیمپلیٹس کا استعمال

  1. ابتدائیہاستعمال:$.setupWebsocket()ہدف ایکسچینج کے ویب ساکٹ کنکشن کو ابتدائیہ بنائیں۔
  2. سبسکرائب کریںاس کے علاوہ ، آپ کو اس بات کا یقین کرنے کی ضرورت ہے کہ آپ کے اکاؤنٹ میں موجود تمام چینلز آپ کے اکاؤنٹ میں موجود ہیں۔
  3. اعداد و شمار حاصل کرناکال کریں:GetDepth()اورGetTrades()ایک فنکشن جو خود بخود ویب ساکٹ کے حقیقی وقت کے اعداد و شمار کا استعمال کرتے ہوئے مارکیٹ کی گہرائی اور ٹرانزیکشن ریکارڈ کی واپسی کرتا ہے۔
  4. غلط استعمال: پالیسی میں ایک ٹریکنگ میکانزم شامل ہے جو کنکشن اور ڈیٹا کی غلطیوں کو ریکارڈ کرنے کے لئے استعمال ہوتا ہے اور جب کنکشن منقطع ہوجاتا ہے تو خود بخود دوبارہ رابطہ قائم کرنے کی کوشش کرتا ہے۔

اگر آپ اس پالیسی میں ایونٹ لوپ () فنکشن کو شامل کرتے ہیں تو ، اسے ٹرگر میکانزم میں تبدیل کردیا جاتا ہے ، جب بھی کوئی ڈبلیو ایس ایس ڈیٹا اپ ڈیٹ ہوتا ہے تو وہ خود بخود فوری طور پر حاصل ہوجاتا ہے ، جب کوئی تازہ ترین ڈیٹا نہیں ہوتا ہے تو انتظار کرنا پڑتا ہے۔ یہ سمارٹ سلیپ فنکشن کے مترادف ہے ، اور یقینا you آپ براہ راست سلیپ کا استعمال کرسکتے ہیں۔

function main() {
    $.setupWebsocket()
    while (true) {
        exchanges.map(e=>{
            Log(e.GetName(), e.GetDepth())
            Log(e.GetName(), e.GetTrades())
        })
        EventLoop(100) // trigger by websocket
    }
}

میری گزشتہ کثیر کرنسی ٹریڈنگ حکمت عملی گائیڈ کا حوالہ دیںhttps://www.fmz.com/digest-topic/10506یہاں ایک بہت ہی آسان طریقہ ہے جس میں ویب ساکٹ کی حمایت میں ترمیم کی جاسکتی ہے:

function MakeOrder() {
    for (let i in Info.trade_symbols) {
        let symbol = Info.trade_symbols[i];
        let buy_price = exchange.GetDepth(symbol + '_USDT').Asks[0].Price;
        let buy_amount = 50 / buy_price;
        if (Info.position[symbol].value < 2000){
            Trade(symbol, "buy", buy_price, buy_amount, symbol);
        }
    }
}

function OnTick() {
    try {
        UpdatePosition();
        MakeOrder();
        UpdateStatus();
    } catch (error) {
        Log("循环出错: " + error);
    }
}

function main() {
    $.setupWebsocket()
    InitInfo();
    while (true) {
        let loop_start_time = Date.now();
        if (Date.now() - Info.time.last_loop_time > Info.interval * 1000) {
            OnTick();
            Info.time.last_loop_time = Date.now();
            Info.time.loop_delay = Date.now() - loop_start_time;
        }
        Sleep(5);
    }
}

نئے تبادلے خود کیسے شامل کریں

اگر آپ اس پالیسی کے مطابق ٹیمپلیٹ پر عمل کرتے ہیں اور نیچے دی گئی فارمیٹ کی نقل کرتے ہیں تو ، آپ اپنے آپ کو ایکسچینج API دستاویزات کا حوالہ دے سکتے ہیں۔

    supports["Binance"] = function (ctx:ICtx) {
        let processMsg = function (obj) {
            let event = {
                ts: obj.E,
                instId: obj.s,
                depth: null,
                trades: [],
            }

            if (obj.e == "depthUpdate") {
                let depth = {
                    asks: [],
                    bids: []
                }
                obj.b.forEach(function (item) {
                    depth.bids.push({
                        price: Number(item[0]),
                        qty: Number(item[1])
                    })
                })
                obj.a.forEach(function (item) {
                    depth.asks.push({
                        price: Number(item[0]),
                        qty: Number(item[1])
                    })
                })
                event.depth = depth
            } else if (obj.e == 'bookTicker') {
                event.depth = {
                    asks: [{ price: Number(obj.a), qty: Number(obj.A) }],
                    bids: [{ price: Number(obj.b), qty: Number(obj.B) }]
                }
            } else if (obj.e == 'aggTrade') {
                event.ts = obj.E
                event.trades = [{
                    price: Number(obj.p),
                    qty: Number(obj.q),
                    ts: obj.T,
                    side: obj.m ? "sell" : "buy"
                }]
            } else if (typeof (obj.asks) !== 'undefined') {
                event.ts = obj.E || new Date().getTime()
                let depth = {
                    asks: [],
                    bids: []
                }
                obj.bids.forEach(function (item) {
                    depth.bids.push({
                        price: Number(item[0]),
                        qty: Number(item[1])
                    })
                })
                obj.asks.forEach(function (item) {
                    depth.asks.push({
                        price: Number(item[0]),
                        qty: Number(item[1])
                    })
                })
                event.depth = depth
            } else {
                return
            }
            return event
        }
        let channels = ["depth20@100ms", /*"bookTicker", */"aggTrade"]
 
        let ws = null
        let endPoint = "wss://stream.binance.com/stream"
        if (ctx.name == "Futures_Binance") {
            endPoint = "wss://fstream.binance.com/stream"
        }
        
        while (true) {
            if (!ws) {
                let subscribes = []
                ctx.symbols.forEach(function (symbol) {
                    channels.forEach(function (channel) {
                        subscribes.push(symbol.toLowerCase() + "@" + channel)
                    })
                })
                ws = MyDial(endPoint + (subscribes.length > 0 ? ("?streams=" + subscribes.join("/")) : ""))
            }
            if (!ws) {
                Sleep(1000)
                continue
            }
            updateSymbols(ctx, function(symbol:string, method:string) {
                ws.write(JSON.stringify({ 
                    "method": method.toUpperCase(), 
                    "params": channels.map(c=>symbol.toLowerCase()+'@'+c),
                    "id": 2
                }))
            })
            let msg = ws.read(1000)
            if (!msg) {
                if (msg == "") {
                    trace("websocket is closed")
                    ws.close()
                    ws = null
                }
                continue
            }
            if (msg == 'ping') {
                ws.write('pong')
            } else if (msg == 'pong') {

            } else {
                let obj = JSON.parse(msg)
                if (obj.error) {
                    trace(obj.error.msg, "#ff0000")
                    continue
                }
                if (!obj.stream) {
                    continue
                }
                if (obj.stream.indexOf("depth") != -1) {
                    if (typeof(obj.data.s) !== 'string') {
                        // patch
                        obj.data.s = obj.stream.split('@')[0].toUpperCase()
                    }
                }
                let event = processMsg(obj.data)
                if (event) {
                    ctx.callback(event)
                }
            }
        }
    }
    

مزید