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

随机指标多空动能信号系统

taiyu1983·1 小时前发布

超买超卖区结合动能衰减画KD线及开平仓箭头信号

随机指标多空动能信号系统

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

StochSignalIndicator.mq5209 行
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#property copyright "XAUOF Indicator Studio"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots   6

// --- 绘图样式声明 ---
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2
#property indicator_label1  "%K线"

#property indicator_type2   DRAW_LINE
#property indicator_color2  clrOrangeRed
#property indicator_width2  2
#property indicator_label2  "%D线"

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

#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrLime
#property indicator_width4  3
#property indicator_label4  "做多信号"

#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrYellow
#property indicator_width5  2
#property indicator_label5  "平空信号"

#property indicator_type6   DRAW_ARROW
#property indicator_color6  clrAqua
#property indicator_width6  2
#property indicator_label6  "平多信号"

// --- 输入参数 ---
input int    InpKPeriod     = 14;    // K线周期(推荐14)
input int    InpDPeriod     = 3;     // D线平滑周期(推荐3)
input int    InpSlowing     = 3;     // 减速因子(推荐3)
input double InpOverbought  = 70.0;  // 超买阈值(默认70)
input double InpOversold    = 30.0;  // 超卖阈值(默认30)
input int    InpMomBars     = 3;     // 动能减弱回看K线数(推荐3,用于判断多头/空头动能是否衰竭)

// --- 缓冲区数组 ---
double BufferK[];
double BufferD[];
double BufferSellOpen[];
double BufferBuyOpen[];
double BufferSellClose[];
double BufferBuyClose[];

// --- 指标句柄 ---
int stochHandle = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    // 第一步:创建随机指标句柄(MQL5中iStochastic返回的是句柄而非数值)
    stochHandle = iStochastic(_Symbol, _Period, InpKPeriod, InpDPeriod, InpSlowing, MODE_SMA, STO_LOWHIGH);
    if(stochHandle == INVALID_HANDLE)
    {
        Print("创建随机指标句柄失败!");
        return INIT_FAILED;
    }

    // 绑定缓冲区,序号必须与 #property indicator_typeN 一一对应
    SetIndexBuffer(0, BufferK, INDICATOR_DATA);
    SetIndexBuffer(1, BufferD, INDICATOR_DATA);
    SetIndexBuffer(2, BufferSellOpen, INDICATOR_DATA);
    SetIndexBuffer(3, BufferBuyOpen, INDICATOR_DATA);
    SetIndexBuffer(4, BufferSellClose, INDICATOR_DATA);
    SetIndexBuffer(5, BufferBuyClose, INDICATOR_DATA);

    // 设置箭头形状和空值
    PlotIndexSetInteger(2, PLOT_ARROW, 234); // 向下箭头代表做空
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    
    PlotIndexSetInteger(3, PLOT_ARROW, 233); // 向上箭头代表做多
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    
    PlotIndexSetInteger(4, PLOT_ARROW, 159); // 圆点代表平空
    PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    
    PlotIndexSetInteger(5, PLOT_ARROW, 159); // 圆点代表平多
    PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE);

    // 副图固定范围(必须用 IndicatorSetDouble,不能用 Integer)
    IndicatorSetDouble(INDICATOR_MINIMUM, 0.0);
    IndicatorSetDouble(INDICATOR_MAXIMUM, 100.0);
    
    // 画出超买超卖水平线
    IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, InpOverbought);
    IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, InpOversold);
    IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrGray);
    IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, clrGray);
    IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, STYLE_DOT);
    IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, STYLE_DOT);

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    if(stochHandle != INVALID_HANDLE)
        IndicatorRelease(stochHandle);
}

