This study looks for a PSAR state transition (either from bullish to bearish or vice versa) and plots a horizontal price line into the expansion area.

If the state transition already triggered, it calculates the number of bars ago the event happened. I've included labels, alerts as well as chart bubbles.

As of this moment if you load a daily chart of GS, you'll see a state transition TODAY!

If the state transition already triggered, it calculates the number of bars ago the event happened. I've included labels, alerts as well as chart bubbles.

As of this moment if you load a daily chart of GS, you'll see a state transition TODAY!

### Here is the code

Code:

```
# PSAR Transition Indicator
# tomsk
# 11.20.2019
# V1.0 - 11.20.2019 - tomsk - Initial release of PSAR Transition Indicator
# This study looks for a PSAR state transition (either from bullish to bearish
# or vice versa) and plots a horizontal price line into the expansion area. If
# the state transition already triggered, it calculates the number of bars ago
# the event happened. I've included labels, alerts as well as chart bubbles
input accelerationFactor = 0.02;
input accelerationLimit = 0.2;
input offSet = 2;
assert(accelerationFactor > 0, "'acceleration factor' must be positive: " + accelerationFactor);
assert(accelerationLimit >= accelerationFactor, "'acceleration limit' (" + accelerationLimit + ") must be greater than or equal to 'acceleration factor' (" + accelerationFactor + ")");
def bar = barNumber();
def state = {default init, long, short};
def extreme;
def SAR;
def acc;
switch (state[1]) {
case init:
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = low;
case short:
if (SAR[1] < high)
then {
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = extreme[1];
} else {
state = state.short;
if (low < extreme[1])
then {
acc = min(acc[1] + accelerationFactor, accelerationLimit);
extreme = low;
} else {
acc = acc[1];
extreme = extreme[1];
}
SAR = max(max(high, high[1]), SAR[1] + acc * (extreme - SAR[1]));
}
case long:
if (SAR[1] > low)
then {
state = state.short;
acc = accelerationFactor;
extreme = low;
SAR = extreme[1];
} else {
state = state.long;
if (high > extreme[1])
then {
acc = min(acc[1] + accelerationFactor, accelerationLimit);
extreme = high;
} else {
acc = acc[1];
extreme = extreme[1];
}
SAR = min(min(low, low[1]), SAR[1] + acc * (extreme - SAR[1]));
}
}
plot parSAR = SAR;
parSAR.SetPaintingStrategy(PaintingStrategy.POINTS);
parSAR.SetDefaultColor(GetColor(5));
def transitionBull = state[1] == state.short and state == state.long;
def transitionBear = state[1] == state.long and state == state.short;
def transitionBar = if transitionBull or transitionBear
then bar
else transitionBar[1];
def transitionPrice = if bar == HighestAll(transitionBar)
then close
else transitionPrice[1];
def transitionBarsAgo = if bar != transitionBar
then bar - transitionBar
else if bar == transitionBar
then Double.NaN
else transitionBarsAgo[1];
def timeAxis = if IsNaN(close[-1]) and !IsNaN(close) then bar else timeAxis[1];
plot horizLine = if GetTime() <= RegularTradingEnd(getYYYYMMDD()) and
transitionBar == HighestAll(transitionBar)
then transitionPrice
else Double.NaN;
horizLine.SetLineWeight(2);
horizLine.SetDefaultColor(Color.Yellow);
AddLabel(transitionBull or transitionBear, "PSAR Transition Detected Now!", Color.Yellow);
AddLabel(!(transitionBull or transitionBear), "PSAR Transition " + transitionBarsAgo + " bars ago", Color.Cyan);
Alert(transitionBull, "PSAR Transition Bull", Alert.BAR, Sound.Ding);
Alert(transitionBear, "PSAR Transition Bear", Alert.Bar, Sound.Ring);
AddChartBubble(bar == HighestAll(timeAxis+offSet), transitionPrice, "PSAR\nTransitioned", Color.Pink);
# End PSAR Transition Indicator
```

Last edited: