仮想通貨先物向けマルティンゲール戦略設計

作者: リン・ハーンリディア, 作成日:2022-08-04 15:41:45, 更新日:2023-09-21 21:10:49

img

仮想通貨先物向けマルティンゲール戦略設計

最近,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日の市場を通過させてください

img

img

マルティンゲール戦略には リスクがまだあることがわかります

オケックス V5 シミュレーションボットで実行できます

戦略アドレス:https://www.fmz.com/strategy/294957

戦略は主に学習のために使用され,実際のお金は慎重に使用されるべきです~!


関連性

もっと