//+------------------------------------------------------------------+ //| ParabolicSAR.mq5 | //| Copyright 2009, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2009, MetaQuotes Software Corp." #property link "http://www.mql5.com" //--- indicator settings #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_ARROW #property indicator_color1 Red,CadetBlue //--- External parametrs input double InpSARStep=0.02; // Step input double InpSARMaximum=0.2; // Maximum //---- buffers double ExtSARBuffer[]; double ExtEPBuffer[]; double ExtAFBuffer[]; double ExtColorBuffer[]; //--- global variables int ExtLastRevPos; bool ExtDirectionLong; double ExtSarStep; double ExtSarMaximum; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- checking input data if(InpSARStep<0.0) { ExtSarStep=0.02; Print("Input parametr InpSARStep has incorrect value. Indicator will use value", ExtSarStep,"for calculations."); } else ExtSarStep=InpSARStep; if(InpSARMaximum<0.0) { ExtSarMaximum=0.2; Print("Input parametr InpSARMaximum has incorrect value. Indicator will use value", ExtSarMaximum,"for calculations."); } else ExtSarMaximum=InpSARMaximum; //---- indicator buffers SetIndexBuffer(0,ExtSARBuffer,INDICATOR_DATA); SetIndexBuffer(1,ExtColorBuffer,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,ExtEPBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(3,ExtAFBuffer,INDICATOR_CALCULATIONS); //--- set arrow symbol PlotIndexSetInteger(0,PLOT_ARROW,159); //--- set indicator digits IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //--- set label name PlotIndexSetString(0,PLOT_LABEL,"SAR("+ DoubleToString(ExtSarStep,2)+","+ DoubleToString(ExtSarMaximum,2)+")"); //--- set global variables ExtLastRevPos=0; ExtDirectionLong=false; //---- } //+------------------------------------------------------------------+ //| 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 &TickVolume[], const long &Volume[], const int &Spread[]) { //--- check for minimum rates count if(rates_total<3) return(0); //--- detect current position int pos=prev_calculated-1; //--- correct position if(pos<1) { //--- first pass, set as SHORT pos=1; ExtAFBuffer[0]=ExtSarStep; ExtAFBuffer[1]=ExtSarStep; ExtSARBuffer[0]=High[0]; ExtLastRevPos=0; ExtDirectionLong=false; ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,High); ExtEPBuffer[0]=Low[pos]; ExtEPBuffer[1]=Low[pos]; } //---main cycle for(int i=pos;iLow[i]) { //--- switch to SHORT ExtDirectionLong=false; ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,High); ExtEPBuffer[i]=Low[i]; ExtLastRevPos=i; ExtAFBuffer[i]=ExtSarStep; } } else { if(ExtSARBuffer[i]ExtEPBuffer[i-1] && i!=ExtLastRevPos) { ExtEPBuffer[i]=High[i]; ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep; if(ExtAFBuffer[i]>ExtSarMaximum) ExtAFBuffer[i]=ExtSarMaximum; } else { //--- when we haven't reversed if(i!=ExtLastRevPos) { ExtAFBuffer[i]=ExtAFBuffer[i-1]; ExtEPBuffer[i]=ExtEPBuffer[i-1]; } } //--- calculate SAR for tomorrow ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]); //--- check for SAR if(ExtSARBuffer[i+1]>Low[i] || ExtSARBuffer[i+1]>Low[i-1]) { ExtSARBuffer[i+1]=MathMin(Low[i],Low[i-1]); } } else { //--- check for new Low if(Low[i]ExtSarMaximum) ExtAFBuffer[i]=ExtSarMaximum; } else { //--- when we haven't reversed if(i!=ExtLastRevPos) { ExtAFBuffer[i]=ExtAFBuffer[i-1]; ExtEPBuffer[i]=ExtEPBuffer[i-1]; } } //--- calculate SAR for tomorrow ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]); //--- check for SAR if(ExtSARBuffer[i+1]=Close[i])ExtColorBuffer[i]=1; else ExtColorBuffer[i]=0; } //---- OnCalculate done. Return new prev_calculated. return(rates_total); } //+------------------------------------------------------------------+ //| Find highest price from start to current position | //+------------------------------------------------------------------+ double GetHigh(int nPosition,int nStartPeriod,const double &HiData[]) { //--- calculate double result=HiData[nStartPeriod]; for(int i=nStartPeriod;i<=nPosition;i++) if(resultLoData[i]) result=LoData[i]; return(result); } //+------------------------------------------------------------------+