Beispiel für die Gestaltung der dYdX-Strategie

Schriftsteller:Lydia., Erstellt: 2022-11-07 10:59:29, Aktualisiert: 2023-09-15 21:03:43

img

Als Reaktion auf die Nachfrage vieler Benutzer hat die FMZ-Plattform kürzlich auf dYdX zugegriffen, eine dezentrale Börse. Jemand, der Strategien hat, kann den Prozess des Erwerbs der digitalen Währung dYdX genießen. Ich wollte vor langer Zeit nur eine stochastische Handelsstrategie schreiben, es spielt keine Rolle, ob sie Gewinne erzielt. Als nächstes kommen wir zusammen, um eine stochastische Austauschstrategie zu entwerfen, egal ob die Strategie gut funktioniert oder nicht, wir lernen nur das Strategiedesign.

Gestaltung einer stochastischen Handelsstrategie

Lassen Sie uns einen Brainstorming haben! Es ist geplant, eine Strategie zu entwerfen, um Befehle zufällig mit zufälligen Indikatoren und Preisen zu platzieren. Befehle zu platzieren ist nichts anderes als lang oder kurz zu gehen, nur auf die Wahrscheinlichkeit zu wetten. Dann werden wir die zufällige Zahl 1 ~ 100 verwenden, um zu bestimmen, ob man lang oder kurz geht.

Bedingung für den Long-Term: zufällige Zahl 1 bis 50. Bedingung für den Shorting: zufällige Zahl 51~100.

