बहु-प्रतीक रणनीति बनाने के लिए क्रिप्टोकरेंसी प्लेटफॉर्म एग्रीगेटेड मार्केट इंटरफेस का उपयोग करें

लेखक:निनाबादास, बनाया गयाः 2022-04-24 17:34:03, अद्यतन किया गयाः

बहु-प्रतीक रणनीति बनाने के लिए क्रिप्टोकरेंसी प्लेटफॉर्म एग्रीगेटेड मार्केट इंटरफेस का उपयोग करें

[ लाइव अनुभाग में] (https://www.fmz.com/live) के FMZ क्वांट ट्रेडिंग प्लेटफॉर्म, बहु-प्रतीक रणनीतियों को अक्सर देखा जाता है, जो एक ही समय में दर्जनों प्रतीकों या यहां तक कि एक पूरे मंच की बाजार स्थितियों का पता लगा सकते हैं। यह कैसे किया जाता है? और इसे कैसे डिजाइन किया जाना चाहिए? यह लेख आपको एक बहु-प्रतीक रणनीति बनाने के लिए मंच एकत्रित बाजार इंटरफ़ेस का उपयोग करने के बारे में चर्चा करने के लिए ले जाता है।

उदाहरण के लिए बिनेंस और हुओबी को लें; यदि आप उनके एपीआई दस्तावेज की जांच करते हैं, तो आप पाएंगे कि संकलित इंटरफ़ेस हैंः

बाजार इंटरफ़ेस

  • बाइनेंस अनुबंधःhttps://fapi.binance.com/fapi/v1/ticker/bookTickerइंटरफ़ेस द्वारा लौटाए गए डेटाः

    [
        {
            "symbol": "BTCUSDT", // trading pair
            "bidPrice": "4.00000000", //optimum bid price 
            "bidQty": "431.00000000", //bid quantity 
            "askPrice": "4.00000200", //optimum ask price 
            "askQty": "9.00000000", //ask quantity 
            "time": 1589437530011   // matching engine time 
        }
        ...
    ]
    
  • हुओबी स्पॉटःhttps://api.huobi.pro/market/tickersइंटरफ़ेस द्वारा लौटाए गए डेटाः

    [  
        {  
            "open":0.044297,      // open price 
            "close":0.042178,     // close price 
            "low":0.040110,       // the lowest price 
            "high":0.045255,      // the highest price 
            "amount":12880.8510,  
            "count":12838,
            "vol":563.0388715740,
            "symbol":"ethbtc",
            "bid":0.007545,
            "bidSize":0.008,
            "ask":0.008088,
            "askSize":0.009
        }, 
        ...
    ]
    

    हालाँकि, परिणाम वास्तव में ऐसा नहीं है, और Huobi इंटरफ़ेस द्वारा लौटाई गई वास्तविक संरचना हैः

    {
        "status": "ok",
        "ts": 1616032188422,
        "data": [{
      	  "symbol": "hbcbtc",
      	  "open": 0.00024813,
      	  "high": 0.00024927,
      	  "low": 0.00022871,
      	  "close": 0.00023495,
      	  "amount": 2124.32,
      	  "vol": 0.517656218,
      	  "count": 1715,
      	  "bid": 0.00023427,
      	  "bidSize": 2.3,
      	  "ask": 0.00023665,
      	  "askSize": 2.93
        }, ...]
    }
    

    इंटरफेस द्वारा लौटाए गए डेटा को संसाधित करते समय ध्यान दिया जाना चाहिए।

रणनीति कार्यक्रम संरचना का निर्माण करें

रणनीति में दोनों इंटरफेस को कैसे शामिल किया जाए और डेटा को कैसे संसाधित किया जाए? चलो एक नज़र डालते हैं.

सबसे पहले, एक कंस्ट्रक्टर लिखें, नियंत्रण वस्तुओं का निर्माण करने के लिए

// parameter e is used to import the exchange object; parameter subscribeList is the trading pair list to be processed, such as ["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]
function createManager(e, subscribeList) {           
    var self = {}
    self.supportList = ["Futures_Binance", "Huobi"]  // the supported platform's 

    // object attribute 
    self.e = e
    self.name = e.GetName()
    self.type = self.name.includes("Futures_") ? "Futures" : "Spot"
    self.label = e.GetLabel()
    self.quoteCurrency = ""  
    self.subscribeList = subscribeList   // subscribeList : [strSymbol1, strSymbol2, ...]
    self.tickers = []                    // all market data obtained by the interfaces; define the data format as: {bid1: 123, ask1: 123, symbol: "xxx"}}
    self.subscribeTickers = []           // the market data needed; define the data format as: {bid1: 123, ask1: 123, symbol: "xxx"}}
    self.accData = null                  // used to record the account asset data 

    // initialization function 
    self.init = function() { 
    	// judge whether a platform is supported 
        if (!_.contains(self.supportList, self.name)) {        	
        	throw "not support"
        }
    }

    // judge the data precision 
    self.judgePrecision = function (p) {
        var arr = p.toString().split(".")
        if (arr.length != 2) {
            if (arr.length == 1) {
                return 0
            }
            throw "judgePrecision error, p:" + String(p)
        }
        
        return arr[1].length
    }

    // update assets 
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

    // update market data 
    self.updateTicker = function(url, callBackFuncGetArr, callBackFuncGetTicker) {
    	var tickers = []
    	var subscribeTickers = []
    	var ret = self.httpQuery(url)
    	if (!ret) {
    		return false 
    	}
    	try {
            _.each(callBackFuncGetArr(ret), function(ele) {
            	var ticker = callBackFuncGetTicker(ele)
            	tickers.push(ticker)
            	for (var i = 0 ; i < self.subscribeList.length ; i++) {
            		if (self.subscribeList[i] == ele.symbol) {
            			subscribeTickers.push(ticker)
            		}
            	}
            })
        } catch(err) {
        	Log("error:", err)
        	return false 
        }

        self.tickers = tickers
        self.subscribeTickers = subscribeTickers
        return true 
    }

    self.httpQuery = function(url) {
    	var ret = null
        try {
            var retHttpQuery = HttpQuery(url)
            ret = JSON.parse(retHttpQuery)
        } catch (err) {
            // Log("error:", err)
            ret = null
        }
        return ret 
    }

    self.returnTickersTbl = function() {
        var tickersTbl = {
        	type : "table", 
        	title : "tickers",
        	cols : ["symbol", "ask1", "bid1"], 
        	rows : []
        }
        _.each(self.subscribeTickers, function(ticker) {        
        	tickersTbl.rows.push([ticker.symbol, ticker.ask1, ticker.bid1])
        })
        return tickersTbl
    }

    // initialization 
    self.init()
	return self 
}

FMZ एपीआई फ़ंक्शन का प्रयोग करेंHttpQueryप्लेटफ़ॉर्म इंटरफ़ेस तक पहुँचने के लिए अनुरोध भेजने के लिए।HttpQuery, आप अपवाद प्रसंस्करण का उपयोग करने की जरूरत हैtry...catchअपवादों को संभालने के लिए जैसे कि इंटरफेस रिटर्न विफलता। यहाँ कुछ छात्र पूछ सकते हैंः प्लेटफ़ॉर्म इंटरफेस द्वारा लौटाए गए डेटा संरचनाएं काफी भिन्न हैं, तो इससे कैसे निपटा जाए? एक ही प्रसंस्करण विधि का उपयोग करना संभव नहीं होना चाहिए। वास्तव में, न केवल प्लेटफ़ॉर्म इंटरफ़ेस द्वारा लौटाए गए डेटा संरचनाएं अलग हैं, बल्कि लौटाए गए डेटा फ़ील्ड के नाम भी अलग हैं। एक ही अर्थ को अलग-अलग नाम दिया जा सकता है। उदाहरण के लिए, हमने ऊपर सूचीबद्ध इंटरफेस। एक ही अभिव्यक्ति का अर्थ है buy1 मूल्य, जिसे कहा जाता हैःbidPriceBinance में, लेकिनbidHuobi में।

हम यहाँ कॉलबैक फ़ंक्शन का उपयोग करते हैं और स्वतंत्र रूप से इन भागों को अलग करते हैं जिन्हें विशेष प्रसंस्करण की आवश्यकता होती है। तो उपरोक्त ऑब्जेक्ट के आरंभ होने के बाद, यह विशिष्ट उपयोग में इस तरह बन जाता हैः (निम्नलिखित कोड में रचनाकार को छोड़ दिया गया हैcreateManager) बिनेंस फ्यूचर्स द्वारा मॉनिटर किए गए अनुबंधः["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]हुओबी स्पॉट द्वारा निगरानी की जाने वाली स्पॉट ट्रेडिंग जोड़ीः["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"]

function main() {
    var manager1 = createManager(exchanges[0], ["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"])
    var manager2 = createManager(exchanges[1], ["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"])   

    while (true) {
    	// update market data 
    	var ticker1GetSucc = manager1.updateTicker("https://fapi.binance.com/fapi/v1/ticker/bookTicker", 
    		function(data) {return data}, 
    		function (ele) {return {bid1: ele.bidPrice, ask1: ele.askPrice, symbol: ele.symbol}})
    	var ticker2GetSucc = manager2.updateTicker("https://api.huobi.pro/market/tickers", 
    		function(data) {return data.data}, 
    		function(ele) {return {bid1: ele.bid, ask1: ele.ask, symbol: ele.symbol}})
        if (!ticker1GetSucc || !ticker2GetSucc) {
        	Sleep(1000)
        	continue
        }
        
        var tbl1 = {
        	type : "table", 
        	title : "futures market data",
        	cols : ["futures contract", "futures buy1", "futures sell1"], 
        	rows : []
        }
        _.each(manager1.subscribeTickers, function(ticker) {
        	tbl1.rows.push([ticker.symbol, ticker.bid1, ticker.ask1])
        })
        var tbl2 = {
        	type : "table", 
        	title : "spot market data",
        	cols : ["spot contract", "spot buy1", "spot sell1"], 
        	rows : []
        }
        _.each(manager2.subscribeTickers, function(ticker) {
        	tbl2.rows.push([ticker.symbol, ticker.bid1, ticker.ask1])
        })
        LogStatus(_D(), "\n`" + JSON.stringify(tbl1) + "`", "\n`" + JSON.stringify(tbl2) + "`")
        Sleep(10000)
    }
}

ऑपरेशन परीक्षणः पहले एक्सचेंज ऑब्जेक्ट के रूप में बिनेंस फ्यूचर्स जोड़ें, और दूसरे एक्सचेंज ऑब्जेक्ट के रूप में हुओबी स्पॉट जोड़ें।
img

img

जैसा कि आप देख सकते हैं, यहाँ callback फ़ंक्शन को विभिन्न प्लेटफार्मों में संचालन पर विशेष प्रसंस्करण करने के लिए बुलाया जाता है, जैसे कि इंटरफ़ेस द्वारा लौटाए गए डेटा को कैसे प्राप्त किया जाए।

    	var ticker1GetSucc = manager1.updateTicker("https://fapi.binance.com/fapi/v1/ticker/bookTicker", 
    		function(data) {return data}, 
    		function (ele) {return {bid1: ele.bidPrice, ask1: ele.askPrice, symbol: ele.symbol}})
    	var ticker2GetSucc = manager2.updateTicker("https://api.huobi.pro/market/tickers", 
    		function(data) {return data.data}, 
    		function(ele) {return {bid1: ele.bid, ask1: ele.ask, symbol: ele.symbol}})

बाजार डेटा प्राप्त करने की विधि को डिजाइन करने के बाद, हम बाजार डेटा प्राप्त करने की एक विधि बना सकते हैं। क्योंकि यह एक बहु-प्रतीक रणनीति है, खाता परिसंपत्ति डेटा भी कई है। सौभाग्य से, एक मंच खाता परिसंपत्ति इंटरफ़ेस आम तौर पर पूर्ण परिसंपत्ति डेटा लौटाता है।

कंस्ट्रक्टर में संपत्ति प्राप्त करने की विधि जोड़ेंcreateManager:

    // update assets
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

इसी तरह, विभिन्न प्लेटफार्म इंटरफेस द्वारा लौटाए गए स्वरूपों के लिए और फ़ील्ड नाम अलग हैं, यहां हमें विशेष प्रसंस्करण करने के लिए कॉलबैक फ़ंक्शन का उपयोग करने की आवश्यकता है।

Huobi स्पॉट और Binance वायदा उदाहरण के रूप में ले लो, और कॉलबैक समारोह इस तरह लिखा जा सकता हैः

    // the callback function of obtaining the account assets 
    var callBackFuncGetHuobiAcc = function(self) {
        var account = self.e.GetAccount()
        var ret = []
        if (!account) {
        	return false 
        }
        // construct the array structure of assets 
        var list = account.Info.data.list
        _.each(self.subscribeList, function(symbol) {
            var coinName = symbol.split("usdt")[0]
            var acc = {symbol: symbol}
            for (var i = 0 ; i < list.length ; i++) {
            	if (coinName == list[i].currency) {
                    if (list[i].type == "trade") {
                        acc.Stocks = parseFloat(list[i].balance)
                    } else if (list[i].type == "frozen") {
                    	acc.FrozenStocks = parseFloat(list[i].balance)
                    }
                } else if (list[i].currency == "usdt") {
                	if (list[i].type == "trade") {
                		acc.Balance = parseFloat(list[i].balance)
                	} else if (list[i].type == "frozen") {
                		acc.FrozenBalance = parseFloat(list[i].balance)
                	}
                }
            }
            ret.push(acc)
        })
        return ret 
    }

    var callBackFuncGetFutures_BinanceAcc = function(self) {
    	self.e.SetCurrency("BTC_USDT")   // set to USDT-margined contract trading pair 
        self.e.SetContractType("swap")   // all are perpetual contracts
        var account = self.e.GetAccount() 
        var ret = []
        if (!account) {
        	return false 
        }
        var balance = account.Balance
        var frozenBalance = account.FrozenBalance
        // construct asset data structure 
        _.each(self.subscribeList, function(symbol) {
            var acc = {symbol: symbol}
            acc.Balance = balance
            acc.FrozenBalance = frozenBalance
            ret.push(acc)
        })
        return ret 
    }

बाजार डेटा और परिसंपत्तियों को प्राप्त करने के कार्य के साथ रणनीति संरचना का संचालन करना

बाजार:img

परिसंपत्तियाँ:img

यह देखा जा सकता है कि बाजार डेटा प्राप्त करने के बाद, आप प्रत्येक प्रतीक के मूल्य प्रसार की गणना करने के लिए डेटा को संसाधित कर सकते हैं, और कई ट्रेडिंग जोड़े के वायदा-स्पॉट मूल्य प्रसार की निगरानी कर सकते हैं। और फिर आप एक बहु-प्रतीक वायदा हेजिंग रणनीति डिजाइन कर सकते हैं।

इस तरह के डिजाइन के अनुसार अन्य प्लेटफार्मों को भी इस तरह से विस्तारित किया जा सकता है, और इच्छुक छात्र इसे आज़मा सकते हैं।


अधिक