0% found this document useful (0 votes)
1K views8 pages

SuperTrend mq5

The document is a code implementation of the SuperTrend indicator for the MetaTrader 5 platform, which includes functions for calculating and displaying upper and lower bands based on the Average True Range (ATR). It initializes the ATR indicator, performs calculations for trend detection, and manages the drawing of trend bands on the chart. The code also includes event handling for timer-based updates according to the selected timeframe.

Uploaded by

mahdifathian11
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views8 pages

SuperTrend mq5

The document is a code implementation of the SuperTrend indicator for the MetaTrader 5 platform, which includes functions for calculating and displaying upper and lower bands based on the Average True Range (ATR). It initializes the ATR indicator, performs calculations for trend detection, and manages the drawing of trend bands on the chart. The code also includes event handling for timer-based updates according to the selected timeframe.

Uploaded by

mahdifathian11
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8

//+------------------------------------------------------------------+

//| SuperTrend.mq5 |
//| gmakhobe |
//| https://github.com/gmakhobe/mql5-supertrend |
//+------------------------------------------------------------------+
#property version "1.00"

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
// Input Variables
input int lookbackPeriod = 10;
// Global Variables
string pairSymbol = Symbol();
int multiplier = 3;
int atrHandler;

datetime prevousCandleTime;

double previousUpperBand = 0;
double previousLowerBand = 0;
double previousFinalUpperBand = 0;
double previousFinalLowerBand = 0;
double previousSuperTrend = 0;

bool isFirstExecution = true;


bool isUpTrend = NULL;
/*
Initialize indicator
*/
int OnInit()
{

averageTrueRangeIndicatorInit(atrHandler, lookbackPeriod, pairSymbol);

if (atrHandler == INVALID_HANDLE)
{
Print("An error happened while copy indicator buffer data: ",
GetLastError());
return (INIT_FAILED);
}

//onEventSetTimeHandler();

return(INIT_SUCCEEDED);
}

