Type/to search
8
Follow
1364
Followers
dYdX 戦略設計例 - ストキャスティクス取引戦略
Discussions
Created 2021-11-03 15:40:56  Updated 2023-09-15 21:02:48
 6
 2828

img

dYdX戦略設計例

多くのユーザーの要望に応えて、FMZ プラットフォームは最近、分散型取引所 dYdX をサポートしました。戦略を持った友人は、楽しく dYdX を採掘できます。たまたまずっと前からランダムな取引戦略を書きたいと思っていました。儲かるか損するかは関係ありません。目的は、戦略設計を実践し、同時に教えることです。それでは、一緒にランダム交換戦略を設計しましょう。戦略のパフォーマンスについては心配しないでください。戦略設計について学びましょう。

まずは採掘の様子を見てみましょう

この記事の戦略的マイニングのスクリーンショット。

img

優れたマイニング戦略のアイデアをお持ちの友人も、ぜひメッセージを残してください。

確率的取引戦略設計

「ワイルドに考えよう」!指標や価格を見ずにランダムに注文を出す戦略を設計する予定です。注文は買いか売りかだけなので、確率を予測するだけです。次に、1 から 100 までの乱数を使用して、長いか短いかを決定します。

長い条件: 1〜50 の乱数。
空売り条件:乱数51~100。

ロングポジションとショートポジションの数は両方とも 50 です。次にポジションをどうやってクローズするかを考えてみましょう。ギャンブルなので勝ち負けの基準があるはずです。そして、取引においては、勝ち負けの基準として、固定の利益確定額と損切り額を設定します。利益を止めれば勝ち、損失を止めれば負けです。適切なテイクプロフィットとストップロスの設定に関しては、これは実際に損益比率に影響します。勝率にも影響します! (この設計戦略は効果的でしょうか? 数学的にプラスの期待値を保証できますか? まずはそれをやってみましょう! 結局のところ、これは学習と研究のためです!)

取引にはコストがかかります。スリッページや手数料などの要因により、ランダム取引の勝率は 50% 未満に低下します。これを念頭に置いて、どのようにデザインを続ければよいでしょうか?
複数のポジションを増やすように設計する方がよいでしょう。これはギャンブルなので、10 回連続でランダムに 8 回取引して負ける確率はそれほど高くないはずです。したがって、最初のトランザクションの注文サイズを可能な限り小さく設計したいと思います。そして、賭けに負けた場合は、注文数量を増やしてランダムな注文を続けます。

はい、戦略設計はそれほど単純です。

設計ソースコード:

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

戦略パラメータ:

img

ああそうだ!この戦略には名前が必要です。「サイズを推測する (dYdX バージョン)」と呼びましょう。

バックテスト

バックテストは参考用です。_<!
主な目的は、戦略にバグがないかを確認し、Binance 先物バックテストを使用することです。

img

img

img

img

バックテストは完了しており、バグはありません。しかし、バックテストシステムを過剰適合したかもしれない気がします...T_T、リアルタイムで試してみます。

実際の取引

img

img

img

この戦略は学習と参照のみを目的としています。1000万~1000万実際に使用しないでください。 !

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)