Sumber dimuat naik... memuat...

Menggunakan pertukaran mata wang digital untuk mengumpul antara muka pasaran untuk membina strategi pelbagai

Penulis:Pencipta Kuantiti - Impian Kecil, Dicipta: 2021-03-17 18:38:47, Dikemas kini: 2024-12-05 22:00:42

img

Menggunakan pertukaran mata wang digital untuk mengumpul antara muka pasaran untuk membina strategi pelbagai

Platform Perdagangan Kuantiti FMZStrategi Penggambaran BlokDalam artikel ini, anda akan melihat beberapa strategi pelbagai jenis yang digunakan untuk mengesan beberapa puluh atau satu bursa keseluruhan pasaran. Bagaimana ia dilakukan? dan bagaimana ia perlu direka?

Mengikut senarai kedua-dua bursa itu, lihat dokumen API bursa dan lihat mereka mempunyai antara muka pasaran agregat:

Antara muka perniagaan

  • Di sini, kita akan melihat apa yang berlaku.https://fapi.binance.com/fapi/v1/ticker/bookTickerAntara muka mengembalikan data

    [
        {
            "symbol": "BTCUSDT", // 交易对
            "bidPrice": "4.00000000", //最优买单价
            "bidQty": "431.00000000", //挂单量
            "askPrice": "4.00000200", //最优卖单价
            "askQty": "9.00000000", //挂单量
            "time": 1589437530011   // 撮合引擎时间
        }
        ...
    ]
    
  • Wang tunai dalam bentuk koin:https://api.huobi.pro/market/tickersAntara muka mengembalikan data

    [  
        {  
            "open":0.044297,      // 开盘价
            "close":0.042178,     // 收盘价
            "low":0.040110,       // 最低价
            "high":0.045255,      // 最高价
            "amount":12880.8510,  
            "count":12838,
            "vol":563.0388715740,
            "symbol":"ethbtc",
            "bid":0.007545,
            "bidSize":0.008,
            "ask":0.008088,
            "askSize":0.009
        }, 
        ...
    ]
    

    Namun, ini tidak berlaku, struktur yang sebenarnya dikembalikan oleh antarmuka token adalah:

    {
        "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
        }, ...]
    }
    

    Perhatian perlu diambil apabila memproses data yang dikembalikan oleh antara muka.

Membina rangka kerja prosedur strategik

Bagaimana untuk membungkus kedua-dua antara muka dalam strategi dan bagaimana untuk memproses data? Mari kita lihat secara perlahan-lahan.

Pertama, tulis fungsi pembina yang digunakan untuk membina objek kawalan.

// 参数e用于传入exchange交易所对象,参数subscribeList是需要处理的交易对列表,例如["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]
function createManager(e, subscribeList) {           
    var self = {}
    self.supportList = ["Futures_Binance", "Huobi"]  // 支持的交易所的

    // 对象属性
    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 = []                    // 接口获取的所有行情数据,定义数据格式:{bid1: 123, ask1: 123, symbol: "xxx"}}
    self.subscribeTickers = []           // 需要的行情数据,定义数据格式:{bid1: 123, ask1: 123, symbol: "xxx"}}
    self.accData = null                  // 用于记录账户资产数据

    // 初始化函数
    self.init = function() { 
    	// 判断是否支持该交易所
        if (!_.contains(self.supportList, self.name)) {        	
        	throw "not support"
        }
    }

    // 判断数据精度
    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
    }

    // 更新资产
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

    // 更新行情数据
    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("错误:", 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("错误:", 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
    }

    // 初始化
    self.init()
	return self 
}

Fungsi API menggunakan FMZHttpQueryFungsi menghantar permintaan, mengakses antara muka bursa.HttpQueryApabila perlu menggunakan rawatan yang luar biasatry...catchMenguruskan keadaan luar biasa seperti kegagalan pengembalian antara muka. Mungkin ada rakan-rakan di sini yang akan bertanya, "Bagaimana untuk menangani struktur data yang dikembalikan oleh antara muka pertukaran yang berbeza? Memang benar, bukan sahaja struktur data yang dikembalikan oleh antara muka pertukaran berbeza, bahkan nama medan data yang dikembalikan juga berbeza. Arti yang sama mungkin nama yang berbeza. Contohnya antara muka yang kami senaraikan di atas. Arti yang sama dinyatakan sebagai membeli satu harga, yang dalam Binance dipanggil:bidPriceDi dalam token, ia dipanggilbid

Kami menggunakan fungsi panggilan balik untuk menyelesaikan masalah ini untuk memisahkan bahagian-bahagian rawatan khas ini. Apabila objek di atas diinstalikan, ia akan menjadi seperti ini apabila digunakan secara khusus: (Kod berikut tidak menyertakan fungsi pembina)createManager(Sunting) Di bawah ini adalah beberapa kontrak yang dipantau dengan mata wang hadapan:["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]Bitcoin Cash memantau transaksi mata wang ini untuk:["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"]Contohnya.

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) {
    	// 更新行情数据
    	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 : "期货行情数据",
        	cols : ["期货合约", "期货买一", "期货卖一"], 
        	rows : []
        }
        _.each(manager1.subscribeTickers, function(ticker) {
        	tbl1.rows.push([ticker.symbol, ticker.bid1, ticker.ask1])
        })
        var tbl2 = {
        	type : "table", 
        	title : "现货行情数据",
        	cols : ["现货合约", "现货买一", "现货卖一"], 
        	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)
    }
}

Jalankan ujian: Objek bursa pertama menambah niaga hadapan, objek bursa kedua menambah token tunaiimg

img

