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)
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).
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.
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
Step 1: 
Step 2: 
do you have this for mt4
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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