MT5 Supertrend Indicator: MQL5 Code and Alerts
A Supertrend indicator for MT5 is a custom MQL5 chart overlay that uses Average True Range to place a trailing band above or below price. This implementation includes complete source code, configurable ATR settings, separate bullish and bearish buffers, and alerts that trigger only after a candle closes.
What this MT5 indicator includes
The standard starting point is ATR period 10 with a multiplier of 3.0.
The code calculates signals in OnCalculate() and keeps indicator logic separate from order execution.
Closed-bar alerts use the last completed candle, so a forming candle cannot trigger a final signal.
Supertrend follows trends well but can flip repeatedly when price moves sideways.
How the Supertrend signal works
Bullish flip
A bullish flip occurs when the current close moves above the final upper band after the previous state was bearish. The indicator then plots the final lower band beneath price. The code calculates the active candle for visual feedback, but alerts inspect the last completed candle and compare it with the candle before it. When I review a Supertrend port, this is the first indexing check I make because reading the forming candle as a confirmed signal is a common source of unstable alerts.
Bearish flip
A bearish flip occurs when the current close falls below the final lower band after the previous state was bullish. The plotted line moves above price and switches to the bearish buffer. Supertrend can be used as a direction filter or a trailing reference, but it is not an order system by itself. If an Expert Advisor uses these buffers, its own position sizing, spread checks, stop placement, and execution rules still need to be defined and tested.
MQL5 Custom Indicator Code
//+------------------------------------------------------------------+
//| SuperTrend_Custom.mq5 |
//| MT5 custom indicator with ATR bands and closed-bar alerts |
//| Educational example. This is not financial advice. |
//+------------------------------------------------------------------+
#property copyright "Pineify"
#property link "https://pineify.app"
#property version "1.10"
#property strict
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 2
#property indicator_label1 "Supertrend Up"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLimeGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_label2 "Supertrend Down"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrTomato
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
input int InpAtrPeriod = 10;
input double InpMultiplier = 3.0;
input bool InpDesktopAlert = true;
input bool InpPushAlert = false;
double UpBuffer[];
double DownBuffer[];
double TrendBuffer[];
double FinalUpperBuffer[];
double FinalLowerBuffer[];
double AtrBuffer[];
int atrHandle = INVALID_HANDLE;
datetime lastAlertBar = 0;
int OnInit()
{
if(InpAtrPeriod < 1 || InpMultiplier <= 0.0)
return INIT_PARAMETERS_INCORRECT;
SetIndexBuffer(0, UpBuffer, INDICATOR_DATA);
SetIndexBuffer(1, DownBuffer, INDICATOR_DATA);
SetIndexBuffer(2, TrendBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(3, FinalUpperBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(4, FinalLowerBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(5, AtrBuffer, INDICATOR_CALCULATIONS);
ArraySetAsSeries(UpBuffer, false);
ArraySetAsSeries(DownBuffer, false);
ArraySetAsSeries(TrendBuffer, false);
ArraySetAsSeries(FinalUpperBuffer, false);
ArraySetAsSeries(FinalLowerBuffer, false);
ArraySetAsSeries(AtrBuffer, false);
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpAtrPeriod);
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpAtrPeriod);
atrHandle = iATR(_Symbol, _Period, InpAtrPeriod);
if(atrHandle == INVALID_HANDLE)
{
Print("Could not create iATR handle. Error: ", GetLastError());
return INIT_FAILED;
}
IndicatorSetString(
INDICATOR_SHORTNAME,
StringFormat("Supertrend(%d, %.2f)", InpAtrPeriod, InpMultiplier)
);
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(atrHandle != INVALID_HANDLE)
IndicatorRelease(atrHandle);
}
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 <= InpAtrPeriod + 2)
return 0;
ArraySetAsSeries(time, false);
ArraySetAsSeries(high, false);
ArraySetAsSeries(low, false);
ArraySetAsSeries(close, false);
int copied = CopyBuffer(atrHandle, 0, 0, rates_total, AtrBuffer);
if(copied < rates_total)
return prev_calculated;
int start = prev_calculated > 0 ? prev_calculated - 1 : InpAtrPeriod;
if(prev_calculated == 0)
{
for(int i = 0; i < InpAtrPeriod; i++)
{
UpBuffer[i] = EMPTY_VALUE;
DownBuffer[i] = EMPTY_VALUE;
TrendBuffer[i] = 0.0;
FinalUpperBuffer[i] = 0.0;
FinalLowerBuffer[i] = 0.0;
}
}
for(int i = start; i < rates_total && !IsStopped(); i++)
{
double midpoint = (high[i] + low[i]) * 0.5;
double basicUpper = midpoint + InpMultiplier * AtrBuffer[i];
double basicLower = midpoint - InpMultiplier * AtrBuffer[i];
if(i == InpAtrPeriod)
{
FinalUpperBuffer[i] = basicUpper;
FinalLowerBuffer[i] = basicLower;
TrendBuffer[i] = 1.0;
}
else
{
int previous = i - 1;
FinalUpperBuffer[i] =
(basicUpper < FinalUpperBuffer[previous] ||
close[previous] > FinalUpperBuffer[previous])
? basicUpper
: FinalUpperBuffer[previous];
FinalLowerBuffer[i] =
(basicLower > FinalLowerBuffer[previous] ||
close[previous] < FinalLowerBuffer[previous])
? basicLower
: FinalLowerBuffer[previous];
if(TrendBuffer[previous] < 0.0)
TrendBuffer[i] =
close[i] > FinalUpperBuffer[i] ? 1.0 : -1.0;
else
TrendBuffer[i] =
close[i] < FinalLowerBuffer[i] ? -1.0 : 1.0;
}
if(TrendBuffer[i] > 0.0)
{
UpBuffer[i] = FinalLowerBuffer[i];
DownBuffer[i] = EMPTY_VALUE;
}
else
{
UpBuffer[i] = EMPTY_VALUE;
DownBuffer[i] = FinalUpperBuffer[i];
}
}
if(prev_calculated > 0 &&
(InpDesktopAlert || InpPushAlert) &&
rates_total > InpAtrPeriod + 3)
{
int closedBar = rates_total - 2;
int priorBar = rates_total - 3;
if(TrendBuffer[closedBar] != TrendBuffer[priorBar] &&
time[closedBar] != lastAlertBar)
{
string direction =
TrendBuffer[closedBar] > 0.0 ? "bullish" : "bearish";
string message = StringFormat(
"%s %s Supertrend closed %s at %.*f",
_Symbol,
EnumToString(_Period),
direction,
_Digits,
close[closedBar]
);
if(InpDesktopAlert)
Alert(message);
if(InpPushAlert)
SendNotification(message);
lastAlertBar = time[closedBar];
}
}
return rates_total;
}
Copy this code into MetaEditor, save it in the MQL5/Indicators folder, and compile with F7.
Change the settings or add your own signal filter
Describe the ATR inputs, alert rules, visual style, or confirmation filter you want. Pineify generates editable MQL5 source code that you can inspect and compile in MetaEditor.
Pine Script vs MQL5: Same Strategy, Different Platforms
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Series evaluated on chart updates | Event handlers with explicit buffers |
| Deployment | Runs in TradingView with alerts | Runs in the MT5 terminal or on a VPS |
| Broker access | Via TradingView broker integration | Direct broker connectivity |
| Backtesting | Strategy Tester for strategy scripts | Strategy Tester for Expert Advisors |
| Code complexity | Simpler, functional syntax | C++-like, more powerful |
The calculation can be implemented on either platform, but the runtime model and buffer APIs differ. Read the Pine Script Supertrend reference before porting logic between them.
Frequently Asked Questions
Related MQL5 pages
Technical references
Risk and testing note
Past performance is not indicative of future results. Backtest statistics are based on historical data and do not guarantee future profits. Trading involves significant risk of loss. This content is for educational purposes only and does not constitute financial advice.
Related Supertrend tools
How to Create Supertrend in TradingView
Learn how to create and customize the Supertrend indicator in TradingView. Covers the ATR-based formula, Pine Script coding, and no-code creation with Pineify.
SuperTrend Strategy Tutorial
Learn how to build, backtest, and optimize the SuperTrend strategy on TradingView using Pine Script v5 and Pineify Deep Report.
Supertrend Screener
Find bullish and bearish daily Supertrend states across Pineify market collections. Direction flips are shown beside the current trend signal.
ta.supertrend() - Supertrend
Learn how to use ta.supertrend() in Pine Script. Syntax, parameters, code examples for the ATR-based trend overlay.