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

SuperTrend 回血止损带(精准复刻版)

15897878899·2 小时前发布

亏损时止损带收缩减少假信号,多空颜色清晰、细腻渐变填充

SuperTrend 回血止损带(精准复刻版)

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

SuperTrendRecovery.mq5236
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
#property copyright   "Adapted from LuxAlgo CC BY-NC-SA 4.0"
#property version     "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   3

// 主线(动态颜色)
#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  C'8,153,129', C'242,54,69'  // 青绿、粉红
#property indicator_width1  2
#property indicator_label1  "SuperTrend 带"

// 多头圆点
#property indicator_type2   DRAW_ARROW
#property indicator_color2  C'8,153,129'
#property indicator_width2  3
#property indicator_label2  "多头切换"

// 空头圆点
#property indicator_type3   DRAW_ARROW
#property indicator_color3  C'242,54,69'
#property indicator_width3  3
#property indicator_label3  "空头切换"

//--- 输入参数
input group "SuperTrend 设置"
input int    ATR_Period      = 10;     // ATR 周期
input double Base_Multiplier = 3.0;    // 基础倍数

input group "回血逻辑"
input double Recovery_Alpha     = 5.0;  // 回血权重 (%)
input double Recovery_Threshold = 1.0;  // 回血阈值 (xATR)

input group "显示设置"
input bool   Show_Fills   = true;      // 显示渐变填充
input bool   Show_Labels  = true;      // 显示信号标签

//--- 指标缓冲区
double BandBuffer[];       // 主线值
double BandColors[];       // 主线颜色索引
double BullDotBuffer[];    // 多头圆点
double BearDotBuffer[];    // 空头圆点
double ATR_Buffer[];       // ATR 值

//--- 全局变量
int atrHandle;
int trend = 1;             
double switchPrice = 0;    

//+------------------------------------------------------------------+
int OnInit()
{
    atrHandle = iATR(_Symbol, PERIOD_CURRENT, ATR_Period);
    if(atrHandle == INVALID_HANDLE)
    {
        Print("创建 ATR 指标失败");
        return INIT_FAILED;
    }
    
    SetIndexBuffer(0, BandBuffer, INDICATOR_DATA);
    SetIndexBuffer(1, BandColors, INDICATOR_COLOR_INDEX);
    SetIndexBuffer(2, BullDotBuffer, INDICATOR_DATA);
    SetIndexBuffer(3, BearDotBuffer, INDICATOR_DATA);
    SetIndexBuffer(4, ATR_Buffer, INDICATOR_CALCULATIONS);
    
    PlotIndexSetInteger(2, PLOT_ARROW, 159);
    PlotIndexSetInteger(3, PLOT_ARROW, 159);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    
    IndicatorSetString(INDICATOR_SHORTNAME, "SuperTrend Recovery");
    
    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    if(atrHandle != INVALID_HANDLE)
        IndicatorRelease(atrHandle);
    
    ObjectsDeleteAll(0, "STR_");
}

