学习如何基于 Stochastic 设计交易系统·进阶篇
(2/3)· 懂指标不等于能赚钱,把 Stochastic 策略变成 MT5 里跑得动的代码才是分水岭
◍ 把 Stochastic 信号拆成三条可执行路径
用 Stochastic 做程序化信号,核心是先卡位置再等交叉。把 %K 与 %D 相对 50 中轴或 20/80 极值区的位置作为前置过滤,能砍掉一半以上无意义触发。 上行趋势只认低位金叉:当 %K 与 %D 都低于 50,程序空仓等待,直到 %K 上穿 %D 才给做多倾向;若双线已在 50 及以上,直接不动作。下行反之,双线高于 50 后等 %K 下穿 %D 才偏空。 横盘用 20/80 区间抓反转。低区(<20)金叉做多,之后盯 80 区死叉了结;高区(>80)死叉做空,之后盯 20 区金叉了结。外汇与贵金属波动跳空多,这种极值反转信号在镑美、XAUUSD 上假突破概率不低,需结合时段流动性过滤。 这三张蓝图的价值不在指标本身,而在于把‘什么条件、空仓还是触发’写成了无歧义的状态机。开 MT5 把 Stochastic(5,3,3) 调出来,对照上述阈值手动画线,能立刻看出哪段行情会被系统放过。
「把 Stochastic 三条策略写成 EA 信号模块」
先把指标线读出来才能谈信号。下面这段是取 Stochastic 当前 %K、%D 值的骨架,参数 14/3/3 对应 K 周期、D 周期、慢速平滑,价格域用 STO_LOWHIGH(含最高最低)。 [CODE] double Karray[]; double Darray[]; ArraySetAsSeries(Karray, true); ArraySetAsSeries(Darray, true); int StochDef = iStochastic(_Symbol,_Period,14,3,3,MODE_SMA,STO_LOWHIGH); CopyBuffer(StochDef,0,0,3,Karray); CopyBuffer(StochDef,1,0,3,Darray); float KValue = Karray[0]; float DValue = Darray[0]; Comment("%K value is ", KValue,"\n""%D Value is ",DValue); [/CODE] 逐行拆:前两行建 double 数组装 %K、%D;ArraySetAsSeries 设 true 让索引 0 为当前柱,方便后面取 Karray[0] 当实时值。iStochastic 把指标句柄拿到,CopyBuffer 分别把主线(0)、信号线(1) 最近 3 根柱灌进数组;用 float 收一下精度只是省内存。Comment 直接在图表左上角打印两线数值,编译后拖进图表就能看到实时读数。 上行策略条件:%K 与 %D 都低于 50,且 K 上穿 D,给做多注释。代码里要单独留 signal 变量初值为空,再设 K0=Karray[0]、K1=Karray[1]、D0/D1 同理,用 if(K1<=D1 && K0>D0) 判向上交叉,命中就 signal="BUY"。 下行反过来:两线高于 50 且 K 下穿 D 才标空。横盘则分两侧——低于 20 金叉做多、高于 80 死叉平多;高于 80 死叉做空、低于 20 金叉平空。四类信号都靠同一套 CopyBuffer 取值,只是交叉方向和阈值判断不同。 外汇与贵金属杠杆高,Stochastic 在震荡市命中率可能偏高,趋势行情中假信号概率明显上升,任何信号仅作纪律化提醒,不等于方向保证。把上面模块分别编译成 EA 拖进 XAUUSD 的 M15,观察 20/80 边界的注释触发频率,比肉眼盯副图更不容易漏。
class="type">class="kw">double Karray[]; class="type">class="kw">double Darray[]; ArraySetAsSeries(Karray, true); ArraySetAsSeries(Darray, true); class="type">int StochDef = iStochastic(_Symbol,_Period,class="num">14,class="num">3,class="num">3,MODE_SMA,STO_LOWHIGH); CopyBuffer(StochDef,class="num">0,class="num">0,class="num">3,Karray); CopyBuffer(StochDef,class="num">1,class="num">0,class="num">3,Darray); class="type">class="kw">float KValue = Karray[class="num">0]; class="type">class="kw">float DValue = Darray[class="num">0]; Comment("%K value is ", KValue,"\n""%D Value is ",DValue);
把随机指标双线交叉写成可跑的 BUY 判定
在 MT5 的 EA 里抓 Stochastic 信号,核心是先拿句柄再拷缓冲区。下面这段用 iStochastic 以当前品种、周期、参数 14/3/3、SMA 平滑、高低价模式建句柄,随后把主线 %K(buffer 0)与信号线 %D(buffer 1)各取最近 3 根到数组,并设成时间序列便于用 [0] 表示最新根。 判定逻辑只盯一个偏多情形:最新根 K、D 均小于 50,且本根 K 上穿 D(K0>D0 而前根 K1<D1),此时给 signal 赋 "BUY"。注意原文未含出场与手数,实盘直接跟单外汇或贵金属属高风险,信号仅代表概率倾向,不承诺上行。 把代码贴进 OnTick 就能在图表用 Comment 看到信号字符串;想验证就开 EURUSD 的 M15,观察 K、D 在 50 下方的金叉频次,再决定是否接订单发送模块。
class="type">int StochDef = iStochastic(_Symbol,_Period,class="num">14,class="num">3,class="num">3,MODE_SMA,STO_LOWHIGH); CopyBuffer(StochDef,class="num">0,class="num">0,class="num">3,Karray); CopyBuffer(StochDef,class="num">1,class="num">0,class="num">3,Darray); class="type">class="kw">double KValue0 = Karray[class="num">0]; class="type">class="kw">double DValue0 = Darray[class="num">0]; class="type">class="kw">double KValue1 = Karray[class="num">1]; class="type">class="kw">double DValue1 = Darray[class="num">1]; if (KValue0<class="num">50&&DValue0<class="num">50) if ((KValue0>DValue0) && (KValue1<DValue1)) { signal = "BUY"; }
◍ 震荡区间里的反向做多触发
把随机指标用在横盘段,思路和上破追多正好反过来:只在 K、D 双线都压在 50 中轴下方时,才允许识别多头反转。参数沿用 5/3/3 的快周期 Stochastic,对噪音敏感,适合 EURUSD 这类亚盘窄幅时段。 代码里先取最近 3 根 K、D 值,比较当前柱与上一柱的位置关系。当 KValue0<50 且 DValue0<50,同时出现 K 上穿 D(KValue0>DValue0 且 KValue1<DValue1),signal 才被赋为 BUY。 这类信号在真实账户上属于概率型触发,外汇与贵金属杠杆高,横盘假突破可能造成连续小止损,建议先在 MT5 策略测试器用 2022 年数据跑一遍再上实盘。
class="type">void OnTick() { class="type">class="kw">string signal=""; class="type">class="kw">double Karray[]; class="type">class="kw">double Darray[]; ArraySetAsSeries(Karray, true); ArraySetAsSeries(Darray, true); class="type">int StochDef = iStochastic(_Symbol,_Period,class="num">5,class="num">3,class="num">3,MODE_SMA,STO_LOWHIGH); CopyBuffer(StochDef,class="num">0,class="num">0,class="num">3,Karray); CopyBuffer(StochDef,class="num">1,class="num">0,class="num">3,Darray); class="type">class="kw">double KValue0 = Karray[class="num">0]; class="type">class="kw">double DValue0 = Darray[class="num">0]; class="type">class="kw">double KValue1 = Karray[class="num">1]; class="type">class="kw">double DValue1 = Darray[class="num">1]; if (KValue0<class="num">50&&DValue0<class="num">50) if ((KValue0>DValue0) && (KValue1<DValue1)) { signal = "BUY"; } Comment("SSS - Sideways Buy Strategy - Signal is ",signal); }