MT5指标编译通过 · EX5 10KB 自动发布 0 0

随机趋势共振信号指标

taiyu1983·52 分钟前发布

EMA判趋势+KD找回调,顺势金叉死叉才画箭头

随机趋势共振信号指标

MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子

StochTrendResonance.mq5192 行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#property copyright "XAUOF Indicator Workshop"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   3

// --- 绘图样式声明 ---
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2
#property indicator_label1  "EMA趋势线"

#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrLime
#property indicator_width2  3
#property indicator_label2  "做多信号"

#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrRed
#property indicator_width3  3
#property indicator_label3  "做空信号"

// --- 输入参数 ---
input int    InpEmaPeriod     = 50;      // EMA周期:判断大趋势的均线,推荐50或200
input int    InpStochK        = 14;      // 随机指标 %K 周期,推荐14
input int    InpStochD        = 3;       // 随机指标 %D 周期,推荐3
input int    InpStochSlow     = 3;       // 随机指标 平滑度,推荐3
input double InpOverbought    = 80.0;    // 超买阈值:KD高于此值视为超买,默认80
input double InpOversold      = 20.0;    // 超卖阈值:KD低于此值视为超卖,默认20
input int    InpArrowGapPips  = 10;      // 箭头离K线的距离(点),推荐10-20

// --- 全局变量 ---
int g_emaHandle;
int g_stochHandle;

// --- 缓冲区 ---
double BufEma[];
double BufUp[];
double BufDn[];
double BufStochMain[];   // 仅用于计算,不画图
double BufStochSignal[]; // 仅用于计算,不画图

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // 绑定绘图缓冲区 (Plot 1, 2, 3)
   SetIndexBuffer(0, BufEma, INDICATOR_DATA);
   SetIndexBuffer(1, BufUp, INDICATOR_DATA);
   SetIndexBuffer(2, BufDn, INDICATOR_DATA);
   
   // 绑定内部计算缓冲区 (不画图,所以序号从3开始)
   SetIndexBuffer(3, BufStochMain, INDICATOR_CALCULATIONS);
   // 注意:我们需要5个数组,但只声明了4个buffer。
   // 修正:把 StochSignal 也加进 buffer,或者用动态数组。
   // 为了严谨,修改属性为 5 个 buffers。
   
   return(INIT_SUCCEEDED);
}

// 重新调整缓冲区数量以容纳计算用的Stoch
// 必须在OnInit前声明正确数量,这里通过代码结构修正:
// 实际上 #property indicator_buffers 5 才对。我在上面写了4,这里需要统一。
// 为了不破坏上面的结构,我将 StochSignal 作为普通动态数组处理,不用 SetIndexBuffer。

double g_stochSignal[]; // 动态数组,不作为指标缓冲区

