avatar of 发明者量化-小小梦 发明者量化-小小梦
focar em Mensagem privada
4
focar em
1271
Seguidores

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Criado em: 2021-11-03 15:40:56, atualizado em: 2023-09-15 21:02:48
comments   6
hits   2500

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Exemplo de design de estratégia dYdX

Em resposta a muitas demandas de usuários, a plataforma FMZ recentemente deu suporte à exchange descentralizada dYdX. Amigos com estratégias podem minerar dYdX com alegria. Acontece que eu queria escrever uma estratégia de negociação aleatória há muito tempo. Não importava se eu ganhasse ou perdesse dinheiro. O propósito era praticar e ensinar design de estratégia ao mesmo tempo. Então, vamos projetar uma estratégia de troca aleatória juntos. Não se preocupe com o desempenho da estratégia. Vamos apenas aprender sobre design de estratégia.

Vamos mostrar um pouco de mineração primeiro

Captura de tela da mineração estratégica neste artigo.

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Amigos que tenham boas ideias de estratégias de mineração também são bem-vindos para deixar uma mensagem!

Design de estratégia de negociação estocástica

Vamos “pensar selvagemente”! Planejo criar uma estratégia que faça ordens aleatoriamente, sem olhar para indicadores ou preços. Ordens nada mais são do que ir longo ou curto, e tudo o que você precisa fazer é prever probabilidades. Em seguida, usamos números aleatórios de 1 a 100 para determinar posições longas e curtas.

Condições longas: números aleatórios de 1 a 50. Condições de venda a descoberto: números aleatórios de 51 a 100.

Os números para posições longas e curtas são 50. Em seguida, vamos pensar em como fechar a posição. Como é uma aposta, deve haver um padrão para ganhar e perder. Então, na transação, definimos take-profit e stop-loss fixos como o padrão para ganhar ou perder. Se você parar o lucro, você ganha; se você parar o prejuízo, você perde. Quanto às configurações adequadas de take-profit e stop-loss, isso realmente afeta a relação de lucros e perdas, ah sim! Isso também afeta a taxa de vitórias! (Essa estratégia de design é eficaz? Ela pode garantir uma expectativa matemática positiva? Vamos fazer isso primeiro! Afinal, é para aprendizado e pesquisa!)

Negociar não é isento de custos. Fatores como slippage e taxas de manuseio são suficientes para puxar nossa taxa de ganho de negociação aleatória para menos de 50%. Como devo continuar projetando com isso em mente? É melhor projetar um aumento de posição múltipla. Como é uma aposta, a probabilidade de perder 8 transações aleatórias de 10 em uma fileira não deve ser muito alta. Então, quero projetar a primeira transação para ter um tamanho de pedido muito pequeno, o menor possível. Então, se você perder a aposta, aumente a quantidade do pedido e continue fazendo pedidos aleatórios.

OK, o design da estratégia é simples assim.

Código fonte do design:

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("重置所有数据", "#FF0000")
    }

    exchange.SetContractType(ct)

    var initPos = _C(exchange.GetPosition)
    if (initPos.length != 0) {
        throw "策略启动时有持仓!"
    }
    
    exchange.SetPrecision(pricePrecision, amountPrecision)
    Log("设置精度", 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 "获取初始权益失败"
            }
        } else {
            totalEq = recoverTotalEq
        }
    } else {
        totalEq = _C(exchange.GetAccount).Balance
    }
    
    while (1) {
        if (openPrice == 0) {
            // 更新账户信息,计算收益
            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("下", direction > 50 ? "买单" : "卖单", ",价格:", 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
            }
            
            // 平仓检测
            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 
                
                // 画线
                $.PlotLine("bid", depth.Bids[0].Price)
                $.PlotLine("ask", depth.Asks[0].Price)
                
                // 止损
                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
                }
                
                // 止盈
                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
                }
                
                // 检测挂单
                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 {
                    // 撤销挂单
                    cancelAll()
                    Sleep(2000)
                    pos = _C(exchange.GetPosition)
                    // 撤销后更新持仓,需要再次检查
                    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 {
            // 撤销挂单
            // 重置openPrice
            cancelAll()
            openPrice = 0
        }
        Sleep(1000)
    }
}

Parâmetros de estratégia:

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Oh sim! A estratégia precisa de um nome, vamos chamá-la de “Adivinhe o tamanho (versão dYdX)”.

Testes retrospectivos

O backtesting é apenas para referência._<! O objetivo principal é verificar se há algum bug na estratégia e usar o backtesting da Binance Futures.

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

O backtesting foi concluído, sem bugs. Mas sinto que posso ter ajustado demais o sistema de backtest…T_T, deixe-me testar em tempo real.

Negociação real

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica

Esta estratégia é apenas para aprendizado e referência.10 milhões~10 milhõesNão use isso de verdade! !