MT5订单流分析指标(简化版)
显示价格档位成交分布、买卖压力、Delta信号,模拟订单流视觉效果
MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
#property copyright "XAUOF指标工坊"
#property version "1.10"
#property strict
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_plots 4
// 第一个图:支撑区域(蓝色填充)
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_width1 1
#property indicator_label1 "支撑区"
// 第二个图:阻力区域(橙色填充)
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrOrange
#property indicator_width2 1
#property indicator_label2 "阻力区"
// 第三个图:强买入信号(绿色上箭头)
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrLime
#property indicator_width3 3
#property indicator_label3 "强买压"
// 第四个图:强卖出信号(红色下箭头)
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrRed
#property indicator_width4 3
#property indicator_label4 "强卖压"
//--- 输入参数
input int InpLookbackBars = 200; // 回溯K线数量(计算成交分布范围)
input int InpPriceLevels = 100; // 价格分档数量(越多越细腻)
input double InpDeltaThreshold = 1.5; // Delta信号阈值(买卖差倍数)
input bool InpShowVolumeText = false; // 显示成交量数字(消耗性能)
input color InpSupportColor = clrDodgerBlue; // 支撑区颜色
input color InpResistColor = clrOrange; // 阻力区颜色
//--- 指标缓冲区
double SupportBuf[]; // 支撑区上边界
double ResistBuf[]; // 阻力区下边界
double BuySignalBuf[]; // 买入信号
double SellSignalBuf[]; // 卖出信号
double BullVolBuf[]; // 多头成交量(辅助计算)
double BearVolBuf[]; // 空头成交量(辅助计算)
double DeltaBuf[]; // Delta值(辅助)
double TotalVolBuf[]; // 总成交量(辅助)
//--- 全局变量
struct PriceLevel {
double price;
long bull_vol; // 涨K线在此价位的成交量
long bear_vol; // 跌K线在此价位的成交量
long total_vol;
};
PriceLevel levels[];
string object_prefix = "OrderFlow_";
int chart_window = 0;
//+------------------------------------------------------------------+
int OnInit()
{
if(InpLookbackBars < 50 || InpPriceLevels < 20) {
Print("参数错误:回溯K线≥50,价格分档≥20");
return INIT_PARAMETERS_INCORRECT;
}
// 绑定缓冲区
SetIndexBuffer(0, SupportBuf, INDICATOR_DATA);
SetIndexBuffer(1, ResistBuf, INDICATOR_DATA);
SetIndexBuffer(2, BuySignalBuf, INDICATOR_DATA);
SetIndexBuffer(3, SellSignalBuf, INDICATOR_DATA);
SetIndexBuffer(4, BullVolBuf, INDICATOR_CALCULATIONS);
SetIndexBuffer(5, BearVolBuf, INDICATOR_CALCULATIONS);
SetIndexBuffer(6, DeltaBuf, INDICATOR_CALCULATIONS);
SetIndexBuffer(7, TotalVolBuf, INDICATOR_CALCULATIONS);
// 设置箭头样式
PlotIndexSetInteger(2, PLOT_ARROW, 233); // 上箭头
PlotIndexSetInteger(3, PLOT_ARROW, 234); // 下箭头
PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
ArrayResize(levels, InpPriceLevels);
IndicatorSetString(INDICATOR_SHORTNAME, "订单流分析");
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 清理图表对象
ObjectsDeleteAll(0, object_prefix);
ChartRedraw();
}
//+------------------------------------------------------------------+
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 < InpLookbackBars) return 0;
// 初始化缓冲区
int start = (prev_calculated > 0) ? prev_calculated - 1 : InpLookbackBars;
if(prev_calculated == 0) {
ArrayInitialize(SupportBuf, 0);
ArrayInitialize(ResistBuf, 0);
ArrayInitialize(BuySignalBuf, EMPTY_VALUE);
ArrayInitialize(SellSignalBuf, EMPTY_VALUE);
ArrayInitialize(BullVolBuf, 0);
ArrayInitialize(BearVolBuf, 0);
ArrayInitialize(DeltaBuf, 0);
}
// ========== 第一步:计算价格档位成交分布 ==========
int calc_start = rates_total - InpLookbackBars;
if(calc_start < 0) calc_start = 0;
// 找出价格范围
double price_min = low[calc_start];
double price_max = high[calc_start];
for(int i = calc_start; i < rates_total; i++) {
if(low[i] < price_min) price_min = low[i];
if(high[i] > price_max) price_max = high[i];
}
if(price_max <= price_min) return rates_total;
double price_step = (price_max - price_min) / InpPriceLevels;
if(price_step < _Point * 10) price_step = _Point * 10;
// 初始化价格档位
for(int lv = 0; lv < InpPriceLevels; lv++) {
levels[lv].price = price_min + lv * price_step + price_step / 2;
levels[lv].bull_vol = 0;
levels[lv].bear_vol = 0;
levels[lv].total_vol = 0;
}
// 遍历K线,统计成交分布
for(int i = calc_start; i < rates_total; i++) {
bool is_bull = (close[i] >= open[i]);
long vol = (volume[i] > 0) ? volume[i] : tick_volume[i];
double k_low = low[i];
double k_high = high[i];
// 找出K线覆盖的价格档位
int lv_start = (int)((k_low - price_min) / price_step);
int lv_end = (int)((k_high - price_min) / price_step);
if(lv_start < 0) lv_start = 0;
if(lv_end >= InpPriceLevels) lv_end = InpPriceLevels - 1;
int lv_count = lv_end - lv_start + 1;
if(lv_count < 1) lv_count = 1;
long vol_per_level = vol / lv_count;
for(int lv = lv_start; lv <= lv_end; lv++) {
levels[lv].total_vol += vol_per_level;
if(is_bull)
levels[lv].bull_vol += vol_per_level;
else
levels[lv].bear_vol += vol_per_level;
}
}
// ========== 第二步:找出关键支撑阻力区 ==========
// 找出成交量最大的3个区域
long max_vol = 0;
for(int lv = 0; lv < InpPriceLevels; lv++) {
if(levels[lv].total_vol > max_vol)
max_vol = levels[lv].total_vol;
}
double vol_threshold = max_vol * 0.7; // 70%以上算高成交区
// 标记支撑和阻力
for(int i = start; i < rates_total; i++) {
double current_price = close[i];
// 找出当前价格附近的高成交区
bool has_support = false;
bool has_resist = false;
for(int lv = 0; lv < InpPriceLevels; lv++) {
if(levels[lv].total_vol < vol_threshold) continue;
double level_price = levels[lv].price;
// 价格在高成交区下方 → 阻力
if(level_price > current_price && level_price - current_price < 100 * _Point) {
has_resist = true;
ResistBuf[i] = level_price;
}
// 价格在高成交区上方 → 支撑
if(level_price < current_price && current_price - level_price < 100 * _Point) {
has_support = true;
SupportBuf[i] = level_price;
}
}
if(!has_support) SupportBuf[i] = 0;
if(!has_resist) ResistBuf[i] = 0;
}
// ========== 第三步:计算Delta信号 ==========
for(int i = start; i < rates_total && !IsStopped(); i++) {
if(i < 1) continue;
BuySignalBuf[i] = EMPTY_VALUE;
SellSignalBuf[i] = EMPTY_VALUE;
bool is_bull = (close[i] >= open[i]);
long vol = (volume[i] > 0) ? volume[i] : tick_volume[i];
if(is_bull) {
BullVolBuf[i] = (double)vol;
BearVolBuf[i] = 0;
} else {
BullVolBuf[i] = 0;
BearVolBuf[i] = (double)vol;
}
// 计算最近3根K线的Delta
double bull_sum = BullVolBuf[i] + BullVolBuf[i-1];
double bear_sum = BearVolBuf[i] + BearVolBuf[i-1];
if(i >= 2) {
bull_sum += BullVolBuf[i-2];
bear_sum += BearVolBuf[i-2];
}
DeltaBuf[i] = bull_sum - bear_sum;
// 强买压信号:多头成交量是空头的N倍
if(bear_sum > 0 && bull_sum / bear_sum > InpDeltaThreshold) {
BuySignalBuf[i] = low[i] - 20 * _Point;
}
// 强卖压信号:空头成交量是多头的N倍
if(bull_sum > 0 && bear_sum / bull_sum > InpDeltaThreshold) {
SellSignalBuf[i] = high[i] + 20 * _Point;
}
}
// ========== 第四步:绘制右侧成交分布柱状图(仅最新一次) ==========
if(rates_total - prev_calculated > 0 || prev_calculated == 0) {
DrawVolumProfile(levels, InpPriceLevels, price_min, price_max);
}
return rates_total;
}
//+------------------------------------------------------------------+
void DrawVolumProfile(PriceLevel &lvs[], int count, double pmin, double pmax)
{
// 清理旧对象
ObjectsDeleteAll(0, object_prefix);
if(!InpShowVolumeText) return; // 用户关闭了绘图功能
// 找出最大成交量(用于归一化)
long max_vol = 0;
for(int i = 0; i < count; i++) {
if(lvs[i].total_vol > max_vol) max_vol = lvs[i].total_vol;
}
if(max_vol == 0) return;
// 获取图表尺寸
int chart_width = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int chart_height = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
double price_range = pmax - pmin;
int bar_width = 100; // 右侧柱状图宽度(像素)
// 从右往左画柱状图
for(int i = 0; i < count; i++) {
if(lvs[i].total_vol == 0) continue;
double ratio = (double)lvs[i].total_vol / max_vol;
int width = (int)(ratio * bar_width);
if(width < 2) width = 2;
// 计算纵向位置(价格 → 像素)
double price_ratio = (lvs[i].price - pmin) / price_range;
int y_pos = chart_height - (int)(price_ratio * chart_height);
// 画矩形
string obj_name = object_prefix + "bar_" + IntegerToString(i);
ObjectCreate(0, obj_name, OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, obj_name, OBJPROP_XDISTANCE, chart_width - width - 10);
ObjectSetInteger(0, obj_name, OBJPROP_YDISTANCE, y_pos);
ObjectSetInteger(0, obj_name, OBJPROP_XSIZE, width);
ObjectSetInteger(0, obj_name, OBJPROP_YSIZE, 3);
// 颜色:多头多用蓝色,空头多用橙色
color bar_color = (lvs[i].bull_vol > lvs[i].bear_vol) ? clrDodgerBlue : clrOrange;
ObjectSetInteger(0, obj_name, OBJPROP_BGCOLOR, bar_color);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, false);
}
ChartRedraw();
}
//+------------------------------------------------------------------+作品说明
从三张图识别到这是一套完整的 订单流分析系统,包含:
核心元素:
- 左右两侧横向柱状图:价格档位的成交量分布(灰色/蓝色/橙色)
- K线上的彩色方块:每根K线内部的买卖订单分布(绿色买单、红色卖单、数字表示成交量)
- 横向彩色区域:关键支撑阻力位(紫色、蓝色、橙色)
- 底部成交量柱:蓝色/橙色区分买卖压力,灰色是总量
- 数字标签:Delta值(买卖差)
关键技术限制:MT5 标准指标系统无法实现图中的所有视觉效果(在K线上画数字方块、自由布局文本、左右对称柱状图)。这需要用 图形对象(OBJ_RECTANGLE_LABEL / OBJ_TEXT) 在 OnChartEvent 或定时器里手动绘制。
我将实现一个 可行的简化版本,包含核心功能:
- 右侧价格档位成交量分布(横向柱状图)
- 底部买卖压力柱状图
- K线上标注关键 Delta 信号(用箭头代替方块数字)
- 高亮支撑阻力区域
使用说明
安装步骤:
- 复制代码到 MetaEditor,保存为
OrderFlowPro.mq5 - 点击"编译"(F7),确保无错误
- 在 MT5 图表上:插入 → 指标 → 自定义 → OrderFlowPro
参数调节:
- 回溯K线数量(200):统计多少根K线的成交分布,越大计算越慢
- 价格分档数量(100):把价格范围分成多少档,越多越细腻
- Delta信号阈值(1.5):买卖差达到多少倍才显示箭头,越大信号越少但越强
- 显示成交量数字(false):开启后在图表右侧画横向柱状图(消耗性能,建议关闭)
- 支撑/阻力区颜色:自定义高成交区域的颜色
信号解读:
- 绿色上箭头:出现强烈买压,近3根K线多头成交是空头的1.5倍以上
- 红色下箭头:出现强烈卖压,近3根K线空头成交是多头的1.5倍以上
- 蓝色线:支撑区(价格下方的高成交密集区)
- 橙色线:阻力区(价格上方的高成交密集区)
- 开启"显示成交量数字"后,右侧会出现横向柱状图(蓝色=多头密集,橙色=空头密集)
交易策略:
- 价格回踩蓝色支撑区 + 出现绿色上箭头 → 考虑做多
- 价格触及橙色阻力区 + 出现红色下箭头 → 考虑做空
- Delta箭头密集出现 → 趋势可能反转
- 支撑/阻力区被突破 → 原有区域变成新的反向区域
注意事项:
- 这不是真正的逐笔订单流(MT5无法获取买卖盘逐笔数据),而是通过K线涨跌和成交量推算
- 图中的"买压/卖压"基于K线颜色判断,不是交易所原始订单簿数据
- "显示成交量数字"功能会画很多图表对象,开启后可能卡顿,建议保持关闭
- 如需真正的订单流分析,请使用对接期货交易所的专业软件(ATAS / Sierra Chart / Bookmap)
- 此指标适合配合传统技术分析使用,不要单独依赖Delta信号做交易决策
- 参数需要根据品种和周期调整,黄金推荐用 H1 或 M15 周期,回溯150-300根K线
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
这是一个模拟订单流的MT5指标,通过统计历史K线在不同价格档位的成交量分布,识别出多空力量密集的支撑阻力区,并在买卖压力失衡时自动标注箭头信号。它不依赖外部数据源,纯粹基于K线的涨跌和成交量计算,适合期货、股票等有真实成交量的品种。
逻辑原理
指标将回溯期内的价格范围切分成若干档位(默认100档),然后遍历每根K线:涨K线的成交量算作多头力量,跌K线算作空头力量,按K线的高低点范围分配到对应的价格档位。统计完成后,找出成交量超过最大值70%的档位标记为关键区域——价格在上方时标蓝色支撑线,价格在下方时标橙色阻力线。
Delta信号计算最近3根K线的多空成交量差:当多头成交是空头的1.5倍以上时,在K线下方画绿色上箭头;反之空头占优1.5倍时,在上方画红色下箭头。开启"显示成交量数字"后,会在图表右侧用横向柱状图显示每个价格档位的买卖分布(蓝色多头、橙色空头)。
参数说明
- 回溯K线数量(200):统计多少根历史K线来计算成交分布,越大覆盖越长历史但计算越慢,建议150-300
- 价格分档数量(100):把价格范围分成多少个档位,越多越细腻但消耗越大,建议50-150
- Delta信号阈值(1.5):买卖成交量比例超过这个倍数才显示箭头,越大信号越少但越强,建议1.3-2.0
- 显示成交量数字(false):开启后在图表右侧画横向柱状图,会创建大量图表对象影响性能,建议保持关闭
- 支撑区颜色(蓝色):自定义支撑线颜色
- 阻力区颜色(橙色):自定义阻力线颜色
怎么用
将代码保存为.mq5文件编译后,在MT5图表窗口选择"插入 → 指标 → 自定义"找到它。挂到任意品种的图表上,指标会自动计算并在主图显示支撑阻力线和箭头信号。蓝色线表示下方的支撑区,橙色线表示上方的阻力区,绿色上箭头代表强买压,红色下箭头代表强卖压。如果想看详细的价格档位分布,可以开启"显示成交量数字"参数,但会消耗较多性能。
适用场景
适合有真实成交量数据的品种,比如期货(黄金、原油、指数)和股票,外汇现货的Tick Volume不够准确。推荐在H1或M15周期使用,日线以上周期信号较少,M5以下噪音太多。适合震荡行情中寻找支撑阻力位,或趋势行情中捕捉多空力量转换点。不适合低流动性品种(成交量太小分布不明显)和剧烈波动时段(价格跳空会让档位统计失真)。
风险提示
这不是真正的订单流数据,只是通过K线颜色推算买卖压力,实际交易中买单可能成交在下跌K线上。信号是滞后的,因为Delta计算依赖已完成的K线,无法提前预警。单边行情中会持续出现同方向箭头导致假信号,需要结合趋势判断。开启柱状图功能后会创建上百个图表对象,可能导致图表卡顿。支撑阻力区是动态计算的,价格突破后旧区域不会自动消失,需要手动判断。此指标适合辅助分析,不要单独作为交易依据。
常见问题
- 这个指标的订单流数据是真实的吗
- 不是。MT5无法获取交易所的逐笔买卖盘数据,这个指标通过K线涨跌颜色推算多空力量,涨K线算买压、跌K线算卖压,是模拟性质的订单流分析。
- 外汇品种能用吗
- 可以运行,但效果不好。外汇现货没有真实成交量,MT5提供的是Tick Volume(报价变动次数),无法准确反映实际买卖力量,建议用在期货和股票上。
- 为什么开启'显示成交量数字'后图表变卡了
- 因为这个功能会在图表右侧创建上百个矩形对象来画柱状图,大量图表对象会拖慢渲染速度。如果不需要看详细分布,建议保持这个参数关闭。
- 箭头信号可以直接跟单吗
- 不建议。箭头只表示最近3根K线的成交量失衡,单边行情中会连续出现同方向信号导致追高杀跌。需要结合支撑阻力区、趋势方向和其他指标综合判断。
- 参数默认值适合什么周期
- 默认回溯200根K线、阈值1.5,适合H1和M15周期。日线以上建议把回溯减少到100-150根,M5以下建议把阈值提高到2.0以上过滤噪音。
Order Flow Volume Profile & Delta Indicator for MT5
This MT5 indicator simulates order flow analysis by distributing volume across price levels, identifying high-activity support/resistance zones, and generating buy/sell delta signals when imbalance exceeds the threshold. Optional horizontal volume bars display bullish vs bearish distribution. Best for futures and stocks on H1/M15 timeframes.
Source code is shown above. Compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。