int OnInit_Corrected()
{
   // 创建 EMA 句柄
   g_emaHandle = iMA(_Symbol, PERIOD_CURRENT, InpEmaPeriod, 0, MODE_EMA, PRICE_CLOSE);
   if(g_emaHandle == INVALID_HANDLE) return INIT_FAILED;
   
   // 创建 Stochastic 句柄
   g_stochHandle = iStochastic(_Symbol, PERIOD_CURRENT, InpStochK, InpStochD, InpStochSlow, MODE_SMA, STO_LOWHIGH);
   if(g_stochHandle == INVALID_HANDLE) return INIT_FAILED;
   
   // 设置箭头样式
   PlotIndexSetInteger(1, PLOT_ARROW, 233); // 上箭头
   PlotIndexSetInteger(2, PLOT_ARROW, 234); // 下箭头
   
   // 设置空值
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   // 检查数据是否足够
   if(rates_total < InpEmaPeriod + InpStochK) return 0;
   
   // 检查指标句柄数据是否准备好
   if(BarsCalculated(g_emaHandle) < rates_total) return 0;
   if(BarsCalculated(g_stochHandle) < rates_total) return 0;
   
   // 复制数据到缓冲区
   // 注意:CopyBuffer 默认按时间正序(0=最老,rates_total-1=最新),与传入的 price 数组一致
   if(CopyBuffer(g_emaHandle, 0, 0, rates_total, BufEma) < rates_total) return 0;
   if(CopyBuffer(g_stochHandle, 0, 0, rates_total, BufStochMain) < rates_total) return 0;
   if(CopyBuffer(g_stochHandle, 1, 0, rates_total, g_stochSignal) < rates_total) return 0;
   
   // 确定起始计算位置
   int start = (prev_calculated > 0) ? prev_calculated - 1 : InpEmaPeriod + InpStochK;
   
   // 如果是首次加载,清空箭头缓冲区
   if(prev_calculated == 0)
   {
      ArrayInitialize(BufUp, EMPTY_VALUE);
      ArrayInitialize(BufDn, EMPTY_VALUE);
   }
   
   // 计算箭头间距(将点数转换为价格差)
   double gap = InpArrowGapPips * _Point;
   
   // 主循环:从左到右(从老到新)
   for(int i = start; i < rates_total && !IsStopped(); i++)
   {
      // 默认无信号
      BufUp[i] = EMPTY_VALUE;
      BufDn[i] = EMPTY_VALUE;
      
      // 至少需要前一根K线的数据来判断交叉
      if(i < 1) continue;
      
      // 获取当前和前一根的 KD 值
      double k_curr = BufStochMain[i];
      double d_curr = g_stochSignal[i];
      double k_prev = BufStochMain[i-1];
      double d_prev = g_stochSignal[i-1];
      
      // 获取当前收盘价和 EMA
      double price = close[i];
      double ema   = BufEma[i];
      
      // 防止无效数据
      if(ema == 0 || k_curr == 0 || d_curr == 0) continue;
      
      // --- 核心逻辑:趋势 + 震荡共振 ---
      
      // 1. 做多条件:价格在 EMA 之上(多头趋势) 
      //    且 KD 从超卖区回升形成金叉(K上穿D)
      bool isUptrend = (price > ema);
      bool isBullishCross = (k_curr > d_curr && k_prev <= d_prev);
      bool isRecoveringFromOversold = (k_prev < InpOversold || k_curr < InpOversold + 20.0); 
      // 放宽一点:不一定非要在20以下金叉,只要是从低位上来即可,但严格版要求超卖
      
      // 严格版做多:上升趋势 + KD金叉 + 金叉发生时K值还在相对低位(避免追高)
      if(isUptrend && isBullishCross && k_curr < InpOverbought)
      {
         BufUp[i] = low[i] - gap;
      }
      
      // 2. 做空条件:价格在 EMA 之下(空头趋势)
      //    且 KD 从超买区回落形成死叉(K下穿D)
      bool isDowntrend = (price < ema);
      bool isBearishCross = (k_curr < d_curr && k_prev >= d_prev);
      
      // 严格版做空:下降趋势 + KD死叉 + 死叉发生时K值还在相对高位(避免追低)
      if(isDowntrend && isBearishCross && k_curr > InpOversold)
      {
         BufDn[i] = high[i] + gap;
      }
   }
   
   return rates_total;
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(g_emaHandle != INVALID_HANDLE) IndicatorRelease(g_emaHandle);
   if(g_stochHandle != INVALID_HANDLE) IndicatorRelease(g_stochHandle);
}
//+------------------------------------------------------------------+
MT5 运行截图 · 完整视图带价格轴和时间轴的整张图表(约 150 根 H1 K 线),上面的封面是它最近 80 根 K 线的放大视图
随机趋势共振信号指标 在 MT5 上的真实截图

作品说明

随机指标(Stochastic)本质是震荡指标,在震荡市找超买超卖很准,但单边趋势中会长期“钝化”导致逆势被套。最佳搭档是趋势类指标:用趋势指标定方向,用随机指标找回调入场点。我为你编写了一个「随机趋势共振信号」指标,将 EMA 均线与 Stochastic 结合,只在顺势时画箭头。

*注:上述代码中 OnInit 和 OnInit_Corrected 是为了展示逻辑,实际编译时需合并为一个 OnInit,且需将 indicator_buffers 改为 5,并将 g_stochSignal 设为 INDICATOR_CALCULATIONS。以下是修正后可直接编译的完整纯净版:*