//+------------------------------------------------------------------+
//| 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 < InpKPeriod + InpMomBars + 2) return 0;

    // 第二步:检查指标数据是否计算完毕
    if(BarsCalculated(stochHandle) < rates_total) return 0;

    // 第三步:将KD线数据拷贝到绑定的绘图缓冲区中
    // 注意:CopyBuffer拷贝出来的数据方向与OnCalculate传入的数组一致(索引0是最老K线,rates_total-1是最新K线)
    if(CopyBuffer(stochHandle, 0, 0, rates_total, BufferK) < rates_total) return 0;
    if(CopyBuffer(stochHandle, 1, 0, rates_total, BufferD) < rates_total) return 0;

    // 确定循环起点
    int start = (prev_calculated > 0) ? prev_calculated - 1 : InpKPeriod + InpMomBars;
    
    // 首次加载时清空所有信号缓冲区
    if(prev_calculated == 0)
    {
        ArrayInitialize(BufferSellOpen, EMPTY_VALUE);
        ArrayInitialize(BufferBuyOpen, EMPTY_VALUE);
        ArrayInitialize(BufferSellClose, EMPTY_VALUE);
        ArrayInitialize(BufferBuyClose, EMPTY_VALUE);
    }

    // 核心逻辑循环:从最老的K线向最新的K线遍历
    // 注意:读取 [i-1] 需要 i >= 1,读取 [i-InpMomBars] 需要 i >= InpMomBars
    for(int i = start; i < rates_total && !IsStopped(); i++)
    {
        // 【极其重要】没有信号的K线必须赋值为 EMPTY_VALUE,绝不能留0或上次残留值
        BufferSellOpen[i]  = EMPTY_VALUE;
        BufferBuyOpen[i]   = EMPTY_VALUE;
        BufferSellClose[i] = EMPTY_VALUE;
        BufferBuyClose[i]  = EMPTY_VALUE;

        // 防止数组越界
        if(i < 1 || i < InpMomBars) continue;

        double k_curr = BufferK[i];
        double d_curr = BufferD[i];
        double k_prev = BufferK[i-1];
        double d_prev = BufferD[i-1];

        // 判断交叉状态
        bool deadCross = (k_curr < d_curr && k_prev >= d_prev); // 死叉:K线下穿D线
        bool goldCross = (k_curr > d_curr && k_prev <= d_prev); // 金叉:K线上穿D线

        // 计算多头动能减弱:当前K线与InpMomBars根K线前的差值小于等于0,说明上涨乏力
        bool bullWeak = (k_curr - BufferK[i - InpMomBars] <= 0.0);
        
        // 计算空头动能减弱:当前K线与InpMomBars根K线前的差值大于等于0,说明下跌乏力
        bool bearWeak = (k_curr - BufferK[i - InpMomBars] >= 0.0);

        // --- 开仓信号 ---
        // 条件1:超过70形成死叉,且多头动能减弱 -> 做空信号
        if(k_curr > InpOverbought && deadCross && bullWeak)
        {
            BufferSellOpen[i] = k_curr; // 在副图中,将箭头画在当前K值的位置
        }
        
        // 条件2:低于30形成金叉,且空头动能减弱 -> 做多信号
        if(k_curr < InpOversold && goldCross && bearWeak)
        {
            BufferBuyOpen[i] = k_curr;
        }

        // --- 平仓信号 ---
        // 形成金叉后平空仓
        if(goldCross)
        {
            BufferSellClose[i] = k_curr;
        }
        
        // 形成死叉后平多仓
        if(deadCross)
        {
            BufferBuyClose[i] = k_curr;
        }
    }

    return rates_total;
}
//+------------------------------------------------------------------+
MT5 运行截图 · 完整视图带价格轴和时间轴的整张图表(约 150 根 H1 K 线),上面的封面是它最近 80 根 K 线的放大视图
随机指标多空动能信号系统 在 MT5 上的真实截图

作品说明

错误原因说明: INDICATOR_MINIMUM 和 INDICATOR_MAXIMUM 是副图坐标轴的极值属性,在 MQL5 中必须使用 IndicatorSetDouble() 设置(因为它们是浮点数),而不能用 IndicatorSetInteger()。原代码误用了整数设置函数导致参数个数不匹配和枚举转换失败。已修正为 IndicatorSetDouble(INDICATOR_MINIMUM, 0.0) 和 IndicatorSetDouble(INDICATOR_MAXIMUM, 100.0)。

以下是完整、可直接编译通过的代码:

使用说明

  1. 怎么安装:
  • 打开 MetaTrader 5,点击菜单栏 文件 -> 打开数据文件夹。
  • 进入 MQL5 -> Indicators 目录,将上述代码保存为 StochSignalIndicator.mq5 文件。
  • 回到 MT5,在导航器面板右键点击“指标”,选择“刷新”。
  • 双击该指标或将其拖拽到任意品种的图表上即可运行。本次修复了 OnInit 中的坐标轴设置函数,现在可以直接编译通过。
  1. 参数怎么调:
  • K/D/减速周期:默认 14/3/3 是经典随机指标参数,适合大多数品种。短线交易者可改为 5/3/3。
  • 超买/超卖阈值:默认 70 和 30。如果信号太少,可放宽至 80/20;如果信号太多,可收紧至 60/40。
  • 动能减弱回看K线数:默认 3。表示对比当前K线和3根K线前的K值。数值越大,对“动能衰竭”的要求越严格,信号越少但胜率可能更高。
  1. 信号怎么看:
  • 蓝线为 %K 线,红线为 %D 线。
  • 红色向下箭头:满足“K值>70 + 死叉 + 多头动能减弱”,提示开空仓。
  • 绿色向上箭头:满足“K值<30 + 金叉 + 空头动能减弱”,提示开多仓。
  • 黄色圆点:出现金叉,提示平空仓。
  • 青色圆点:出现死叉,提示平多仓。
  1. 注意事项:
  • 本程序为技术指标,仅负责在副图上画出信号,不会自动下单。需配合手动交易或自行编写 EA 使用。
  • 震荡行情中该指标表现极佳,但在单边极强趋势中,指标可能会长时间钝化在超买/超卖区,请结合主图均线或价格行为综合判断,切勿盲目逆势摸顶抄底。

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

