SMC 机构级交易指标
智能过滤高质量订单块与 FVG,自动管理失效区域,适合专业交易
MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
#property copyright "XAUOF 指标工坊"
#property version "2.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
//--- 输入参数
input group "=== 核心设置 ==="
input int SwingStrength = 7; // 结构强度(左右确认 K 线数)
input double MinOBBodyPips = 10; // 订单块最小实体(点数)
input double MinFVGSizePips = 8; // FVG 最小尺寸(点数)
input bool AutoRemoveInvalidOB = true; // 自动移除失效订单块
input int MaxActiveOB = 8; // 最多显示订单块数量
input int MaxActiveFVG = 6; // 最多显示 FVG 数量
input group "=== 显示选项 ==="
input bool ShowSwingPoints = false; // 显示结构高低点(默认关闭)
input bool ShowOrderBlocks = true; // 显示订单块
input bool ShowFVG = true; // 显示公允价值缺口
input bool ShowOBLabels = true; // 显示订单块标签
input int OBExtendBars = 100; // 订单块延伸长度
input group "=== 专业配色 ==="
input color BullOBColor = C'30,144,255'; // 看涨订单块(深蓝)
input color BearOBColor = C'220,20,60'; // 看跌订单块(深红)
input color BullFVGColor = C'64,224,208';// 看涨 FVG(青绿)
input color BearFVGColor = C'255,182,193';// 看跌 FVG(浅粉)
input int OBTransparency = 85; // 订单块透明度(0-100)
input int FVGTransparency = 90; // FVG 透明度(0-100)
//--- 订单块结构
struct OrderBlock
{
datetime time;
double top;
double bottom;
bool isBullish;
string objName;
bool isValid;
double strength; // 强度评分
};
OrderBlock activeOBs[];
int obCount = 0;
//--- FVG 结构
struct FairValueGap
{
datetime time;
double top;
double bottom;
bool isBullish;
string objName;
bool isValid;
};
FairValueGap activeFVGs[];
int fvgCount = 0;
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
ArrayResize(activeOBs, 0);
ArrayResize(activeFVGs, 0);
obCount = 0;
fvgCount = 0;
// 清理旧对象
ObjectsDeleteAll(0, "SMC_");
// 扫描历史
ScanHistoricalData();
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 < SwingStrength * 2 + 10) return 0;
static datetime lastProcessed = 0;
datetime currentBar = time[rates_total - 1];
if(currentBar == lastProcessed) return rates_total;
lastProcessed = currentBar;
// 检查确认 K 线位置
int checkBar = rates_total - SwingStrength - 2;
if(checkBar < SwingStrength + 3) return rates_total;
// 1. 验证现有订单块是否仍然有效
if(AutoRemoveInvalidOB)
{
ValidateOrderBlocks(close[rates_total - 1]);
}
// 2. 检测新订单块
if(ShowOrderBlocks)
{
DetectNewOrderBlock(checkBar, time, open, high, low, close);
}
// 3. 检测新 FVG
if(ShowFVG)
{
DetectNewFVG(checkBar, time, high, low);
}
// 4. 检测结构点(可选)
if(ShowSwingPoints)
{
DetectSwingPoints(checkBar, rates_total, time, high, low);
}
return rates_total;
}
//+------------------------------------------------------------------+
//| 扫描历史数据 |
//+------------------------------------------------------------------+
void ScanHistoricalData()
{
int lookback = 500;
MqlRates rates[];
ArraySetAsSeries(rates, true);
int copied = CopyRates(_Symbol, PERIOD_CURRENT, 0, lookback, rates);
if(copied <= SwingStrength + 10)
{
Print("数据不足,无法扫描历史");
return;
}
// 从老到新扫描(倒序索引)
for(int i = copied - SwingStrength - 3; i >= SwingStrength + 2; i--)
{
// 检测订单块
if(ShowOrderBlocks)
{
CheckOBInHistory(i, rates);
}
// 检测 FVG
if(ShowFVG)
{
CheckFVGInHistory(i, rates);
}
}
// 只保留最强的几个
FilterTopOrderBlocks();
FilterTopFVGs();
Print(StringFormat("已加载 %d 个订单块,%d 个 FVG", obCount, fvgCount));
}
//+------------------------------------------------------------------+
//| 历史订单块检测 |
//+------------------------------------------------------------------+
void CheckOBInHistory(int idx, const MqlRates &rates[])
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double minBody = MinOBBodyPips * point;
// 看涨订单块:idx 大阳线吞没 idx+1 阴线
bool isBullOB = false;
double body1 = MathAbs(rates[idx + 1].close - rates[idx + 1].open);
double body2 = rates[idx].close - rates[idx].open;
if(rates[idx + 1].close < rates[idx + 1].open && // idx+1 是阴线
rates[idx].close > rates[idx].open && // idx 是阳线
body2 > minBody && // 阳线实体够大
rates[idx].close > rates[idx + 1].high) // 吞没前高
{
isBullOB = true;
}
// 看跌订单块:idx 大阴线吞没 idx+1 阳线
bool isBearOB = false;
double body3 = rates[idx].open - rates[idx].close;
if(rates[idx + 1].close > rates[idx + 1].open && // idx+1 是阳线
rates[idx].close < rates[idx].open && // idx 是阴线
body3 > minBody && // 阴线实体够大
rates[idx].close < rates[idx + 1].low) // 吞没前低
{
isBearOB = true;
}
// 创建订单块
if(isBullOB || isBearOB)
{
OrderBlock ob;
ob.time = rates[idx + 1].time;
ob.top = rates[idx + 1].high;
ob.bottom = rates[idx + 1].low;
ob.isBullish = isBullOB;
ob.isValid = true;
ob.strength = isBullOB ? body2 / point : body3 / point;
ob.objName = "SMC_OB_" + TimeToString(ob.time, TIME_DATE|TIME_MINUTES);
// 检查是否已存在
bool exists = false;
for(int j = 0; j < obCount; j++)
{
if(activeOBs[j].objName == ob.objName)
{
exists = true;
break;
}
}
if(!exists && obCount < 100)
{
ArrayResize(activeOBs, obCount + 1);
activeOBs[obCount] = ob;
obCount++;
}
}
}
//+------------------------------------------------------------------+
//| 历史 FVG 检测 |
//+------------------------------------------------------------------+
void CheckFVGInHistory(int idx, const MqlRates &rates[])
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double minSize = MinFVGSizePips * point;
// 看涨 FVG:idx+2.high < idx.low
if(rates[idx + 2].high < rates[idx].low)
{
double gapSize = rates[idx].low - rates[idx + 2].high;
if(gapSize >= minSize)
{
FairValueGap fvg;
fvg.time = rates[idx + 1].time;
fvg.top = rates[idx].low;
fvg.bottom = rates[idx + 2].high;
fvg.isBullish = true;
fvg.isValid = true;
fvg.objName = "SMC_FVG_" + TimeToString(rates[idx].time, TIME_DATE|TIME_MINUTES);
bool exists = false;
for(int j = 0; j < fvgCount; j++)
{
if(activeFVGs[j].objName == fvg.objName)
{
exists = true;
break;
}
}
if(!exists && fvgCount < 100)
{
ArrayResize(activeFVGs, fvgCount + 1);
activeFVGs[fvgCount] = fvg;
fvgCount++;
}
}
}
// 看跌 FVG:idx+2.low > idx.high
if(rates[idx + 2].low > rates[idx].high)
{
double gapSize = rates[idx + 2].low - rates[idx].high;
if(gapSize >= minSize)
{
FairValueGap fvg;
fvg.time = rates[idx + 1].time;
fvg.top = rates[idx + 2].low;
fvg.bottom = rates[idx].high;
fvg.isBullish = false;
fvg.isValid = true;
fvg.objName = "SMC_FVG_" + TimeToString(rates[idx].time, TIME_DATE|TIME_MINUTES);
bool exists = false;
for(int j = 0; j < fvgCount; j++)
{
if(activeFVGs[j].objName == fvg.objName)
{
exists = true;
break;
}
}
if(!exists && fvgCount < 100)
{
ArrayResize(activeFVGs, fvgCount + 1);
activeFVGs[fvgCount] = fvg;
fvgCount++;
}
}
}
}
//+------------------------------------------------------------------+
//| 只保留最强的订单块 |
//+------------------------------------------------------------------+
void FilterTopOrderBlocks()
{
if(obCount <= MaxActiveOB)
{
DrawAllOrderBlocks();
return;
}
// 按强度排序(冒泡排序)
for(int i = 0; i < obCount - 1; i++)
{
for(int j = 0; j < obCount - i - 1; j++)
{
if(activeOBs[j].strength < activeOBs[j + 1].strength)
{
OrderBlock temp = activeOBs[j];
activeOBs[j] = activeOBs[j + 1];
activeOBs[j + 1] = temp;
}
}
}
// 只保留前 MaxActiveOB 个
ArrayResize(activeOBs, MaxActiveOB);
obCount = MaxActiveOB;
DrawAllOrderBlocks();
}
//+------------------------------------------------------------------+
//| 只保留最近的 FVG |
//+------------------------------------------------------------------+
void FilterTopFVGs()
{
if(fvgCount <= MaxActiveFVG)
{
DrawAllFVGs();
return;
}
// 只保留最新的
ArrayResize(activeFVGs, MaxActiveFVG);
fvgCount = MaxActiveFVG;
DrawAllFVGs();
}
//+------------------------------------------------------------------+
//| 绘制所有订单块 |
//+------------------------------------------------------------------+
void DrawAllOrderBlocks()
{
for(int i = 0; i < obCount; i++)
{
if(!activeOBs[i].isValid) continue;
datetime t2 = activeOBs[i].time + PeriodSeconds(PERIOD_CURRENT) * OBExtendBars;
if(ObjectFind(0, activeOBs[i].objName) < 0)
{
ObjectCreate(0, activeOBs[i].objName, OBJ_RECTANGLE, 0,
activeOBs[i].time, activeOBs[i].top,
t2, activeOBs[i].bottom);
color clr = activeOBs[i].isBullish ? BullOBColor : BearOBColor;
ObjectSetInteger(0, activeOBs[i].objName, OBJPROP_COLOR, clr);
ObjectSetInteger(0, activeOBs[i].objName, OBJPROP_FILL, true);
ObjectSetInteger(0, activeOBs[i].objName, OBJPROP_BACK, true);
ObjectSetInteger(0, activeOBs[i].objName, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, activeOBs[i].objName, OBJPROP_STYLE, STYLE_SOLID);
// 设置透明度
long rgb = ObjectGetInteger(0, activeOBs[i].objName, OBJPROP_COLOR);
long alpha = (100 - OBTransparency) * 255 / 100;
ObjectSetInteger(0, activeOBs[i].objName, OBJPROP_COLOR, (alpha << 24) | rgb);
// 添加标签
if(ShowOBLabels)
{
string label = activeOBs[i].objName + "_L";
double labelPrice = activeOBs[i].isBullish ? activeOBs[i].bottom : activeOBs[i].top;
ObjectCreate(0, label, OBJ_TEXT, 0, activeOBs[i].time, labelPrice);
ObjectSetString(0, label, OBJPROP_TEXT, activeOBs[i].isBullish ? "OB↑" : "OB↓");
ObjectSetInteger(0, label, OBJPROP_COLOR, clr);
ObjectSetInteger(0, label, OBJPROP_FONTSIZE, 8);
ObjectSetInteger(0, label, OBJPROP_ANCHOR, activeOBs[i].isBullish ? ANCHOR_TOP : ANCHOR_BOTTOM);
}
}
}
}
//+------------------------------------------------------------------+
//| 绘制所有 FVG |
//+------------------------------------------------------------------+
void DrawAllFVGs()
{
for(int i = 0; i < fvgCount; i++)
{
if(!activeFVGs[i].isValid) continue;
datetime t2 = activeFVGs[i].time + PeriodSeconds(PERIOD_CURRENT) * (OBExtendBars / 2);
if(ObjectFind(0, activeFVGs[i].objName) < 0)
{
ObjectCreate(0, activeFVGs[i].objName, OBJ_RECTANGLE, 0,
activeFVGs[i].time, activeFVGs[i].top,
t2, activeFVGs[i].bottom);
color clr = activeFVGs[i].isBullish ? BullFVGColor : BearFVGColor;
ObjectSetInteger(0, activeFVGs[i].objName, OBJPROP_COLOR, clr);
ObjectSetInteger(0, activeFVGs[i].objName, OBJPROP_FILL, true);
ObjectSetInteger(0, activeFVGs[i].objName, OBJPROP_BACK, true);
ObjectSetInteger(0, activeFVGs[i].objName, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, activeFVGs[i].objName, OBJPROP_STYLE, STYLE_DOT);
// 透明度
long rgb = ObjectGetInteger(0, activeFVGs[i].objName, OBJPROP_COLOR);
long alpha = (100 - FVGTransparency) * 255 / 100;
ObjectSetInteger(0, activeFVGs[i].objName, OBJPROP_COLOR, (alpha << 24) | rgb);
}
}
}
//+------------------------------------------------------------------+
//| 验证订单块是否仍然有效 |
//+------------------------------------------------------------------+
void ValidateOrderBlocks(double currentPrice)
{
for(int i = 0; i < obCount; i++)
{
if(!activeOBs[i].isValid) continue;
// 看涨订单块被完全跌破 = 失效
if(activeOBs[i].isBullish && currentPrice < activeOBs[i].bottom)
{
activeOBs[i].isValid = false;
ObjectDelete(0, activeOBs[i].objName);
ObjectDelete(0, activeOBs[i].objName + "_L");
}
// 看跌订单块被完全突破 = 失效
if(!activeOBs[i].isBullish && currentPrice > activeOBs[i].top)
{
activeOBs[i].isValid = false;
ObjectDelete(0, activeOBs[i].objName);
ObjectDelete(0, activeOBs[i].objName + "_L");
}
}
}
//+------------------------------------------------------------------+
//| 实时检测新订单块 |
//+------------------------------------------------------------------+
void DetectNewOrderBlock(int bar, const datetime &time[], const double &open[],
const double &high[], const double &low[], const double &close[])
{
if(bar < 2) return;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double minBody = MinOBBodyPips * point;
double body = MathAbs(close[bar] - open[bar]);
if(body < minBody) return;
// 看涨 OB
if(close[bar] > open[bar] &&
close[bar] > high[bar - 1] &&
close[bar - 1] < open[bar - 1])
{
AddOrderBlock(time[bar - 1], high[bar - 1], low[bar - 1], true, body / point);
}
// 看跌 OB
if(close[bar] < open[bar] &&
close[bar] < low[bar - 1] &&
close[bar - 1] > open[bar - 1])
{
AddOrderBlock(time[bar - 1], high[bar - 1], low[bar - 1], false, body / point);
}
}
//+------------------------------------------------------------------+
//| 添加订单块 |
//+------------------------------------------------------------------+
void AddOrderBlock(datetime t, double top, double bottom, bool bull, double strength)
{
if(obCount >= MaxActiveOB) return;
OrderBlock ob;
ob.time = t;
ob.top = top;
ob.bottom = bottom;
ob.isBullish = bull;
ob.isValid = true;
ob.strength = strength;
ob.objName = "SMC_OB_" + TimeToString(t, TIME_DATE|TIME_MINUTES);
// 检查重复
for(int i = 0; i < obCount; i++)
{
if(activeOBs[i].objName == ob.objName) return;
}
ArrayResize(activeOBs, obCount + 1);
activeOBs[obCount] = ob;
obCount++;
DrawAllOrderBlocks();
}
//+------------------------------------------------------------------+
//| 实时检测 FVG |
//+------------------------------------------------------------------+
void DetectNewFVG(int bar, const datetime &time[], const double &high[], const double &low[])
{
if(bar < 2) return;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double minSize = MinFVGSizePips * point;
// 看涨 FVG
if(high[bar - 2] < low[bar])
{
double gap = low[bar] - high[bar - 2];
if(gap >= minSize)
{
AddFVG(time[bar - 1], low[bar], high[bar - 2], true);
}
}
// 看跌 FVG
if(low[bar - 2] > high[bar])
{
double gap = low[bar - 2] - high[bar];
if(gap >= minSize)
{
AddFVG(time[bar - 1], low[bar - 2], high[bar], false);
}
}
}
//+------------------------------------------------------------------+
//| 添加 FVG |
//+------------------------------------------------------------------+
void AddFVG(datetime t, double top, double bottom, bool bull)
{
if(fvgCount >= MaxActiveFVG) return;
FairValueGap fvg;
fvg.time = t;
fvg.top = top;
fvg.bottom = bottom;
fvg.isBullish = bull;
fvg.isValid = true;
fvg.objName = "SMC_FVG_" + TimeToString(t, TIME_DATE|TIME_MINUTES);
for(int i = 0; i < fvgCount; i++)
{
if(activeFVGs[i].objName == fvg.objName) return;
}
ArrayResize(activeFVGs, fvgCount + 1);
activeFVGs[fvgCount] = fvg;
fvgCount++;
DrawAllFVGs();
}
//+------------------------------------------------------------------+
//| 检测结构点 |
//+------------------------------------------------------------------+
void DetectSwingPoints(int bar, int total, const datetime &time[],
const double &high[], const double &low[])
{
if(bar < SwingStrength || bar + SwingStrength >= total) return;
bool isHigh = true;
for(int i = 1; i <= SwingStrength; i++)
{
if(high[bar - i] > high[bar] || high[bar + i] >= high[bar])
{
isHigh = false;
break;
}
}
bool isLow = true;
for(int i = 1; i <= SwingStrength; i++)
{
if(low[bar - i] < low[bar] || low[bar + i] <= low[bar])
{
isLow = false;
break;
}
}
if(isHigh)
{
string name = "SMC_SwH_" + TimeToString(time[bar], TIME_DATE|TIME_MINUTES);
if(ObjectFind(0, name) < 0)
{
ObjectCreate(0, name, OBJ_ARROW_DOWN, 0, time[bar], high[bar]);
ObjectSetInteger(0, name, OBJPROP_COLOR, clrDarkRed);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
}
}
if(isLow)
{
string name = "SMC_SwL_" + TimeToString(time[bar], TIME_DATE|TIME_MINUTES);
if(ObjectFind(0, name) < 0)
{
ObjectCreate(0, name, OBJ_ARROW_UP, 0, time[bar], low[bar]);
ObjectSetInteger(0, name, OBJPROP_COLOR, clrDarkGreen);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
}
}
}
//+------------------------------------------------------------------+
//| 清理函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "SMC_");
Comment("");
}作品说明
明白了,机构级别的指标需要清晰、专业,只显示高质量信号。我重新设计一个干净的版本:只保留有效的订单块和 FVG,自动过滤低质量信号,订单块被突破后自动失效。
使用说明
核心改进(机构级特性):
- 智能过滤:只显示实体大于 10 点的订单块,FVG 小于 8 点直接忽略
- 自动失效管理:订单块被完全突破后自动从图表移除,保持干净
- 数量控制:最多显示 8 个订单块和 6 个 FVG,防止信息过载
- 强度排序:自动保留最强的订单块(按反转 K 线实体大小)
- 专业配色:使用半透明效果,背景不遮挡 K 线,标签清晰简洁
- 结构点可选:默认关闭高低点箭头,避免混乱,需要时再开启
参数建议(黄金 H1):
- 结构强度:7(严格确认,减少假信号)
- 订单块最小实体:10-15 点(黄金波动大,过滤小反转)
- FVG 最小尺寸:8-12 点(只标记明显缺口)
- 最多订单块数量:5-8 个(图表保持整洁)
- 自动移除失效:必须开启(这是机构级的关键)
配色方案:
- 看涨订单块:深蓝色半透明(专业、不刺眼)
- 看跌订单块:深红色半透明
- FVG:更淡的青绿/浅粉,虚线边框
- 透明度:85-90%,既能看清区域又不遮挡价格
交易逻辑:
- 等待价格首次回到订单块区域(未被触碰的最佳)
- 在订单块内寻找反转确认(针形线、吞没)
- 止损放在订单块外 5-10 点
- 订单块被完全突破 = 结构失效,指标会自动移除
与普通版本的区别:
- 普通版:所有信号都显示,图表像圣诞树
- 机构版:只显示高概率区域,一眼看清关键位置
- 失效管理:自动清理无效订单块,保持专业外观
- 视觉设计:配色、透明度、标签都按机构交易室标准
注意事项:
- 首次加载扫描 500 根 K 线,H1 周期约 1 个月历史
- 如果订单块太少,降低"最小实体"参数
- 如果图表仍然混乱,减小"最多显示数量"
- 此指标只标记区域,入场时机需结合价格行为确认
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
这是一个基于 Smart Money Concepts(SMC,智能资金概念)的 MT5 指标,主要标记订单块(Order Block)和公允价值缺口(Fair Value Gap,FVG)两类关键区域。与常见的 SMC 指标不同,它内置了智能过滤和失效管理机制:只显示实体足够大的订单块和缺口,订单块被价格完全突破后自动从图表上移除,避免信息过载。适合需要干净图表、专注于高概率交易区域的用户。
逻辑原理
订单块识别:扫描 K 线序列,当出现一根大实体 K 线(实体大于设定点数)吞没前一根反向 K 线时,将被吞没的那根 K 线的高低点范围标记为订单块。看涨订单块是阳线吞没前一根阴线并突破其高点,看跌订单块是阴线吞没前一根阳线并跌破其低点。每个订单块会记录其强度(反转 K 线的实体大小),系统按强度排序并只保留最强的若干个(由"最多显示订单块数量"参数控制)。
FVG 识别:检测三根连续 K 线,如果第三根 K 线的低点高于第一根的高点(看涨缺口),或第三根的高点低于第一根的低点(看跌缺口),且缺口尺寸大于设定值,则在第二根 K 线位置标记 FVG 区域。系统保留最新的若干个 FVG。
失效管理:每次新 K 线生成时,检查所有订单块。看涨订单块如果被价格跌破其下沿,看跌订单块如果被突破其上沿,立即将该区域标记为失效并从图表删除。这避免了过期区域堆积。
结构点(可选):使用左右各 N 根 K 线确认法标记波段高点和低点,默认关闭,需要时可打开。
参数说明
- 结构强度(默认 7):确认结构高低点时需要左右各多少根 K 线支撑。数值越大,确认越严格,结构点越少但更可靠。关系到订单块和结构点检测的严谨度,建议 5-10。
- 订单块最小实体(默认 10 点):订单块的反转 K 线实体必须大于这个点数才会被标记。黄金等波动大的品种建议 10-15 点,货币对可用 5-8 点。过小会产生大量低质量区域。
- FVG 最小尺寸(默认 8 点):缺口的垂直距离必须大于此值才显示。调高可过滤噪音,调低可捕捉更多小缺口。黄金建议 8-12 点。
- 自动移除失效订单块(默认开启):订单块被突破后是否自动删除。强烈建议开启,这是本指标的核心特性,保持图表专业整洁。
- 最多显示订单块数量(默认 8):图表上同时显示的订单块上限。超过此数量时,只保留强度最高的若干个。建议 5-10,避免混乱。
- 最多显示 FVG 数量(默认 6):图表上同时显示的 FVG 上限,保留最新的几个。建议 5-8。
- 显示结构高低点(默认关闭):是否在波段高低点画箭头。一般不需要,开启后会增加视觉干扰。
- 显示订单块 / FVG / 标签:控制各类元素的显示开关。标签是订单块旁边的"OB↑"/"OB↓"文字。
- 订单块延伸长度(默认 100):订单块矩形向右延伸多少根 K 线。如果周期较大,可适当增加。
- 配色和透明度:订单块用深蓝(看涨)和深红(看跌),FVG 用青绿和浅粉。透明度 85-90% 可在标记区域的同时不遮挡价格走势。
怎么用
将 .mq5 文件放入 MT5 的 Indicators 目录,编译后拖到任意品种任意周期的图表上。指标初始化时会自动扫描最近 500 根 K 线的历史数据,标记出满足条件的订单块和 FVG。之后每生成新 K 线都会实时检测和更新。
订单块显示为半透明矩形,看涨的蓝色、看跌的红色;FVG 显示为更淡的矩形且用虚线边框。交易时等待价格回到订单块区域(尤其是未被触碰过的),在区域内寻找反转确认信号(如针形线、吞没形态),止损设在订单块外几个点。如果价格完全突破订单块,区域会自动消失,说明该结构已失效,不应再依赖它做交易。
FVG 通常被视为价格回补目标,可结合订单块使用:价格回到 FVG 内部可能遇到支撑/阻力,或继续回补缺口。
适用场景
适合黄金(XAUUSD)、主要货币对(EURUSD、GBPUSD 等)和指数,在 H1、H4、D1 等较大周期上效果较好。订单块和 FVG 在趋势行情中作为回调入场点有较高胜率,震荡市中也可作为区间边界参考。
不适合极短周期(M1、M5)——噪音太多,过滤阈值难以把握。不适合低波动品种或冷门交易时段——K 线实体太小,难以形成有效订单块。强趋势单边行情中,价格可能不回调就直接突破订单块,此时失效管理会快速清除旧区域,需结合其他工具确认入场。
风险提示
订单块和 FVG 都是基于历史 K 线形态识别的,不预测未来,只标记潜在的支撑阻力区域。价格回到区域后是否真的反转,取决于当时的市场结构和资金流向,指标本身不提供入场时机确认。
滞后性:订单块需要等待反转 K 线收盘并经过"结构强度"参数设定的确认期才会显示,实时性较差。如果参数设置过于宽松(最小实体过小、最大数量过多),图表仍会变得混乱,失去筛选意义。
失效判断是机械的:只要价格触及订单块边界就算突破,不考虑假突破或插针。真实交易中可能需要等待 K 线实体收盘确认。
不处理重绘:历史扫描和实时检测的逻辑一致,不会重绘已确认的订单块,但如果修改参数或切换周期,指标会重新计算并可能显示不同的区域。
透明度问题:代码中透明度设置使用了 RGBA 格式(alpha 通道左移 24 位),但 MT5 的对象透明度实现可能因平台版本而异,部分情况下透明效果可能不明显或无效,需自行调整参数。
常见问题
- 这个指标会重绘吗?
- 不会。订单块和 FVG 一旦确认就固定在图表上,只会因为被突破而删除,不会改变已标记区域的位置或属性。但如果重新加载指标或修改参数,会根据新参数重新计算。
- 订单块被突破后还能用吗?
- 不能。代码设计逻辑是订单块被完全突破后立即失效并从图表删除,说明该支撑/阻力已被打破,不应继续依赖它交易。
- 能用在 XAUUSD 以外的品种吗?
- 可以。代码没有限制品种,黄金、外汇、指数都能用。但需要根据品种的点值和波动特性调整"最小实体"和"最小 FVG 尺寸"参数。例如 EURUSD 可以用 5-8 点,黄金用 10-15 点。
- 为什么图表上订单块很少或没有?
- 可能是"订单块最小实体"参数设置过大,或"最多显示数量"过小。降低最小实体阈值或增加显示数量。也可能当前周期内没有形成符合条件的强反转形态。
- MT4 能用吗?
- 不能直接用。这是 MQL5 代码,MT4 使用 MQL4,语法和函数不兼容。需要将代码改写为 MQL4 版本才能在 MT4 上运行。
MT5 SMC Institutional Order Block & FVG Indicator
A professional Smart Money Concepts indicator that automatically identifies high-quality order blocks and fair value gaps. Features intelligent filtering, automatic invalidation management, and clean visualization with strength-based ranking.
Source code is shown above. Compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。