FMZ量化取引プラットフォーム戦略的な枠組この記事では,取引所の集約市場インターフェースを使用して多種戦略を構築する方法について説明します. 取引所の集約市場インターフェイスを使用して多種戦略を構築する方法について説明します.
この2つの取引所をリストし,APIのドキュメントを見てみると,すべての取引所が集約された市場インターフェースを持っていることがわかります.
金融取引:https://fapi.binance.com/fapi/v1/ticker/bookTickerインタフェースがデータ返却
[
{
"symbol": "BTCUSDT", // 交易对
"bidPrice": "4.00000000", //最优买单价
"bidQty": "431.00000000", //挂单量
"askPrice": "4.00000200", //最优卖单价
"askQty": "9.00000000", //挂单量
"time": 1589437530011 // 撮合引擎时间
}
...
]
コイン現金:https://api.huobi.pro/market/tickersインタフェースがデータ返却
[
{
"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
},
...
]
しかし,実際はそうではなく,トークンインターフェースが実際に返ってくる構造は,
{
"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
}, ...]
}
インタフェースが返したデータを処理する際には注意が必要です.
この2つのインターフェースを戦略的にどのように包み込むか? ゆっくりと一緒にやってください.
制御オブジェクトを構成するコンストラクター関数を書きます.
// 参数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
}
FMZのAPI関数を使用するHttpQuery
交換インターフェースにアクセスするリクエストを送信する機能.HttpQuery
異常処理が必要な場合try...catch
インターフェースの返信失敗などの異常を処理します.
bidPrice
仮想通貨は,bid
。
特殊処理の部分を分離するために,呼び戻し関数で解く.
このオブジェクトを初期化すると,特定の用途では以下のようになります.
(次のコードでは,コンストラクター関数が省略されています)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) {
// 更新行情数据
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)
}
}
テストを実行する: 最初の取引所対象は,コイン・アンの先物を追加し,第2取引所対象は,トークン・現物を追加します.
インターフェースから返されるデータをどのように取り出すかなどの操作が,返却関数を使用して,異なる取引所の特化処理を行うことが見えます.
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
資産の取得方法を追加
// 更新资产
self.updateAcc = function(callBackFuncGetAcc) {
var ret = callBackFuncGetAcc(self)
if (!ret) {
return false
}
self.accData = ret
return true
}
また,交換インターフェイスが返信するフォーマットにより,フィールド名付けが異なるため,ここでも返信関数の特化処理を使用する必要があります.
トークン現金,コイン安貨を例に挙げると,返却関数は次のように書ける.
// 获取账户资产的回调函数
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
}
事件について:
資産:
市場データにアクセスすると,各品種の差を計算し,複数の取引対の期日差をモニターすることができます. 投資家は,投資のコストを削減し,投資のコストを削減し,投資のコストを削減する.
このデザインは,他の取引所に拡大し,興味のある同級生が試すことができます.
ジミーを愛してるアセット内のcallBackFuncGetAccは参数か関数か?また,アセットアカウントの2つのコールバック関数 callBackFuncGetHuobiAccと callBackFuncGetFutures_BinanceAccは,callBackFuncGetAccと何の関係があるのでしょうか?
ジミーを愛してる取引相手の現金Bid1と先物Ask1の価格を同時に抽出するにはどうすればよいですか?
スルティム素晴らしい
発明者 量化 - 微かな夢百度リコール関数.
発明者 量化 - 微かな夢この2つの回路は互いに絡み合っている.
発明者 量化 - 微かな夢この記事では,現貨と先物価格の差について説明します. 統計は全てあるが,具体的にはどうするか,あなたはそれを減算するか?
ジミーを愛してるもしBTCUSDTの現貨買取価格とBTCUSDTの現貨売出価格の差値を得たいなら:まず,先行市場数组Manager1.subscribeTickersを閲覧し,BTCUSDTの売出価格Manager1.subscribeTickers[i].ask1を見つけます.問題は,先行市場数组を閲覧するときに,現貨BTCUSDTのbid1価格をどのように抽出するかです.
ジミーを愛してる私は,先物と現貨の差を意味している. 未来物や現貨の買出と売出の差ではなく,同じ取引の先物と現貨の買出と売出の両方を同時に取得できないという問題です. 例えば:BTCUSDTの現貨と現貨の買出と売出の差をどのように取得する? 私は,次のコードの問題がどこから来ているのかわからないことを書きました. 機能 GetBAspot ((syboml,tickerspot,BA) { は,この関数で表示される. for (var i = 0; i < tickerspot.length; i++) { if ((tickerspot[i].syboml!==syboml) {) について 続きを読む {a1pos (114,268) } if ((tickerspot[i].syboml===syboml) { チェックインする var bidspot=tickerspot[i].bid1 ポイントは1つ var askspot=tickerspot[i].ask1 チェックインする {cH00ffff} {cH00ffff} if ((BA==="bid") return bidspot 返品する if ((BA==="ask") return askspot 返信する 返信する {cH00ffff} この関数で, _.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") ")) ]) について説明しています. (笑) {cH00ffff}
発明者 量化 - 微かな夢この特定の書き込みは行われ,買ったり売ったりして,価格の差は互いを減らしたりしません.
ジミーを愛してるこの記事の画像のソースコードはなぜ公開されていないのか?
発明者 量化 - 微かな夢ブログに載っているのは,
ジミーを愛してるしかし,同じトランザクションのペアを統一して指定していません.
発明者 量化 - 微かな夢買って売って,買って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って,売って.