构建蜡烛图趋势约束模型(第7部分):为EA开发优化我们的模型(基础篇)
从趋势约束模型切入EA优化
这一节是整篇系列的开头,作者先给出全文地图:围绕「蜡烛图趋势约束模型」做第7次迭代,目标是把它从研究稿改造成可跑的 EA 骨架。原文列出的路线包含识别系统限制、重看图与代码、融入均线交叉、画盈亏矩形、给出场点、测试验证,共 9 个环节。 对读者来说,关键点在于——别一上来就写 EA,先把现有模型在哪一步卡住想清楚。原文明确点出要先「识别当前系统的限制」,这意味着前 6 版模型大概率在实盘触发频率、噪声误判或出场滞后上有硬伤。 外汇与贵金属属高杠杆高风险品种,任何模型在 MT5 里回测过关,也不代表实盘概率分布不变。建议你在读后续小节前,先开 MT5 把作者前几版提到的约束逻辑手动画一遍,确认自己能复现再往下走。
◍ EA 调用指标的两条路和 RRR 落地起点
在 MT5 上把现有指标接进 EA,有两条现实路径。其一,把指标条件直接写进 EA 算法,回测和实盘都快,EA 自己跑不需要额外挂指标;其二,让 EA 去读指标缓冲区,True/False 触发动作,但这要求 EA 和指标两个文件都躺在平台对应目录里。后一种方式想往 MQL5 社区发基本会卡验证——系统找不到配套指标,作者本人就撞过这个错,只能本机私用。 两种办法各有长短,后续再拆。接指标的最大好处是降复杂度:条件已在指标里算完,EA 只需盯少数几个输出点。到第六篇的 Trend Constraint V1.08,已把两套主要集成并进一个程序,Telegram 和 WhatsApp 推信号都通了,但信号够不够好、什么时候退场,仍得回图表看历史表现、改源码加功能。 手动可跟的策略才能自动化。用风险报酬比(RRR)画矩形是个直白办法:绿框是盈利目标区,红框是亏损区。公式就一条:RRR = 潜在损失 / 潜在收益。举个股票例子,50 美元买,止损 48(亏 2),目标 56(赚 6),RRR = 2/6 = 1/3,即冒 1 美元险搏 3 美元。比率越低(如 1:1 往下)风险越压头,越高越划算。外汇和贵金属杠杆高,红绿框只是参考,真金白银下单前先想清楚这笔若反向会吞多少净值。 下一步要在指标里把入场出场概念画出来,让交易者先手动跟、再谈自动。重点就五个:算法交易里风险管理为什么不能省、RRR 的数学底、动态退出怎么写、视觉指标怎么增强、实盘怎么测。
「先揪出旧指标的盲区」
要给 MT5 指标加新功能,第一步不是写代码,而是把现有系统的短板摊开看。很多老指标在极端行情里会画出误导性的信号带,但平时看图根本发现不了,只有翻历史图表窗口才能撞见。 具体做法分两层。先重翻图表:把指标拖到不同周期(比如从 H1 切到 M15 和 D1),观察同一段行情里展示逻辑是否一致,记下那些跳变、重叠或空白的异常区。 第二步才动代码:带着图表里圈出的问题,去定位对应的计算模块。比如某段异常若集中在非农蜡烛,就直接查处理 extern 输入和时间过滤的那几行,而不是通篇重构。外汇与贵金属杠杆高,这类显示错位可能让你误判波动边界,实盘前务必在策略测试器回放验证。
箭头画错位置与枢轴点出场逻辑
Boom 500 图表里标 (A) 的那根尖峰蜡烛,买入箭头被画在了蜡烛下方,实际应落在上方。根因是箭头绑定的是 RSI 超买信号,而该信号只能等蜡烛收盘后才成立,盘中提前绘制就会错位。 DRAW_LINE 的变色线目前能正常提示趋势切换,但仅靠它发摆动信号不够——市场转向时常伴大波动,可原逻辑没把这点转成可执行信号。蓝色买入箭头现在只标 D1 级别 RSI 超卖后的趋势延续,记住本系列把信号锁在日线与市场情绪上;RSI 极端值多是区域提示,不是反转确认,趋势延续的概率并不低。 补一条思路:重新接回均线交叉做辅助入场,它和价格行为吻合度更高。同时在信号触发时画风险收益长方形,EURUSD M1 与 Boom 500 M1 的手动截图已验证这套画法能直观暴露盈亏比。 枢轴点按多数技术派用法当止损/止盈参考,截图场景里有时风险远大于收益,1:3 的固定比价会失效。可确定的两点:枢轴点作出场参考点;入场与出场价要存下来供后续逻辑调用。外汇与指数差价合约属高风险品种,枢轴位也仅作概率参考。
◍ 把卖区箭头钉在K线高点
这段指标逻辑里,Buffer2 负责在满足条件时给 K 线打卖出箭头。原代码把箭头坐标写死在 Low[i],也就是蜡烛最低价;如果你希望箭头浮在 K 线高点更醒目,只要把那一行换成 High[i],渲染位置就立刻从下影线挪到实体顶端。 具体触发条件没动:RSI[i] 上穿 Overbought、前一根 RSI 还在超买线下、Open 小于等于前日 Close、两组均线 MA<MA2 且 MA3<MA4,全部成立才写值。改坐标不影响信号本身,只影响视觉落点。 顺手把 indicator_label2 从 "Sell" 改成 "Sell Zone",弹窗警报字符串也同步成 "Sell Zone",在 MT5 里复盘时区隔更清楚。外汇与贵金属波动剧烈,这类视觉调整不改变策略胜率,实盘前请用历史数据验证信号密度。
class="macro">#class="kw">property indicator_type1 DRAW_ARROW class="macro">#class="kw">property indicator_width1 class="num">5 class="macro">#class="kw">property indicator_color1 0xFF3C00 class="macro">#class="kw">property indicator_label1 "Buy" class=class="str">"cmt">// We are going to change it to "Buy Zone" class="macro">#class="kw">property indicator_type2 DRAW_ARROW class="macro">#class="kw">property indicator_width2 class="num">5 class="macro">#class="kw">property indicator_color2 0x0000FF class="macro">#class="kw">property indicator_label2 "Sell"class=class="str">"cmt">// We are going to change it to "Sell Zone" class=class="str">"cmt">//Indicator Buffer class="num">2 // We are going to set the indicator to display at candlestick high by changing the highlighted text to High[i] if(RSI[i] > Overbought && RSI[i+class="num">1] < Overbought class=class="str">"cmt">//Relative Strength Index crosses above fixed value && Open[barshift_M1[i]] <= Close[class="num">1+barshift_D1[i]] class=class="str">"cmt">//Candlestick Open <= Candlestick Close && MA[i] < MA2[i] class=class="str">"cmt">//Moving Average < Moving Average && MA3[i] < MA4[i] class=class="str">"cmt">//Moving Average < Moving Average ) { Buffer2[i] = Low[i]; class=class="str">"cmt">//Set indicator value at Candlestick Low // change to High[i] if(i == class="num">1 && Time[class="num">1] != time_alert) myAlert("indicator", "Sell Zone"); class=class="str">"cmt">//Alert on next bar open time_alert = Time[class="num">1]; } else { Buffer2[i] = EMPTY_VALUE; }