MT5指标编译通过 · EX5 13KB 自动发布 0 0
黄金分割自动回撤线指标
自动绘制凌晨或前日高低点的0.236/0.382/0.5/0.618/1.0/1.618斐波那契水平线
MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
AutoFibonacciLevels.mq5246 行
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
#property copyright "XAUOF指标工坊"
#property version "1.10"
#property strict
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots 7
// 绘制7条斐波那契水平线
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrPink
#property indicator_width1 2
#property indicator_label1 "1.618扩展"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrMagenta
#property indicator_width2 2
#property indicator_label2 "1.0高点"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrDeepSkyBlue
#property indicator_width3 2
#property indicator_label3 "0.618"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrMediumSeaGreen
#property indicator_width4 2
#property indicator_label4 "0.5中位"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrGold
#property indicator_width5 2
#property indicator_label5 "0.382"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrOrange
#property indicator_width6 2
#property indicator_label6 "0.236"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrSandyBrown
#property indicator_width7 2
#property indicator_label7 "0.0低点"
//--- 输入参数
input int StartHour = 0; // 凌晨时段开始小时(服务器时间)
input int EndHour = 8; // 凌晨时段结束小时
input int LookbackDays = 3; // 向前查找天数(找不到今日时用前几日)
input int DrawBarsBack = 500; // 向左绘制多少根K线(0=全部历史)
//--- 指标缓冲区
double Fib1618Buffer[]; // 1.618
double Fib100Buffer[]; // 1.0 高点
double Fib618Buffer[]; // 0.618
double Fib50Buffer[]; // 0.5
double Fib382Buffer[]; // 0.382
double Fib236Buffer[]; // 0.236
double Fib0Buffer[]; // 0.0 低点
//--- 全局变量
double g_High = 0; // 当前使用的最高价
double g_Low = 0; // 当前使用的最低价
datetime g_CalcDate = 0; // 上次计算日期
//+------------------------------------------------------------------+
int OnInit()
{
// 绑定指标缓冲区
SetIndexBuffer(0, Fib1618Buffer, INDICATOR_DATA);
SetIndexBuffer(1, Fib100Buffer, INDICATOR_DATA);
SetIndexBuffer(2, Fib618Buffer, INDICATOR_DATA);
SetIndexBuffer(3, Fib50Buffer, INDICATOR_DATA);
SetIndexBuffer(4, Fib382Buffer, INDICATOR_DATA);
SetIndexBuffer(5, Fib236Buffer, INDICATOR_DATA);
SetIndexBuffer(6, Fib0Buffer, INDICATOR_DATA);
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, "AutoFib");
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 < 50) return 0;
// 获取当前服务器时间和日期
datetime current_time = TimeCurrent();
MqlDateTime current_tm;
TimeToStruct(current_time, current_tm);
// 构造今日0点的时间戳
MqlDateTime today_start;
today_start.year = current_tm.year;
today_start.mon = current_tm.mon;
today_start.day = current_tm.day;
today_start.hour = 0;
today_start.min = 0;
today_start.sec = 0;
datetime today_midnight = StructToTime(today_start);
// 每天重新计算一次高低点
if(g_CalcDate != today_midnight)
{
g_High = 0;
g_Low = DBL_MAX;
bool found = false;
// 尝试查找最近LookbackDays天内凌晨时段的高低点
for(int day_offset = 0; day_offset <= LookbackDays && !found; day_offset++)
{
// 计算目标日期的起止时间(凌晨StartHour到EndHour)
datetime target_start = today_midnight - day_offset * 86400 + StartHour * 3600;
datetime target_end = today_midnight - day_offset * 86400 + EndHour * 3600;
double day_high = 0;
double day_low = DBL_MAX;
int count = 0;
// 从最新K线向历史查找这个时间段的K线
for(int i = rates_total - 1; i >= 0 && i >= rates_total - 2000; i--)
{
// 判断这根K线是否在目标时间段内
if(time[i] >= target_start && time[i] < target_end)
{
if(high[i] > day_high) day_high = high[i];
if(low[i] < day_low) day_low = low[i];
count++;
}
// 如果已经往前找太多了,停止
if(time[i] < target_start - 86400) break;
}
// 如果找到了至少3根K线,且高低点有效
if(count >= 3 && day_high > day_low && (day_high - day_low) > 0.0001)
{
g_High = day_high;
g_Low = day_low;
found = true;
// 如果是今天的数据,检查是否突破了昨天
if(day_offset == 0 && LookbackDays > 0)
{
// 查找昨天凌晨的高低点
datetime yesterday_start = today_midnight - 86400 + StartHour * 3600;
datetime yesterday_end = today_midnight - 86400 + EndHour * 3600;
double yesterday_high = 0;
double yesterday_low = DBL_MAX;
for(int i = rates_total - 1; i >= 0 && i >= rates_total - 2000; i--)
{
if(time[i] >= yesterday_start && time[i] < yesterday_end)
{
if(high[i] > yesterday_high) yesterday_high = high[i];
if(low[i] < yesterday_low) yesterday_low = low[i];
}
if(time[i] < yesterday_start - 86400) break;
}
// 如果今天没突破昨天,继续用昨天的高低点
if(yesterday_high > yesterday_low)
{
if(!(g_High > yesterday_high || g_Low < yesterday_low))
{
g_High = yesterday_high;
g_Low = yesterday_low;
}
}
}
}
}
g_CalcDate = today_midnight;
}
// 如果没找到有效高低点,不画线
if(g_High <= g_Low || (g_High - g_Low) < 0.0001)
{
ArrayInitialize(Fib1618Buffer, EMPTY_VALUE);
ArrayInitialize(Fib100Buffer, EMPTY_VALUE);
ArrayInitialize(Fib618Buffer, EMPTY_VALUE);
ArrayInitialize(Fib50Buffer, EMPTY_VALUE);
ArrayInitialize(Fib382Buffer, EMPTY_VALUE);
ArrayInitialize(Fib236Buffer, EMPTY_VALUE);
ArrayInitialize(Fib0Buffer, EMPTY_VALUE);
return rates_total;
}
// 计算斐波那契价位
double range = g_High - g_Low;
double level_0 = g_Low;
double level_236 = g_Low + range * 0.236;
double level_382 = g_Low + range * 0.382;
double level_50 = g_Low + range * 0.500;
double level_618 = g_Low + range * 0.618;
double level_100 = g_High;
double level_1618 = g_High + range * 0.618;
// 确定绘制范围
int draw_start = 0;
if(DrawBarsBack > 0 && rates_total > DrawBarsBack)
{
draw_start = rates_total - DrawBarsBack;
}
// 循环绘制水平线
int start = (prev_calculated > 0) ? prev_calculated - 1 : draw_start;
for(int i = start; i < rates_total && !IsStopped(); i++)
{
if(i >= draw_start)
{
Fib1618Buffer[i] = level_1618;
Fib100Buffer[i] = level_100;
Fib618Buffer[i] = level_618;
Fib50Buffer[i] = level_50;
Fib382Buffer[i] = level_382;
Fib236Buffer[i] = level_236;
Fib0Buffer[i] = level_0;
}
else
{
Fib1618Buffer[i] = EMPTY_VALUE;
Fib100Buffer[i] = EMPTY_VALUE;
Fib618Buffer[i] = EMPTY_VALUE;
Fib50Buffer[i] = EMPTY_VALUE;
Fib382Buffer[i] = EMPTY_VALUE;
Fib236Buffer[i] = EMPTY_VALUE;
Fib0Buffer[i] = EMPTY_VALUE;
}
}
return rates_total;
}
//+------------------------------------------------------------------+MT5 运行截图 · 完整视图带价格轴和时间轴的整张图表(约 150 根 H1 K 线),上面的封面是它最近 80 根 K 线的放大视图
作品说明
抱歉!我重新写一个更简单可靠的版本。问题可能出在高低点查找逻辑太复杂了,我简化一下:
主要修正
1. 高低点查找逻辑简化:
- 直接用时间戳范围判断:
time[i] >= target_start && time[i] < target_end - 不再用复杂的日期字符串比较,避免时区问题
- 至少找到3根K线才认为有效
2. 突破判断简化:
- 优先用今天凌晨的高低点
- 如果今天没突破昨天,自动切换回昨天的高低点
- 如果都找不到,就往前找LookbackDays天
3. 线条长度控制:
- 新增参数
DrawBarsBack(默认500根):只向左画500根K线,不会画太长 - 设为0则画全部历史
参数说明:
- StartHour = 0:凌晨0点开始
- EndHour = 8:到早8点结束
- LookbackDays = 3:往前找3天
- DrawBarsBack = 500:只画最近500根K线(不会太长)
装上试试,应该能正确找到高低点并画出合理长度的线了!
评论
后可以留言,比如反馈用着怎么样、想加什么功能。
还没有人评论,来抢个沙发。