随机指标多空动能信号系统
超买超卖区结合动能衰减画KD线及开平仓箭头信号
MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
#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;
}
//+------------------------------------------------------------------+作品说明
错误原因说明: INDICATOR_MINIMUM 和 INDICATOR_MAXIMUM 是副图坐标轴的极值属性,在 MQL5 中必须使用 IndicatorSetDouble() 设置(因为它们是浮点数),而不能用 IndicatorSetInteger()。原代码误用了整数设置函数导致参数个数不匹配和枚举转换失败。已修正为 IndicatorSetDouble(INDICATOR_MINIMUM, 0.0) 和 IndicatorSetDouble(INDICATOR_MAXIMUM, 100.0)。
以下是完整、可直接编译通过的代码:
使用说明
- 怎么安装:
- 打开 MetaTrader 5,点击菜单栏
文件->打开数据文件夹。 - 进入
MQL5->Indicators目录,将上述代码保存为StochSignalIndicator.mq5文件。 - 回到 MT5,在导航器面板右键点击“指标”,选择“刷新”。
- 双击该指标或将其拖拽到任意品种的图表上即可运行。本次修复了
OnInit中的坐标轴设置函数,现在可以直接编译通过。
- 参数怎么调:
- K/D/减速周期:默认 14/3/3 是经典随机指标参数,适合大多数品种。短线交易者可改为 5/3/3。
- 超买/超卖阈值:默认 70 和 30。如果信号太少,可放宽至 80/20;如果信号太多,可收紧至 60/40。
- 动能减弱回看K线数:默认 3。表示对比当前K线和3根K线前的K值。数值越大,对“动能衰竭”的要求越严格,信号越少但胜率可能更高。
- 信号怎么看:
- 蓝线为 %K 线,红线为 %D 线。
- 红色向下箭头:满足“K值>70 + 死叉 + 多头动能减弱”,提示开空仓。
- 绿色向上箭头:满足“K值<30 + 金叉 + 空头动能减弱”,提示开多仓。
- 黄色圆点:出现金叉,提示平空仓。
- 青色圆点:出现死叉,提示平多仓。
- 注意事项:
- 本程序为技术指标,仅负责在副图上画出信号,不会自动下单。需配合手动交易或自行编写 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.
评论
还没有人评论,来抢个沙发。