Exemple de conception de stratégie dYdX

Auteur:Je suis désolée., Créé: 2022-04-08 16:47:32, Mis à jour: 2022-04-08 17:47:39

Exemple de conception de stratégie dYdX

En réponse aux besoins de nombreux utilisateurs, la plate-forme FMZ a récemment pris en charge la plate-forme décentralisée dYdX. Les amis ayant des stratégies peuvent extraire sur dYdX avec plaisir. Il y a très longtemps, je voulais écrire une stratégie de trading aléatoire. Peu importe que je fasse du profit ou non. Le but est de pratiquer ma technique et d'enseigner la conception de la stratégie en passant.

Partagez d'abord la mine

La capture d'écran de la stratégie minière dans l'article.

img

Bienvenue aux amis qui ont de bonnes idées de stratégie minière à partager!

Conception de stratégie de négociation aléatoire

Nous prévoyons de concevoir une stratégie pour placer des ordres au hasard sans regarder les indicateurs ou les prix. L'ordre n'est rien de plus que faire long et court, ce qui est parier sur la probabilité. Ensuite, nous utilisons des nombres aléatoires de 1 à 100 pour déterminer si faire long ou faire court.

Condition de faire long: nombres aléatoires de 1 à 50. Condition de faire court: nombres aléatoires de 51 à 100.

Les positions longues et courtes ont toutes deux besoin de 50 chiffres. Ensuite, réfléchissons à la façon de fermer les positions. Puisqu'il s'agit d'un pari, il doit y avoir un standard gagnant ou perdant. Ensuite, définissons un stopProfit et un stopLoss fixes comme norme de gain ou de perte. Prenons stopProfit comme gain et stopLoss comme perte. Quant à l'adéquation de stopProfit et stopLoss, cela affecte en fait le ratio profit-perte, ainsi que le taux de gain! (Est-il efficace de concevoir une stratégie de cette façon? Peut-on garantir qu'il s'agit d'une attente mathématique positive? Quoi qu'il en soit, faisons-le d'abord! Parce que c'est pour l'apprentissage et la recherche!)

Le trading n'est pas gratuit, et il y a des facteurs tels que le point de glissement et les frais qui sont suffisants pour tirer notre taux de gain de trading aléatoire à moins de 50%. Il est préférable de concevoir l'échelle par multiple pour augmenter les positions. Puisqu'il s'agit d'un pari, la probabilité de perdre successivement 10 ou 8 fois ne devrait pas être très grande. Je veux donc concevoir en plaçant un petit montant d'ordre dans le premier commerce, aussi petit que possible. Ensuite, si je perds le pari, augmentez le montant de l'ordre et continuez à placer des ordres aléatoires.

La stratégie est très simple.

Code source du dessin:

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 "Position detected when starting the strategy!"
    }
    
    exchange.SetPrecision(pricePrecision, amountPrecision)
    Log("setPrecision", 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 "fail to obtain the initial equity"
            }
        } else {
            totalEq = recoverTotalEq
        }
    } else {
        totalEq = _C(exchange.GetAccount).Balance
    }
    
    while (1) {
        if (openPrice == 0) {
            // update account information, and calculate the profit
            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 ? "buy order" : "sell 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
            }
            
            // detect close positions 
            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 
                
                // plot 
                $.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
                }
                
                // detect 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)
                    // after canceling, update positions, which needs to be detected 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 pending orders 
            // reset openPrice
            cancelAll()
            openPrice = 0
        }
        Sleep(1000)
    }
}

Paramètres de stratégie:

img

La stratégie a besoin d'un nom, et appelons-la " Devinez lequel est le plus grand (version dYdX).

Test de retour

Le backtest est juste pour référence! Il s'agit principalement de vérifier s'il y a des bugs dans la stratégie; backtest avec Binance Futures.

img

img

img

img

Le backtest est terminé, pas de bugs, mais j'ai l'impression que le système de backtest a été assorti... allons le faire fonctionner dans un vrai bot pour l'observation.

Exécuter dans un bot

img

img

img

Cette stratégie est uniquement à des fins d'apprentissage et de référence.Ne le fais pas.!! Ne le fais pas.Utilisez-le dans un vrai robot!


Plus de