价格行为分析工具包开发(第七部分):信号脉冲智能交易系统(EA)·综合运用
◍ 卖信号落点与防重叠箭头逻辑
当空单信号成立且当前价位附近没有已画箭头时,脚本会先在终端打印一句跨周期 Stochastic 共振的提示,随后用 TimeCurrent() 拼出唯一对象名,避免同根 K 线重复创建。OBJ_ARROW 的 arrowcode 242 对应 MT5 内置的向下箭头字形,宽度设 2、颜色 clrRed,肉眼上比默认 1 像素更扎眼。 存储环节对 signalTimes、signalPrices、signalBuySignals 三个动态数组各做一次 ArrayResize 加 1,再把最新时间、收盘价与 false 标记写进末尾下标。这样后续回看信号流时,能直接按数组索引对齐每笔触发价。 ArrowExists 用 MathAbs(signalPrices[i] - price) <= MinArrowDistance 做价格邻域判定。若 MinArrowDistance 设成 5 点(EURUSD 点值 0.0001 下即 0.0005),那么同一波动区间不会叠出第二颗箭头,图表噪声倾向明显降低。 OnTick 只做一件事:每次报价进来就跑 CheckAndGenerateSignal()。OnDeinit 里用 ObjectsTotal 倒序循环删对象,防止 EA 卸载后图表留一堆死箭头。外汇与贵金属杠杆高,这类信号仅做多周期共振参考,实盘触发概率不等于胜率。
signalPrices[ArraySize(signalPrices) - class="num">1] = close1; signalBuySignals[ArraySize(signalBuySignals) - class="num">1] = true; } if(sellSignal && !ArrowExists(close1)) { Print("Sell signal detected on all timeframes with Stochastic confirmation!"); class="type">class="kw">string arrowName = "SellSignal" + IntegerToString(TimeCurrent()); ObjectCreate(class="num">0, arrowName, OBJ_ARROW, class="num">0, TimeCurrent(), close1); ObjectSetInteger(class="num">0, arrowName, OBJPROP_ARROWCODE, class="num">242); ObjectSetInteger(class="num">0, arrowName, OBJPROP_COLOR, clrRed); ObjectSetInteger(class="num">0, arrowName, OBJPROP_WIDTH, class="num">2); class=class="str">"cmt">// Store signal data ArrayResize(signalTimes, ArraySize(signalTimes) + class="num">1); ArrayResize(signalPrices, ArraySize(signalPrices) + class="num">1); ArrayResize(signalBuySignals, ArraySize(signalBuySignals) + class="num">1); signalTimes[ArraySize(signalTimes) - class="num">1] = TimeCurrent(); signalPrices[ArraySize(signalPrices) - class="num">1] = close1; signalBuySignals[ArraySize(signalBuySignals) - class="num">1] = false; } } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Check if an arrow already exists within the MinArrowDistance | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool ArrowExists(class="type">class="kw">double price) { for(class="type">int i = class="num">0; i < ArraySize(signalPrices); i++) { if(MathAbs(signalPrices[i] - price) <= MinArrowDistance) { class="kw">return true; class=class="str">"cmt">// Arrow exists in the same price region } } class="kw">return false; class=class="str">"cmt">// No arrow exists in the same region } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| OnTick Event | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { CheckAndGenerateSignal(); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| OnDeinit Function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnDeinit(class="kw">const class="type">int reason) { class=class="str">"cmt">// Clean up the objects class="type">long chart_id = class="num">0; for(class="type">int i = ObjectsTotal(chart_id) - class="num">1; i >= class="num">0; i--) { class="type">class="kw">string name = ObjectName(chart_id, i);
三周期共振的布林带超买超卖判定
多周期信号清理只是前奏,真正的触发逻辑落在三周期布林带与随机指标的联合条件上。下面这段判定把 M1、M5、M15(或你设定的三个周期)的收盘价与各自布林下轨、上轨,以及 Stochastic 的 K 值绑死。 买入倾向出现在三个周期同时跌破布林下轨,且各自 K 值都小于 5 的时候——这是典型的跨周期超卖堆叠,价格短期反弹的概率偏高。卖出则反过来,三周期同破上轨且 K 值全大于 95,属于超买共振,下行风险在外汇和贵金属品种上尤其需要警惕。 代码里写死的 5 和 95 是常见阈值,但你完全可以在 MT5 里改成 10 / 90 做宽松过滤,回测时会发现信号数量与胜率此消彼长。 别把阈值当铁律 K 值卡在 5 以下的三周期同破,在震荡市里假信号少,但趋势市中容易踏空。建议先开 MT5 用 EURUSD 的 H1 嵌套三小周期跑一遍再调参。
class="type">bool buySignal = (close1 <= lower1 && close2 <= lower2 && close3 <= lower3) && (k1 < class="num">5 && k2 < class="num">5 && k3 < class="num">5); class=class="str">"cmt">// Oversold condition class="type">bool sellSignal = (close1 >= upper1 && close2 >= upper2 && close3 >= upper3) && (k1 > class="num">95 && k2 > class="num">95 && k3 > class="num">95); class=class="str">"cmt">// Overbought condition
「回测落地与参数调校」
EA 开发里回测不是走过场,而是用历史价格数据反推策略的盈利能力、准确度和稳健性。数据底子不牢,后面所有结论都可能是假的——必须给选定品种和时间框架加载逐笔(tick)级历史数据,任何缺口或拼接误差都会让绩效评估偏航。 进 MT5 策略测试器后,先钉死三件事:交易品种、时间周期(须与 EA 内部设定一致,如 M15/H1)、点差(用实盘或固定点差模拟成本)。优化开关打开后,重点跑布林带周期、随机震荡器阈值这类输入参数,找局部最优组合。 结果不能只看净利润。盈利因子看整体赚赔比,最大回撤标定你能扛的极限回撤幅度,胜率加交易频率才暴露 EA 在震荡/趋势切换时的真实表现。上面两张测试图里每个信号都被 GIF 动态记录,你可以直接改随机震荡水平、换时间框架重跑,直到曲线符合自己的风险偏好。外汇与贵金属杠杆高、滑点跳空频繁,回测通过不等于实盘稳,仍需小资金验证。
◍ 多周期共振之外的下一步
信号脉冲 EA 只在 M15、M30、H1 三个周期同时给出超买或超卖时才下单,这种多时间框架过滤思路能压低假信号概率,但外汇与贵金属的高杠杆特性意味着任何共振信号都可能因突发流动性断裂而失效,实盘前必须自跑回测。 该工具箱从 01/10/24 的图表展示器到 9/01/2025 的信号脉冲已迭代到 7 个工具,其中 09/12/24 发布的波动率导航仪用布林带、RSI、ATR 三者综合判市,和信号脉冲形成互补,可一并加载到 MT5 观察共振表现。 后续若加趋势方向过滤器与按市场类型切分的信号逻辑,才谈得上脱离“震荡专用”的局限;现在直接把 ea 挂真仓属于冒进,建议先用策略测试器跑 2024 年欧美对数据验证信号分布。