改编版 MQL5 网格对冲 EA(第 1 部分):制作一个简单的对冲 EA·综合运用
对冲网格的起手价区怎么钉
对冲循环启动时,先按初始方向锁定首仓买卖盘:若是买仓就用 SYMBOL_ASK 取价,卖仓则用 SYMBOL_BID,这一步决定了后面 A/B/C/D 四条水平线的基准点。 代码里 A/B/C/D 全部以 _Point*10 为步距单位,意味着 buySellDiff、buyTP、sellTP 这几个外部参数若填的是『点数』,实际落线位置会被放大 10 倍——比如 buyTP=50 时,A 线距初始价 500 点。外汇与贵金属杠杆高,这种倍数偏差可能让止损远超预期,实盘前务必在策略测试器核一遍。 四根线用 ObjectCreate 画成 OBJ_HLINE 并统一染绿,同时把 C 或 B 设为 SL、A 或 D 设为 TP,交给 CTrade.PositionOpen 发首仓。返回值 10009 代表下单成功,此时才把 hedgeCycleRunning 置真,并翻转 isPositionBuy 等待下一腿。 别把正态当圣经:这段代码没有校验账户保证金占用,initialLotSize 若偏大,首仓就可能直接触发保证金警告,建议先在 MT5 用极小 lot 跑一遍观察 A~D 间距。
class="type">void StartHedgeCycle() { isPositionBuy = initialPositionBuy; class="type">class="kw">double initialPrice = isPositionBuy ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); A = isPositionBuy ? initialPrice + buyTP * _Point * class="num">10 : initialPrice + (buySellDiff + buyTP) * _Point * class="num">10; B = isPositionBuy ? initialPrice : initialPrice + buySellDiff * _Point * class="num">10; C = isPositionBuy ? initialPrice - buySellDiff * _Point * class="num">10 : initialPrice; D = isPositionBuy ? initialPrice - (buySellDiff + sellTP) * _Point * class="num">10 : initialPrice - sellTP * _Point * class="num">10; ObjectCreate(class="num">0, "A", OBJ_HLINE, class="num">0, class="num">0, A); ObjectSetInteger(class="num">0, "A", OBJPROP_COLOR, clrGreen); ObjectCreate(class="num">0, "B", OBJ_HLINE, class="num">0, class="num">0, B); ObjectSetInteger(class="num">0, "B", OBJPROP_COLOR, clrGreen); ObjectCreate(class="num">0, "C", OBJ_HLINE, class="num">0, class="num">0, C); ObjectSetInteger(class="num">0, "C", OBJPROP_COLOR, clrGreen); ObjectCreate(class="num">0, "D", OBJ_HLINE, class="num">0, class="num">0, D); ObjectSetInteger(class="num">0, "D", OBJPROP_COLOR, clrGreen); ENUM_ORDER_TYPE positionType = isPositionBuy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; class="type">class="kw">double SL = isPositionBuy ? C : B; class="type">class="kw">double TP = isPositionBuy ? A : D; CTrade trade; trade.PositionOpen(_Symbol, positionType, initialLotSize, initialPrice, SL, TP); lastPositionLotSize = initialLotSize; if(trade.ResultRetcode() == class="num">10009) hedgeCycleRunning = true; isPositionBuy = isPositionBuy ? false : true; }
「翻倍加仓下的保证金悬崖与回撤真相」
把 EA 跑一遍就能看清问题。我用 initialBuyPosition=true、buyTP=15、sellTP=15、buySellDiff=15、initialLotSize=0.01、lotSizeMultiplier=2.0,在 EURUSD 上回测 2023-01-01 至 2023-12-06,杠杆 1:500,本金 $10,000。时间帧对这套策略无关,随便选都不影响输出。 账面看着还行:净利润 $1470.62,毛利润 $13,153.68,毛亏损 $11,683.06。但回撤数据才是重点——余额最大回撤 15.04%($1563.12),净值最大回撤 26.77%($2781.97)。净值回撤覆盖余额回撤,等于是后者的超集,所以盯净值就够了。 翻倍加仓让手数指数膨胀。第 0 笔 0.01 手要保证金 $2.16,到第 12 笔未开仓手数 40.96、保证金 $8847.36,第 13 笔直接 $17,694.72,远超 $10,000 本金,这还没算止损。 若前 12 笔全损、每笔止损 15 点,累计手数 81.91,按 EURUSD 每 0.01 手 10 点值 $1 算,亏损 (81.91/0.01)*1.5 = $12,286.5,本金直接穿仓。退一步,撑到开第 11 笔还行:前 10 笔亏 $1,534.5 加第 11 笔保证金 $4,423.68,共 $5,958.18,仍在阈值内;但想开第 12 笔时,前 11 笔亏 $3,070.5 加保证金 $8,847.36 达 $11,917.86,已经资不抵债。 回测里最大连亏 10 笔,离崩盘就差一笔。绝对回撤 $2,388.66,若第 11 笔止损触发,亏损跳到 $3,070.5,距全面失败仅 $681.84。外汇及贵金属高风险,这种结构随时被点差和连亏带走。 图里红圈处赢了最后一笔最大手数却没盈利,根因是点差吃掉利润。经典对冲只有当手数乘数 ≥2 且 buyTP=sellTP=buySellDiff(忽略点差)时才保本,小于 2 随单量增可能转负。点差怎么搅局,下一篇拆。
◍ 下一步该让参数自己跑出来
前面三篇把这套双方向建仓的逻辑和 MT5 自动化都搭完了,但 lotSizeMultiplier、initialLotSize、buySellDiff、sellTP、buyTP 这几个输入目前还是拍脑袋写的固定值。想把这事做扎实,下一步就是丢进策略测试器做优化,让历史行情替你把最优组合筛出来。 顺带一个变量值得单独验证:同一套参数在 EURUSD 和 XAUUSD 上,从做多还是做空先开仓,回撤曲线可能完全两样。外汇和贵金属杠杆高、跳空频繁,这种网格类手法一旦遇单边,浮亏放大速度远超普通单笔,优化前先想清楚自己扛不扛得住。 系列后面会直接上优化框架和实测对比,到时候把 EA 拖进回测,跑完看报告里的 max drawdown 和 profit factor 再决定手数怎么定。