avatar of 发明者量化-小小梦 发明者量化-小小梦
konzentrieren Sie sich auf Private Nachricht
4
konzentrieren Sie sich auf
1271
Anhänger

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Erstellt in: 2021-07-30 16:36:48, aktualisiert am: 2023-09-20 10:36:43
comments   5
hits   2474

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Im vorherigen Artikel haben wir eine einfache Absicherungsstrategie implementiert. Als Nächstes erfahren wir, wie man diese Strategie erweitert. Die Strategieänderungen werden nicht groß sein, aber die Einzelheiten der Änderungen erfordern Aufmerksamkeit. Die Definitionen einiger Teile im Code haben sich gegenüber früher geändert und müssen verstanden werden.

Die Notwendigkeit einer Modernisierung dieser Strategie

  • Wechseln Sie den Hebelmodus des Spot-Exchange-Objekts Diese Änderung betrifft nur den realen Handel. Einige Spotbörsen verfügen über Spot-Leverage-Schnittstellen, die ebenfalls auf FMZ gekapselt sind. Bei Tauschobjekten, die direkt auf FMZ gekapselt wurden und Spot-Hebelwirkung unterstützen, können Sie den Modus direkt umschalten.
  • Spread-Chart-Anzeige hinzugefügt Fügen Sie die Spread-Chart-Anzeige hinzu, da nur gezeichnet wirdA交易所->B交易所B交易所->A交易所Zeichnen Sie die horizontale Linie, die die Ausbreitung auslöst. Wir verwenden direkt画线类库Der Vorteil ist, dass es einfach und leicht zu bedienen ist. Hier erfahren Sie auch, wie Sie FMZ verwenden模版类库Funktion.
  • Einweg-Hedging-Funktion Diese Änderung ist ziemlich bedeutsam, da es schwierig ist, den Preisunterschied zwischen den beiden Börsen in bestimmten Absicherungsgeschäften vollständig umzukehren. Meistens ist der Preis an einer Börse durchweg höher als der Preis an einer anderen Börse. Wenn zu diesem Zeitpunkt alle unsere Vermögenswerte abgesichert sind (d. h. die Münzen befinden sich alle an den Börsen mit niedrigen Preisen und das gesamte Geld befindet sich an den Börsen mit hohen Preisen). Das Hedging ist zum Erliegen gekommen und man kann sich nicht mehr auf Preisschwankungen verlassen, um Gewinne zu erzielen. Zu diesem Zeitpunkt muss die Strategie so sein, dass Sie ein wenig Geld verlieren können, um die Münzen wieder abzusichern (die Münzen wieder in einer Börse mit einem hohen Preis existieren zu lassen), und dann können Sie weiter absichern und Gewinne erzielen, wenn der Preis Der Unterschied wird wieder größer.
  • Interaktives Ändern von Parametern wie Hedging-Spread-Linien Fügen Sie der Strategie interaktive Funktionen hinzu, und Sie können die Spread-Triggerlinie in Echtzeit ändern.
  • Organisieren Sie die Statusleisteninformationen und zeigen Sie sie in Tabellenform an Organisieren Sie die anzuzeigenden Daten für eine einfache Beobachtung.

Als nächstes implementieren wir diese Designs nacheinander.

Wechseln Sie den Hebelmodus des Spot-Exchange-Objekts

Am Beispiel des Binance Spothandels wechseln Sie mit dem Code in den Spot Leverage-Modusexchanges[i].IO, Parameter übergebentrade_normalWechseln Sie zu Leveraged Position-by-Position und geben Sie intrade_super_marginWechseln Sie zur gehebelten Vollposition, Backtesting wird nicht unterstützt. Dies wird nur im realen Handel verwendet.

existierenmainFügen Sie am Anfang der Funktion folgende Vorbereitungsphase hinzu:

    // 切换杠杆模式
    for (var i = 0 ; i < exchanges.length ; i++) {   // 遍历检测所有添加的交易所对象
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   // 如果当前i索引代表的交易所对象是币安现货,并且策略界面参数marginType选择的不是「普通币币」选项,执行切换
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "设置为杠杆逐仓")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "设置为杠杆全仓")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

