FMZ-QuantifizierungsplattformStrategische UmrisseEs gibt häufig verschiedene Strategien, die verschiedene Märkte auf der ganzen Börse aufspüren. Wie kann man das tun? Und wie muss man sie entwerfen?
Bei der Liste der beiden Börsen, Binance und Token, wird in der API-Dokumentation der Börse festgestellt, dass sie alle eine aggregierte Markt-Schnittstelle haben:
Der Bitcoin-Vertrag:https://fapi.binance.com/fapi/v1/ticker/bookTickerSchnittstelle gibt Daten zurück
[
{
"symbol": "BTCUSDT", // 交易对
"bidPrice": "4.00000000", //最优买单价
"bidQty": "431.00000000", //挂单量
"askPrice": "4.00000200", //最优卖单价
"askQty": "9.00000000", //挂单量
"time": 1589437530011 // 撮合引擎时间
}
...
]
Die Münze in Bargeld:https://api.huobi.pro/market/tickersSchnittstelle gibt Daten zurück
[
{
"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
},
...
]
Das ist jedoch nicht der Fall, denn die Struktur, die die Token-Interface tatsächlich zurückgibt, ist:
{
"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
}, ...]
}
Die Daten, die von der Schnittstelle zurückgegeben werden, müssen sorgfältig verarbeitet werden.
Wie können wir diese beiden Schnittstellen in die Strategie einpacken und die Daten verarbeiten? Wir müssen alle langsam zusammenschauen.
Schreiben Sie zunächst eine Konstruktionsfunktion, um Kontrollobjekte zu konstruieren.
// 参数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
}
API-Funktionen mit FMZHttpQuery
Funktionen, die Anfragen stellen und die Anschlüsse auf die Börse aufrufen.HttpQuery
Wenn Sie eine Ausnahmeregelung benötigentry...catch
Handling von Ausnahmen wie Interface Return Failure.
Einige Schüler, die das hier sehen, werden sich vielleicht fragen: Wie soll man mit den verschiedenen Datenstrukturen umgehen, die von den Anschlüssen der Börsen zurückgegeben werden?
Ja, nicht nur die Datenstruktur, die die Interface zurückgibt, ist unterschiedlich, sondern auch die Namen der zurückgegebenen Datenfelder. Eine gleiche Bedeutung kann eine andere Bedeutung haben.bidPrice
Das ist ein großes Problem.bid
。
Wir haben hier die Rückruffunktionen verwendet, um diese speziellen Behandlungsbereiche zu lösen.
Wenn das Objekt initializiert wird, wird es für den konkreten Gebrauch wie folgt:
(Der folgende Code entzieht die Konstruktionsfunktion)createManager
Ich weiß nicht.
Die Anzeige von Bitcoin-Futures zeigt, dass die folgenden Konzepte überwacht werden:["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]
Die Münzkasse überwacht die Transaktionen in folgenden Bereichen:["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"]
Das ist ein Beispiel.
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)
}
}
Lauftest: Das erste Austauschobjekt fügt Münzen-Futures hinzu, das zweite Austauschobjekt fügt Token-Cash hinzu
Man kann sehen, dass hier die Spezialisierung von verschiedenen Börsen mit Hilfe von Rückruffunktionen durchgeführt wird, beispielsweise wie man die Daten aus der Interface zurückholt.
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}})
Die Marktaufnahme ist festgelegt, die Aktivaufnahme kann dann festgelegt werden, da es sich bei einer Vielzahl von Strategien um mehrere Konto-Assetdaten handelt.
Die Konstruktion der FunktioncreateManager
Hinzufügen von Methoden zur Annahme von Vermögenswerten
// 更新资产
self.updateAcc = function(callBackFuncGetAcc) {
var ret = callBackFuncGetAcc(self)
if (!ret) {
return false
}
self.accData = ret
return true
}
Ebenso variieren die Feldnamen aufgrund des Formats, in dem die Interface der Börse zurückgegeben wird, und hier muss auch eine Spezialisierung der Rückruffunktion verwendet werden.
Die Rückruffunktion kann wie folgt geschrieben werden:
// 获取账户资产的回调函数
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
}
Die Geschichte:
Vermögen:
Sie sehen, dass nach dem Erhalt von Marktdaten die Daten berechnet werden können, um die Differenz zwischen den verschiedenen Sorten zu berechnen und die Verzinsungsdifferenz von mehreren Paaren zu überwachen. Das bedeutet, dass wir eine Vielzahl von Futures-Hedging-Strategien entwerfen können.
Wenn man sich mit diesem Design beschäftigt, kann man auch andere Börsen erweitern, und Studenten, die Interesse daran haben, können es versuchen.
Ich liebe Jimmy.Was hat CallBackFuncGetAcc mit CallBackFuncGetAcc zu tun? Ich habe das Gefühl, dass es eine Funktion ist, die in einer Funktion ist?
Ich liebe Jimmy.Wie kann man bei einem Futures-Differenzpreis gleichzeitig den Preis von Bid1 und Ask1 für ein Handelspaar extrahieren?
ZltimSehr gut.
Die Erfinder quantifizieren - Kleine TräumeDie Baudacity-Rückruffunktion.
Die Erfinder quantifizieren - Kleine TräumeDas sind zwei Kreisläufe, die sich aneinandergreifen und durchlaufen.
Die Erfinder quantifizieren - Kleine TräumeIch habe Ihnen die Differenz zwischen den Aktien und den Futures gesagt, nicht alle Bilder, die ich in diesem Artikel gezeigt habe, die Differenz zwischen den Aktien und den Futures. Die Daten sind vorhanden, aber wie genau, wenn man sie abzieht oder nicht?
Ich liebe Jimmy.Wenn Sie die Differenz zwischen dem Kaufpreis und dem Verkaufspreis von BTCUSDT ermitteln möchten, gehen Sie zuerst durch die Futures Market Matrix Manager 1.subscribe Tickers, und finden Sie heraus, ob Sie den Verkaufspreis von BTCUSDT Manager 1.subscribe Tickers[i].ask1 finden.
Ich liebe Jimmy.Ich meine die Differenz zwischen Futures und Aktien, nicht die Differenz zwischen Futures und Aktien; das Problem ist, dass es nicht möglich ist, den Kaufpreis und den Verkaufspreis der Aktien für die gleiche Transaktion zu erhalten. Zum Beispiel: Wie kann ich die Differenz zwischen dem Kaufpreis und dem Verkaufspreis von BTC USDT erhalten? Funktion GetBAspot ((syboml, tickerspot, BA) { für (var i = 0; i < tickerspot.length; i++) { Wenn Sie sich für einen anderen Anbieter entscheiden möchten, dann sollten Sie sich für einen anderen Anbieter entscheiden. Weiter }else Wenn Sie sich für einen anderen Anbieter entscheiden möchten, sollten Sie sich für einen anderen Anbieter entscheiden. Var bidspot=tickerspot[i].bid1 Var askspot=tickerspot[i].ask1 Wir sind hier. Wir sind hier. Wenn Sie eine Anmeldung vornehmen, dann geben Sie die Anmeldung an die Anmelder weiter. Wenn Sie eine Frage haben, dann geben Sie die Antwort. Wir sind hier. Die Funktion "main() { _.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")]))) Wir sind hier. Wir sind hier.
Die Erfinder quantifizieren - Kleine TräumeDas Konzept funktioniert, man kauft und verkauft und der Preis unterscheidet sich nicht.
Ich liebe Jimmy.Warum wurde der Quellcode für die Bilder, aus denen die Futures-Differenz des Artikels stammt, nicht veröffentlicht?
Die Erfinder quantifizieren - Kleine TräumeIch weiß nicht, was du meinst.
Ich liebe Jimmy.Ich sehe es, aber es gibt keine einheitliche Angabe der gleichen Transaktionspaare.
Die Erfinder quantifizieren - Kleine TräumeSie sehen in dem Code, dass es Daten gibt, die sagen, ob man kaufen oder verkaufen will.