So sind sowohl Long als auch Short 50 Zahlen. Als nächstes sollten wir darüber nachdenken, wie man die Position schließt, da es sich um eine Wette handelt, dann muss es ein Kriterium für Gewinn oder Verlust geben. Wir setzen ein Kriterium für festes Stop-Profit und Verlust in der Transaktion fest. Stop-Profit für den Gewinn, Stop-Loss für den Verlust. Was die Menge des Stop-Profits und Verlustes angeht, so ist es eigentlich der Einfluss der Gewinn-Verlust-Ratio, oh ja! Es beeinflusst auch die Gewinnrate! (Ist dieses Strategie-Design effektiv? Kann es als positive mathematische Erwartungen garantiert werden? Machen Sie es zuerst! (Nachher ist es nur zum Lernen, Forschung!)

Der Handel ist nicht kostenlos, es gibt genug Slippage, Gebühren usw., um unsere stochastische Handelsgewinnrate auf die Seite von weniger als 50% zu ziehen. Wie entwerfen wir es also kontinuierlich? Wie wäre es mit dem Entwurf eines Multiplikators, um die Position zu erhöhen? Da es sich um eine Wette handelt, sollte die Wahrscheinlichkeit, dass ich 8 ~ 10 Mal in einer Reihe von zufälligen Trades verliere, gering sein. Die erste Transaktion wurde entworfen, um eine kleine Anzahl von Aufträgen zu platzieren, so klein wie möglich. Wenn ich dann verliere, erhöhe ich die Anzahl der Aufträge und werde weiterhin zufällig Aufträge platzieren.

Okay, die Strategie ist einfach.

Quellcode entworfen:

var openPrice = 0 
var ratio = 1
var totalEq = null 
var nowEq = null 

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

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

    exchange.SetContractType(ct)

    var initPos = _C(exchange.GetPosition)
    if (initPos.length != 0) {
        throw "Strategy starts with a position!"
    }
    
    exchange.SetPrecision(pricePrecision, amountPrecision)
    Log("set the pricePrecision", pricePrecision, amountPrecision)
    
    if (!IsVirtual()) {
        var recoverTotalEq = _G("totalEq")
        if (!recoverTotalEq) {
            var currTotalEq = _C(exchange.GetAccount).Balance   // equity
            if (currTotalEq) {
                totalEq = currTotalEq
                _G("totalEq", currTotalEq)
            } else {
                throw "failed to obtain initial interest"
            }
        } else {
            totalEq = recoverTotalEq
        }
    } else {
        totalEq = _C(exchange.GetAccount).Balance
    }
    
    while (1) {
        if (openPrice == 0) {
            // Update account information and calculate profits
            var nowAcc = _C(exchange.GetAccount)
            nowEq = IsVirtual() ? nowAcc.Balance : nowAcc.Balance  // equity
            LogProfit(nowEq - totalEq, nowAcc)
            
            var direction = Math.floor((Math.random()*100)+1)   // 1~50 , 51~100
            var depth = _C(exchange.GetDepth)
            if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
                Sleep(1000)
                continue 
            }
            if (direction > 50) {
                // long
                openPrice = depth.Bids[1].Price
                exchange.SetDirection("buy")
                exchange.Buy(Math.abs(openPrice) + slidePrice, amount * ratio)
            } else {
                // short
                openPrice = -depth.Asks[1].Price
                exchange.SetDirection("sell")
                exchange.Sell(Math.abs(openPrice) - slidePrice, amount * ratio)
            }       
            Log("place", direction > 50 ? "buying order" : "selling order", ", price:", Math.abs(openPrice))
            continue
        }

        var orders = _C(exchange.GetOrders)
        if (orders.length == 0) {
            var pos = _C(exchange.GetPosition)
            if (pos.length == 0) {
                openPrice = 0
                continue
            }
            
            // Test for closing the position
            while (1) {
                var depth = _C(exchange.GetDepth)
                if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
                    Sleep(1000)
                    continue 
                }
                var stopLossPrice = openPrice > 0 ? Math.abs(openPrice) - stopLoss : Math.abs(openPrice) + stopLoss 
                var stopProfitPrice = openPrice > 0 ? Math.abs(openPrice) + stopProfit : Math.abs(openPrice) - stopProfit
                var winOrLoss = 0 // 1 win , -1 loss 
                
                // drawing the line
                $.PlotLine("bid", depth.Bids[0].Price)
                $.PlotLine("ask", depth.Asks[0].Price)
                
                // stop loss
                if (openPrice > 0 && depth.Bids[0].Price < stopLossPrice) {
                    exchange.SetDirection("closebuy")
                    exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
                    winOrLoss = -1
                } else if (openPrice < 0 && depth.Asks[0].Price > stopLossPrice) {
                    exchange.SetDirection("closesell")
                    exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
                    winOrLoss = -1
                }
                
                // stop profit
                if (openPrice > 0 && depth.Bids[0].Price > stopProfitPrice) {
                    exchange.SetDirection("closebuy")
                    exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)  
                    winOrLoss = 1
                } else if (openPrice < 0 && depth.Asks[0].Price < stopProfitPrice) {
                    exchange.SetDirection("closesell")
                    exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
                    winOrLoss = 1
                }
                
                // Test the pending orders
                Sleep(2000)
                var orders = _C(exchange.GetOrders)                
                if (orders.length == 0) {
                    pos = _C(exchange.GetPosition)
                    if (pos.length == 0) {
                        if (winOrLoss == -1) {
                            ratio++
                        } else if (winOrLoss == 1) {
                            ratio = 1
                        }
                        break
                    }                    
                } else {
                    // cancel pending orders
                    cancelAll()
                    Sleep(2000)
                    pos = _C(exchange.GetPosition)
                    // update the position after cancellation, and check it again
                    if (pos.length == 0) {
                        if (winOrLoss == -1) {
                            ratio++
                        } else if (winOrLoss == 1) {
                            ratio = 1
                        }
                        break
                    }    
                }
                
                var tbl = {
                    "type" : "table", 
                    "title" : "info", 
                    "cols" : ["totalEq", "nowEq", "openPrice", "bid1Price", "ask1Price", "ratio", "pos.length"], 
                    "rows" : [], 
                }
                tbl.rows.push([totalEq, nowEq, Math.abs(openPrice), depth.Bids[0].Price, depth.Asks[0].Price, ratio, pos.length])
                tbl.rows.push(["pos", "type", "amount", "price", "--", "--", "--"])
                for (var j = 0 ; j < pos.length ; j++) {
                    tbl.rows.push([j, pos[j].Type, pos[j].Amount, pos[j].Price, "--", "--", "--"])
                }
                LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
            }
        } else {
            // cancel the pending orders
            // reset openPrice
            cancelAll()
            openPrice = 0
        }
        Sleep(1000)
    }
}

Strategieparameter:

img

Oh ja! Die Strategie braucht einen Namen, nennen wir sie raten Sie die Größe (dYdX Version) .

Zurückprüfung

Das Backtesting ist nur zur Referenz, >_

img

img

img

img

Der Backtest ist abgeschlossen, es gibt keinen Fehler.

Diese Strategie dient nur zum Lernen und zur Referenz, nicht im echten Bot!


Verwandt

Mehr