订单块自动识别指标
自动标记看涨看跌订单块矩形区域,价格回测时弹窗提醒
#property copyright "XAUOF 指标工坊"
#property version "1.00"
#property strict
#property indicator_chart_window
//--- 输入参数
input int MaxBlocks = 10; // 最多显示订单块数量(1-50)
input int MinBodyPips = 100; // 最小实体点数(识别敏感度,越大越严格)
input int ConfirmBars = 5; // 确认K线数量(反转后几根确认)
input int LookbackBars = 500; // 回溯K线数量(扫描范围)
input color BullColor = clrDodgerBlue; // 看涨订单块颜色
input color BearColor = clrCrimson; // 看跌订单块颜色
input int Transparency = 85; // 透明度(0-255,数值越大越不透明)
input bool EnableAlert = true; // 开启价格回测提醒
input bool ExtendRight = true; // 矩形向右延伸
//--- 订单块结构
struct OrderBlock
{
datetime time; // 订单块K线时间
double high; // 上边界
double low; // 下边界
int type; // 1=看涨,-1=看跌
bool alerted; // 是否已提醒
string objName; // 对象名称
};
//--- 全局变量
OrderBlock g_blocks[];
int g_blockCount = 0;
datetime g_lastBarTime = 0;
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 参数校验
if(MaxBlocks < 1 || MaxBlocks > 50)
{
Print("MaxBlocks 参数必须在 1-50 之间");
return INIT_PARAMETERS_INCORRECT;
}
// 初始化数组
ArrayResize(g_blocks, MaxBlocks);
g_blockCount = 0;
g_lastBarTime = 0;
Print("订单块指标初始化成功");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| 清理函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 删除所有订单块对象
for(int i = 0; i < g_blockCount; i++)
{
if(g_blocks[i].objName != "")
ObjectDelete(0, g_blocks[i].objName);
}
Print("订单块指标已卸载");
}
//+------------------------------------------------------------------+
//| 主计算函数 |
//+------------------------------------------------------------------+
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 < ConfirmBars + 10)
return 0;
// 检查是否有新K线
if(time[rates_total - 1] != g_lastBarTime)
{
g_lastBarTime = time[rates_total - 1];
// 扫描并识别新订单块
ScanForOrderBlocks(rates_total, time, open, high, low, close);
}
// 检查价格回测
if(EnableAlert && g_blockCount > 0)
{
CheckPriceRetest(close[rates_total - 1]);
}
return rates_total;
}
//+------------------------------------------------------------------+
//| 扫描并识别订单块 |
//+------------------------------------------------------------------+
void ScanForOrderBlocks(const int rates_total,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[])
{
int startBar = MathMax(rates_total - LookbackBars, ConfirmBars + 1);
int endBar = rates_total - ConfirmBars - 1; // 留出确认空间
// 从较早的K线向当前扫描
for(int i = startBar; i < endBar; i++)
{
// 跳过已识别区域(避免重复)
if(IsOverlapping(time[i], high[i], low[i]))
continue;
// 计算实体大小
double body = MathAbs(close[i] - open[i]);
if(body < MinBodyPips * _Point)
continue;
// 看涨订单块:大阴线 + 后续突破高点
if(close[i] < open[i])
{
bool bullishBreak = false;
for(int j = i + 1; j <= i + ConfirmBars && j < rates_total; j++)
{
if(close[j] > high[i])
{
bullishBreak = true;
break;
}
}
if(bullishBreak)
{
AddOrderBlock(time[i], high[i], low[i], 1);
continue; // 避免同一根K线既是看涨又是看跌
}
}
// 看跌订单块:大阳线 + 后续跌破低点
if(close[i] > open[i])
{
bool bearishBreak = false;
for(int j = i + 1; j <= i + ConfirmBars && j < rates_total; j++)
{
if(close[j] < low[i])
{
bearishBreak = true;
break;
}
}
if(bearishBreak)
{
AddOrderBlock(time[i], high[i], low[i], -1);
}
}
}
}
//+------------------------------------------------------------------+
//| 检查是否与已有订单块重叠 |
//+------------------------------------------------------------------+
bool IsOverlapping(datetime checkTime, double checkHigh, double checkLow)
{
for(int i = 0; i < g_blockCount; i++)
{
// 时间相同或价格区域重叠
if(g_blocks[i].time == checkTime)
return true;
if(!(checkHigh < g_blocks[i].low || checkLow > g_blocks[i].high))
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 添加订单块 |
//+------------------------------------------------------------------+
void AddOrderBlock(datetime blockTime, double blockHigh, double blockLow, int blockType)
{
// 如果已满,删除最老的
if(g_blockCount >= MaxBlocks)
{
ObjectDelete(0, g_blocks[0].objName);
// 前移数组
for(int i = 0; i < g_blockCount - 1; i++)
{
g_blocks[i] = g_blocks[i + 1];
}
g_blockCount--;
}
// 创建新订单块
OrderBlock newBlock;
newBlock.time = blockTime;
newBlock.high = blockHigh;
newBlock.low = blockLow;
newBlock.type = blockType;
newBlock.alerted = false;
newBlock.objName = "OB_" + (blockType == 1 ? "Bull_" : "Bear_") + TimeToString(blockTime, TIME_DATE | TIME_SECONDS);
// 画矩形
DrawOrderBlock(newBlock);
// 添加到数组
g_blocks[g_blockCount] = newBlock;
g_blockCount++;
}
//+------------------------------------------------------------------+
//| 画订单块矩形 |
//+------------------------------------------------------------------+
void DrawOrderBlock(OrderBlock &block)
{
datetime timeEnd = ExtendRight ? TimeCurrent() + PeriodSeconds() * 100 : TimeCurrent();
// 创建矩形对象
if(!ObjectCreate(0, block.objName, OBJ_RECTANGLE, 0, block.time, block.high, timeEnd, block.low))
{
Print("创建矩形失败: ", GetLastError());
return;
}
// 设置颜色和样式
color blockColor = (block.type == 1) ? BullColor : BearColor;
// 组合透明度:格式为 0xAARRGGBB (AA=透明度, RR=红, GG=绿, BB=蓝)
uint alpha = (uint)Transparency << 24;
uint rgb = (uint)blockColor & 0x00FFFFFF;
color finalColor = (color)(alpha | rgb);
ObjectSetInteger(0, block.objName, OBJPROP_COLOR, blockColor); // 边框颜色
ObjectSetInteger(0, block.objName, OBJPROP_BGCOLOR, finalColor); // 填充颜色(带透明度)
ObjectSetInteger(0, block.objName, OBJPROP_FILL, true); // 开启填充
ObjectSetInteger(0, block.objName, OBJPROP_BACK, true); // 背景显示
ObjectSetInteger(0, block.objName, OBJPROP_SELECTABLE, false); // 不可选中
ObjectSetInteger(0, block.objName, OBJPROP_HIDDEN, true); // 对象列表隐藏
ObjectSetInteger(0, block.objName, OBJPROP_WIDTH, 1); // 边框宽度
if(ExtendRight)
{
ObjectSetInteger(0, block.objName, OBJPROP_RAY_RIGHT, true); // 向右延伸
}
// 添加文字标签
string label = (block.type == 1) ? "看涨OB" : "看跌OB";
ObjectSetString(0, block.objName, OBJPROP_TEXT, label);
}
//+------------------------------------------------------------------+
//| 检查价格回测 |
//+------------------------------------------------------------------+
void CheckPriceRetest(double currentPrice)
{
for(int i = 0; i < g_blockCount; i++)
{
// 判断当前价格是否在订单块区域内
bool inZone = (currentPrice >= g_blocks[i].low && currentPrice <= g_blocks[i].high);
if(inZone && !g_blocks[i].alerted)
{
// 第一次回测,弹窗提醒
string msg = StringFormat("价格回测到%s订单块!\n区域:%.5f - %.5f",
g_blocks[i].type == 1 ? "看涨" : "看跌",
g_blocks[i].low,
g_blocks[i].high);
Alert(msg);
g_blocks[i].alerted = true;
}
else if(!inZone && g_blocks[i].alerted)
{
// 离开区域后重置,以便下次回测再提醒
g_blocks[i].alerted = false;
}
// 更新矩形右端(如果开启延伸)
if(ExtendRight)
{
datetime timeEnd = TimeCurrent() + PeriodSeconds() * 100;
ObjectSetInteger(0, g_blocks[i].objName, OBJPROP_TIME, 1, timeEnd);
}
}
}
//+------------------------------------------------------------------+作品说明
好的,我来写一个订单块(Order Block)指标。订单块是 Smart Money Concept(SMC)中的核心概念:市场中大资金建仓的区域,价格回测时往往会产生反应。
识别逻辑:
- 看涨订单块:下跌后出现的大阴线,随后价格突破其高点反转上涨,该阴线区域即为潜在买方订单块
- 看跌订单块:上涨后出现的大阳线,随后价格跌破其低点反转下跌,该阳线区域即为潜在卖方订单块
代码会自动扫描历史K线,识别符合条件的订单块,画成半透明矩形,当价格回测到区域时弹窗提醒。
使用说明
安装步骤
- 将代码保存为
OrderBlockIndicator.mq5,放入 MT5 的MQL5\Indicators目录 - 在 MetaEditor 中编译,或重启 MT5 自动编译
- 在图表上右键 → "技术指标" → "自定义" → 选择 "OrderBlockIndicator"
参数调节
- 最多显示订单块数量:建议 5-15 个,太多会显得杂乱
- 最小实体点数:黄金建议 100-200 点(0.10-0.20 美元),过滤掉小 K 线
- 确认K线数量:3-5 根,太小会误判,太大会滞后
- 回溯K线数量:500-1000 根,控制扫描范围和性能
- 透明度:85-150 合适,既能看清又不遮挡 K 线
信号解读
- 蓝色矩形:看涨订单块,价格回测时考虑做多
- 红色矩形:看跌订单块,价格回测时考虑做空
- 订单块是大资金建仓区域,价格回测常有支撑/阻力作用
- 配合趋势使用:上涨趋势中关注看涨 OB,下跌趋势关注看跌 OB
注意事项
- 订单块不是万能信号,需结合趋势、结构、量能综合判断
- 弹窗提醒只在收盘时检查,避免盘中频繁打扰
- 旧订单块价格多次穿越后有效性降低,可考虑手动删除
- 小周期(M1/M5)订单块较多,建议调高最小实体点数过滤
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
这是一个基于 Smart Money Concept(SMC)的订单块自动识别指标。订单块是大资金建仓留下的痕迹区域,价格回测到这些区域时往往会产生支撑或阻力。指标会在图表上画出蓝色(看涨)和红色(看跌)的半透明矩形,当价格重新回到这些区域时弹窗提醒,帮助你抓住回调入场的机会。
逻辑原理
看涨订单块(蓝色矩形):代码扫描历史 K 线,找到实体足够大的阴线(收盘价低于开盘价),然后检查后续几根 K 线是否有收盘价突破这根阴线的高点。如果有,说明价格在这根阴线区域反转上涨,这个区域就是潜在的买方订单块。矩形的上下边界就是这根阴线的最高价和最低价。
看跌订单块(红色矩形):逻辑相反,找实体大的阳线(收盘价高于开盘价),检查后续是否有收盘价跌破这根阳线的低点。如果有,说明价格在这个区域反转下跌,这是潜在的卖方订单块。
回测提醒:每根 K 线收盘时,指标检查当前价格是否进入已标记的订单块区域。如果进入且之前没提醒过,就弹窗通知你。离开区域后状态重置,下次回测还会再提醒。
参数说明
- MaxBlocks(默认 10):最多在图上显示几个订单块。超出数量时删除最老的。建议 5-15 个,太多会显得杂乱。
- MinBodyPips(默认 100):K 线实体至少要多少点才算有效订单块。黄金建议 100-200 点,欧美可以 30-50 点,用来过滤掉小 K 线。
- ConfirmBars(默认 5):反转后用几根 K 线来确认突破。3-5 根比较合适,太小容易误判,太大会滞后。
- LookbackBars(默认 500):向前扫描多少根 K 线。500-1000 根能覆盖足够历史,也不会太拖性能。
- BullColor(默认 clrDodgerBlue):看涨订单块的矩形颜色,默认蓝色。
- BearColor(默认 clrCrimson):看跌订单块的矩形颜色,默认红色。
- Transparency(默认 85):矩形透明度,0 是完全透明,255 是完全不透明。85-150 合适,既能看清又不遮挡 K 线。
- EnableAlert(默认 true):开启价格回测弹窗提醒。不想被打扰可以关掉。
- ExtendRight(默认 true):矩形是否向右延伸到当前时间。开启后能看到未来价格接近哪个订单块。
怎么用
- 把代码保存为
OrderBlockIndicator.mq5,放到 MT5 安装目录下的MQL5\Indicators文件夹 - 在 MetaEditor 里编译,或者重启 MT5 让它自动编译
- 打开任意图表,右键 → "技术指标" → "自定义" → 选择 "OrderBlockIndicator"
- 调整参数后点确定,图表上就会显示蓝色和红色的矩形区域
- 看涨订单块(蓝色)适合在上涨趋势中等回调买入,看跌订单块(红色)适合在下跌趋势中等反弹卖出
- 价格回测到区域时会弹窗,你可以结合其他信号判断是否入场
适用场景
订单块概念来自机构交易逻辑,适合趋势明显的品种和周期。黄金、原油、主要外汇对在 H1、H4、D1 周期效果比较好,因为大资金在这些周期留下的痕迹更清晰。上涨趋势中关注蓝色订单块做回调多单,下跌趋势中关注红色订单块做反弹空单。
不适合震荡行情和小周期。横盘整理时订单块信号会很多且相互矛盾,M1、M5 这种小周期订单块密密麻麻,噪音太大。如果非要用小周期,建议把 MinBodyPips 调高(比如 200-300 点),只保留最明显的几个。
配合趋势判断工具一起用效果更好,比如均线、趋势线、结构高低点。订单块本身只是潜在的支撑阻力,不是独立的交易系统。
风险提示
滞后性:订单块需要等反转确认后才画出来,所以你看到的矩形都是事后标记的,不是实时预测。入场时那根大 K 线早就走完了,只能等价格回测。
假信号:不是所有订单块都会有效。价格可能直接穿透区域不停留,或者停留后继续原方向。震荡行情里订单块信号会很乱,需要你自己过滤。
弹窗频繁:如果订单块很多且价格在区域附近反复震荡,可能短时间内多次弹窗。可以关闭 EnableAlert 参数,或者减少 MaxBlocks 数量。
参数敏感:MinBodyPips 和 ConfirmBars 对结果影响很大。设太小会识别出很多无效区域,设太大会漏掉有效的。不同品种和周期需要分别测试调优,黄金的 100 点对欧美可能就是 30 点。
旧订单块失效:代码会一直保留最近的 MaxBlocks 个订单块,但实际上被多次穿透的区域有效性会降低。指标不会自动删除失效的,你需要观察并手动判断。
常见问题
- 这个指标会重绘吗?
- 不会。订单块一旦画出来,位置就固定了,不会随新 K 线变化。但需要等确认 K 线走完才会显示,所以有滞后。
- 可以用在黄金以外的品种吗?
- 可以。原油、主要外汇对、指数都行。但 MinBodyPips 参数要根据品种点值调整,黄金 100 点合适,欧美可能要改成 30-50 点。
- MT4 能用吗?
- 不能直接用,这是 MQL5 代码,只支持 MT5。MT4 需要用 MQL4 重写,语法和函数不一样。
- 参数默认值适合什么周期?
- 默认值(MinBodyPips=100、ConfirmBars=5)比较适合黄金 H1 和 H4 周期。小周期建议调高 MinBodyPips 到 200 以上,日线可以降到 50-80。
- 为什么有的订单块价格穿过去没反应?
- 订单块只是潜在支撑阻力,不保证每次都有效。需要结合趋势方向、多次回测情况、其他信号综合判断,不能单独作为入场依据。
Order Block Auto Detection Indicator for MT5
Automatically identifies bullish and bearish order blocks based on Smart Money concepts. Draws semi-transparent rectangles on the chart and alerts when price retests these zones. Configurable parameters include minimum body size, confirmation bars, and alert settings.
Source code is shown above. Compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。