Type/to search
8
Follow
1364
Followers
Exemplo de design de estratégia dYdX - Estratégia de negociação estocástica
Discussions
Created 2021-11-03 15:40:56  Updated 2023-09-15 21:02:48
 6
 2828

img

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.

img

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:

img

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.

img

img

img

img

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

img

img

img

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

Related Recommendations
Comment
All comments (4)

    问一下, dydx去中心化交易所现在是否支持现货交易? 还是只能永续合约? 从来没用过 去中心化交易所, 如果dydx支持现货交易, 可以考虑做个现货网格交易策略. 还有就是去中心化交易所, 确认买卖是否成功还需要等待时间, 不像中心化交易所那么闪电般快, 需要旷工确认. 要是速度这些克服了, 又支持写网格等量化策略, 那是非常好.

    5 years ago

    dYdX我公开的有实盘,永续合约。

    5 years ago

    小白一个,请问怎么跑不起来

    5 years ago

    策略源码只是策略代码,还要配置上参数。参数在文章里有截图。

    5 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)