Die Strategie hier fügt lediglich den Code zum Umschalten des Coin-to-Coin-Hebelmodus für Binance Spot hinzu, sodass der in den Strategieparametern festgelegte Schalter nur für Binance Spot gültig ist.

Spread-Chart-Anzeige hinzugefügt

Die Verwendung der mitgelieferten Zeichenvorlagen ist ganz einfach. Die von uns verwendete Vorlage heißt画线类库. Suchen und beziehen können Sie es direkt auf der FMZ-Plattform StrategiePlatz.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Oder klicken Sie direkt auf den Link: https://www.fmz.com/strategy/27293, um zur Kopierseite dieser Vorlage zu springen.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Klicken Sie auf die Schaltfläche, um diese Vorlagenbibliothek in Ihre eigene Strategiebibliothek zu kopieren.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Anschließend können Sie auf der Seite zur Richtlinienbearbeitung in der Vorlagenspalte die benötigte Vorlagenbibliothek überprüfen. Nachdem Sie das Kontrollkästchen aktiviert und die Richtlinie gespeichert haben, verweist diese Richtlinie auf diese Vorlage. Hier erklären wir nur kurz die Verwendung der Vorlagenbibliothek. Diese Strategie hat bereits auf diese Vorlage verwiesen, sodass der Vorgang nicht wiederholt werden muss. Nachdem Sie diese Strategie im Strategy Square kopiert haben, können Sie sie in der Vorlagenspalte der Strategiebearbeitungsseite sehen.画线类库Bereits zitiert.

Wir lernen vor allem den Umgang mit画线类库Funktion zum Zeichnen des Diagramms.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Wir planenA->BDer Preisunterschied,B->ADie Preisdifferenz und die Preisdifferenz-Auslöselinie werden eingezeichnet. Sie müssen zwei Kurven (die aktuelle Preisdifferenz von A nach B und von B nach A) und zwei horizontale Linien (Auslöselinien der Preisdifferenz) zeichnen, wie in der Abbildung oben dargestellt.

Weil wir eine einseitige Absicherung entwerfen müssen,A->BUndB->ADie Auslöseleitung ist unterschiedlich. Das Design im vorherigen Artikel kann nicht verwendet werden. Im vorherigen Artikel:

      var targetDiffPrice = hedgeDiffPrice
      if (diffAsPercentage) {
          targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
      }

Es gibt nur einen Trigger-SpreadtargetDiffPrice。 Hier müssen wir also den Code ändern, zuerst die Parameter ändern.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Ändern Sie dann den Code:

        var targetDiffPriceA2B = hedgeDiffPriceA2B
        var targetDiffPriceB2A = hedgeDiffPriceB2A
        if (diffAsPercentage) {
            targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
            targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
        }

Auf diese Weise ändert sich die Preisdifferenz-Triggerlinie von der vorherigentargetDiffPriceAus Eins wurden ZweitargetDiffPriceA2BtargetDiffPriceB2A。 Als Nächstes können Sie die Linienzeichnungsfunktion der Linienzeichnungsbibliothek verwenden, um diese Daten in das Diagramm zu zeichnen.

        // 画图
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // 该函数第一个参数是水平线在Y轴方向上的值,第二个参数是显示文本
        $.PlotHLine(targetDiffPriceB2A, "B->A")

Wenn die Strategie ausgeführt wird, wird ein Diagramm wie dieses angezeigt.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Zeichnen Sie als Nächstes die Echtzeit-Spread-Kurve, um ein Überzeichnen zu vermeiden. Fügen Sie den Code zum Zeichnen von Kurven mit Echtzeit-Preisdifferenzdaten in die Saldenprüfung ein.

        if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
            nowAccs = _C(updateAccs, exchanges)
            var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
            cancelAll()
            if (isBalance) {
                lastKeepBalanceTS = ts
                if (isTrade) {
                    var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
                    isTrade = false 
                }                
            }

            $.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price)  // 画实时差价曲线
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // 第一个参数是曲线名称,第二个参数是曲线当前时刻的值,即当前时刻Y轴方向上的值
        }

Auf diese Weise kann die Strategie mit nur 4 Zeilen Zeichencode während der Ausführung ein Diagramm anzeigen.

Einweg-Hedging-Funktion

Wie oben erwähnt, wurde die Preisdifferenz-Triggerlinie in zwei umgewandelt, die kontrollierenA->BDer Hedge-TriggerB->ADie Absicherung wird ausgelöst. Auf diese Weise kann der vorherige Orderpreisalgorithmus nicht verwendet werden, stattdessen wird die Methode Marktpreis plus Slippage verwendet.

        if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A -> B 盘口条件满足            
            var priceSell = depthA.Bids[0].Price - slidePrice
            var priceBuy = depthB.Asks[0].Price + slidePrice
            var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
            if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
                Log("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // 提示信息
                hedge(exB, exA, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        } else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) {   // B -> A 盘口条件满足
            var priceBuy = depthA.Asks[0].Price + slidePrice
            var priceSell = depthB.Bids[0].Price - slidePrice
            var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
            if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
                Log("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  // 提示信息
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

Da die Kauf- und Verkaufspreise in zwei Daten aufgeteilt werden, ist die Hedging-FunktionhedgeEs muss auch geändert werden.

function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
    var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
    var sellRoutine = sellEx.Go("Sell", priceSell, amount)
    Sleep(500)
    buyRoutine.wait()
    sellRoutine.wait()
}

Aufgrund dieser Änderungen gibt es auch einige kleinere Anpassungen, auf die ich hier nicht näher eingehen werde. Einzelheiten können Sie im Code nachlesen.

Interaktives Ändern von Parametern wie Hedging-Spread-Linien

Fügen Sie der Strategie Interaktivität hinzu, sodass die Strategie die Spread-Triggerlinie in Echtzeit ändern kann. Dies ist eine Designanforderung für eine halbautomatische Strategie, die hier auch als Lehrdemonstration umgesetzt wird. Das Design der Strategieinteraktion ist ebenfalls sehr einfach. Fügen Sie der Strategie zunächst auf der Strategiebearbeitungsseite interaktive Steuerelemente hinzu.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Es werden zwei Steuerelemente hinzugefügt, eines mit der Bezeichnung A2B und das andere mit der Bezeichnung B2A. Nachdem Sie einen Wert in das Steuereingabefeld eingegeben haben, klicken Sie auf die Schaltfläche auf der rechten Seite des Eingabefelds. Es wird sofort eine Anweisung an die Strategie gesendet, zum Beispiel: Geben Sie einen Wert in das Eingabefeld ein123aufA2BÜber diese Schaltfläche werden sofort Anweisungen an die Strategie gesendet.

A2B:123

Entwerfen Sie Code zur Interaktionserkennung und -verarbeitung im Strategiecode.

        // 交互
        var cmd = GetCommand()   // 每次循环执行到这里时,都检测有没有交互指令过来,没有则返回空字符串
        if (cmd) {               // 检测到有交互指令,例如:A2B:123
            Log("接收到命令:", cmd)
            var arr = cmd.split(":")   // 拆分出交互控件名称和输入框中的值,arr[0]就是A2B,arr[1]就是123
            if (arr[0] == "A2B") {     // 判断触发的交互控件是不是A2B
                Log("修改A2B的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // 修改触发差价线
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // 修改触发差价线
                }
            } else if (arr[0] == "B2A") {           // 检测到触发的控件是B2A     
                Log("修改B2A的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Organisieren Sie die Statusleisteninformationen und zeigen Sie sie in Tabellenform an

Sorgen Sie für eine übersichtlichere Organisation der Statusleistendaten und für eine einfachere Anzeige.

        var tbl = {
            "type" : "table", 
            "title" : "数据", 
            "cols" : ["交易所", "币", "冻结币", "计价币", "冻结计价币", "触发差价", "当前差价"], 
            "rows" : [], 
        }
        tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
        tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Backtesting

Backtesting ist nur ein Test der Strategie und eine vorläufige Erkennung von Funktionen. Viele Fehler können tatsächlich während der Backtesting-Phase ausgetestet werden. Den Backtest-Ergebnissen muss nicht allzu viel Aufmerksamkeit geschenkt werden. Die endgültige Strategie muss noch in einer realen Umgebung getestet werden.

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Gestaltung einer Spot-Hedging-Strategie für digitale Währungen (2)

Strategie-Quellcode: https://www.fmz.com/strategy/302834