Parabolic SAR inconsistency?

 

Once a SAR is calculated for a given period is it allowed to change?

It's my understanding that the SAR for "tomorrow" is calculated using data from "today". If this is true, then shouldn't SAR remain constant once it is calculated for period [0]?

My basic concern is that when I check SAR[0] at the beginning of an M15 bar can it change by the end of the M15 bar?

Thanks - Don

 
From a quick glance at the code, Parabolic SAR includes the High[0]/Low[0] values, so SAR would change along with those values for the current bar.
 
blogzr3 wrote >>
From a quick glance at the code, Parabolic SAR includes the High[0]/Low[0] values, so SAR would change along with those values for the current bar.

Thank you for your time.

 

https://www.mql5.com/en/code/7892

The only time it looks at High[0]/Low[0] is to switch directions

price = SarBuffer[i+1];
sar = price + start*(ep - price);
 

Well this one is really throwing me for a loop. I now have several instances where SAR changes between the opening of a bar and the closing of a bar.

If this is a bug in the MT4 indicator, who would I contact to report it?

 
did it switch and then switch back?
 
justhooked01 wrote >>

Well this one is really throwing me for a loop. I now have several instances where SAR changes between the opening of a bar and the closing of a bar.

If this is a bug in the MT4 indicator, who would I contact to report it?

Have a look at how SAR is calculated here: https://en.wikipedia.org/wiki/Parabolic_SAR

Now note the exceptions:

The SAR is recursively calculated in this manner for each new period. There are, however, two special cases that will modify the SAR value:

  • If tomorrow's SAR value lies within (or beyond) today's or yesterday's price range, the SAR must be set to the closest price bound. For example, if in an uptrend, the new SAR value is calculated and it results to be greater than today's or yesterday's lowest price, the SAR must be set equal to that lower boundary.
  • If tomorrow's SAR value lies within (or beyond) tomorrow's price range, a new trend direction is then signaled, and the SAR must "switch sides."

As you can see, dependant on where the close price is, SAR will switch sides.

That is the way it works. It is not a bug.

It is recommended when you use SAR to not make your trade decision based on the 1st dot in the SAR series after it switches sides. Rather wait at least for 3 dots to the indicator generate some acceleration. Unfortuntely that often means that you will catch the "good" moves too late.

whocares

 

While it may not be working how I would prefer, apparently it is working as designed. In all cases where I did find what I thought was a discrepancy, it was either the 4th or 5th dot in the series which is why I thought it was a bug. Guess I'll be creating a custom indicator CASP (calculate and stay put).

Thanks to everyone for your input.

 
Just roll your own.
if (newBar) {
	static double 	SL.SAR, SL.SAR.HH, SL.SAR.PS;	// OrderSend().

	if (order.type == OP_BUY) {			// Compute new SAR
		SL.SAR 	= MathMin( SL.SAR + SL.SAR.PS*(SL.SAR.HH-SL.SAR)
						 , MathMin(Low[1], Low[2]) );
		if (High[1] > SL.SAR.HH) {
			SL.SAR.HH = High[1];
			SL.SAR.PS = MathMin( SL.SAR.PS + SL.SAR.Step, SL.SAR.Max );
		}
	} else {
		SL.SAR 	= MathMax( SL.SAR + SL.SAR.PS*(SL.SAR.HH-SL.SAR)
						 , MathMax(High[1], High[2]) );
		if (Low[1] < SL.SAR.HH) {
			SL.SAR.HH = Low[1];
			SL.SAR.PS = MathMin( SL.SAR.PS + SL.SAR.Step, SL.SAR.Max );
		}
	}
}
// orderModify(...SL.SAR...)
//...

OrderSend(...SL.INIT...);  // After opening order, init SAR
if (order.type == OP_BUY) {
	SL.SAR.HH 	= High[shift.best];		SL.SAR	=  Low[shift.best];
} else {
	SL.SAR.HH 	=  Low[shift.best];		SL.SAR	= High[shift.best];
}
SL.SAR.PS	= SL.SAR.Step;
for(int shift=shift.best-1; shift>=0; shift--) {
	if (order.type == OP_BUY) {
		SL.SAR 	= MathMin( SL.SAR + SL.SAR.PS*(SL.SAR.HH-SL.SAR)
						 , MathMin(Low[shift+1], Low[shift+2]) );
		if (High[shift] > SL.SAR.HH) {
			SL.SAR.HH = High[shift];
			SL.SAR.PS = MathMin( SL.SAR.PS + SL.SAR.Step, SL.SAR.Max );
		}
	} else {
		SL.SAR 	= MathMax( SL.SAR + SL.SAR.PS*(SL.SAR.HH-SL.SAR)
						 , MathMax(High[shift+1], High[shift+2]) );
		if (Low[shift] < SL.SAR.HH) {
			SL.SAR.HH = Low[shift];
			SL.SAR.PS = MathMin( SL.SAR.PS + SL.SAR.Step, SL.SAR.Max );
		}
	}
}
FWIW, I'm no longer using SAR for my stops, I use
extern double   SL.ATR.Trail    = 2.5;    	// SLTrail=High-SAT*ATR(shift.best)
//...
double ATR =iATR(Symbol(), 0, shift.best+1, 0);

if (order.type == OP_BUY) {    		double
        HH 	= High[0],
	SL.ATR	= HH - ATR * SL.ATR.Trail;
} else {
        HH      =  Low[0];   		// Chart values are Bid values.
	SL.ATR	= HH + ATR * SL.ATR.Trail + spread;
}