Ejemplo de diseño de estrategia dYdX

El autor:No lo sé., Creado: 2022-04-08 16:47:32, Actualizado: 2022-04-08 17:47:39

Ejemplo de diseño de estrategia dYdX

En respuesta a las necesidades de muchos usuarios, la plataforma FMZ recientemente ha apoyado la plataforma descentralizada dYdX. Los amigos con estrategias pueden minar en dYdX felizmente. Hace mucho tiempo, quería escribir una estrategia de trading aleatoria. No importa si gano o no. El propósito es practicar mi técnica y enseñar el diseño de estrategia por cierto.

Comparte primero la minería

La captura de pantalla de la estrategia minera en el artículo.

img

¡Bienvenidos los amigos que tienen buenas ideas de estrategia minera para compartir!

Diseño de estrategias de trading aleatorias

Vamos a tener una lluvia de ideas! Planeamos diseñar una estrategia para colocar órdenes al azar sin mirar indicadores o precios. Ordenar no es más que hacer largo y corto, que es apostar a la probabilidad. Luego usamos números aleatorios de 1 a 100 para determinar si hacer largo o hacer corto.

Condición de hacer largo: números aleatorios de 1 a 50. Condición de hacer corto: números aleatorios de 51 a 100.

Para hacer largo y corto, ambos necesitan 50 números. A continuación, pensemos en cómo cerrar posiciones. Ya que es una apuesta, debe haber un estándar ganador o perdedor. Luego, establezcamos un stopProfit fijo y un stopLoss como el estándar de ganar o perder. Tomemos stopProfit como ganar y stopLoss como perder. En cuanto a la idoneidad de stopProfit y stopLoss, en realidad afecta la relación de ganancias y pérdidas, y la tasa de ganancias también! (¿Es efectivo diseñar una estrategia de esta manera? ¿Se puede garantizar que sea una expectativa matemática positiva? De todos modos, hagámoslo primero! ¡Porque es para aprender y investigar!)

El comercio no es libre de costos, y hay factores como el punto de deslizamiento y las tarifas que son suficientes para tirar nuestra tasa de ganancia de comercio aleatorio al lado de menos del 50%. Pensando en eso, ¿cómo continuar el diseño de aquí? Es mejor diseñar escalar por múltiples para aumentar las posiciones. Como es una apuesta, la probabilidad de perder sucesivamente 10 u 8 veces no debe ser muy grande. Así que quiero diseñar colocando una pequeña cantidad de orden en la primera operación, tan pequeña como sea posible. Luego, si pierdo la apuesta, aumentar la cantidad de orden y continuar colocando órdenes al azar.

La estrategia está bien, tan simple como esto.

Código fuente del diseño:

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

Parámetros de la estrategia:

img

La estrategia necesita un nombre, y vamos a llamarlo "Adivina cuál es más grande (versión dYdX).

Prueba de retroceso

¡La prueba de retroceso es sólo para referencia! Es principalmente para comprobar si hay algún error en la estrategia; backtest con Binance Futures.

img

img

img

img

La prueba de retroceso ha terminado, no hay errores, pero siento que el sistema de retroceso fue emparejado... vamos a ejecutarlo en un bot real para observación.

Corre en un bot

img

img

img

Esta estrategia es sólo para aprendizaje y referencia.No lo hagas!! No lo hagas¡ Usarlo en un robot de verdad!


Más.