//+------------------------------------------------------------------+ //| supertrendPro.mq5 | //| Copyright 2026, MetaQuotes Ltd. Developer: Gloria Diana | //| https://www.mql5.com/en/users/gloriadiana | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian" #property link "https://www.mql5.com/en/users/chachaian" #property version "1.00" #property indicator_chart_window #property indicator_buffers 8 #property indicator_plots 3 #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_type2 DRAW_LINE #property indicator_type3 DRAW_LINE //+------------------------------------------------------------------+ //| Input parameters | //+------------------------------------------------------------------+ input group "Supertrend Settings" input int InpATRPeriod = 10; // ATR calculation period input double InpATRMultiplier = 1.5; // ATR multiplier used to position the Supertrend bands input group "Notifications" input bool InpEnablePushNotifications = true; // Send mobile push notifications on confirmed trend changes //+------------------------------------------------------------------+ //| Trend states exposed through Buffer 7 | //+------------------------------------------------------------------+ const double TREND_BULLISH = 1.0; // Confirmed bullish trend const double TREND_BEARISH = 0.0; // Confirmed bearish trend const double TREND_NEUTRAL = -1.0; // Initial unresolved trend state //+------------------------------------------------------------------+ //| Indicator theme colors | //+------------------------------------------------------------------+ const color COLOR_BACKGROUND = clrWhiteSmoke; // Main chart background const color COLOR_FOREGROUND = clrBlack; // Chart text and scale labels const color COLOR_BULLISH = clrSeaGreen; // Bullish candles, bands, and Bid line const color COLOR_BEARISH = clrCrimson; // Bearish candles, bands, and Ask line //+------------------------------------------------------------------+ //| Stores the chart appearance before Supertrend Pro changes it | //+------------------------------------------------------------------+ struct SChartAppearance { long backgroundColor; // Original chart background color long foregroundColor; // Original chart text and scale color long showGrid; // Original grid visibility long chartMode; // Original chart drawing mode long chartUpColor; // Original bullish chart color long chartDownColor; // Original bearish chart color long candleBullColor; // Original bullish candle color long candleBearColor; // Original bearish candle color long bidColor; // Original Bid line color long askColor; // Original Ask line color }; //+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ int g_atrHandle = INVALID_HANDLE; // Handle of the ATR indicator double g_atrValues[]; // Working array for copied ATR values SChartAppearance g_chartAppearance; // Chart appearance saved before applying the theme bool g_chartAppearanceSaved = false; // Confirms that restoration data is available datetime g_lastNotifiedBarTime = 0; // Open time of the last bar that generated a push notification datetime g_lastObservedLiveBarTime = 0; // Live bar tracked during the previous successful calculation //+------------------------------------------------------------------+ //| Public indicator buffers | //+------------------------------------------------------------------+ double g_candleOpen[]; // Buffer 0: trend-colored candle Open double g_candleHigh[]; // Buffer 1: trend-colored candle High double g_candleLow[]; // Buffer 2: trend-colored candle Low double g_candleClose[]; // Buffer 3: trend-colored candle Close double g_candleColor[]; // Buffer 4: candle trend color index double g_upperBand[]; // Buffer 5: upper/bearish Supertrend band double g_lowerBand[]; // Buffer 6: lower/bullish Supertrend band double g_trendState[]; // Buffer 7: 1.0 bullish, 0.0 bearish, -1.0 neutral //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Validate all user-configurable Supertrend parameters before //--- allocating or configuring indicator resources. if(!ValidateInputs()) return(INIT_PARAMETERS_INCORRECT); //--- Reset notification tracking so every initialization establishes //--- a fresh live-bar baseline before any push alert can be generated. g_lastNotifiedBarTime=0; g_lastObservedLiveBarTime=0; //--- Bind the declared arrays to their permanent indicator buffer //--- indexes before configuring their visual plots. if(!ConfigureIndicatorBuffers()) { Print("Failed to configure Supertrend Pro indicator buffers."); return(INIT_FAILED); } //--- Configure the candle and Supertrend plots that present the //--- calculated trend state on the chart. if(!ConfigureIndicatorPlots()) { Print("Failed to configure Supertrend Pro indicator plots."); return(INIT_FAILED); } //--- Create the ATR handle used by the Supertrend calculation. g_atrHandle=iATR(_Symbol,PERIOD_CURRENT,InpATRPeriod); if(g_atrHandle==INVALID_HANDLE) { PrintFormat("Failed to create ATR handle. Error=%d",GetLastError()); return(INIT_FAILED); } //--- Preserve the user's current chart appearance before applying //--- the mandatory Supertrend Pro visual theme. if(!SaveChartAppearance()) { Print("Failed to save the current chart appearance."); return(INIT_FAILED); } //--- Apply the Supertrend Pro theme after the original appearance //--- has been stored successfully. if(!ApplyIndicatorTheme()) { Print("Failed to apply the Supertrend Pro chart theme."); //--- Restore any chart properties changed before theme setup failed. RestoreChartAppearance(); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- Explicitly use chronological indexing throughout the indicator. ArraySetAsSeries(time,false); ArraySetAsSeries(open,false); ArraySetAsSeries(high,false); ArraySetAsSeries(low,false); ArraySetAsSeries(close,false); ArraySetAsSeries(tick_volume,false); ArraySetAsSeries(volume,false); ArraySetAsSeries(spread,false); //--- Wait until enough price history exists to calculate the ATR. if(rates_total0 && rates_total==prev_calculated+1 && g_lastObservedLiveBarTime!=0 && time[lastClosedIndex]==g_lastObservedLiveBarTime) liveTrendChange=true; //--- Rebuild the complete Supertrend state when previous calculations //--- cannot be reused. Historical reconstruction never generates alerts. if(prev_calculated==0) { //--- Clear all public buffers before reconstructing history. ArrayInitialize(g_candleOpen,EMPTY_VALUE); ArrayInitialize(g_candleHigh,EMPTY_VALUE); ArrayInitialize(g_candleLow,EMPTY_VALUE); ArrayInitialize(g_candleClose,EMPTY_VALUE); ArrayInitialize(g_candleColor,0.0); ArrayInitialize(g_upperBand,EMPTY_VALUE); ArrayInitialize(g_lowerBand,EMPTY_VALUE); ArrayInitialize(g_trendState,EMPTY_VALUE); //--- ATR data is required from the first valid seed bar onward. start=firstValidIndex; } else { //--- Resume from the bar that was live during the previous //--- calculation and may now have become confirmed. start=prev_calculated-1; if(startg_upperBand[previousIndex]) { g_trendState[index]=TREND_BULLISH; g_upperBand[index]=EMPTY_VALUE; g_lowerBand[index]=lowerBandValue; return(true); } //--- Establish the first bearish trend when price closes below the //--- previous neutral lower band. if(close[index]g_lowerBand[previousIndex]) g_lowerBand[index]=lowerBandValue; else g_lowerBand[index]=g_lowerBand[previousIndex]; //--- Preserve the neutral state until either boundary is breached. g_trendState[index]=TREND_NEUTRAL; return(false); } //+------------------------------------------------------------------+ //| Processes one bar when the previous trend state is bullish | //+------------------------------------------------------------------+ void CalculateBullishState(const int index, const double &open[], const double &high[], const double &low[], const double &close[]) { //--- Calculate the raw ATR-based bands for the current confirmed bar. double barMidpoint=(high[index]+low[index])/2.0; double upperBandValue=barMidpoint+ g_atrValues[index]*InpATRMultiplier; double lowerBandValue=barMidpoint- g_atrValues[index]*InpATRMultiplier; int previousIndex=index-1; //--- Reverse to bearish when price closes below the previous active //--- lower band. The upper band becomes active from this bar onward. if(close[index]g_lowerBand[previousIndex]) g_lowerBand[index]=lowerBandValue; else g_lowerBand[index]=g_lowerBand[previousIndex]; //--- Keep the bearish upper band inactive while bullish control remains. g_upperBand[index]=EMPTY_VALUE; g_trendState[index]=TREND_BULLISH; //--- Draw the confirmed bar using the bullish candle color. SetBullishCandle(index,open,high,low,close); } //+------------------------------------------------------------------+ //| Processes one bar when the previous trend state is bearish | //+------------------------------------------------------------------+ void CalculateBearishState(const int index, const double &open[], const double &high[], const double &low[], const double &close[]) { //--- Calculate the raw ATR-based bands for the current confirmed bar. double barMidpoint=(high[index]+low[index])/2.0; double upperBandValue=barMidpoint+ g_atrValues[index]*InpATRMultiplier; double lowerBandValue=barMidpoint- g_atrValues[index]*InpATRMultiplier; int previousIndex=index-1; //--- Reverse to bullish when price closes above the previous active //--- upper band. The lower band becomes active from this bar onward. if(close[index]>g_upperBand[previousIndex]) { g_trendState[index]=TREND_BULLISH; g_upperBand[index]=EMPTY_VALUE; g_lowerBand[index]=lowerBandValue; //--- Recolor the reversal bar immediately as part of the new //--- confirmed bullish trend. SetBullishCandle(index,open,high,low,close); return; } //--- Preserve the bearish trend while allowing the upper band to //--- tighten downward without moving back upward. if(upperBandValue