MT5指标编译通过 · EX5 15KB 自动发布 4 0

智能货币订单块与结构突破信号

191727760·3 小时前发布

自动识别订单块区域并在市场结构突破时显示买卖箭头信号

智能货币订单块与结构突破信号

MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子

SMC_OrderBlock_Arrows.mq5334
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#property copyright "XAUOF指标工坊"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

// 买入箭头
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrDodgerBlue
#property indicator_width1  3
#property indicator_label1  "买入信号"

// 卖出箭头
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  3
#property indicator_label2  "卖出信号"

//--- 输入参数
input int    SwingPeriod = 5;              // 摆动周期:识别高低点的K线数量,推荐5-10
input int    ArrowOffset = 50;             // 箭头偏移:距离K线的点数,推荐30-100
input bool   ShowBullishOB = true;         // 显示看涨订单块(蓝色)
input bool   ShowBearishOB = true;         // 显示看跌订单块(橙色)
input color  BullishOBColor = clrDodgerBlue;    // 看涨订单块颜色
input color  BearishOBColor = clrOrange;        // 看跌订单块颜色
input int    OBTransparency = 80;          // 订单块透明度:0=不透明,90=很透明
input int    MaxOBToShow = 10;             // 最多显示订单块数量:避免图表过于混乱

//--- 指标缓冲区
double BuyArrowBuffer[];
double SellArrowBuffer[];

//--- 全局变量
struct OrderBlockInfo {
   datetime time_start;
   datetime time_end;
   double   price_high;
   double   price_low;
   bool     is_bullish;  // true=看涨OB,false=看跌OB
};

OrderBlockInfo OBList[];
int OBCount = 0;

//+------------------------------------------------------------------+
//| 初始化函数                                                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // 绑定指标缓冲区
   SetIndexBuffer(0, BuyArrowBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, SellArrowBuffer, INDICATOR_DATA);
   
   // 设置箭头符号:233=上箭头,234=下箭头
   PlotIndexSetInteger(0, PLOT_ARROW, 233);
   PlotIndexSetInteger(1, PLOT_ARROW, 234);
   
   // 设置空值
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   
   // 初始化数组
   ArrayResize(OBList, MaxOBToShow);
   OBCount = 0;
   
   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 < SwingPeriod * 2 + 1)
      return 0;
   
   // 确定起始位置
   int start = (prev_calculated > SwingPeriod) ? prev_calculated - 1 : SwingPeriod;
   
   // 首次运行,初始化缓冲区
   if(prev_calculated == 0)
   {
      ArrayInitialize(BuyArrowBuffer, EMPTY_VALUE);
      ArrayInitialize(SellArrowBuffer, EMPTY_VALUE);
      
      // 清除旧的图形对象
      ObjectsDeleteAll(0, "OB_");
   }
   
   // 逐根K线扫描
   for(int i = start; i < rates_total && !IsStopped(); i++)
   {
      // 重置当前K线的箭头
      BuyArrowBuffer[i] = EMPTY_VALUE;
      SellArrowBuffer[i] = EMPTY_VALUE;
      
      // 需要足够的历史数据
      if(i < SwingPeriod * 2)
         continue;
      
      // 检查是否形成摆动高点(Swing High)
      if(IsSwingHigh(high, i, SwingPeriod))
      {
         // 找到摆动高点前的最后一根看涨K线作为看跌订单块
         int obIndex = FindLastBullishCandle(open, close, i, SwingPeriod);
         if(obIndex > 0 && ShowBearishOB)
         {
            // 创建看跌订单块
            CreateOrderBlock(time[obIndex], time[i], high[obIndex], low[obIndex], false, i);
         }
         
         // 检查是否突破了之前的高点(结构突破)
         if(IsBOS_High(high, i, SwingPeriod * 2))
         {
            // 显示卖出箭头
            SellArrowBuffer[i] = high[i] + ArrowOffset * _Point;
         }
      }
      
      // 检查是否形成摆动低点(Swing Low)
      if(IsSwingLow(low, i, SwingPeriod))
      {
         // 找到摆动低点前的最后一根看跌K线作为看涨订单块
         int obIndex = FindLastBearishCandle(open, close, i, SwingPeriod);
         if(obIndex > 0 && ShowBullishOB)
         {
            // 创建看涨订单块
            CreateOrderBlock(time[obIndex], time[i], high[obIndex], low[obIndex], true, i);
         }
         
         // 检查是否突破了之前的低点(结构突破)
         if(IsBOS_Low(low, i, SwingPeriod * 2))
         {
            // 显示买入箭头
            BuyArrowBuffer[i] = low[i] - ArrowOffset * _Point;
         }
      }
   }
   
   return rates_total;
}

//+------------------------------------------------------------------+
//| 判断是否为摆动高点                                                |
//+------------------------------------------------------------------+
bool IsSwingHigh(const double &high[], int index, int period)
{
   if(index < period || index >= ArraySize(high) - 1)
      return false;
   
   double centerHigh = high[index];
   
   // 检查左侧period根K线
   for(int i = 1; i <= period; i++)
   {
      if(high[index - i] >= centerHigh)
         return false;
   }
   
   // 检查右侧period根K线(实时K线不检查右侧)
   for(int i = 1; i <= period && index + i < ArraySize(high); i++)
   {
      if(high[index + i] > centerHigh)
         return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 判断是否为摆动低点                                                |
//+------------------------------------------------------------------+
bool IsSwingLow(const double &low[], int index, int period)
{
   if(index < period || index >= ArraySize(low) - 1)
      return false;
   
   double centerLow = low[index];
   
   // 检查左侧period根K线
   for(int i = 1; i <= period; i++)
   {
      if(low[index - i] <= centerLow)
         return false;
   }
   
   // 检查右侧period根K线(实时K线不检查右侧)
   for(int i = 1; i <= period && index + i < ArraySize(low); i++)
   {
      if(low[index + i] < centerLow)
         return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 找到摆动点之前最后一根看涨K线                                      |
//+------------------------------------------------------------------+
int FindLastBullishCandle(const double &open[], const double &close[], int swingIndex, int lookback)
{
   for(int i = swingIndex - 1; i >= swingIndex - lookback && i >= 0; i--)
   {
      if(close[i] > open[i])  // 阳线
         return i;
   }
   return -1;
}

//+------------------------------------------------------------------+
//| 找到摆动点之前最后一根看跌K线                                      |
//+------------------------------------------------------------------+
int FindLastBearishCandle(const double &open[], const double &close[], int swingIndex, int lookback)
{
   for(int i = swingIndex - 1; i >= swingIndex - lookback && i >= 0; i--)
   {
      if(close[i] < open[i])  // 阴线
         return i;
   }
   return -1;
}

//+------------------------------------------------------------------+
//| 检查是否突破了之前的高点(向上BOS)                                |
//+------------------------------------------------------------------+
bool IsBOS_High(const double &high[], int index, int lookback)
{
   if(index < lookback + 1)
      return false;
   
   double currentHigh = high[index];
   
   // 检查是否突破了lookback范围内的最高点
   double maxHigh = high[index - 1];
   for(int i = index - lookback; i < index; i++)
   {
      if(high[i] > maxHigh)
         maxHigh = high[i];
   }
   
   return (currentHigh > maxHigh);
}

//+------------------------------------------------------------------+
//| 检查是否突破了之前的低点(向下BOS)                                |
//+------------------------------------------------------------------+
bool IsBOS_Low(const double &low[], int index, int lookback)
{
   if(index < lookback + 1)
      return false;
   
   double currentLow = low[index];
   
   // 检查是否突破了lookback范围内的最低点
   double minLow = low[index - 1];
   for(int i = index - lookback; i < index; i++)
   {
      if(low[i] < minLow)
         minLow = low[i];
   }
   
   return (currentLow < minLow);
}

//+------------------------------------------------------------------+
//| 创建订单块矩形                                                    |
//+------------------------------------------------------------------+
void CreateOrderBlock(datetime timeStart, datetime timeEnd, double priceHigh, double priceLow, bool isBullish, int barIndex)
{
   // 限制订单块数量
   if(OBCount >= MaxOBToShow)
      return;
   
   // 生成唯一的对象名称
   string objName = "OB_" + IntegerToString(barIndex) + "_" + (isBullish ? "Bull" : "Bear");
   
   // 如果对象已存在,先删除
   if(ObjectFind(0, objName) >= 0)
      ObjectDelete(0, objName);
   
   // 创建矩形对象
   if(!ObjectCreate(0, objName, OBJ_RECTANGLE, 0, timeStart, priceHigh, timeEnd + PeriodSeconds(PERIOD_CURRENT) * 50, priceLow))
   {
      Print("创建订单块失败: ", GetLastError());
      return;
   }
   
   // 设置矩形属性
   color obColor = isBullish ? BullishOBColor : BearishOBColor;
   ObjectSetInteger(0, objName, OBJPROP_COLOR, obColor);
   ObjectSetInteger(0, objName, OBJPROP_FILL, true);
   ObjectSetInteger(0, objName, OBJPROP_BACK, true);  // 放在背景层
   ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false);
   ObjectSetInteger(0, objName, OBJPROP_SELECTED, false);
   ObjectSetInteger(0, objName, OBJPROP_HIDDEN, true);
   ObjectSetInteger(0, objName, OBJPROP_WIDTH, 1);
   
   // 设置透明度(0-255,值越大越不透明,这里转换一下)
   int alpha = (int)((100 - OBTransparency) * 255 / 100);
   if(alpha < 0) alpha = 0;
   if(alpha > 255) alpha = 255;
   
   // 修改颜色的Alpha通道(注意:MQL5的颜色格式是0xAABBGGRR)
   color transparentColor = (color)((alpha << 24) | (obColor & 0x00FFFFFF));
   ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, transparentColor);
   
   // 添加到列表
   OBList[OBCount].time_start = timeStart;
   OBList[OBCount].time_end = timeEnd;
   OBList[OBCount].price_high = priceHigh;
   OBList[OBCount].price_low = priceLow;
   OBList[OBCount].is_bullish = isBullish;
   OBCount++;
}

//+------------------------------------------------------------------+
//| 清理函数                                                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 删除所有订单块对象
   ObjectsDeleteAll(0, "OB_");
}
MT5 运行截图 · 完整视图带价格轴和时间轴的整张图表(约 150 根 H1 K 线),上面的封面是它最近 80 根 K 线的放大视图
智能货币订单块与结构突破信号 在 MT5 上的真实截图

作品说明

从图上识别到的元素:

这是一套SMC智能货币概念指标,包含以下核心组件:

  1. 彩色订单块(Order Block):橙色、紫色、蓝色、青色等矩形区域,标记关键的供需区域
  2. 买卖箭头信号:蓝色向上箭头标记买入机会,红色向下箭头标记卖出机会
  3. 水平虚线:黄色OP线和红色EOH线,标记关键价格位
  4. 文本标签:OB(订单块)、QB、BOS(结构突破)、CHoCH(结构变化)等

指标逻辑:识别摆动高低点→绘制突破前的最后一根反向K线作为订单块→在价格突破结构时生成信号箭头。我会实现订单块识别、矩形绘制和箭头信号这三个核心功能。

使用说明

安装步骤:

  1. 将代码保存为 SMC_OrderBlock_Arrows.mq5,放入 MQL5/Indicators 目录
  2. 在MT5的导航器中编译(双击文件自动编译)
  3. 拖到XAUUSD或任意品种的图表上

参数调节:

  • 摆动周期:默认5,越小越灵敏(信号多但噪音大),越大越稳定(信号少但质量高)
  • 箭头偏移:调整箭头与K线的距离,图表缩放后可能需要调大此值
  • 订单块颜色:看涨用蓝色、看跌用橙色,可根据个人喜好修改
  • 透明度:80表示20%不透明度,避免矩形遮挡K线;调小此值可让订单块更明显
  • 最多显示数量:默认10个,避免历史订单块太多导致图表混乱

信号解读:

  • 蓝色向上箭头:价格突破前期低点,形成看涨结构突破(BOS),可考虑做多
  • 红色向下箭头:价格突破前期高点,形成看跌结构突破,可考虑做空
  • 蓝色矩形:看涨订单块(买方力量聚集区),价格回调到此区域可能获得支撑
  • 橙色矩形:看跌订单块(卖方力量聚集区),价格反弹到此区域可能遇到阻力

注意事项:

  1. 订单块是机构可能留下的未成交订单区域,价格再次触及时容易产生反应
  2. 结合更大周期的订单块使用效果更好(例如H1图表参考H4的订单块)
  3. 箭头仅为结构突破提示,实际交易需结合其他确认信号(如价格行为、成交量)
  4. 本指标不含止损止盈逻辑,务必自行设置风险管理
  5. 历史信号会重绘(因为需要右侧K线确认摆动点),实盘使用时注意实时K线的确认

AI 解读根据源码逐行分析写成,供参考,以实际运行为准

这是什么

这是一个基于智能货币概念(SMC)的MT5指标,自动在图表上标记订单块(Order Block)区域,并在价格突破市场结构时显示买卖箭头信号。订单块是机构可能留下大量未成交订单的价格区域,价格回到这些区域时容易产生反应。指标用蓝色矩形标记看涨订单块,橙色矩形标记看跌订单块,在结构突破时显示蓝色向上箭头(做多)或红色向下箭头(做空)。

逻辑原理

指标通过三步识别信号:

  1. 识别摆动点:扫描K线找出摆动高点和摆动低点。摆动高点是指某根K线的最高价高于左右各N根K线(N由摆动周期参数决定),摆动低点则相反。
  1. 绘制订单块:找到摆动点后,向前回溯,找到摆动点之前最后一根反向K线。例如形成摆动高点前的最后一根阳线(收盘价>开盘价)作为看跌订单块,形成摆动低点前的最后一根阴线作为看涨订单块,用矩形画出该K线的高低价范围。
  1. 显示突破箭头:当价格突破前N根K线的最高点(向上BOS)时在K线上方显示红色向下箭头,突破最低点(向下BOS)时在下方显示蓝色向上箭头。

矩形会一直延伸到当前,透明度可调,避免遮挡K线。

参数说明

  • SwingPeriod(默认5):识别摆动高低点的K线数量。设为5表示中间K线的高/低点必须高于/低于左右各5根K线才算摆动点。数值越小信号越多但噪音大,越大则信号越稳定但反应慢,推荐5-10。
  • ArrowOffset(默认50):箭头距离K线最高/最低价的点数,用于调整箭头位置避免重叠。图表缩放后可能需要调大此值,推荐30-100。
  • ShowBullishOB(默认true):是否显示看涨订单块(蓝色矩形)。
  • ShowBearishOB(默认true):是否显示看跌订单块(橙色矩形)。
  • BullishOBColor(默认蓝色):看涨订单块的颜色。
  • BearishOBColor(默认橙色):看跌订单块的颜色。
  • OBTransparency(默认80):订单块透明度,0表示完全不透明,90表示非常透明。数值越大矩形越淡,推荐70-85。
  • MaxOBToShow(默认10):图表上最多同时显示多少个订单块,避免历史订单块太多导致混乱。

怎么用

将代码保存为 SMC_OrderBlock_Arrows.mq5,放入MT5数据文件夹的 MQL5/Indicators 目录(文件→打开数据文件夹),在导航器窗口中双击文件自动编译。编译成功后拖到任意品种的图表上(推荐H1或H4周期),弹出参数窗口可调节上述参数。

看信号:蓝色向上箭头表示价格突破前期低点形成看涨结构,可考虑做多;红色向下箭头表示突破前期高点形成看跌结构,可考虑做空。蓝色矩形是潜在支撑区(买方力量聚集),橙色矩形是潜在阻力区(卖方力量聚集),价格回到这些区域时可能产生反应。

适用场景

适合品种:XAUUSD、EURUSD、GBPUSD等主流货币对和指数,任何有明显波动的品种都可用。

适合周期:H1、H4、D1。M15和M5也能用但信号较多,需结合更大周期的订单块过滤。日内剥头皮不适合此逻辑。

适合行情:趋势行情和震荡突破行情。在明确趋势中,订单块可作为回调入场点;在震荡区间突破时,箭头提示结构改变。不适合无方向的窄幅震荡,会产生大量假突破信号。

风险提示

  1. 重绘问题:摆动点需要右侧K线确认,历史信号会随新K线出现而改变位置或消失。实盘使用时,当前未走完的K线上的箭头和订单块可能在下一根K线刷新后消失。
  1. 滞后性:箭头信号出现时价格已经突破,可能错过最佳入场点。建议结合订单块回调入场,而不是追着箭头直接开仓。
  1. 假突破:小周期上的结构突破可能只是大周期的正常回调,单独使用此指标容易被反向扫损。务必结合更大周期的趋势和订单块判断。
  1. 无止损逻辑:指标只显示信号,不包含止损止盈和仓位管理。必须自行设置止损(建议放在订单块另一侧或摆动点外),严格控制单笔风险。
  1. 订单块可能失效:价格多次触碰订单块后该区域的订单可能已消耗殆尽,不能盲目依赖历史订单块。代码中订单块会一直显示直到被新订单块替代,需自行判断有效性。

常见问题

这个指标会重绘吗
会。因为摆动高低点需要右侧K线确认,历史信号的位置和订单块会随新K线出现而调整。实盘时注意当前K线上的箭头可能在下一根K线消失。
默认参数适合什么周期
默认摆动周期5适合H1和H4周期。如果用在M15需要调小到3,用在D1可以调大到7-10,否则信号太少。
可以用在XAUUSD以外的品种吗
可以。代码里没有品种限制,任何有波动的品种都能用,包括外汇、指数、商品。但不同品种的点值和波动幅度不同,箭头偏移参数可能需要调整。
箭头出现后可以直接开仓吗
不建议。箭头只是结构突破提示,出现时价格已经走了一段。更稳妥的做法是等价格回调到订单块区域再入场,或结合其他确认信号(如K线形态、成交量)。
MT4能用这个指标吗
不能直接用。这是MQL5代码,只能在MT5上运行。MT4使用MQL4语言,语法和函数不同,需要重写代码才能移植。

SMC Order Block & Structure Breakout Indicator for MT5

An MT5 indicator based on Smart Money Concepts that automatically identifies swing highs/lows, draws order block rectangles, and displays buy/sell arrows on market structure breakouts (BOS). Adjustable sensitivity and display limits included.

Source code is shown above. Compiled EX5 files are available to VIP members.

评论

后可以留言,比如反馈用着怎么样、想加什么功能。

还没有人评论,来抢个沙发。