//+------------------------------------------------------------------+
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(BarsCalculated(atrHandle) < rates_total)
        return 0;
    
    if(CopyBuffer(atrHandle, 0, 0, rates_total, ATR_Buffer) < rates_total)
        return 0;
    
    int start = (prev_calculated > 1) ? prev_calculated - 1 : ATR_Period;
    
    if(prev_calculated == 0)
    {
        ArrayInitialize(BandBuffer, EMPTY_VALUE);
        ArrayInitialize(BandColors, 0);
        ArrayInitialize(BullDotBuffer, EMPTY_VALUE);
        ArrayInitialize(BearDotBuffer, EMPTY_VALUE);
        trend = 1;
        switchPrice = close[start];
    }
    
    // 主循环
    for(int i = start; i < rates_total && !IsStopped(); i++)
    {
        if(i < ATR_Period) continue;
        
        double src = (high[i] + low[i]) / 2.0;
        double atr = ATR_Buffer[i];
        double alpha = Recovery_Alpha / 100.0;
        
        double upperBase = src + Base_Multiplier * atr;
        double lowerBase = src - Base_Multiplier * atr;
        
        double prevBand = (i > 0 && BandBuffer[i-1] != EMPTY_VALUE) ? BandBuffer[i-1] : 
                          (trend == 1 ? lowerBase : upperBase);
        
        double deviation = Recovery_Threshold * atr;
        bool isAtLoss = false;
        
        if(trend == 1)
            isAtLoss = (switchPrice - close[i]) > deviation;
        else
            isAtLoss = (close[i] - switchPrice) > deviation;
        
        BullDotBuffer[i] = EMPTY_VALUE;
        BearDotBuffer[i] = EMPTY_VALUE;
        
        if(trend == 1)
        {
            double targetBand = isAtLoss ? (alpha * close[i] + (1.0 - alpha) * prevBand) : lowerBase;
            BandBuffer[i] = MathMax(targetBand, prevBand);
            BandColors[i] = 0;
            
            if(close[i] < BandBuffer[i])
            {
                trend = -1;
                BandBuffer[i] = upperBase;
                BandColors[i] = 1;
                switchPrice = close[i];
                BearDotBuffer[i] = BandBuffer[i];
                
                if(Show_Labels)
                {
                    string name = "STR_Arrow_" + IntegerToString(i);
                    ObjectCreate(0, name, OBJ_ARROW_DOWN, 0, time[i], BandBuffer[i] + 5 * _Point);
                    ObjectSetInteger(0, name, OBJPROP_COLOR, C'242,54,69');
                    ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
                    
                    string txtName = "STR_Text_" + IntegerToString(i);
                    ObjectCreate(0, txtName, OBJ_TEXT, 0, time[i], BandBuffer[i] + 8 * _Point);
                    ObjectSetString(0, txtName, OBJPROP_TEXT, "BEAR");
                    ObjectSetInteger(0, txtName, OBJPROP_COLOR, clrWhite);
                    ObjectSetInteger(0, txtName, OBJPROP_FONTSIZE, 7);
                    ObjectSetInteger(0, txtName, OBJPROP_ANCHOR, ANCHOR_UPPER);
                }
            }
        }
        else
        {
            double targetBand = isAtLoss ? (alpha * close[i] + (1.0 - alpha) * prevBand) : upperBase;
            BandBuffer[i] = MathMin(targetBand, prevBand);
            BandColors[i] = 1;
            
            if(close[i] > BandBuffer[i])
            {
                trend = 1;
                BandBuffer[i] = lowerBase;
                BandColors[i] = 0;
                switchPrice = close[i];
                BullDotBuffer[i] = BandBuffer[i];
                
                if(Show_Labels)
                {
                    string name = "STR_Arrow_" + IntegerToString(i);
                    ObjectCreate(0, name, OBJ_ARROW_UP, 0, time[i], BandBuffer[i] - 5 * _Point);
                    ObjectSetInteger(0, name, OBJPROP_COLOR, C'8,153,129');
                    ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
                    
                    string txtName = "STR_Text_" + IntegerToString(i);
                    ObjectCreate(0, txtName, OBJ_TEXT, 0, time[i], BandBuffer[i] - 8 * _Point);
                    ObjectSetString(0, txtName, OBJPROP_TEXT, "BULL");
                    ObjectSetInteger(0, txtName, OBJPROP_COLOR, clrWhite);
                    ObjectSetInteger(0, txtName, OBJPROP_FONTSIZE, 7);
                    ObjectSetInteger(0, txtName, OBJPROP_ANCHOR, ANCHOR_LOWER);
                }
            }
        }
        
        // 创建精细填充:只在价格和止损带之间,减少透明度让颜色淡一些
        if(Show_Fills && i > 0 && i < rates_total - 1)
        {
            // 确保只在带和价格之间填充,不要扩大范围
            double bandPrice = BandBuffer[i];
            double priceNow = close[i];
            
            // 只有当价格和带之间有明显距离才画填充
            if(MathAbs(bandPrice - priceNow) > 2 * _Point)
            {
                string name = "STR_Fill_" + IntegerToString(i);
                
                if(ObjectFind(0, name) < 0)
                {
                    double top = MathMax(bandPrice, priceNow);
                    double bottom = MathMin(bandPrice, priceNow);
                    
                    // 颜色更淡,透明度更高
                    color fillColor = (trend == 1) ? C'8,153,129' : C'242,54,69';
                    
                    ObjectCreate(0, name, OBJ_RECTANGLE, 0, time[i], top, time[i+1], bottom);
                    ObjectSetInteger(0, name, OBJPROP_COLOR, fillColor);
                    ObjectSetInteger(0, name, OBJPROP_FILL, true);
                    ObjectSetInteger(0, name, OBJPROP_BACK, true);
                    ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
                    ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
                    ObjectSetInteger(0, name, OBJPROP_WIDTH, 0);
                }
            }
        }
    }
    
    return rates_total;
}
MT5 运行截图 · 完整视图带价格轴和时间轴的整张图表(约 150 根 H1 K 线),上面的封面是它最近 80 根 K 线的放大视图
SuperTrend 回血止损带(精准复刻版) 在 MT5 上的真实截图

作品说明

明白了,我会把填充色带做窄一些,更贴合原图的精致效果。关键是让填充区域只在价格和止损带之间形成薄薄一层,而不是大面积覆盖。

使用说明

安装方法

  1. MT5 按 F4 打开 MetaEditor
  2. 新建指标,粘贴代码,保存为 SuperTrendRecovery.mq5
  3. 编译(F7),无错后在图表加载

参数说明

  • ATR 周期(默认 10):计算波动率周期
  • 基础倍数(默认 3.0):止损带宽度
  • 回血权重(默认 5%):亏损时带收缩速度
  • 回血阈值(默认 1.0xATR):超过此亏损才收缩
  • 显示填充:价格和止损带间的淡色填充
  • 显示标签:BULL/BEAR 文字标签

信号解读

  • 青绿线 = 多头,粉红线 = 空头
  • 圆点 = 趋势切换确认点
  • 淡色填充 = 趋势区域可视化

注意事项

  • 色带现在只在价格和止损带之间,不会大面积覆盖
  • 颜色已调淡,更接近原图风格
  • 回血机制可减少震荡假信号

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

