Also das ist absolut nicht mein Programmierstil.
Man sieht ja vor Bäumen den Wald nicht mehr = man sieht ja vor lauter Commentar den Code nicht mehr.
Auserdem wird der input parameter 'shift' überhaupt nicht verwendet.
Ich hab das neu programmiert, in meinem Stil, vielleicht können sich die Herren 'Superprogrammierer' ein Scheiberl abschneiden.
//+------------------------------------------------------------------+ //| Supertrend.mq5 | //| Original code found on https://www.mql5.com/de/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 initialization 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/de/users/kronenchakra | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| definitions | //+------------------------------------------------------------------+ #define COPY "Copyright © 2018, Ing. Otto Pauser" #define LINK "https://www.mql5.com/de/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; // initialize bufferindex to 0 SetIndexBuffer (idx,_buffer); // initialize buffer ArrayInitialize (_buffer ,NULL); // initialize 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 }
Sieht doch gleich ganz übersichtlich aus.
Könnte sich eventuell auch MetaQutes was abschauen, zB: wie man Plotbuffer in nur einer Zeile definiert.
Otto,
das:
TrendUp[bar]=NULL; // clear all buffers TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL;
ist gefährlich. NULL ist vom typ 'void'. Irgendwann später könnte vielleicht, um MT5 noch schneller zu machen, tatsächlich nix zugewiesen werden (dann bliebe der alt bestehen) oder es entsteht ein Zufallswert, wenn der Speicherplatz wechselt.
Imho wäere es besser für das Symbol _Symbol und für Werte entweder EMPTY_VALUE oder direkt 0 verwenden. So verleihst Du dem Nichts ein Sein. ;)
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
SuperTrend:
SuperTrend Trendindikator.
Autor: Nikolay Kositsin