avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada Pesan pribadi
4
fokus pada
1271
Pengikut

Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

Dibuat di: 2021-03-17 18:38:47, diperbarui pada: 2024-12-05 22:00:42
comments   13
hits   2466

Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

Platform Perdagangan Kuantitatif FMZBagian Pengawasan StrategiAdalah umum untuk melihat beberapa strategi multi-produk yang secara bersamaan memantau kondisi pasar dari lusinan atau bahkan seluruh pasar di suatu bursa. Bagaimana ini dilakukan? Dan bagaimana seharusnya itu dirancang? Artikel ini akan membahas cara menggunakan antarmuka pasar agregat bursa untuk membangun strategi multiproduk.

Ambil Binance dan Huobi sebagai contoh, dan periksa dokumen API mereka. Kami menemukan bahwa keduanya memiliki antarmuka informasi pasar agregat:

Antarmuka pasar

  [
      {
          "symbol": "BTCUSDT", // 交易对
          "bidPrice": "4.00000000", //最优买单价
          "bidQty": "431.00000000", //挂单量
          "askPrice": "4.00000200", //最优卖单价
          "askQty": "9.00000000", //挂单量
          "time": 1589437530011   // 撮合引擎时间
      }
      ...
  ]
  [  
      {  
          "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 terjadi. Struktur yang sebenarnya dikembalikan oleh antarmuka Huobi 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
      }, ...]
  }

Berhati-hatilah saat memproses data yang dikembalikan oleh antarmuka.

Membangun kerangka program kebijakan

Bagaimana cara merangkum kedua antarmuka ini dalam strategi dan bagaimana cara memproses datanya? Mari kita simak bersama.

Pertama-tama mari kita tulis sebuah konstruktor untuk membangun objek kontrol.

// 参数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 
}

Menggunakan fungsi API FMZHttpQueryFungsi ini mengirimkan permintaan untuk mengakses antarmuka pertukaran. menggunakanHttpQueryPenanganan pengecualian diperlukantry...catchMenangani pengecualian seperti kegagalan pengembalian antarmuka. Beberapa siswa mungkin bertanya: “Struktur data yang dikembalikan oleh antarmuka pertukaran berbeda. Bagaimana kita harus menanganinya? Jelas tidak mungkin menggunakan metode pemrosesan yang sama.” Memang, tidak hanya struktur data yang dikembalikan oleh antarmuka pertukaran berbeda, tetapi bahkan penamaan bidang data yang dikembalikan juga berbeda. Arti yang sama mungkin diberi nama yang berbeda. Misalnya, antarmuka yang kami sebutkan di atas. Ungkapan yang sama berarti harga beli, yang disebut:bidPrice, yang disebutbid

Kami menggunakan fungsi panggilan balik di sini untuk memisahkan bagian pemrosesan khusus ini. Jadi setelah objek di atas diinisialisasi, akan menjadi seperti ini saat digunakan: (Kode berikut menghilangkan konstruktorcreateManager) Pantau kontrak berikut dengan Binance Futures:["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"] Huobi Spot memantau pasangan perdagangan koin ke koin berikut:["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"]Misalnya.

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 pengujian: Objek pertukaran pertama menambahkan Binance futures, dan objek pertukaran kedua menambahkan Huobi spot Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

Dapat dilihat bahwa di sini, operasi seperti cara mendapatkan data yang dikembalikan oleh antarmuka diproses secara khusus untuk pertukaran yang berbeda 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}})

Setelah merumuskan akuisisi informasi pasar, selanjutnya kita dapat merumuskan akuisisi aset akun. Karena strategi multiproduk, data aset akun juga harus beragam. Untungnya, antarmuka aset akun pertukaran umumnya mengembalikan semua data aset.

Di dalam konstruktorcreateManagerTambahkan metode untuk mendapatkan aset

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

Selain itu, karena perbedaan format dan nama bidang yang dikembalikan oleh antarmuka pertukaran, fungsi panggilan balik juga diperlukan untuk pemrosesan khusus.

Mengambil contoh Huobi spot dan Binance futures, fungsi panggilan balik dapat 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 
    }

Jalankan kerangka strategi dengan fungsi memperoleh informasi pasar dan aset

Kutipan: Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

aktiva: Gunakan antarmuka pasar agregat dari pertukaran mata uang digital untuk membangun strategi multi-produk

Dapat dilihat bahwa setelah memperoleh data pasar, data tersebut dapat diolah untuk menghitung selisih harga setiap varietas dan memantau selisih harga spot-futures dari beberapa pasangan perdagangan. Selanjutnya, strategi lindung nilai berjangka multivariasi dan lindung nilai spot dapat dirancang.

Berdasarkan metode desain ini, pertukaran lainnya juga dapat diperluas. Siswa yang tertarik dapat mencobanya.