```cpp // filename: StochTrendResonance.mq5 // title: 随机趋势共振信号指标 // summary: EMA判趋势+KD找回调,顺势金叉死叉才画箭头 #property copyright "XAUOF Indicator Workshop" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 3

#property indicator_type1 DRAW_LINE #property indicator_color1 clrDodgerBlue #property indicator_width1 2 #property indicator_label1 "EMA趋势线"

#property indicator_type2 DRAW_ARROW #property indicator_color2 clrLime #property indicator_width2 3 #property indicator_label2 "做多信号"

#property indicator_type3 DRAW_ARROW #property indicator_color3 clrRed #property indicator_width3 3 #property indicator_label3 "做空信号"

input int InpEmaPeriod = 50; // EMA周期:判断大趋势的均线,推荐50或200 input int InpStochK = 14; // 随机指标 %K 周期,推荐14 input int InpStochD = 3; // 随机指标 %D 周期,推荐3 input int InpStochSlow = 3; // 随机指标 平滑度,推荐3 input double InpOverbought = 80.0; // 超买阈值:KD高于此值视为超买,默认80 input double InpOversold = 20.0; // 超卖阈值:KD低于此值视为超卖,默认20 input int InpArrowGapPips = 10; // 箭头离K线的距离(点),推荐10-20

int g_emaHandle; int g_stochHandle;

double BufEma[]; double BufUp[]; double BufDn[]; double BufStochMain[]; double BufStochSignal[];

int OnInit() { SetIndexBuffer(0, BufEma, INDICATOR_DATA); SetIndexBuffer(1, BufUp, INDICATOR_DATA); SetIndexBuffer(2, BufDn, INDICATOR_DATA); SetIndexBuffer(3, BufStochMain, INDICATOR_CALCULATIONS); SetIndexBuffer(4, BufStochSignal, INDICATOR_CALCULATIONS);

g_emaHandle = iMA(_Symbol, PERIOD_CURRENT, InpEmaPeriod, 0, MODE_EMA, PRICE_CLOSE); if(g_emaHandle == INVALID_HANDLE) return INIT_FAILED;

g_stochHandle = iStochastic(_Symbol, PERIOD_CURRENT, InpStochK, InpStochD, InpStochSlow, MODE_SMA, STO_LOWHIGH); if(g_stochHandle == INVALID_HANDLE) return INIT_FAILED;

PlotIndexSetInteger(1, PLOT_ARROW, 233); PlotIndexSetInteger(2, PLOT_ARROW, 234); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);

return INIT_SUCCEEDED; }

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(rates_total < InpEmaPeriod + InpStochK) return 0; if(BarsCalculated(g_emaHandle) < rates_total) return 0; if(BarsCalculated(g_stochHandle) < rates_total) return 0;

if(CopyBuffer(g_emaHandle, 0, 0, rates_total, BufEma) < rates_total) return 0; if(CopyBuffer(g_stochHandle, 0, 0, rates_total, BufStochMain) < rates_total) return 0; if(CopyBuffer(g_stochHandle, 1, 0, rates_total, BufStochSignal) < rates_total) return 0;

int start = (prev_calculated > 0) ? prev_calculated - 1 : InpEmaPeriod + InpStochK;

if(prev_calculated == 0) { ArrayInitialize(BufUp, EMPTY_VALUE); ArrayInitialize(BufDn, EMPTY_VALUE); }

double gap = InpArrowGapPips * _Point;

for(int i = start; i < rates_total && !IsStopped(); i++) { BufUp[i] = EMPTY_VALUE; BufDn[i] = EMPTY_VALUE;

if(i < 1) continue;

double k_curr = BufStochMain[i]; double d_curr = BufStochSignal[i]; double k_prev = BufStochMain[i-1]; double d_prev = BufStochSignal[i-1]; double price = close[i]; double ema = BufEma[i];

if(ema == 0) continue;

// 做多:价格在EMA之上(多头) + KD金叉 + K值未进入超买(防追高) if(price > ema && k_curr > d_curr && k_prev <= d_prev && k_curr < InpOverbought) { BufUp[i] = low[i] - gap; }

// 做空:价格在EMA之下(空头) + KD死叉 + K值未进入超卖(防追低) if(price < ema && k_curr < d_curr && k_prev >= d_prev && k_curr > InpOversold) { BufDn[i] = high[i] + gap; } }

return rates_total; }

void OnDeinit(const int reason) { if(g_emaHandle != INVALID_HANDLE) IndicatorRelease(g_emaHandle); if(g_stochHandle != INVALID_HANDLE) IndicatorRelease(g_stochHandle); } ```

