在MQL5中实现盈亏平衡机制(第一部分):基类与固定点数的盈亏平衡模式·综合运用
(3/3)·从基类到ATR动态止损,三种盈亏平衡写法如何在同一系统里协同落地
「保本偏移参数的边界校验逻辑」
在 MT5 的 CBreakEvenSimple 类里,SetSimple 直接接管成员变量的赋值,绕开了 MalParams 的封装。它接收两个 int:points_be_ 是触发保本的基准点数,extra_points_be_ 是触发后额外让出的点数。 代码先卡死非法输入:points_be_ 小于等于 0 会打印错误并调用 ExpertRemove() 卸载 EA;extra_points_be_ 小于 0 同理。这两处校验保证 EA 不会在参数荒谬时继续跑。 更隐蔽的是第三道关:若 extra_points_be_ 大于等于 points_be_,代码不报错,只发警告并把 extra_points_be_ 强制置 0。这意味着你若把「额外点数」设得比「保本点数」还大,实际生效的额外偏移就是 0,保本价直接贴在基准价上。 外汇与贵金属杠杆高、滑点随机,这类参数边界错配可能在复盘时毫无痕迹,实盘却让保本单提前平在成本线。开 MT5 把 points_be_ 设 10、extra_points_be_ 设 15,编译运行就能在日志看到那条警告被触发。
class="type">void CBreakEvenSimple::SetSimple(class="type">int points_be_, class="type">int extra_points_be_) { if(points_be_ <= class="num">0) { printf("%s:: Error when setting the class="kw">break even value for fixed points, be points %I32d are invalid.", __FUNCTION__, extra_points_be_); ExpertRemove(); class="kw">return; } if(extra_points_be_ < class="num">0) { printf("%s:: Error when setting the class="kw">break even value for fixed points, extra points %I32d are invalid.", __FUNCTION__, extra_points_be_); ExpertRemove(); class="kw">return; } if(extra_points_be_ >= points_be_) { printf("%s:: Warning: The class="kw">break even points(breakeven_price) is greater than the breakeven points(price_to_beat)\nTherefore the value of the extra breakeven points will be modified class="num">0.", __FUNCTION__); this.points_be = points_be_; class=class="str">"cmt">//class="num">0 this.extra_points_be = class="num">0; class=class="str">"cmt">//class="num">1 class="kw">return; } this.points_be = points_be_; class=class="str">"cmt">//class="num">0 this.extra_points_be = extra_points_be_; class=class="str">"cmt">//class="num">1 }
固定点数盈亏平衡在 OB 策略里的回测表现
把 Order Blocks EA 改成可切换盈亏平衡很简单:新增一组参数,用 bool 开关控制是否启用,再挂一个 CBreakEvenSimple 对象,在 OnTradeTransaction 里登记成交、在 OnTick 里判断开关后调用 BreakEven()。代码里 be_fixed_points_to_put_be 是触发平移止损所需的价格行程点数,be_fixed_points_extra 是激活时额外让止损超出成本的点数。 回测不设资金上限,风险回报比锁死 1:2,持仓只靠止损或止盈离场。未开盈亏平衡时,初始 15000 美元跌到 8700,亏约 7000,作为基准曲线。 开盈亏平衡后,be_fixed_points_to_put_be=600、be_fixed_points_extra=100,余额从 10900 回撤到 7900,亏 3000。连续亏损段回撤明显更浅,说明该机制倾向削弱连亏对本金的冲击,外汇与贵金属交易本身杠杆高、波动剧烈,这类保护对控风险有现实意义。 但代价是过早平仓:2024-03 前两段都普遍亏损,之后转盈,无盈亏平衡余额破 16000,而开了的只到 10900。解释很直接——价格回调未触止损却被盈亏平衡踢出,错失后续趋势。高波动下它保本金快,清淡市可能永不触发,更适合把资金安全放第一位、不追单笔暴利的人。
sinput group "-----| Break Even |----" input class="type">bool use_be = true; class=class="str">"cmt">// Enable Break Even usage sinput group "- BreakEven based on Fixed Points -" input class="type">int be_fixed_points_to_put_be = class="num">200; class=class="str">"cmt">// Points traveled needed to activate Break Even input class="type">int be_fixed_points_extra = class="num">100; class=class="str">"cmt">// Extra adjustment points when activating Break Even CBreakEvenSimple break_even(_Symbol, Magic, BREAKEVEN_MODE_AUTOMATIC); class=class="str">"cmt">//--- if(use_be) break_even.SetSimple(be_fixed_points_to_put_be, be_fixed_points_extra); class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| TradeTransaction function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTradeTransaction(const MqlTradeTransaction& trans, const class="type">MqlTradeRequest& request, const class="type">MqlTradeResult& result) { risk.OnTradeTransactionEvent(trans); break_even.OnTradeTransactionEvent(trans); } if(use_be) break_even.BreakEven();
◍ 画得少,看得清
把盈亏平衡塞进 Order Block EA 后,跑了两套 .set 配置做对照:OB_SET_WITHOUT_BREAKEVEN 关掉机制,OB_SET_WITH_BREAKEVEN 打开。连续盈利段里,开盈亏平衡的那条曲线爬得慢一点;连续亏损段里,它把深回撤的概率压下去了。这套两面性不是 bug,是风险与收益换了种排布方式。 底层策略本身在不限盈亏时的统计表现,决定了这套机制到底值不值。偏爱平稳权益曲线、想自己卡死离场节点的交易者,比激进派更该用它。Risk_Management.mqh 与 PositionManagement.mqh 两个头文件已经把逻辑拆开,MT5 里直接换 set 文件就能复现对照。 外汇和贵金属杠杆高,回测顺不代表实盘稳,拿模拟盘先跑两轮再谈真金白银。