【解説】 【MQL5 community】 Parabolic Stop and Reverse (パラボリック ストップ アンド リバース): トレンドが反転した時や相場の転換期を判断するために使用。
【計算法】
SAR = (EP − 前日のSAR) × AF + 前日のSAR
EP(Extreme Point):EPとは極大値のことで、上昇相場なら一定期間の最高値を用い、その後ポジションが変わらない限り最高値が更新されればEPも更新されます。 逆に下げ相場の時は最安値を用いて、これが更新されればEPも更新されます。
AF(Acceleration Factor):AFとは加速因数のことで初期値は0.02でEPが更新される毎に0.005ずつ加算されますが、ただしAFの最大値は0.2でそれを超えることはありません。 AFの値が大きくなると、SARのシグナルが早く転換しやすくなります。
【シグナル】
ローソク足がSARを上抜けたら「買いサイン」、下抜けたら「売りサイン」。
//+------------------------------------------------------------------+ //| 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 3 #property indicator_plots 1 #property indicator_type1 DRAW_ARROW #property indicator_color1 DodgerBlue //--- External parametrs input double InpSARStep=0.02; // Step input double InpSARMaximum=0.2; // Maximum //---- buffers double ExtSARBuffer[]; double ExtEPBuffer[]; double ExtAFBuffer[]; //--- 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); SetIndexBuffer(1,ExtEPBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,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;i<rates_total-1;i++) { //--- check for reverse if(ExtDirectionLong) { if(ExtSARBuffer[i]>Low[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]<High[i]) { //--- switch to LONG ExtDirectionLong=true; ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,Low); ExtEPBuffer[i]=High[i]; ExtLastRevPos=i; ExtAFBuffer[i]=ExtSarStep; } } //--- continue calculations if(ExtDirectionLong) { //--- check for new High if(High[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]<ExtEPBuffer[i-1] && i!=ExtLastRevPos) { ExtEPBuffer[i]=Low[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]<High[i] || ExtSARBuffer[i+1]<High[i-1]) ExtSARBuffer[i+1]=MathMax(High[i],High[i-1]); } } //---- 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(result<HiData[i]) result=HiData[i]; return(result); } //+------------------------------------------------------------------+ //| Find lowest price from start to current position | //+------------------------------------------------------------------+ double GetLow(int nPosition,int nStartPeriod,const double &LoData[]) { //--- calculate double result=LoData[nStartPeriod]; for(int i=nStartPeriod;i<=nPosition;i++) if(result>LoData[i]) result=LoData[i]; return(result); } //+------------------------------------------------------------------+
【表示結果】
AF=0.02。トレンドが始まるときは、ちゃんとシグナルを発している。
Back to Meta Trader