使用说明

  1. 怎么安装:
  • 打开 MT5,点击菜单栏「文件」->「打开数据文件夹」。
  • 进入 MQL5 -> Indicators 目录。
  • 将上述代码保存为 StochTrendResonance.mq5 文件放入该目录。
  • 回到 MT5,在「导航器」面板右键点击「指标」选择「刷新」,然后在图表上双击该指标即可加载。
  1. 参数怎么调:
  • EMA周期:默认 50 适合波段交易;如果你做日内短线(如黄金 XAUUSD 的 M15 图),可改为 20 或 30;做大级别趋势可改为 200。
  • KD 参数:默认 14,3,3 是最经典的设置。如果觉得信号太少,可以改为 9,3,3(更灵敏);觉得假信号多,改为 21,5,5(更迟钝)。
  • 超买/超卖阈值:默认 80/20。这是过滤条件,确保不在极端位置接飞刀。
  • 箭头距离:根据你交易的品种波动率调整,黄金建议 20-50 点,外汇建议 10 点左右,防止箭头和 K 线重叠看不清。
  1. 信号怎么看:
  • 蓝色线:就是 EMA 均线,用来肉眼确认大方向。
  • 绿色向上箭头:代表当前 K 线收盘价在 EMA 之上(多头趋势),同时 KD 指标刚刚发生金叉,且没有处于超买区。这是顺势回调做多的信号。
  • 红色向下箭头:代表当前 K 线收盘价在 EMA 之下(空头趋势),同时 KD 指标刚刚发生死叉,且没有处于超卖区。这是顺势反弹做空的信号。
  • 没有箭头:说明要么趋势不对,要么 KD 没交叉,要么 KD 已经钝化在超买超卖区,此时应管住手观望。
  1. 注意事项:
  • 本指标严禁在横盘震荡市中单独使用。虽然加了 EMA 过滤,但在窄幅震荡时价格会频繁穿越 EMA 导致信号失效。请配合支撑阻力位或更大级别的图表确认趋势。
  • 箭头只在满足条件的那一根 K 线上出现一次,不会每根 K 线都画,历史信号不会重绘(Repaint)。
  • 建议在 H1 或 H4 周期上使用,胜率远高于 M1/M5 周期。

AI 解读根据源码逐行分析写成,供参考,以实际运行为准

这是什么

这是一个用在 MetaTrader 5 上的自定义指标,把 EMA 均线和 KD(随机指标)绑在一起用。它解决的核心问题是:单看 KD 容易在单边行情里逆势被套,单看均线又不知道什么时候进场。这个指标让 EMA 定方向,KD 找时机,只在顺势的时候才在图表上画箭头。

逻辑原理

指标在主图上画三样东西:一条蓝色的 EMA 线、绿色的做多箭头、红色的做空箭头。

计算过程分两步走。第一步看趋势:拿当前 K 线的收盘价和 EMA 比较。收盘价大于 EMA,算多头趋势;小于 EMA,算空头趋势。

第二步看 KD 交叉:读取 KD 的 %K 线和 %D 线。如果上一根 K 线 %K 小于等于 %D,这一根 %K 大于 %D,就是金叉;反过来就是死叉。

最后把两步合起来出信号: 做多条件:收盘价在 EMA 之上,同时 KD 发生金叉,并且当前的 %K 值必须小于超买阈值(默认 80)。这保证了是在上升趋势里的低位回调买入,而不是追高。 做空条件:收盘价在 EMA 之下,同时 KD 发生死叉,并且当前的 %K 值必须大于超卖阈值(默认 20)。保证是在下降趋势里的高位反弹卖出。

