FMZ
順序と位置の同期を達成するための1つの戦略で参照アカウントと同期アカウントを管理します. そして今日,私たちは別のデザインを試みます. FMZ Quant Trading Platformの強力な拡張 API インターフェースに基づいた注文同期管理システムを設計します.
先ほどの2つの順序と位置同期戦略には,いくつかの明らかな欠点があります.
解決策:
FMZOrder Synchronous Server
参照アカウントの所有者 (オーダーリーダー) に FMZ 拡張 API KEY (交換アカウントの API KEY ではないことに注意してください) と Order Synchronous Server real bot ID を提供してください.
参照アカウント所有者 (注文フォロワー) が本物ボット (Order Synchronization Management System Class Library (Single Server)
この記事で設計されたシステムで) 信号を送信すると,同期アカウント所有者の実際のボットが取引信号を受け取り,次の注文を自動的にします.
Order Synchronization Management System Class Library (Single Server)
この記事で設計されたシステムにおける戦略) で,参照アカウントの所有者 (オーダーリーダー) は,このテンプレートクラスライブラリを直接自分の戦略に組み込み,順序と位置の同期機能を達成することができます.システムには2つの部分があります.
デザインを始めましょう!
これは戦略ではないことに注意してください. これは FMZ のテンプレートクラスライブラリです. テンプレートクラスライブラリの概念は FMZ API ドキュメンテーションで検索できます.
テンプレートクラスのライブラリコード:
// Global variables
var keyName_label = "label"
var keyName_robotId = "robotId"
var keyName_extendAccessKey = "extendAccessKey"
var keyName_extendSecretKey = "extendSecretKey"
var fmzExtendApis = parseConfigs([config1, config2, config3, config4, config5])
var mapInitRefPosAmount = {}
function parseConfigs(configs) {
var arr = []
_.each(configs, function(config) {
if (config == "") {
return
}
var strArr = config.split(",")
if (strArr.length != 4) {
throw "configs error!"
}
var obj = {}
obj[keyName_label] = strArr[0]
obj[keyName_robotId] = strArr[1]
obj[keyName_extendAccessKey] = strArr[2]
obj[keyName_extendSecretKey] = strArr[3]
arr.push(obj)
})
return arr
}
function getPosAmount(pos, ct) {
var longPosAmount = 0
var shortPosAmount = 0
_.each(pos, function(ele) {
if (ele.ContractType == ct && ele.Type == PD_LONG) {
longPosAmount = ele.Amount
} else if (ele.ContractType == ct && ele.Type == PD_SHORT) {
shortPosAmount = ele.Amount
}
})
var timestamp = new Date().getTime()
return {ts: timestamp, long: longPosAmount, short: shortPosAmount}
}
function sendCommandRobotMsg (robotId, accessKey, secretKey, msg) {
// https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"ok12345"]
var url = "https://www.fmz.com/api/v1?access_key=" + accessKey + "&secret_key=" + secretKey + "&method=CommandRobot&args=[" + robotId + ',"' + msg + '"]'
Log(url)
var ret = HttpQuery(url)
return ret
}
function follow(nowPosAmount, symbol, ct, type, delta) {
var msg = ""
var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
if (delta > 0) {
// open the position
var tradeDirection = type == PD_LONG ? "buy" : "sell"
// send signals
msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
} else if (delta < 0) {
// close the position
var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
if (nowAmount <= 0) {
Log("no positions found")
return
}
// send signals
msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
} else {
throw "error"
}
if (msg) {
_.each(fmzExtendApis, function(extendApiConfig) {
var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg)
Log("call the CommandRobot interface, ", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret)
Sleep(1000)
})
}
}
$.PosMonitor = function(exIndex, symbol, ct) {
var ts = new Date().getTime()
var ex = exchanges[exIndex]
// judge the type of ex
var exName = ex.GetName()
var isFutures = exName.includes("Futures_")
var exType = isFutures ? "futures" : "spot"
if (!isFutures) {
throw "only future-following is supported"
}
if (exType == "futures") {
// caching symbol ct
var buffSymbol = ex.GetCurrency()
var buffCt = ex.GetContractType()
// switch to the corresponding contract pair, contract code
ex.SetCurrency(symbol)
if (!ex.SetContractType(ct)) {
throw "SetContractType failed"
}
// monitor positions
var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct // refPos-exIndex-symbol-contractType
var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
if (!initRefPosAmount) {
// no initialization data, initialize it
mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
}
// monitor
var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
// calculate the position changes
var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short
// detect changes
if (!(longPosDelta == 0 && shortPosDelta == 0)) {
// Perform long positions
if (longPosDelta != 0) {
Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform long position-following, changes in volume:", longPosDelta)
follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
}
// Perform short positions
if (shortPosDelta != 0) {
Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform short position-following, changes in volume:", shortPosDelta)
follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
}
// Update after performing the order-following operation
mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
}
// restore symbol ct
ex.SetCurrency(buffSymbol)
ex.SetContractType(buffCt)
} else if (exType == "spot") {
// Spots
}
}
$.getTbl = function() {
var tbl = {
"type" : "table",
"title" : "synchronization of data",
"cols" : [],
"rows" : []
}
// construct the table headers
tbl.cols.push("monitor the account: refPos-exIndex-symbol-contractType")
tbl.cols.push(`monitor the position: {"timestamp":xxx,"long positions":xxx,"short positions":xxx}`)
_.each(fmzExtendApis, function(extendApiData, index) {
tbl.cols.push(keyName_robotId + "-" + index)
})
// Write data in
_.each(mapInitRefPosAmount, function(initRefPosAmount, key) {
var arr = [key, JSON.stringify(initRefPosAmount)]
_.each(fmzExtendApis, function(extendApiData) {
arr.push(extendApiData[keyName_robotId])
})
tbl.rows.push(arr)
})
return tbl
}
// Example of the strategy call that references the template class library
function main() {
// Clear all logs
LogReset(1)
// Switch to OKEX demo to test
exchanges[0].IO("simulate", true)
// Set the contract
exchanges[0].SetCurrency("ETH_USDT")
exchanges[0].SetContractType("swap")
// Timed trading interval
var tradeInterval = 1000 * 60 * 3 // Trade for every three minutes to observe the order-following signals
var lastTradeTS = new Date().getTime()
while (true) {
// Other logic of the strategy...
// Simulated trading triggers for testing
var ts = new Date().getTime()
if (ts - lastTradeTS > tradeInterval) {
Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
exchanges[0].SetDirection("buy")
exchanges[0].Buy(-1, 1)
lastTradeTS = ts
}
// Interface functions that use templates
$.PosMonitor(0, "ETH_USDT", "swap") // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy
var tbl = $.getTbl()
// Display status bar
LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
FMZ プラットフォームのプログラミング取引戦略が FMZ のテンプレートクラスライブラリを参照するときに,Order Synchronization Management System Class Library (Single Server)
戦略は次の関数を使うことができます.
$ PosMonitor について この機能の目的は,戦略内の交換オブジェクトの位置変化を監視し,その後,テンプレートのパラメータに設定された実際のボット市場に取引信号を送信することです: Order Synchronization Management Systemクラスライブラリ (シングルサーバー).
$$$$$$$ 監視した同期データに戻る
この例は,main
Order Synchronization Management System Class Library (Single Server) テンプレートの関数について
// Example of the strategy call that references the template class library
function main() {
// Clear all logs
LogReset(1)
// Switch to OKEX demo to test
exchanges[0].IO("simulate", true)
// Set the contract
exchanges[0].SetCurrency("ETH_USDT")
exchanges[0].SetContractType("swap")
// Timed trading interval
var tradeInterval = 1000 * 60 * 3 // Trade for every three minutes to observe the order-following signals
var lastTradeTS = new Date().getTime()
while (true) {
// Other logic of the strategy...
// Simulated trading triggers for testing
var ts = new Date().getTime()
if (ts - lastTradeTS > tradeInterval) {
Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
exchanges[0].SetDirection("buy")
exchanges[0].Buy(-1, 1)
lastTradeTS = ts
}
// Interface functions by using templates
$.PosMonitor(0, "ETH_USDT", "swap") // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy
var tbl = $.getTbl()
// Display status bar
LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
テンプレートクラスのライブラリでは,テンプレートのテストなど,テンプレートクラスのライブラリをテストするために通常使用される戦略リアルボットも作成できます.main
テンプレート内の関数はmain
自分の戦略の一つの機能です.
テストコードは,OKEX デモを使用してテストするように書かれています. FMZ の OKEX デモ API KEY を参照アカウント (オーダーリード) として設定し,メイン機能でデモに切り替えるようになります. その後,取引ペアを ETH_USDT に設定し,契約をスワップに設定します. その後,一時ループに入ります.ループでは,戦略取引のトリガーシミュレーションのために 3 分ごとに注文が表示されます.$.PosMonitor(0, "ETH_USDT", "swap")
この関数の最初のパラメータは0に転送され,これはThES交換オブジェクト交換を監視することを意味します[0], ETH_USDT取引ペア,スワップ契約を監視します.$.getTbl()
グラフ情報を得るにはLogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
状態バーに表示されるチャートデータを作ります
特定の種の位置を監視する能力を持つことができます. そして,位置変更を使用してメッセージを送信します.$.PosMonitor(0, "ETH_USDT", "swap")
モデルを参照する戦略で.
戦略パラメータの設計について説明します.Order Synchronization Management System Class Library (Single Server)
わかった
テンプレートのインターフェース関数を使って 戦略をアップグレードして オーダーリード機能を持つ方法について話しました. ポジションが変わると送信される信号はどうですか? 誰に送られますか?
送る相手の質問は,Order Synchronization Management System Class Library (Single Server)
.
設定文字列フォーマット: label,robotId,accessKey,secretKey. 設定文字列形式: label,robotId,accessKey,secretKey. 設定文字列形式: label,robotId,accessKey,secretKey.
ラベル 同期アカウントのラベル,任意に設定できる名前を持つアカウントのラベルを設定するために使用されます.
ロボット
ロボットのIDはOrder Synchronous Server
本物のボットで 同期アカウントの所有者が作成しました
アクセスKey FMZ の拡張 API アクセスキー
秘密キー FMZ の拡張 API 秘密キー
注文同期管理システム (同期サーバー) の一時コード:
function main() {
LogReset(1)
while (true) {
var cmd = GetCommand()
if (cmd) {
// cmd: ETH_USDT,swap,buy,1
Log("cmd: ", cmd)
}
Sleep(1000)
}
}
このメッセージが受信されました.ETH_USDT,swap,buy,1
わかった
取引の方向性,情報量に基づいて,次のステップで自律的な順序を設定します.
これまでのところ,Order Synchronization Management System (Synchronous Server)
そのデザインを次の号で 探求していきます.