MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
#property copyright "XAUOF 指标工坊"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
// ==================== 输入参数 ====================
input int InpLookback = 300; // 回溯K线数:扫描最近多少根K线寻找订单块,推荐 200-500
input int InpMaxBlocks = 5; // 最大显示数量:图上最多同时保留几个订单块,推荐 3-10
input color InpBullColor = clrDodgerBlue; // 看涨订单块颜色:推荐 DodgerBlue 或 LimeGreen
input color InpBearColor = clrCrimson; // 看跌订单块颜色:推荐 Crimson 或 OrangeRed
input int InpRectAlpha = 40; // 矩形透明度:0完全透明~255完全不透明,推荐 30-60
input bool InpEnableAlert = true; // 是否开启弹窗提醒:价格回到订单块区域时弹窗
input int InpAlertCooldown = 10; // 提醒冷却时间(分钟):同一订单块多久内不重复弹窗,推荐 5-15
// ==================== 全局变量 ====================
struct OrderBlock
{
string name; // 图表对象名称
bool isBullish; // true=看涨, false=看跌
double topPrice; // 区域上沿价格
double bottomPrice; // 区域下沿价格
datetime startTime; // 订单块起始时间
bool alerted; // 本轮是否已提醒过
};
OrderBlock g_blocks[]; // 存储当前所有订单块的数组
string g_prefix = "OB_XAUOF_"; // 对象名称前缀,防止与其他指标冲突
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 清除可能残留的旧对象
ObjectsDeleteAll(0, g_prefix);
ArrayFree(g_blocks);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 反初始化函数:卸载指标时清理图表上的矩形 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, g_prefix);
}
//+------------------------------------------------------------------+
//| 主计算函数(MQL5 指标必须实现) |
//+------------------------------------------------------------------+
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 < 5) return 0;
// 只在每根新K线开盘时重新扫描一次,避免逐笔跳动导致频繁重绘和卡顿
static datetime s_lastBarTime = 0;
if(time[rates_total - 1] == s_lastBarTime)
{
// 非新K线时,仅检查价格是否进入已有订单块以触发提醒
CheckAlerts(close[rates_total - 1], time[rates_total - 1]);
return rates_total;
}
s_lastBarTime = time[rates_total - 1];
// 第一步:删除旧的订单块对象和数组
ObjectsDeleteAll(0, g_prefix);
ArrayFree(g_blocks);
// 第二步:扫描并识别新的订单块
ScanOrderBlocks(rates_total, time, open, high, low, close);
// 第三步:将识别到的订单块画到图表上
DrawOrderBlocks();
// 第四步:检查当前价格是否在某个订单块内,触发提醒
CheckAlerts(close[rates_total - 1], time[rates_total - 1]);
return rates_total;
}
//+------------------------------------------------------------------+
//| 核心逻辑:扫描历史K线,寻找看涨和看跌订单块 |
//+------------------------------------------------------------------+
void ScanOrderBlocks(int rates_total,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[])
{
// 确定扫描起点,防止数组越界
int startIdx = rates_total - InpLookback;
if(startIdx < 2) startIdx = 2;
// 终点留一根K线余量,因为需要看后面的K线是否突破了它
int endIdx = rates_total - 2;
for(int i = startIdx; i <= endIdx; i++)
{
// 限制最大数量,达到上限就不再找了
if(ArraySize(g_blocks) >= InpMaxBlocks) break;
// --------------------------------------------------
// 1. 寻找看涨订单块 (Bullish Order Block)
// 条件:当前K线是阴线(收盘<开盘),且后面某根K线的收盘价突破了这根阴线的最高价
// --------------------------------------------------
if(close[i] < open[i])
{
bool broken = false;
// 向后最多找 50 根 K 线看有没有突破
int searchLimit = i + 50;
if(searchLimit > rates_total - 1) searchLimit = rates_total - 1;
for(int j = i + 1; j <= searchLimit; j++)
{
if(close[j] > high[i]) // 阳线实体突破阴线最高点,确认订单块有效
{
broken = true;
break;
}
}
if(broken)
{
AddBlock(true, high[i], low[i], time[i]);
}
}
// --------------------------------------------------
// 2. 寻找看跌订单块 (Bearish Order Block)
// 条件:当前K线是阳线(收盘>开盘),且后面某根K线的收盘价跌破了这根阳线的最低价
// --------------------------------------------------
if(close[i] > open[i])
{
bool broken = false;
int searchLimit = i + 50;
if(searchLimit > rates_total - 1) searchLimit = rates_total - 1;
for(int j = i + 1; j <= searchLimit; j++)
{
if(close[j] < low[i]) // 阴线实体跌破阳线最低点,确认订单块有效
{
broken = true;
break;
}
}
if(broken)
{
AddBlock(false, high[i], low[i], time[i]);
}
}
}
}
//+------------------------------------------------------------------+
//| 辅助函数:将一个识别出的订单块加入数组(带去重判断) |
//+------------------------------------------------------------------+
void AddBlock(bool isBullish, double top, double bottom, datetime tStart)
{
// 防止除数为0及无效价格
if(top <= 0 || bottom <= 0 || top < bottom) return;
// 简单去重:如果价格区间和时间与已有的高度重合,就不重复添加
for(int k = 0; k < ArraySize(g_blocks); k++)
{
if(MathAbs(g_blocks[k].topPrice - top) < 10 * _Point &&
g_blocks[k].startTime == tStart)
{
return;
}
}
int size = ArraySize(g_blocks);
ArrayResize(g_blocks, size + 1);
g_blocks[size].isBullish = isBullish;
g_blocks[size].topPrice = top;
g_blocks[size].bottomPrice = bottom;
g_blocks[size].startTime = tStart;
g_blocks[size].alerted = false;
g_blocks[size].name = g_prefix + IntegerToString(tStart) + "_" + IntegerToString(size);
}
//+------------------------------------------------------------------+
//| 绘图函数:把数组里的订单块画成半透明矩形 |
//+------------------------------------------------------------------+
void DrawOrderBlocks()
{
for(int i = 0; i < ArraySize(g_blocks); i++)
{
string name = g_blocks[i].name;
color rColor = g_blocks[i].isBullish ? InpBullColor : InpBearColor;
// 矩形起点为订单块形成的K线时间,终点延伸到图表最右侧
datetime t1 = g_blocks[i].startTime;
datetime t2 = TimeCurrent() + PeriodSeconds() * 20;
// 创建矩形对象
ObjectCreate(0, name, OBJ_RECTANGLE, 0, t1, g_blocks[i].topPrice, t2, g_blocks[i].bottomPrice);
// 设置边框颜色和填充颜色一致
ObjectSetInteger(0, name, OBJPROP_COLOR, rColor);
ObjectSetInteger(0, name, OBJPROP_FILL, true); // 开启填充
ObjectSetInteger(0, name, OBJPROP_BACK, true); // 放在K线背景层,不遮挡K线
// 设置透明度 (0-255)
int alpha = InpRectAlpha;
if(alpha < 0) alpha = 0;
if(alpha > 255) alpha = 255;
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, ColorToARGB(rColor, alpha));
// 边框设为虚线更美观
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DASH);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
// 设置鼠标悬停时的提示文字
string tip = (g_blocks[i].isBullish ? "【看涨订单块】" : "【看跌订单块】") +
"\n上沿: " + DoubleToString(g_blocks[i].topPrice, _Digits) +
"\n下沿: " + DoubleToString(g_blocks[i].bottomPrice, _Digits);
ObjectSetString(0, name, OBJPROP_TOOLTIP, tip);
}
}
//+------------------------------------------------------------------+
//| 提醒函数:判断当前价格是否进入了某个订单块区域 |
//+------------------------------------------------------------------+
void CheckAlerts(double currentPrice, datetime currentTime)
{
if(!InpEnableAlert) return;
for(int i = 0; i < ArraySize(g_blocks); i++)
{
double top = g_blocks[i].topPrice;
double bot = g_blocks[i].bottomPrice;
// 判断当前价格是否在订单块的上下沿之间
if(currentPrice >= bot && currentPrice <= top)
{
if(!g_blocks[i].alerted)
{
string typeStr = g_blocks[i].isBullish ? "看涨(做多)" : "看跌(做空)";
string msg = StringFormat("XAUOF订单块提醒: %s 价格已进入 %s 订单块区域! [%.2f - %.2f]",
_Symbol, typeStr, bot, top);
Alert(msg); // 弹窗提醒
PlaySound("alert.wav"); // 播放声音
g_blocks[i].alerted = true; // 标记为已提醒,防止疯狂弹窗
}
}
else
{
// 价格离开订单块区域后,重置提醒状态,下次再进来还能提醒
if(g_blocks[i].alerted)
{
// 可选:加入冷却时间判断,这里简化处理,离开即重置
g_blocks[i].alerted = false;
}
}
}
}
//+------------------------------------------------------------------+作品说明
思路说明: 本指标基于 SMC(聪明钱概念)识别订单块。看涨 OB:下跌趋势中,最后一根阴线被后续阳线实体突破后,该阴线的最高/最低价构成支撑区;看跌 OB 反之。代码通过遍历 K 线寻找结构突破,用 OBJ_RECTANGLE 画半透明矩形,价格回踩时弹窗提醒。
使用说明
- 安装方法:
- 打开 MetaTrader 5,点击菜单栏「文件」->「打开数据文件夹」。
- 进入
MQL5\Indicators\目录,将上述代码保存为OrderBlock_Indicator.mq5。 - 回到 MT5,在「导航器」面板右键点击「指标」选择「刷新」,然后将其拖拽到图表上即可。
- 参数调节建议:
- 回溯K线数 (`InpLookback`):决定指标往前看多远去寻找订单块。短线交易(如 M5/M15)建议设 100-200;长线(H4/D1)建议设 300-500。数值越大计算越慢。
- 最大显示数量 (`InpMaxBlocks`):控制图上最多画几个矩形。建议保持 3-8 个,太多会导致图表杂乱失去参考价值。
- 矩形透明度 (`InpRectAlpha`):范围 0~255。推荐设为 30-60,既能看清区域又不会完全遮挡背后的 K 线走势。
- 提醒冷却:当价格进入矩形区域时会弹窗一次,价格离开该区域后重置。这避免了价格在区域内波动时连续疯狂弹窗。
- 信号怎么看:
- 蓝色矩形(看涨订单块):代表机构曾在此处吸筹。当价格回调跌入该蓝色区域时,是潜在的做多机会,可结合 K 线反转形态(如锤子线、吞没)入场。
- 红色矩形(看跌订单块):代表机构曾在此处派发。当价格反弹涨入该红色区域时,是潜在的做空机会。
- 弹窗提醒:当实时价格触及这些关键区域时,MT5 会自动弹出警告窗口并发出提示音,防止你盯盘遗漏。
- 注意事项:
- 订单块属于 SMC(聪明钱)体系中的左侧参考区域,不能无脑挂单。价格回到订单块后,务必切到小级别(如 M1/M5)观察是否有结构破坏(CHoCH)或动能衰竭再进场。
- 如果订单块被大实体 K 线直接贯穿且没有停顿,说明该订单块已失效(被流动性猎取),指标会在下一次新 K 线刷新时自动将其剔除。
- 本指标仅在图表上绘制矩形对象,不会自动执行任何买卖下单操作。
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
这是一个运行在 MetaTrader 5 上的图表指标,基于 SMC(聪明钱概念)自动寻找看涨和看跌订单块。它会在图表上画出半透明矩形标出这些关键区域,当实时价格回到矩形范围内时,会自动弹窗并发出声音提醒。解决的是手动找订单块费时费力、容易盯盘遗漏的问题。
逻辑原理
指标不画线,只画矩形对象。计算逻辑分四步:
- 每根新 K 线开盘时,往回扫描指定数量的历史 K 线。
- 找看涨订单块:如果某根 K 线是阴线(收盘价小于开盘价),且往后最多 50 根 K 线内有一根的收盘价突破了这根阴线的最高价,就把这根阴线的最高价和最低价记为一个看涨订单块。
- 找看跌订单块:反过来,阳线被后续 K 线收盘价跌破最低价,就记为看跌订单块。
- 用
OBJ_RECTANGLE把找到的区域画成虚线边框的半透明矩形,起点是订单块形成的时间,终点延伸到图表右侧。同时检查当前价格是否在某个矩形内,如果在且没提醒过,就弹窗并播放 alert.wav;价格离开后重置状态,下次再进还能提醒。
参数说明
- InpLookback(300):往前扫描多少根 K 线寻找订单块。数值越大找得越远,但计算量增加。短线可改小,长线可改大。
- InpMaxBlocks(5):图表上最多同时保留几个订单块矩形。达到上限就不再找新的了。
- InpBullColor(clrDodgerBlue):看涨订单块的矩形颜色。
- InpBearColor(clrCrimson):看跌订单块的矩形颜色。
- InpRectAlpha(40):矩形填充透明度,范围 0 到 255。0 是完全透明,255 是不透明。
- InpEnableAlert(true):是否开启价格进入订单块时的弹窗提醒。
- InpAlertCooldown(10):代码中声明了此参数作为冷却时间参考,但实际提醒重置逻辑是价格离开矩形区域即重置。
怎么用
打开 MT5,点击「文件」->「打开数据文件夹」,进入 MQL5\Indicators 目录,将源码保存为 .mq5 文件。回到 MT5 导航器面板右键刷新指标列表,把它拖到你想看的图表上即可。图上会出现蓝色或红色的半透明虚线矩形。鼠标悬停在矩形上能看到提示文字,显示这是看涨还是看跌以及上下沿价格。当价格走进矩形时,MT5 会弹出警告窗口并响铃。
适用场景
适合习惯用 SMC 体系交易的人,用来快速定位潜在的供需区。品种和周期代码里没有限制,外汇、黄金、指数都能挂。因为每次新 K 线都会重新扫描,短周期(如 M5、M15)配合较小的 InpLookback 值反应较快;长周期(H4、D1)可以把回溯数调大。不适合指望它直接给出买卖点的人,它只画区域,不判断进出场。
风险提示
第一,新 K 线出现时会删除旧矩形重新扫描,所以订单块的位置可能会变,这不是传统意义上的重绘,而是动态更新。第二,突破判定只看收盘价,盘中插针穿过不算,可能漏掉一些极端行情的订单块。第三,向后搜索突破最多只看 50 根 K 线,超过 50 根才突破的结构不会被识别。第四,提醒重置条件是价格离开矩形,如果价格在矩形边缘反复横跳,可能会频繁弹窗。第五,订单块只是参考区域,不能无脑挂单,需结合小级别走势自行判断。
常见问题
- 这个指标会重绘吗?
- 每根新K线开盘时会清除旧矩形重新扫描,订单块位置可能随新结构变化而更新,属于动态刷新而非恶意重绘。
- 可以用在XAUUSD以外的品种吗?
- 代码里没有品种限制,外汇、指数、加密货币等MT5支持的品种都可以挂上去测试。
- MT4能用吗?
- 这是MQL5代码,只能在MetaTrader 5上使用,不能直接用于MT4。
- 参数默认值适合什么周期?
- InpLookback默认300,适合H1或H4级别。如果是M5或M15短线,建议改小到100至200,避免计算过多无用历史。
- 弹窗太频繁怎么办?
- 代码里的重置逻辑是价格离开矩形区域就重置。如果嫌频繁,可以关掉InpEnableAlert,或者调小InpRectAlpha让视觉干扰少一点,自己盯盘。
Smart Order Block Auto Detection Indicator for MT5
This MT5 indicator automatically identifies bullish and bearish order blocks based on SMC concepts. It draws semi-transparent rectangles on the chart and triggers popup alerts when price returns to these zones.
Source code is shown above. Compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。