mod note:
This is not just another PSAR.
This is a custom‑rolled Parabolic SAR engine with two meaningful upgrades:
This is not just another PSAR.
This is a custom‑rolled Parabolic SAR engine with two meaningful upgrades:
1. It exposes the last confirmed SAR levels as horizontal support/resistance, which classic PSAR does not do.
2. It gives you a stable midline between those levels, which is actually the most useful part for intraday structure.
Code:
################################
# Original script by Cwparker23#
################################
#-----------------
#- DISCLAIMER
#-----------------
#- I am not a certified financial advisor. The content of this page/site and tools are for informational purposes only and does not constitute financial or legal advice. Under no circumstances will the author be responsible for errors or use of this tool and site. User assumes all risks.
input accelerationFactor = 0.02;
input accelerationLimit = 0.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 state = {default init, long, short};
def extreme;
def SAR;
def acc;
def first = IsNaN(SAR[1]);
switch (state[1]) {
case init:
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = low;
case short:
if (first or 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 (first or 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 Psar = sar;
Psar.SetPaintingStrategy(PaintingStrategy.points);
Psar.DefineColor("Bearish", Color.red);
Psar.DefineColor("Bullish", Color.green);
Psar.AssignValueColor(if Psar > close then Psar.color("Bearish") else Psar.color("Bullish"));
# Detect flips
def flippedToLong = state == state.long and state[1] == state.short;
def flippedToShort = state == state.short and state[1] == state.long;
# Store only the most recent completed levels
def lastBullSAR = CompoundValue(1,
if flippedToLong then SAR else lastBullSAR[1],
Double.NaN);
def lastBearSAR = CompoundValue(1,
if flippedToShort then SAR else lastBearSAR[1],
Double.NaN);
plot SAR_Support = lastBullSAR;
plot SAR_Resistance = lastBearSAR;
plot Mid = (SAR_Support + SAR_Resistance)/2;
mid.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
mid.SetDefaultColor(Color.white);
mid.SetLineWeight(2);
SAR_Support.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
SAR_Resistance.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
SAR_Support.SetDefaultColor(Color.GREEN);
SAR_Resistance.SetDefaultColor(Color.RED);
SAR_Support.SetLineWeight(2);
SAR_Resistance.SetLineWeight(2);
Last edited by a moderator: