Martingale-Strategieentwurf für Kryptowährungs-Futures

Schriftsteller:Lydia., Erstellt: 2022-08-04 15:41:45, Aktualisiert: 2023-09-21 21:10:49

img

Martingale-Strategieentwurf für Kryptowährungs-Futures

Vor kurzem wurden in der offiziellen FMZ-Gruppe viele Martingale-Strategien diskutiert, und es gibt nicht viele Martingale-Strategien von Kryptowährungsverträgen auf der Plattform. Daher nutzte ich diese Gelegenheit, um eine einfache Martingale-Strategie für Kryptowährungs-Futures zu entwerfen. Warum wird sie eine Martingale-Strategie genannt? Weil die potenziellen Risiken der Martin-Strategie in der Tat nicht klein sind, ist sie nicht genau nach der Martin-Strategie konzipiert. Diese Art von Strategie hat jedoch immer noch viele Risiken, und die Parameter-Einstellungen der Martin-Art-Strategie hängen eng mit dem Risiko zusammen, und das Risiko sollte nicht ignoriert werden.

Dieser Artikel erläutert hauptsächlich und lernt aus dem Design von Martin-artigen Strategien. Da die Strategieidee sehr klar ist, betrachten wir als Benutzer von FMZ das Strategiedesign mehr.

Erhalten von Gesamtkapital

Das Gesamtkapital wird häufig bei der Gestaltung von Kryptowährungs-Futures-Strategien verwendet. Dies liegt daran, dass die Renditen berechnet werden müssen, insbesondere wenn Sie schwimmende Renditen berechnen müssen. Da die Position mit Marge besetzt ist, wird auch die ausstehende Order besetzt. Zu diesem Zeitpunkt wird die API-Schnittstelleexchange.GetAccount()In der Tat liefern die meisten Kryptowährungs-Futures-Börsen die Daten des Gesamtkapitals, aber dieses Attribut ist nicht einheitlich auf FMZ verpackt.

Wir entwerfen also Funktionen, um diese Daten nach verschiedenen Austausch zu erhalten:

// 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
}

DietotalEquityDann schreiben wir eine Funktion als Call-Eintrag und rufen die entsprechende Funktion nach dem Namen der Börse an.

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"
    }
}

Entwerfen von Hilfsfunktionen

Bevor wir die Hauptfunktion und die Hauptlogik entwerfen, müssen wir einige Vorbereitungen treffen und einige Hilfsfunktionen entwerfen.

  • Alle laufenden Bestellungen stornieren

    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)
        }
    }
    

    Diese Funktion ist denen bekannt, die oft den Strategiebeispielcode auf dem FMZ-Strategie-Feld lesen, und viele Strategien haben ähnliche Designs verwendet.

  • Positionsgeschäfte für Futures

    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)
    }
    

    Es gibt vier Richtungen für den Futures-Handel: openLong, openShort, coverLong und coverShort. Also haben wir vier Auftragsfunktionen entworfen, die diesen Operationen entsprechen. Wenn Sie nur die Order betrachten, dann gibt es mehrere notwendige Faktoren: Richtung, Auftragspreis und Auftragsvolumen. Also haben wir auch eine Funktion namens:tradeUm die Operation zu bearbeiten, wenndistance, price, amountsind spezifiziert. Die Funktionsanrufe auf openLong, openShort, coverLong und coverShort werden letztendlich durch dentradeFunktion, d. h. Aufgabe einer Bestellung an einer Futures-Börse auf der Grundlage der festgelegten Entfernung, des Preises und der Menge.

Hauptfunktion

Die Strategieidee ist sehr einfach, nehmen Sie den aktuellen Preis als Basislinie und platzieren Sie Verkaufs- (Short) und Kauf- (Long) Aufträge auf einer bestimmten Entfernung nach oben oder unten. Sobald die Transaktion abgeschlossen ist, werden alle verbleibenden Aufträge storniert, und dann wird eine neue Schließorder an einer bestimmten Entfernung nach dem Preis der Position platziert, und eine Erhöhungsorder wird zum aktualisierten aktuellen Preis platziert, aber das Auftragsvolumen wird nicht für zusätzliche Positionen verdoppelt.

  • Erste Arbeiten Aufgrund des ausstehenden Auftrags brauchen wir zwei globale Variablen, um die Auftrags-ID aufzuzeichnen.

    var buyOrderId = null
    var sellOrderId = null
    

    Dann sind die Strategie-Schnittstellenparameter so konzipiert, dass sie die OKEX_V5 simulierte Bot-Option verwenden, so dass einige Verarbeitungen im Code durchgeführt werden müssen:

    var exName = exchange.GetName()    
    // Switch OKEX V5 simulated bot
    if (isSimulate && exName == "Futures_OKCoin") {
        exchange.IO("simulate", true)
    }
    

    Es gibt auch die Möglichkeit, alle Informationen in den Schnittstellenparametern zurückzusetzen, sodass die entsprechende Verarbeitung im Code erfolgen sollte:

    if (isReset) {
        _G(null)
        LogReset(1)
        LogProfitReset()
        LogVacuum()
        Log("reset all data", "#FF0000")
    }
    

    Wir führen nur dauerhafte Verträge, also ist die Schrift hier fixiert und nur auf dauerhaft eingestellt.

    exchange.SetContractType("swap")
    

    Dann müssen wir auch die Genauigkeit des Auftragspreises und des Auftragsbetrags berücksichtigen. Wenn die Genauigkeit nicht ordnungsgemäß eingestellt ist, geht die Genauigkeit während des Strategieberechnungsvorgangs verloren. Wenn die Daten eine große Anzahl von Dezimalstellen haben, kann es leicht sein, dass die Bestellung von der Austauschoberfläche abgelehnt wird.

    exchange.SetPrecision(pricePrecision, amountPrecision)
    Log("set precision", pricePrecision, amountPrecision)
    

    Einfache Datenwiederherstellung durch Design

    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
        }
    }
    

    Wenn Sie das anfängliche Gesamtkapital des Kontos angeben möchten, wenn die Strategie ausgeführt wird, können Sie den ParametertotalEq. Wenn dieser Parameter auf -1 gesetzt ist, wird die Strategie die gespeicherten Gesamtkapitaldaten auslesen. Wenn keine gespeicherten Gesamtkapitaldaten vorliegen, wird das aktuelle gelesenen Gesamtkapital als das anfängliche Gesamtkapital der laufenden Strategie verwendet. Danach zeigt eine Erhöhung des Gesamtkapitals einen Gewinn an und eine Abnahme des Gesamtkapitals einen Verlust an. Wenn die Gesamtkapitaldaten gelesen werden, wird die Strategie weiterhin mit diesen Daten ausgeführt.

  • Hauptlogik Nach der ersten Arbeit sind wir endlich zum logischen Teil der Strategie gekommen.

      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)
      }
    

Die ganze Logik und das Design werden erklärt.

Zurückprüfung

Lassen Sie die Strategie durch einen Markt am 19. Mai gehen.

img

img

Es ist zu sehen, daß die Martingale-Strategie noch gewisse Risiken birgt.

Der echte Bot kann mit dem OKEX V5 Simulationsbot ausgeführt werden

Strategieadresse:https://www.fmz.com/strategy/294957

Strategien werden hauptsächlich zum Lernen verwendet, und echtes Geld sollte mit Vorsicht verwendet werden~!


Verwandt

Mehr