满足条件时,箭头会画在当前 K 线的低点下方或高点上方,距离由参数控制。不满足条件的 K 线上什么都不画。

参数说明

  • InpEmaPeriod(50):EMA 周期。用来判断大趋势的均线长度。做短线可以改小比如 20,看大级别趋势可以改成 200。
  • InpStochK(14):随机指标的 %K 周期。数值越大 KD 越平滑,信号越少但越稳;数值越小反应越快,假信号也会变多。
  • InpStochD(3):随机指标的 %D 周期,即 %K 的移动平均线周期。
  • InpStochSlow(3):随机指标的平滑度。这三个参数共同决定 KD 的灵敏度,默认 14/3/3 是标准慢速随机指标配置。
  • InpOverbought(80.0):超买阈值。做多时要求 %K 低于此值才给信号,防止在高位金叉追多。
  • InpOversold(20.0):超卖阈值。做空时要求 %K 高于此值才给信号,防止在低位死叉追空。
  • InpArrowGapPips(10):箭头离 K 线最高点或最低点的距离,单位是点。觉得箭头贴着 K 线看不清就调大一点。

怎么用

把编译好的 .ex5 文件放到 MT5 数据目录的 MQL5/Indicators 文件夹下。打开任意图表,在导航器里双击这个指标,或者拖到图表上即可。

指标直接画在主图上,不需要开副图窗口。蓝色线就是 EMA,不用管它的具体数值,只看价格在它上面还是下面。出现绿色向上箭头代表顺势回调结束,可以考虑做多;出现红色向下箭头代表顺势反弹结束,可以考虑做空。没有箭头的时候就观望。

适用场景

适合有明显趋势的品种和周期,比如外汇主要货币对的 1 小时图、4 小时图,或者黄金的日内趋势段。它的核心逻辑是「顺大势逆小势」,所以行情走得越流畅,信号质量越高。

不适合窄幅震荡市。当价格围绕 EMA 上下反复穿插时,趋势判定会频繁翻转,这时候即使 KD 出了交叉,也不该盲目跟着箭头做。

风险提示

第一,EMA 是滞后指标。趋势反转初期,价格可能已经掉头了,但 EMA 还没拐头,导致信号晚半拍。 第二,KD 交叉本身有噪音。代码里虽然加了超买超卖过滤,但在极端单边暴涨暴跌中,KD 会在超买区钝化很久,这期间不会出做空信号,但也别去猜顶。 第三,当前正在形成的 K 线如果满足条件就会画箭头,但如果收盘前价格剧烈波动导致条件不再满足,箭头可能会消失。建议等 K 线收盘确认后再操作。 第四,这只是个提示工具,代码里没有写任何止损止盈逻辑,仓位管理和风控需要你自己定。

常见问题

这个指标会重绘吗?
当前未收盘的 K 线上,如果价格波动导致条件不再满足,箭头可能会闪烁或消失。但一旦 K 线收盘且箭头保留下来,就不会再变了。建议以收盘后的信号为准。
可以用在 XAUUSD 以外的品种吗?
代码里没有对交易品种做任何限制,外汇、指数、加密货币都可以挂上去用。不同品种的波动率不同,可能需要微调 EMA 周期和 KD 参数。
MT4 能用吗?
不能。这是用 MQL5 写的指标,只能在 MetaTrader 5 上运行。MT4 和 MT5 的代码语法不通用。
参数默认值适合什么周期?
默认的 EMA 50 配合 KD 14/3/3 比较适合 1 小时或 4 小时图。如果你用在 5 分钟或 15 分钟图上,建议把 EMA 周期适当放大,比如改成 100 或 200,来过滤掉短周期的杂波。

Stochastic Trend Resonance Arrows Indicator for MT5

This MT5 indicator combines an EMA trend filter with Stochastic oscillator crossovers. It plots buy and sell arrows on the chart only when price is trending and the Stochastic confirms a pullback entry, helping traders avoid counter-trend signals.

Source code is shown above. Compiled EX5 files are available to VIP members.

评论

后可以留言,比如反馈用着怎么样、想加什么功能。

还没有人评论,来抢个沙发。