Indicators: SuperTrend

 

SuperTrend:

SuperTrend trend indicator.

This indicator is considered to be a trend one and its operation principle is quite simple: as soon as it changes its color to green, it means the start of an uptrend, if the color is changed to red, a downtrend starts. The indicator has one disadvantage - it often lags but, nevertheless, it is quite popular among traders. For better results the indicator should be used as confirmation for the market entry.

Author: Nikolay Kositsin

Super Trend indicator

 

Nikolay! Which of your brainchildren with the least lag and the least number of false signals (if, of course, this can be determined at all)

 
Makser:

Nikolay! Which of your brainchildren has the least lag and the least number of false signals (if, of course, this can be determined at all).

Here is a question, so the question. I use JFatlSpeed on crosses, and recently on everything else. But only on the four-hour markers. And I catch bounces on five-minute trades on X2MA_BBx9.
 

So that's absolutely not my programming style.

You can't see the wood for the trees = you can't see the code for all the comments.

In addition, the input parameter 'shift' is not used at all.

I have reprogrammed this in my style, maybe the 'super programmers' can take a leaf out of my book.

//+------------------------------------------------------------------+
//|Supertrend.mq5 |
//| Original code found on https://www.mql5.com/en/code/527 | 
//| Original code from Jason Robinson, rewritten by Nikolay Kositsin |
//| Improved by Ing. Otto Pauser alias Kronenchakra |
//+------------------------------------------------------------------+ 

//--- inckudes
#include <Utils.mqh>

//--- general properties
#property copyright COPY 
#property link      LINK 
#property version   "1.00"

//--- indicator properties
#property indicator_chart_window
#property indicator_buffers 4 
#property indicator_plots   4

//--- input parameters
input int CCIPeriod  =  50;   // CCI indicator period 
input int ATRPeriod  =   5;   // ATR indicator period
input int Level      =   0;   // CCI activation level

//---- indicator buffers
double   ATR[],
         CCI[];
double   TrendUp[],
         TrendDn[];
double   SignUp[],
         SignDn[];
         
//---- global variables
int      min_rates_total;
int      ATR_Handle,
         CCI_Handle;

//+------------------------------------------------------------------+
//| Custom indicator initialisation function |
//+------------------------------------------------------------------+
int OnInit()
{
   min_rates_total=MathMax(CCIPeriod,ATRPeriod);

   CCI_Handle=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL);
   if(InvalidHandle(CCI_Handle,"iCCI"))
      return(INIT_FAILED);

   ATR_Handle=iATR(NULL,0,ATRPeriod);
   if(InvalidHandle(ATR_Handle,"iATR"))
      return(INIT_FAILED);

   string shortname=IndiShortName("Supertrend",CCIPeriod,ATRPeriod);
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);

   InitBuffer(TrendUp,DRAW_LINE ,"Supertrend Up"         ,clrLime,min_rates_total,0  ,2,true);
   InitBuffer(TrendDn,DRAW_LINE ,"Supertrend Down"       ,clrRed ,min_rates_total,0  ,2,true);
   InitBuffer(SignUp ,DRAW_ARROW,"Supertrend signal Buy" ,clrLime,min_rates_total,108,1,true);
   InitBuffer(SignDn ,DRAW_ARROW,"Supertrend signal Sell",clrRed ,min_rates_total,108,1,true);

   ArraySetAsSeries(ATR,true);
   ArraySetAsSeries(CCI,true);

   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[])
{
   if                                                    // check
      (
          BarsCalculated(CCI_Handle)<rates_total ||      // check CCI indicator
          BarsCalculated(ATR_Handle)<rates_total ||      // check ATR indicator
          rates_total<min_rates_total                    // check for enough bars
      )
          return(0);                                     // try next tick

   int limit,to_copy,bar;

   ArraySetAsSeries(high,true);                          // has to be set AsSeries every tick
   ArraySetAsSeries(low ,true);

   if(prev_calculated>rates_total || prev_calculated<=0) // checking for the first start of the indicator calculation
      limit=rates_total-min_rates_total;                 // starting index for calculation of all bars
   else
      limit=rates_total-prev_calculated;                 // starting index for calculation of new bars

   to_copy=limit+1;                                      // copy ATR-Data to buffer
   if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0);

   to_copy++;                                            // copy CCI-Data to buffer
   if(CopyBuffer(CCI_Handle,0,0,to_copy,CCI)<=0) return(0);

   for(bar=limit; bar>=0; bar--)                         // calculation main loop
     {
      TrendUp[bar]=NULL;                                 // clear all buffers
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;
                                                         // calculate the lines
      if(CCI[bar]>=Level && CCI[bar+1]<Level) TrendUp[bar]=TrendDn[bar+1];
      if(CCI[bar]<=Level && CCI[bar+1]>Level) TrendDn[bar]=TrendUp[bar+1];

      if(CCI[bar]>Level)                                 
        {
         TrendUp[bar]=low[bar]-ATR[bar];
         if(TrendUp[bar]<TrendUp[bar+1] && CCI[bar+1]>=Level) TrendUp[bar]=TrendUp[bar+1];
        }

      if(CCI[bar]<Level)                                 
        {
         TrendDn[bar]=high[bar]+ATR[bar];
         if(TrendDn[bar]>TrendDn[bar+1] && CCI[bar+1]<=Level) TrendDn[bar]=TrendDn[bar+1];
        }

      if(TrendDn[bar+1]!=0.0 && TrendUp[bar]!=0.0) SignUp[bar]=TrendUp[bar];  // check signal UP
      if(TrendUp[bar+1]!=0.0 && TrendDn[bar]!=0.0) SignDn[bar]=TrendDn[bar];  // check signal DOWN
     }
    
   return(rates_total);
}
//+------------------------------------------------------------------+
//|Utils.mqh |
//| Copyright © 2018, Ing. Otto Pauser | 
//| https://www.mql5.com/en/users/kronenchakra | 
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| definitions|
//+------------------------------------------------------------------+