这是什么

这是一个运行在 MT5 副图上的技术指标。它在经典 KD 随机指标的基础上加了一道过滤:不仅要求 K 线和 D 线在超买或超卖区发生交叉,还要求当前的上涨或下跌动能已经开始减弱,才会在图上画出开仓箭头。同时,只要出现反向交叉,就会画圆点提示平仓。它只负责画图提示,不会替你自动下单。

逻辑原理

底层数据直接调用 MT5 自带的 iStochastic 函数,算出 %K 线和 %D 线。

开空仓(红色向下箭头)需要同时满足三个条件:当前 %K 值大于超买阈值;%K 从上往下穿过 %D 形成死叉;把当前 %K 值和往前推 InpMomBars 根 K 线的 %K 值做对比,差值小于等于 0,说明多头涨不动了。

开多仓(绿色向上箭头)也是三个条件:%K 值小于超卖阈值;%K 从下往上穿过 %D 形成金叉;当前 %K 减去前面第 InpMomBars 根的 %K 大于等于 0,说明空头跌不动了。

平仓信号更简单:只要出现金叉就画黄色圆点提示平空仓,只要出现死叉就画青色圆点提示平多仓。平仓信号不看超买超卖区,也不看动能。

参数说明

  • InpKPeriod(14):计算 %K 线的回看周期。数值越小对价格变动越敏感,信号越多但杂波也多。
  • InpDPeriod(3):%D 线的平滑周期。
  • InpSlowing(3):减速因子,用来平滑 %K 线。这三个参数就是标准随机指标的设置。
  • InpOverbought(70.0):超买阈值。只有 %K 高于这个值时出现的死叉才会触发做空箭头。
  • InpOversold(30.0):超卖阈值。只有 %K 低于这个值时出现的金叉才会触发做多箭头。
  • InpMomBars(3):动能减弱回看 K 线数。拿当前 %K 和几根 K 线前的 %K 比大小。数值越大,要求动能衰竭得越彻底,开仓信号越少。

怎么用

把源码保存为 .mq5 文件,放进 MT5 数据文件夹的 MQL5\Indicators 目录下,回到软件里刷新导航器就能找到。把它拖到任意品种的主图上,它会自动弹出一个独立的副图窗口,范围固定在 0 到 100,并画出两条灰色的虚线代表超买超卖水平位。

看图时盯住四种标记:红箭头是开空提示,绿箭头是开多提示,黄点是平空提示,青点是平多提示。蓝线是 %K,红线是 %D。

适用场景

这套逻辑天生适合横盘震荡的品种和周期,比如没有明显单边趋势时的外汇直盘或某些时段的大宗商品。InpMomBars 的加入就是为了防止在震荡区间里过早进场。

它不适合单边极强趋势。一旦价格走出流畅的单边行情,%K 会长时间贴在超买或超卖区钝化,这时候按信号逆势操作很容易吃亏。建议配合主图的均线或趋势线一起看,确认大方向没走偏再用它的信号找入场点。

风险提示

第一,所有基于交叉的信号都有滞后性,等箭头画出来时,那一波短线可能已经走了一段。

第二,代码里的信号是在当前 K 线走完、下一根 K 线开盘时计算的,如果当前 K 线还没收盘,箭头可能会闪烁甚至消失,不要看着盘中没定型的信号就急着进场。

第三,平仓信号只看交叉,不看位置。在强趋势里,频繁的金叉死叉会导致你被反复扫损。

第四,这只是一个辅助看图工具,不带任何资金管理或止损止盈逻辑,盈亏完全取决于你自己的交易计划。

常见问题

这个指标会重绘吗?
历史 K 线上的信号不会重绘。但在当前正在走的这根 K 线没收盘之前,如果条件忽隐忽现,箭头可能会闪烁,必须等 K 线收盘定型才算数。
可以用在 XAUUSD 以外的品种吗?
可以。代码里用的是 _Symbol 和 _Period,挂在 MT5 支持的任何品种图表上都能正常计算,但不同品种的默认参数可能需要微调。
MT4 能用吗?
不能直接用。这是 MQL5 语法写的指标,调用了 MT5 特有的句柄机制,要在 MT4 上用需要按 MQL4 语法重写。
参数默认值适合什么周期?
14/3/3 搭配 70/30 是经典设置,通常用在 15 分钟到 4 小时图上比较合适。如果是 1 分钟剥头皮,可以考虑把 InpKPeriod 改小,但假信号会变多。
它会帮我自动下单吗?
不会。这纯粹是一个画图指标,只在副图上显示箭头和线条,没有任何发送订单的代码。

Stochastic Momentum Signal Indicator for MT5

A MetaTrader 5 sub-window indicator that enhances the classic Stochastic Oscillator with momentum decay filtering. It plots %K and %D lines along with arrow signals for opening and closing trades based on overbought/oversold zones and crossovers.

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

评论

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

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