//+------------------------------------------------------------------+ //| SAR index based on MA.mq5 | //| Copyright © 2018, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2018, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.004" //--- indicator settings #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 2 #property indicator_type1 DRAW_ARROW #property indicator_color1 clrDodgerBlue #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed //--- External parametrs input double InpSARStep=0.02; // Step input double InpSARMaximum=0.04; // Maximum //---- buffers double ExtSARBuffer[]; double ExtMABuffer[]; double ExtEPBuffer[]; double ExtAFBuffer[]; //--- global variables int ExtLastRevPos; bool ExtDirectionLong; double ExtSarStep; double ExtSarMaximum; //--- int handle_iMA; // variable for storing the handle of the iMA indicator //--- we will keep the number of values in the Moving Average indicator int bars_calculated=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int 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,ExtMABuffer,INDICATOR_DATA); 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; //--- create handle of the indicator iMA handle_iMA=iMA(Symbol(),Period(),14,0,MODE_LWMA,PRICE_CLOSE); //--- if the handle is not created if(handle_iMA==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- 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[]) { //--- 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]LoData[i]) result=LoData[i]; return(result); } //+------------------------------------------------------------------+ //| Filling indicator buffers from the MA indicator | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &values[], // indicator buffer of Moving Average values int shift, // shift int ind_handle, // handle of the iMA indicator int amount // number of copied values ) { //--- reset error code ResetLastError(); //--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index if(CopyBuffer(ind_handle,0,-shift,amount,values)<0) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } //--- everything is fine return(true); } //+------------------------------------------------------------------+