这是什么

这是一个 MT5 平台的 SuperTrend 趋势指标,核心特点是加入了「回血机制」:当价格回撤、浮亏超过一定阈值时,止损带会自动向价格方向收缩,减少震荡市假突破导致的过早平仓。多头用青绿线、空头用粉红线,价格与止损带之间有淡色渐变填充,视觉上更清晰。

逻辑原理

指标用 ATR(平均真实波幅)计算止损带。常规 SuperTrend 的带宽是 (最高价+最低价)/2 ± 倍数×ATR,多头时用下带,空头时用上带。本指标在此基础上加入动态调整:

  • 记录趋势切换时的价格(switchPrice
  • 每根 K 线判断浮亏是否超过「回血阈值」(默认 1.0×ATR)
  • 若超过,止损带不再取基础带,而是向当前收盘价靠拢:新带 = 回血权重 × 收盘价 + (1 - 回血权重) × 上一根带;默认权重 5%,即每根 K 线向价格方向收 5%
  • 若未超过阈值,止损带按常规 SuperTrend 逻辑更新(多头时只能上移,空头时只能下移)
  • 当价格突破止损带,趋势反转,在突破点画圆点,重新记录 switchPrice

渐变填充画在价格与止损带之间,颜色与趋势一致,透明度较高不遮挡 K 线。

参数说明

  • ATR_Period(默认 10):计算 ATR 的周期,越大越平滑、越滞后
  • Base_Multiplier(默认 3.0):基础止损带宽度倍数,越大带离价格越远,越不易触发反转
  • Recovery_Alpha(默认 5.0%):回血权重,浮亏时每根 K 线止损带向价格靠拢的比例;越大收缩越快,但过大会让带过于贴近价格失去缓冲
  • Recovery_Threshold(默认 1.0):触发回血的浮亏阈值,单位是 ATR 倍数;低于此值带正常移动,超过才启动收缩
  • Show_Fills(默认开启):是否显示价格与止损带间的淡色填充
  • Show_Labels(默认开启):是否在趋势切换点显示 BULL / BEAR 文字和箭头

怎么用

  1. MetaEditor(F4)新建指标,粘贴源码,保存为 .mq5,编译(F7)
  2. 在任意图表插入自定义指标 SuperTrendRecovery
  3. 青绿线向上 = 多头趋势,粉红线向下 = 空头趋势
  4. 圆点 = 趋势刚切换,可作为进出场参考点
  5. 结合其他确认指标(如量能、RSI)过滤信号更稳妥

适用场景

  • 适合:中长周期趋势行情(H1 及以上),波动较大的品种(XAUUSD、原油、指数),趋势跟踪策略
  • 适合调整:回血机制在震荡转趋势的过渡阶段能减少假信号,比传统 SuperTrend 更抗回撤
  • 不适合:高频剥头皮(信号滞后)、极窄区间震荡(ATR 过小时带会频繁切换)、低波动货币对(如 EURCHF,回血效果不明显)

危险提示

  1. 滞后性:趋势反转确认需要价格完全突破止损带,顶底往往已走掉一截
  2. 参数敏感Base_Multiplier 太小会频繁切换产生假信号,太大则入场太晚;Recovery_Alpha 太大会让带过早贴价,失去保护作用
  3. 无重绘:代码未使用未来数据,历史信号不会改变,但回血逻辑依赖实时浮亏计算,复盘时需注意
  4. 填充对象:代码用 OBJ_RECTANGLE 画填充,对象数量会随 K 线累积,长时间挂载可能影响图表性能,建议定期清理历史对象或关闭 Show_Fills
  5. 不含交易逻辑:这是纯指标,不自动下单,需手动或配合 EA 执行

常见问题

这个指标会重绘吗?
不会。代码未使用未来数据,历史信号固定。但回血机制依赖实时浮亏,复盘时新 K 线形成的带可能与实盘略有差异,这是正常的动态调整,不属于重绘。
可以用在 XAUUSD 以外的品种吗?
可以。代码未限制品种,但回血机制在高波动品种(黄金、原油、指数)效果更明显。低波动货币对(如 EURCHF)可能需降低 Recovery_Threshold 或提高 Recovery_Alpha。
MT4 能用吗?
不能直接用。这是 MQL5 代码,MT4 用 MQL4。若需 MT4 版本,需重写为 MQL4 语法(缓冲区、对象 API 差异较大)。
参数默认值适合什么周期?
H1 及以上中长周期。默认 ATR 周期 10、倍数 3.0 是经典 SuperTrend 配置,适合日内到日线级别趋势。M15 以下可能需减小 ATR 周期到 7 或降低倍数到 2.5,自行回测优化。
回血权重设多少合适?
默认 5% 较保守。激进跟单者可提高到 10-15%,但过高会让带过早贴价失去缓冲,增加假突破风险。建议先用默认值观察一周实盘表现再调。

SuperTrend Recovery Band Indicator for MT5

An adaptive SuperTrend indicator for MT5 that tightens the stop band during drawdown to reduce false signals. Features color-coded trend lines, gradient fills, and configurable recovery parameters for trend-following strategies.

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

评论

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

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