#define  COPY   "Copyright © 2018, Ing. Otto Pauser"
#define  LINK   "https://www.mql5.com/en/users/kronenchakra"
#define  SPACER "---------------------" 

//+------------------------------------------------------------------+
//| abbreviations|
//+------------------------------------------------------------------+

#define  PRICE ENUM_APPLIED_PRICE
#define  TIMEF ENUM_TIMEFRAMES

//+------------------------------------------------------------------+
//| Auxiliary functions|
//+------------------------------------------------------------------+

void InitBuffer(double &_buffer[], ENUM_DRAW_TYPE _type, string _label, color _color, int _begin, int _arrow=159, int _width=1, bool _series=false)
{
   static int idx=0;                                  // initialise bufferindex to 0
   SetIndexBuffer     (idx,_buffer);                  // initialise buffer
   ArrayInitialize    (_buffer ,NULL);                // initialise buffer
   ArraySetAsSeries   (_buffer ,_series);             // set AsSeries
                                                      // set properties
   PlotIndexSetInteger(idx,PLOT_DRAW_TYPE  ,_type );
   PlotIndexSetInteger(idx,PLOT_LINE_COLOR ,_color);
   PlotIndexSetInteger(idx,PLOT_LINE_WIDTH ,_width);
   PlotIndexSetInteger(idx,PLOT_DRAW_BEGIN ,_begin);
   PlotIndexSetInteger(idx,PLOT_ARROW      ,_arrow);
   PlotIndexSetString (idx,PLOT_LABEL      ,_label);
   PlotIndexSetDouble (idx,PLOT_EMPTY_VALUE,NULL  );
   idx++;                                             // increment bufferindex for next call
}

bool InvalidHandle(int _handle, string _msg)
{
   if(_handle==INVALID_HANDLE)                     // check handle
      Alert("*ERROR* creating "+_msg+" handle.");  // info
   return(_handle==INVALID_HANDLE);                // return true if invalid
}

string IndiShortName(string _name, int val_1, int val_2=NULL, int val_3=NULL)
{
   string result=_name+"("+IntegerToString(val_1);
   if(val_2!=NULL)
      result=result+","+IntegerToString(val_2);
   if(val_3!=NULL)
      result=result+","+IntegerToString(val_3);
   return(result+")");
}

//+------------------------------------------------------------------+
//| Calculation functions|
//+------------------------------------------------------------------+
double StdDeviation(int position,const double &price[],const double &MAprice[],int period)
{
   int i;
   double StdDev_dTmp=0.0;

   if(position<period) return(StdDev_dTmp);        // check position

   for(i=0;i<period;i++)                           // calcualte StdDev
      StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);

   StdDev_dTmp=MathSqrt(StdDev_dTmp/period);

   return(StdDev_dTmp);                            // return calculated value
}

It looks quite clear right away.

Perhaps MetaQutes could also learn something, e.g. how to define plot buffers in just one line.

Files:
supertrend.mq5  11 kb
Utils.mqh  7 kb
 

Otto,

that:

      TrendUp[bar]=NULL;                                 // clear all buffers
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;

is dangerous. NULL is of type'void'. Sometime later, to make MT5 even faster, perhaps nothing could actually be assigned (then the old would remain) or a random value is created when the memory location changes.

Imho it would be better to use _symbol for the symbol and either EMPTY_VALUE or 0 directly for values. That way you give nothingness a being ;)

 
How can I get
 
I want to use this indicator
 
ka03ht8096:
How can I get

Step 1: 

Step 2: 

 
Which input is Multiplier and ATR value?
 

do you have this for mt4