最近,FMZ公式グループで議論されているマルティンゲール戦略は多く,プラットフォーム上の仮想通貨契約のマルティンゲール戦略はあまり多くありません.したがって,この機会を利用して,仮想通貨先物向けにシンプルなマルティンゲール戦略を設計しました.なぜマルティンゲール戦略と呼ばれるのでしょうか.マルティンゲール戦略の潜在的なリスクは確かに小さいので,マルティン戦略に従って正確に設計されていません.しかし,このタイプの戦略にはまだ多くのリスクがあり,マルティン型戦略のパラメータ設定はリスクと密接に関連しており,リスクは無視すべきではありません.
この記事では,主にマーティン型戦略の設計について説明し,学びます.戦略のアイデアが非常に明確であるため,FMZのユーザーとして,戦略設計をより考慮します.
仮想通貨先物戦略を設計する際に,総資本はしばしば使用されます.これは,特に浮動的収益を計算する必要があるとき,リターンが計算されなければならないためです.ポジションがマージンで占拠されているため,待機中のオーダーも占拠されています.この時点で,APIインターフェースは,リターンを計算します.exchange.GetAccount()
FMZプラットフォームの利用可能な資産と待機中の注文凍結資産を取得するために呼び出されています. 実際,ほとんどの仮想通貨先物取引所は総資本のデータを提供していますが,この属性はFMZに均一にパッケージされていません.
異なる情報交換によって データを取得する機能を設計します
// OKEX V5 obtain total equity
function getTotalEquity_OKEX_V5() {
var totalEquity = null
var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
if (ret) {
try {
totalEquity = parseFloat(ret.data[0].details[0].eq)
} catch(e) {
Log("failed to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
// Binance futures
function getTotalEquity_Binance() {
var totalEquity = null
var ret = exchange.GetAccount()
if (ret) {
try {
totalEquity = parseFloat(ret.Info.totalWalletBalance)
} catch(e) {
Log("failed to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
についてtotalEquity
呼び出し入力として関数を書いて, 交換の名前に従って対応する関数を呼び出します.
function getTotalEquity() {
var exName = exchange.GetName()
if (exName == "Futures_OKCoin") {
return getTotalEquity_OKEX_V5()
} else if (exName == "Futures_Binance") {
return getTotalEquity_Binance()
} else {
throw "This exchange is not supported"
}
}
主な機能と主論理を設計する前に 準備をし 補助機能を設計する必要があります
すべての現在待機中の注文をキャンセル
function cancelAll() {
while (1) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
exchange.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
Sleep(500)
}
}
この機能は,FMZ戦略スクエア上の戦略例コードをよく読む人に馴染みがあり,多くの戦略が同様のデザインを使用しています.機能は,現在の待機順序リストを取得し,それらを一つずつキャンセルすることです.
フューチャーへの投資
function trade(distance, price, amount) {
var tradeFunc = null
if (distance == "buy") {
tradeFunc = exchange.Buy
} else if (distance == "sell") {
tradeFunc = exchange.Sell
} else if (distance == "closebuy") {
tradeFunc = exchange.Sell
} else {
tradeFunc = exchange.Buy
}
exchange.SetDirection(distance)
return tradeFunc(price, amount)
}
function openLong(price, amount) {
return trade("buy", price, amount)
}
function openShort(price, amount) {
return trade("sell", price, amount)
}
function coverLong(price, amount) {
return trade("closebuy", price, amount)
}
function coverShort(price, amount) {
return trade("closesell", price, amount)
}
フューチャー取引には4つの方向性があります. openLong, openShort, coverLong andcoverShort. したがって,これらの操作に対応する4つのオーダー関数を設計しました. オーダーのみを考えると,方向性,オーダー価格,オーダーボリュームなどいくつかの必要要素があります.
この関数にはtrade
操作を処理するためにdistance
, price
, amount
指定されている.
函数 openLong, openShort, coverLong と coverShort を呼び出すことは,最終的にtrade
つまり 既定の距離,価格,数量に基づいて フューチャー取引所に注文を出すことです
戦略のアイデアは非常にシンプルで,現在の価格をベースラインとして取り,特定の距離上下でセール (ショート) と買い (ロング) の注文をします.取引が完了すると,残りのすべての注文はキャンセルされ,その後にポジションの価格に応じて特定の距離で新しい閉じるオーダーが配置され,更新された現在の価格で増加オーダーが配置されますが,追加のポジションのオーダーボリュームは倍になることはありません.
初期作業 2つのグローバル変数が必要で 注文を記録します
var buyOrderId = null
var sellOrderId = null
OKEX_V5シミュレーションボットオプションを使用するように設計されているため,コードにいくつかの処理を行う必要があります.
var exName = exchange.GetName()
// Switch OKEX V5 simulated bot
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
インターフェースパラメータのすべての情報をリセットするオプションもありますので,対応する処理がコードに含まれます.
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
永久契約のみです 書き込みはここに固定され 永久のみに設定されています
exchange.SetContractType("swap")
また,注文価格と注文金額の正確性についても考慮する必要があります.正確性が正しく設定されていない場合,戦略計算プロセス中に正確性が失われます.データが多くの小数点を持つ場合,取引インターフェースによって注文が拒否されるのは簡単です.
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set precision", pricePrecision, amountPrecision)
デザインによる単純なデータ復元
if (totalEq == -1 && !IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "failed to obtain initial equity"
}
} else {
totalEq = recoverTotalEq
}
}
戦略が実行されているとき,あなたはパラメータを設定することができますtotalEq
. このパラメータが -1 に設定されている場合,戦略は保存された総株式データを読み取る. 保存された総株式データがない場合,現在の読み取られた総株式は,進行中の戦略の初期総株式として使用されます. その後,総株式の増加は利益を示し,総株式減少は損失を示します. 総株式データが読み取られた場合,戦略はこのデータで実行し続けます.
主な論理 初期作業が完了した後,最終的に戦略の主要な論理部分にたどり着きました.説明の便利のために,私はコードコメントに直接指示を書きました.
while (1) { // The main logic of the strategy is designed as an infinite loop
var ticker = _C(exchange.GetTicker) // Read the current market information first, mainly using the latest transaction price
var pos = _C(exchange.GetPosition) // Read current position data
if (pos.length > 1) { // Judging the position data, because of the logic of this strategy, it is unlikely that long and short positions will appear at the same time, so if there are long and short positions at the same time, an error will be thrown
Log(pos)
throw "Simultaneous long and short positions" // Throw an error to stop the strategy
}
//Depends on status
if (pos.length == 0) { // Make different operations according to the position status, when there is no position, pos.length == 0
// If you have not held a position, count the profit once
if (!IsVirtual()) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
LogProfit(currTotalEq - totalEq, "current total equity:", currTotalEq)
}
}
buyOrderId = openLong(ticker.Last - targetProfit, amount) // Open a buy order for a long position
sellOrderId = openShort(ticker.Last + targetProfit, amount) // Open a short sell order
} else if (pos[0].Type == PD_LONG) { // For long positions, the position and quantity of pending orders are different
var n = 1
var price = ticker.Last
buyOrderId = openLong(price - targetProfit * n, amount)
sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
} else if (pos[0].Type == PD_SHORT) { // For short positions, the position and quantity of pending orders are different
var n = 1
var price = ticker.Last
buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
sellOrderId = openShort(price + targetProfit * n, amount)
}
if (!sellOrderId || !buyOrderId) { // If one side of the pending order fails, cancel all pending orders and start over
cancelAll()
buyOrderId = null
sellOrderId = null
continue
}
while (1) { // The pending order is completed, start monitoring the order
var isFindBuyId = false
var isFindSellId = false
var orders = _C(exchange.GetOrders)
for (var i = 0 ; i < orders.length ; i++) {
if (buyOrderId == orders[i].Id) {
isFindBuyId = true
}
if (sellOrderId == orders[i].Id) {
isFindSellId = true
}
}
if (!isFindSellId && !isFindBuyId) { // Detected that both buy and sell orders have been filled
cancelAll()
break
} else if (!isFindBuyId) { // Detected buy order closing
Log("buy order closing")
cancelAll()
break
} else if (!isFindSellId) { // Detected sell order closing
Log("sell order closing")
cancelAll()
break
}
LogStatus(_D())
Sleep(3000)
}
Sleep(500)
}
論理と設計が説明されています
5月19日の市場を通過させてください
マルティンゲール戦略には リスクがまだあることがわかります
オケックス V5 シミュレーションボットで実行できます
戦略アドレス:https://www.fmz.com/strategy/294957
戦略は主に学習のために使用され,実際のお金は慎重に使用されるべきです~!