DYdX Exemplo de Design de Estratégia

Autora:Ninabadass, Criado: 2022-04-08 16:47:32, Atualizado: 2022-04-08 17:47:39

DYdX Exemplo de Design de Estratégia

Em resposta às necessidades de muitos usuários, a plataforma FMZ recentemente apoiou a plataforma descentralizada dYdX. Amigos com estratégias podem minerar na dYdX felizmente. Há muito tempo, eu queria escrever uma estratégia de negociação aleatória. Não importa se eu ganhe ou não. O objetivo é praticar minha técnica e ensinar o design de estratégia a propósito. Então, em seguida, vamos projetar uma estratégia de plataforma aleatória juntos. Não se preocupe com o desempenho da estratégia e apenas aprenda o design de estratégia.

Primeiro, compartilhe a mineração

A captura de tela da estratégia de mineração no artigo.

img

Bem-vindos amigos que têm boas ideias de estratégia de mineração para compartilhar!

Desenho de estratégia de negociação aleatória

Vamos fazer um brainstorming! Planejamos projetar uma estratégia para colocar ordens aleatoriamente sem olhar para indicadores ou preços. Ordenar não é nada mais do que fazer longo e curto, que é apostar na probabilidade. Então usamos números aleatórios de 1 a 100 para determinar se fazer longo ou fazer curto.

Condição de fazer long: números aleatórios de 1 a 50. Condição de fazer curto: números aleatórios de 51 a 100.

Para fazer longo e curto, ambos precisam de 50 números. Em seguida, vamos pensar em como fechar posições. Como é uma aposta, deve haver um padrão de ganhar ou perder. Então, vamos definir um stopProfit fixo e stopLoss como padrão de ganhar ou perder. Tomemos o stopProfit como ganhar e o stopLoss como perder. Quanto à adequação do stopProfit e stopLoss, ele realmente afeta a proporção de lucro e perda, e a taxa de ganho também! (É eficaz projetar uma estratégia dessa maneira? É garantido que seja uma expectativa matemática positiva? De qualquer forma, vamos fazê-lo primeiro! Porque é para aprendizado e pesquisa!)

A negociação não é livre de custos, e há fatores como slipppoint e taxas que são suficientes para puxar nossa taxa de ganho de negociação aleatória para o lado de menos de 50%. Pensando nisso, como continuar o projeto a partir daqui? É melhor projetar a escalagem por múltiplos para aumentar as posições. Uma vez que é uma aposta, a probabilidade de perder 10 ou 8 vezes sucessivamente não deve ser muito grande. Então eu quero projetar colocando um pequeno valor de ordem no primeiro comércio, o menor possível. Então, se eu perder a aposta, aumentar o valor da ordem e continuar a colocar ordens aleatórias.

A estratégia é tão simples quanto isto.

Código de origem do desenho:

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 da estratégia:

img

A estratégia precisa de um nome, e vamos chamá-lo "Adivinha qual é maior (versão dYdX).

Teste de retrocesso

O backtest é apenas para referência! É principalmente para verificar se há algum bug na estratégia; backtest com Binance Futures.

img

img

img

img

O backtest acabou, não há bugs, mas sinto que o sistema de backtest foi combinado... vamos executá-lo num robô real para observação.

Execute em um bot

img

img

img

Esta estratégia é apenas para aprendizagem e referência.Não.!! Não.Use-o num robô de verdade!


Mais.