/*
Perform calculations
*/
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[])
{
/* Convert Price Data to Price series */
bool asSeries = true;

ArraySetAsSeries(time,asSeries);
ArraySetAsSeries(high,asSeries);
ArraySetAsSeries(low,asSeries);
ArraySetAsSeries(close,asSeries);

superTrend(time[0], time[1], prevousCandleTime, high[1], low[1], close[1],


previousUpperBand, previousLowerBand,
previousFinalUpperBand, previousFinalLowerBand, atrHandler, isFirstExecution,
isUpTrend);

return(rates_total);
}
/*
SuperTrend: Main function handling SuperTrend fuctionality
*/
void superTrend(datetime _time_0, datetime _time_1, datetime& _prevousCandleTime,
double _high_1, double _low_1, double _close_1,
double& _previousUpperBand, double& _previousLowerBand, double&
_previousFinalUpperBand, double& _previousFinalLowerBand,
int& _atrHandler, bool& _isFirstExecution, bool& _isUpTrend)
{
uint dataPoints = 2;
double averageTrueRangeData[];
double lowerBand;
double upperBand;
double finalLowerBand;
double finalUpperBand;
double superTrend = 0;

if (prevousCandleTime != _time_1)
{
averageTrueRangeIndicatorData(averageTrueRangeData, _atrHandler, dataPoints);
upperBand = getBasicUpperBand(_high_1, _low_1, multiplier,
averageTrueRangeData[1]);
lowerBand = getBasicLowerBand(_high_1, _low_1, multiplier,
averageTrueRangeData[1]);
finalUpperBand = getFinalUpperBand(upperBand, previousFinalUpperBand,
_close_1);
finalLowerBand = getFinalLowerBand(lowerBand, previousFinalLowerBand,
_close_1);
superTrend = getSuperTrend(previousSuperTrend,
previousFinalUpperBand,previousFinalLowerBand,
finalUpperBand,finalLowerBand,_close_1);
_prevousCandleTime = _time_1;

if (finalUpperBand != 0 && finalLowerBand != 0 && previousFinalUpperBand != 0


&& previousFinalLowerBand != 0)
{
if (_close_1 > previousFinalUpperBand && !_isFirstExecution)
{
_isUpTrend = true;
}
if (_close_1 < previousFinalLowerBand && !_isFirstExecution)
{
_isUpTrend = false;
}
Print("Is Close > Upper = ", _close_1 > previousFinalUpperBand, "\n Close=
", _close_1, " - UpperBand= ", previousFinalUpperBand);
Print("Is Close < Lower = ", _close_1 > previousFinalLowerBand, "\n Close=
", _close_1, " - UpperBand= ", previousFinalLowerBand);

//Print("_isFirstExecution = ", _isFirstExecution);


if (_isFirstExecution)
{
checkFirstExecutionXOver(_isFirstExecution, _isUpTrend, finalUpperBand,
finalLowerBand, previousFinalUpperBand, previousFinalLowerBand);
}
printSuperTrend(_isFirstExecution, _isUpTrend, finalUpperBand,
finalLowerBand, previousFinalUpperBand,
previousFinalLowerBand, _time_0, _time_1);
}

_previousUpperBand = upperBand;
_previousLowerBand = lowerBand;
_previousFinalUpperBand = finalUpperBand;
_previousFinalLowerBand = finalLowerBand;
}
}
/*
Print our super trend
*/
void printSuperTrend(bool& _isFirstExecution, bool& _isUpTrend, double
_finalUpperBand, double _finalLowerBand,
double _previousFinalUpperBand, double _previousFinalLowerBand, datetime
_time_0, datetime _time_1)
{
string _upperBandName = TimeToString(_time_1) + "-" + TimeToString(_time_0) +
"Upperband";
string _lowerBandName = TimeToString(_time_1) + "-"+TimeToString(_time_0) +
"Lowerband";
//_isFirstExecution = true;
//_isUpTrend = NULL;

if (_isFirstExecution && _isUpTrend == NULL)


{
drawBand(_previousFinalUpperBand, _time_1, _finalUpperBand, _time_0,
_upperBandName, clrAqua);
drawBand(_previousFinalLowerBand, _time_1, _finalLowerBand, _time_0,
_lowerBandName, clrAqua);
Print("Is Neutral Trend!");
}

if (!_isFirstExecution && _isUpTrend)


{
drawBand(_previousFinalLowerBand, _time_1, _finalLowerBand, _time_0,
_lowerBandName, clrGreen);
}

if (!_isFirstExecution && !_isUpTrend)


{
drawBand(_previousFinalUpperBand, _time_1, _finalUpperBand, _time_0,
_upperBandName, clrRed);
}
}
/*
Check if it the program has been recently run and the crossover has not occured
*/
void checkFirstExecutionXOver(bool& _isFirstExecution, bool& _isUpTrend, double
_finalUpperBand, double _finalLowerBand,
double _previousFinalUpperBand, double _previousFinalLowerBand)
{
if (_isFirstExecution && (_previousFinalUpperBand >= _finalUpperBand) &&
(_previousFinalLowerBand <= _finalLowerBand))
{
_isFirstExecution = true;
return ;
}
else
{
_isFirstExecution = false;
}

// We are trending down


if (!_isFirstExecution && (_previousFinalUpperBand >= _finalUpperBand) &&
_isUpTrend == NULL)
{
_isUpTrend = false;
return ;
}

// We are trending up
if (!_isFirstExecution && (_previousFinalLowerBand <= _finalLowerBand) &&
_isUpTrend == NULL)
{
_isUpTrend = true;
return ;
}

}
/*
Get Super Trend
*/
double getSuperTrend(double _previousSuperTrend,
double _previousFinalUpperBand,double _previousFinalLowerBand,
double _currentFinalUpperBand, double _currentFinalLowerBand,
double _currentClose)
{
// To-Do

return (0);
}
/*
Get Final Bands
*/
// Get Final Lower Band
/*
Final Lowerband = If Current Basic Lowerband > Previous Final Lowerband OR
Previous Close < Previous Final Lowerband Then Current Basic Lowerband Else
Previous Final Lowerband
*/
double getFinalLowerBand(double _currentbasicLowerBand, double
_previousFinalLowerBand, double _previousClose)
{
double _currentBand;

if (_currentbasicLowerBand > _previousFinalLowerBand || _previousClose <


_previousFinalLowerBand)
{
_currentBand = _currentbasicLowerBand;
}
else
{
_currentBand = _previousFinalLowerBand;
}

return _currentBand;
}
// Get Final Upper Band
/*
Final Upperband = If Current Basic Upperband < Previous Final Upperband OR
Previous Close > Previous Final Upperband Then Current Basic Upperband Else
Previous Final Upperband
*/
double getFinalUpperBand(double _currentbasicUpperBand, double
_previousFinalUpperBand, double _previousClose)
{
double _currentBand;

if (_currentbasicUpperBand < _previousFinalUpperBand || _previousClose >


_previousFinalUpperBand)
{
_currentBand = _currentbasicUpperBand;
}
else
{
_currentBand = _previousFinalUpperBand;
}

return _currentBand;
}
/*
Draw band and give it a color
*/
bool drawBand(
double _previousBandValue,
datetime _fromDatetime,
double _currentBandValue,
datetime _toDatetime,
string _bandName,
color _bandColor)
{
int _chartId = 0; // current chart

bool _isRendered = ObjectCreate(


_chartId,
_bandName,
OBJ_TREND,
0,
_fromDatetime,
_previousBandValue,
_toDatetime,
_currentBandValue
);

ObjectSetInteger(_chartId, _bandName, OBJPROP_COLOR, _bandColor);

return _isRendered;
}

/*
Basic Upper Band
Formula: BASIC UPPER BAND = HLA + [ MULTIPLIER * 10-DAY ATR ]
*/
double getBasicUpperBand(
double _high,
double _low,
int _multiplier,
double _averageTrueRange)
{
double _highLowAverage = (_high + _low) / 2;
double _basicBand = _highLowAverage + (multiplier * _averageTrueRange);

return _basicBand;
}
/*
Basic Lower Band
Formula: BASIC LOWER BAND = HLA - [ MULTIPLIER * 10-DAY ATR ]
*/
double getBasicLowerBand(
double _high,
double _low,
int _multiplier,
double _averageTrueRange)
{
double _highLowAverage = (_high + _low) / 2;
double _basicBand = _highLowAverage - (multiplier * _averageTrueRange);

return _basicBand;
}
/*
Initialize the ATR indicator
*/
void averageTrueRangeIndicatorInit(
int& _atrHandler,
int _lookbackPeriod,
string& _pairSymbol)
{
MqlParam _indicatorParameters[1];
int _parameterCount = 1;

if (_pairSymbol == NULL)
{
_pairSymbol = Symbol();
}

_indicatorParameters[0].type = TYPE_INT; // indicator parameter type (lookback


period)
_indicatorParameters[0].integer_value = _lookbackPeriod; //lookback period
_atrHandler = IndicatorCreate(_pairSymbol, PERIOD_CURRENT, IND_ATR,
_parameterCount, _indicatorParameters);
}

/*
Get ATR Data from the buffer using a handler
*/
void averageTrueRangeIndicatorData(
double& _averageTrueRangeData[],
int& _atrHandler,
uint _dataPoints = 1)
{
bool _asSeries = true;

if(_atrHandler != INVALID_HANDLE)
{
ArraySetAsSeries(_averageTrueRangeData, _asSeries);

if (CopyBuffer(_atrHandler, 0, 0, _dataPoints, _averageTrueRangeData) == 0)


{
Print("An error happened while copy indicator buffer data: ",
GetLastError());
}
}
}

// Perform Action on Timer


void OnTimer()
{

/*
Execute onTimer per the number of seconds in relation with the timeframe
selected.
*/
void onEventSetTimeHandler()
{
switch(Period())
{
case PERIOD_M1:
EventSetTimer(60);
break;
case PERIOD_M2:
EventSetTimer(120);
break;
case PERIOD_M4:
EventSetTimer(240);
break;
case PERIOD_M5:
EventSetTimer(300);
break;
case PERIOD_M6:
EventSetTimer(360);
break;
case PERIOD_M10:
EventSetTimer(600);
break;
case PERIOD_M12:
EventSetTimer(720);
break;
case PERIOD_M15:
EventSetTimer(900);
break;
case PERIOD_M20:
EventSetTimer(1200);
break;
case PERIOD_M30:
EventSetTimer(1800);
break;
case PERIOD_H1:
EventSetTimer(3600);
break;
case PERIOD_H4:
EventSetTimer(14400);
break;
case PERIOD_D1:
EventSetTimer(86400);
break;
case PERIOD_W1:
EventSetTimer(432000);
break;
default:
break;
}
}

You might also like