Seperti yang dapat dilihat, di sini, operasi seperti mengambil data yang dikembalikan antara muka digunakan untuk memproses spesialisasi pertukaran yang berbeza menggunakan fungsi panggilan balik.

    	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}})

Pengambilalihan pasaran telah ditetapkan, dan kemudian pengambilalihan aset akaun boleh dibuat, kerana strategi pelbagai jenis, data aset akaun juga harus berbilang.

Pada fungsi pembinacreateManagerTambah kaedah untuk mendapatkan aset

    // 更新资产
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

Juga kerana format yang dikembalikan antara muka pertukaran, nama medan berbeza, di sini juga memerlukan pemprosesan khusus menggunakan fungsi panggilan balik.

Sebagai contoh, dengan token cash, bitcoin futures, fungsi panggilan balik boleh ditulis seperti ini:

    // 获取账户资产的回调函数
    var callBackFuncGetHuobiAcc = function(self) {
        var account = self.e.GetAccount()
        var ret = []
        if (!account) {
        	return false 
        }
        // 构造资产的数组结构
        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")   // 设置为U本位合约的交易对
        self.e.SetContractType("swap")   // 合约都是永续合约
        var account = self.e.GetAccount() 
        var ret = []
        if (!account) {
        	return false 
        }
        var balance = account.Balance
        var frozenBalance = account.FrozenBalance
        // 构造资产数据结构
        _.each(self.subscribeList, function(symbol) {
            var acc = {symbol: symbol}
            acc.Balance = balance
            acc.FrozenBalance = frozenBalance
            ret.push(acc)
        })
        return ret 
    }

Mengendalikan kerangka strategi yang mempunyai fungsi akses kepada pasaran, aset

Perkataan:img

Aset:img

Dengan melihat data pasaran yang diperoleh, data boleh diproses untuk mengira perbezaan antara pelbagai jenis dan memantau perbezaan masa hadapan beberapa pasangan dagangan. Dengan cara ini, anda boleh merancang strategi lindung nilai masa hadapan yang pelbagai.

Dengan reka bentuk seperti ini, pertukaran lain boleh diperluas, dan rakan-rakan yang berminat boleh mencuba sendiri.


Berkaitan

Lebih lanjut

Cinta Jimmy.Apakah callBackFuncGetAcc dalam aset adalah parameter atau fungsi? Selain itu, dua fungsi panggilan balik untuk mendapatkan akaun aset adalah callBackFuncGetHuobiAcc dan callBackFuncGetFutures_BinanceAcc.

Cinta Jimmy.Bagaimana untuk mendapatkan harga Bid1 dan Ask1 pada masa yang sama untuk pasangan dagangan semasa permintaan perbezaan masa hadapan?

Zltimhebat.

Pencipta Kuantiti - Impian KecilFungsi panggilan balik Baudacity.

Pencipta Kuantiti - Impian KecilIni adalah dua pusingan yang saling berpelukan dan melintasi.

Pencipta Kuantiti - Impian KecilSaya telah memberitahu anda tentang perbezaan antara harga sekarang dan harga hadapan, bukan semua gambar di atas, tetapi harga hadapan. Jika anda mempunyai data yang cukup, bagaimana anda boleh kira, adakah anda mengurangkan atau tidak?

Cinta Jimmy.Jika anda ingin mendapatkan perbezaan antara harga beli dan harga jual BTCUSDT dengan masa hadapan: mula-mula pergi ke manajer 1.subscribeTickers, cari manajer 1.subscribeTickers[i].ask1, soalan adalah bagaimana untuk mendapatkan harga tawaran BTCUSDT dengan masa hadapan semasa menjalankan manajer 1.subscribeTickers? tidak tahu cikgu, adakah anda faham soalan saya?

Cinta Jimmy.Saya maksudkan perbezaan antara harga hadapan dengan harga hadapan, bukan harga hadapan atau harga jual beli langsung; masalah yang saya hadapi ialah tidak mungkin untuk mendapatkan harga jual dan harga beli pada masa yang sama. Contohnya: bagaimana untuk mendapatkan perbezaan antara harga beli dan harga jual BTC USDT pada masa yang sama. Saya menulis, saya tidak tahu di mana masalah kod berikut muncul. fungsi GetBAspot ((syboml, tickerspot, BA) { for (var i = 0; i < tickerspot.length; i++) { if ((tickerspot[i].syboml!==syboml) { teruskan }else if ((tickerspot[i].syboml===syboml) { var bidspot=tickerspot[i].bid1 var askspot=tickerspot[i].ask1 {C:$0000FF} {C:$0000FF} if ((BA==="bid") return bidspot if ((BA==="ask") return askspot {C:$0000FF} fungsi utama (() { _.each ((manager1.subscribe Tickers, function ((ticker)) { var symb=ticker.symbol var symb1=manager1.symFuturesToSpot (symb) tbl1.rows.push (([ticker.symbol, ticker.bid1, ticker.ask1, manager1.Getfundingrate ((symb), manager1.Getrealrate ((symb, 50), GetBAspot ((symb1, SpotTickers, "ask"))))) {C:$0000FF} {C:$0000FF}

Pencipta Kuantiti - Impian KecilIni adalah cara yang tepat untuk membuat satu pembelian dan satu jualan, dan perbezaan harga tidak boleh dikurangkan.

Cinta Jimmy.Kenapa sumber gambar yang diambil dari harga hadapan dalam artikel ini tidak diterbitkan?

Pencipta Kuantiti - Impian KecilSaya tidak faham apa yang anda maksudkan.

Cinta Jimmy.Saya lihat, tetapi tidak ada persamaan untuk menetapkan pasangan transaksi yang sama.

Pencipta Kuantiti - Impian KecilJika anda melihat kodnya, anda akan melihat semua data yang ada.