Parabolic SAR (PSAR) Scan, Watchlist, Labels, Charts For ThinkOrSwim

I want to see Labels (switchable on and off, with editable colors for state change ) that will show a state change of both PSAR and Linear Regression Reversal (NOTE: both of these studies are Native to TOS)

I will place this study with Labels on any of these time frames (4 Hr, D, 3D and W)

Requirements:

The existing TOS PSAR study dots should change their color based on Bullish or Bearish direction (initially white=bullish, black = bearish). Colors should be configurable.

Both of the following conditions must be true for label to change its color and text:
  • Parabolic SAR dots have switched their state from Bullish to Bearish (or vice versa)
  • Linear Regression Reversal has switched from Bullish to Bearish (or vice versa)
LABEL TEXT should read as follows : (Label Changes Color from Bull to Bear (White to BLACK)) when the studies dictate.

4Hr PSAR/LRR BULL (Or Bear)

D PSAR/LRR BULL (Or Bear)

3D PSAR/LRR BULL (Or Bear)

W PSAR/LRR BULL (Or Bear)

I’d like to see all these labels when I place the study on a chart.

The goal is to quickly see the strength of a change in price direction, as it affects each progressively larger time frame.

Can anyone code this in Thinkscript?

Thanks!
 
Hi all, is there a way to draw a box from the last dot on the old ParabolicSar Trend to the current dot? I'm a newbie so I don't even know where to begin.
Ruby:
# 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

this can draw 2 lines and a cloud, from the last dot on the previous psar trend, to the current dot.

the last dot line and cloud are colored,
...green , if last dot > previous dot.
...red , if last dot < previous dot.

this has 2 options for displaying a cloud,
...draw the cloud on top of the bars,
...or draw the cloud after the last bar. (if you don't like having shapes cover up the bars.)

options for the cloud after last bar,
...how many bars away from the last bar
...how many bars wide to made the cloud

in the original code, i disabled,
...the yellow line, by adding this, if 0 and
...a bubble


Code:
# psar_chg_box_00

#https://usethinkscript.com/threads/psar-transition-box.12706/
# PSAR Transition Box
# draw a box from the last dot on the old ParabolicSar Trend to the current dot?


# 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 bn = barnumber();
def na = double.nan;
def lastbar = !isnan(close[0]) and isnan(close[-1]);
def lastbn = HighestAll(If(IsNaN(close), 0, bn));

#---------------------------

# last bar in trend series
def Bull2 = state[0] == state.short and state[-1] == state.long;
def Bear2 = state[0] == state.long and state[-1] == state.short;

# bn of last bar in trend
def chg_bn2 = if bn == 1 then 1
  else if bull2 or bear2 then bn
  else chg_bn2[1];

def last_chg_bn2 = highestall(chg_bn2);

#def prev_sar = if bn == 1 or isnan(close) then 0
def prev_sar = if bn == 1 then 0
  else if bn == last_chg_bn2 then sar
  else prev_sar[1];

def last_trend = (bn >= highestall(chg_bn2) and !isnan(close));

input draw_cloud_on_bars = yes;
plot p = if draw_cloud_on_bars and last_trend then prev_sar else na;
#p.SetStyle(Curve.MEDIUM_DASH);
p.SetDefaultColor(Color.light_gray);
p.setlineweight(2);
p.hidebubble();

def last_sar = highestall(if lastbn == bn then sar else 0);
def issarup = ( last_sar > prev_sar);

plot l = if draw_cloud_on_bars and last_trend then last_sar else na;
#l.SetStyle(Curve.MEDIUM_DASH);
l.AssignValueColor(if issarup then color.green else color.red);
l.setlineweight(1);
l.hidebubble();

addcloud(p,l,color.red,color.green);

#-------------------------------

# cloud after last bar
input show_cloud_after_last_bar = yes;
input cloud_width = 3;
input bars_in_future = 2;
def bif = bars_in_future;
def cls = close;
def x = isNaN(cls[bif]) and !isNaN(cls[bif+1+cloud_width]);

plot p2 = if show_cloud_after_last_bar and x then prev_sar else na;
plot l2 = if show_cloud_after_last_bar and x then last_sar else na;
p2.SetDefaultColor(Color.light_gray);
p2.setlineweight(2);
p2.hidebubble();
l2.AssignValueColor(if issarup then color.green else color.red);
l2.setlineweight(1);
l2.hidebubble();

addcloud(p2,l2,color.red,color.green);

#---------------------------

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 0 and 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
#

CCZe5Lt.jpg
 
I want to see Labels (switchable on and off, with editable colors for state change ) that will show a state change of both PSAR and Linear Regression Reversal (NOTE: both of these studies are Native to TOS)

I will place this study with Labels on any of these time frames (4 Hr, D, 3D and W)

Requirements:

The existing TOS PSAR study dots should change their color based on Bullish or Bearish direction (initially white=bullish, black = bearish). Colors should be configurable.

Both of the following conditions must be true for label to change its color and text:
  • Parabolic SAR dots have switched their state from Bullish to Bearish (or vice versa)
  • Linear Regression Reversal has switched from Bullish to Bearish (or vice versa)
LABEL TEXT should read as follows : (Label Changes Color from Bull to Bear (White to BLACK)) when the studies dictate.

4Hr PSAR/LRR BULL (Or Bear)

D PSAR/LRR BULL (Or Bear)

3D PSAR/LRR BULL (Or Bear)

W PSAR/LRR BULL (Or Bear)

I’d like to see all these labels when I place the study on a chart.

The goal is to quickly see the strength of a change in price direction, as it affects each progressively larger time frame.

Can anyone code this in Thinkscript?

Thanks!


here is a MTF version of parabolicsar. add the desired label, then load it mutiple times , for each desired time frame.
https://usethinkscript.com/threads/looking-for-parabolic-sar-mtf-multi-time-frame.1285/#post-11701
 
Is there any way to store the PSAR flip count using the script in the below link? I'd like to be able to compare the length of the last X number of PSAR flips.
https://usethinkscript.com/threads/psar-transition-indicator-for-thinkorswim.1130/#post-9944


i'm not sure what you want to compare to what.
i made this, to find some counts and stats, that might be a starting point for you.
this will count the sar dots on each up/down trend.
count the quantity of transistions.
count the total of bull dots and total of bear dots.
calculate the average of bull and bear trends.

it shows a bubble below the bars, with the stats

Code:
# PSAR_Transition_barcnt_01


# https://usethinkscript.com/threads/psar-flips.13056/
# UnAnswered PSAR Flips
# mbrennan5  Oct 7, 2022

#Is there any way to store the PSAR flip count using the script in the below link? I'd like to be able to compare the length of the last X number of PSAR flips.




#https://usethinkscript.com/threads/psar-transition-indicator-for-thinkorswim.1130/#post-9944
#tomsk
#Nov 20, 2019
#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!


# 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


#-----------------------------

# var1, get bn's of 1st bar in set
# find bns, loop, copy to var2, in 1st bars

def bn = barnumber();

# transitionBull , dots below
# transitionBear , dots above
#-----------------------------

# make a new way to count dots in each sar set

def bulltrendsarcnt;
def beartrendsarcnt;
def flipcnt;
def bulltotal;
def beartotal;
if bn == 1 then {
 bulltrendsarcnt = 0;
 beartrendsarcnt = 0;
 flipcnt = 0;
 bulltotal = 0;
 beartotal = 0;

} else if transitionBull then {
  bulltrendsarcnt = fold i = 1 to 100
    with p = 1
    while getvalue(!transitionBear, -i)
    do p + ( if !isnan(getvalue(close, -i)) then 1 else 0);
  beartrendsarcnt = 0;
  flipcnt = flipcnt[1] + 1;
  bulltotal =  bulltotal[1] +  bulltrendsarcnt;
  beartotal = beartotal[1];

} else if transitionBear then {
  bulltrendsarcnt = 0;
  beartrendsarcnt = fold j = 1 to 100
    with q = 1
    while getvalue(!transitionBull, -j)
    do q + ( if !isnan(getvalue(close, -j)) then 1 else 0);
  flipcnt = flipcnt[1] + 1;
  bulltotal =  bulltotal[1];
  beartotal = beartotal[1] + beartrendsarcnt;

} else {
 bulltrendsarcnt = bulltrendsarcnt[1];
 beartrendsarcnt = beartrendsarcnt[1];
 flipcnt = flipcnt[1];
 bulltotal = bulltotal[1];
 beartotal = beartotal[1];
}


def bull_avg = (bulltotal/flipcnt);
def bear_avg = (beartotal/flipcnt);

addchartbubble(1, low*0.990,
  bn + "\n" +
  bulltrendsarcnt + " bull\n" +
  beartrendsarcnt + " bear\n" +
  flipcnt + " flips\n" +
  bulltotal + " bull_t\n" +
  beartotal + " bear_t\n" +
  bull_avg + " bull_avg\n" +
  bear_avg + " bear-avg"
, ( if transitionBull then color.green else if transitionBear then color.magenta else color.gray), no);



#--------------------------------------
# old way, look for barnumbers , not used


def bearbn = if bn == 1 then 0 
  else if transitionBear then bn
  else bearbn[1];

def bullbn = if bn == 1 then 0 
  else if transitionBull then bn
  else bullbn[1];

# calc qty of sar dots, and save on 1st bar of next set
def bulllen = if bn == 1 then 0
else if transitionBear then (bearbn - bullbn)
else 0;

# make the count negative, for bear dots
def bearlen = if bn == 1 then 0
else if transitionBull then -(bullbn - bearbn)
else 0;


addchartbubble(0, low*0.990,
bn + "\n" +
bearbn + "\n" +
bearlen + "\n" +
bullbn + "\n" +
bulllen
, ( if transitionBull then color.green else if transitionBear then color.magenta else color.gray), no);

#

SQ 1min 11/4
mGZ2QWb.jpg
 
@halcyonguy this is awesome! Just the sort of thing I was thinking of. Since I've been thinking about it more, I've realized what'd probably be most helpful would be to measure %change since flip and give the stats on that. It'd quantify areas of chop and averages would differentiate typical choppers from trenders. Length of PSAR kind of does this, but punishes fast volatile moves relative to slow trends up.
 
Hello, is there a way to have a psar overlay for lower studies. For example... have the PSAR and RSI ... or PSAR and MACD in a lower study. Could this be done? Thank you.
 
Hello, is there a way to have a psar overlay for lower studies. For example... have the PSAR and RSI ... or PSAR and MACD in a lower study. Could this be done? Thank you.

This has both the RSI and MACD each combined in one way. You can then decide how you might do other methods.
Ruby:
#RSI combined with ParabolicSAR
declare lower;
input length   = 14;
input avg_type = AverageType.WILDERS;
def rsi_low  = reference RSI(length, price = low, averagetype = avg_type);
def rsi_high = reference RSI(length, price = high, averagetype = avg_type);

def low  = rsi_low;
def high = rsi_high;

plot rsi =  reference RSI(length, price = close, averagetype = avg_type);
#
# TD Ameritrade IP Company, Inc. (c) 2008-2022
#

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;

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.AssignValueColor(if state == state.short then Color.RED else Color.GREEN);
Ruby:
#MACD combined with ParabolicSAR
declare lower;
input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input averageType = AverageType.EXPONENTIAL;
input showBreakoutSignals = no;

def macd_low  = MovingAverage(averageType, low, fastLength) - MovingAverage(averageType, low, slowLength);
def macd_high = MovingAverage(averageType, high, fastLength) - MovingAverage(averageType, high, slowLength);

def low  = macd_low;
def high = macd_high;

plot macd_value =  MovingAverage(averageType, close, fastLength) - MovingAverage(averageType, close, slowLength);


#
# TD Ameritrade IP Company, Inc. (c) 2008-2022
#

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;

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.AssignValueColor(if state == state.short then Color.RED else Color.GREEN);
 
@SleepyZ ... THIS IS CRAZY AF... Wow dude.

I watched this dude from the youtube channel figuringoutmoney ... and it looked very interesting.


Cant believe you could do the same with regular studies. This is a game changer.
 
I just want to grab the end of day (yesterday's) value of the PSAR on the daily timeframe, and use it on a smaller timeframe calc.

Any help appreciated.
 
Last edited by a moderator:
Here you go:

Code:
#
# Display Previous Day's PSAR on Lower timeframe
# BenTen

input Period = aggregationPeriod.DAY;
def close = close(period = Period);
def low = low(period = Period);
def high = high(period = Period);
def open = open(period = Period);

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;

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[1];
parSAR.SetPaintingStrategy(PaintingStrategy.POINTS);
parSAR.SetDefaultColor(GetColor(5));
 
Hello,
I've been using the PSAR indicator for a while now and I've been tasked to learn if there is a way to add a sound alert for when the PSAR indicator flips.
I'm familiar with ToS Alert function and roughly how it works.
Alert(condition, "text", AlertType, Sound)

What I'm not sure of is how to best define the condition. I came across this code regarding defining 'bullish' and 'bearish':
def sar = reference ParabolicSAR(0.02, 0.2) ;
def bullish = close crosses above sar ;
def bearish = close crosses below sar ;

Maybe after adding those into where everything is defined in the PSAR code, I can just put 'bullish' or 'bearish' for my condition for the alert? I'm just not sure if that'd work correctly. Any help would be appreciated. I've included the default code for the PSAR study.


#
# TD Ameritrade IP Company, Inc. (c) 2008-2022
#



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;


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));
 
Hello,
I've been using the PSAR indicator for a while now and I've been tasked to learn if there is a way to add a sound alert for when the PSAR indicator flips.
I'm familiar with ToS Alert function and roughly how it works.
Alert(condition, "text", AlertType, Sound)

What I'm not sure of is how to best define the condition. I came across this code regarding defining 'bullish' and 'bearish':
def sar = reference ParabolicSAR(0.02, 0.2) ;
def bullish = close crosses above sar ;
def bearish = close crosses below sar ;

Maybe after adding those into where everything is defined in the PSAR code, I can just put 'bullish' or 'bearish' for my condition for the alert? I'm just not sure if that'd work correctly. Any help would be appreciated. I've included the default code for the PSAR study.


#
# TD Ameritrade IP Company, Inc. (c) 2008-2022
#



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;


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));

if you want a parabolicsar 'flip' sound, then think about what you are looking at on the chart, and what it does.
psar plots a series of dots, either above the candles or below them.

so one thing to check for , could be if ,
SAR > close on current bar and SAR < close on previous bar
or
SAR < close on current bar and SAR > close on previous bar



here is one version i made awhile ago.
it uses a higher pitch sound for up and a lower pitch sound for down.

Code:
# psar_alerts_01
# -------------
# 2021-05-12
# halcyonguy
# -------------
# copy original parabolicsar study
# add alerts on crossovers
# add arrows on crossovers
# -------------------
# TD Ameritrade IP Company, Inc. (c) 2008-2021
#
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;

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));

# ---- end original code -------------
# check if psar dots have crossed over price
def xdwn = (sar[1] < close[1] and sar > close);
def xup = (sar[1] > close[1] and sar < close);
def na = double.nan;
input show_arrows = yes;
plot xup2 = if show_arrows then xup else na;
xup2.SetPaintingStrategy(PaintingStrategy.boolean_arrow_up);
xup2.SetDefaultColor(color.green);
xup2.setlineweight(3);
plot xdwn2 = if show_arrows then xdwn else na;
xdwn2.SetPaintingStrategy(PaintingStrategy.boolean_arrow_down);
xdwn2.SetDefaultColor(color.red);
xdwn2.setlineweight(3);
# =====================================
# alerts , sounds
# alert(condition, text, alert type, sound);
# Sound.Ding,  higher , up sound
# Sound.Bell,  lower , down sound
input enable_alerts = yes;
alert(enable_alerts and xup, "crossed up" ,alert.BAR, sound.DING);
alert(enable_alerts and xdwn, "crossed down" ,alert.BAR, sound.bell);
# =====================================
#
 
  • Like
Reactions: SMF
for those who might find useful, I added to the default Parabolic SAR the code below, which will:

1-show %distance of the NEW pSAR level to corresponding close as well as pSAR price level at that moment
2-plot a price line of that initial level while pSAR state (long or short) stays the same



#=========================================================================================
#pSAR direction coloring

parSAR.DefineColor("Up", Color.DARK_GREEN);
parSAR.DefineColor("Down", Color.RED);
parSAR.DefineColor("Flat", Color.GRAY);

parSAR.AssignValueColor(if (SAR < low) then parSAR.Color("Up") else parSAR.Color("Down") );

#=========================================================================================
# shows percentage distance of initial psar change to close to serve as reference of the gap
# and price level at that change. also plot a price level for the initial sar of each sar state

input ShowLabel = yes;

def StateChange = if state == state.long and state[1] == state.short then 1 else if state == state.short and state[1] == state.long then -1 else 0;

def sar_level = if statechange <> 0 then sar else sar_level[1];
plot level = if ShowLabel then sar_level else Double.Nan;


AddChartBubble(StateChange == 1 and ShowLabel, sar*1.000, (sar-close)/close*100 +"% $"+level, Color.UPTICK, no);
AddChartBubble(StateChange == -1 and ShowLabel,sar*1.000, (sar-close)/close*100 +"% $"+level,Color.DOWNTICK ,yes);
 
for those who might find useful, I added to the default Parabolic SAR the code below, which will:

1-show %distance of the NEW pSAR level to corresponding close as well as pSAR price level at that moment
2-plot a price line of that initial level while pSAR state (long or short) stays the same



#=========================================================================================
#pSAR direction coloring

parSAR.DefineColor("Up", Color.DARK_GREEN);
parSAR.DefineColor("Down", Color.RED);
parSAR.DefineColor("Flat", Color.GRAY);

parSAR.AssignValueColor(if (SAR < low) then parSAR.Color("Up") else parSAR.Color("Down") );

#=========================================================================================
# shows percentage distance of initial psar change to close to serve as reference of the gap
# and price level at that change. also plot a price level for the initial sar of each sar state

input ShowLabel = yes;

def StateChange = if state == state.long and state[1] == state.short then 1 else if state == state.short and state[1] == state.long then -1 else 0;

def sar_level = if statechange <> 0 then sar else sar_level[1];
plot level = if ShowLabel then sar_level else Double.Nan;


AddChartBubble(StateChange == 1 and ShowLabel, sar*1.000, (sar-close)/close*100 +"% $"+level, Color.UPTICK, no);
AddChartBubble(StateChange == -1 and ShowLabel,sar*1.000, (sar-close)/close*100 +"% $"+level,Color.DOWNTICK ,yes);
in the picture you can see the addition, but I still would like to plot in the same line of the other information (% and $), at the left end of it, the number of periods it remained in the corresponding state for past situations, and also for current.

Is anyone able to give a hint how to add that?

1697680025957.png
 
in the picture you can see the addition, but I still would like to plot in the same line of the other information (% and $), at the left end of it, the number of periods it remained in the corresponding state for past situations, and also for current.

Is anyone able to give a hint how to add that?

View attachment 19947

The count code and bubbles are at the bottom of this script

Screenshot 2023-10-19 085638.png
Code:
#
# TD Ameritrade IP Company, Inc. (c) 2008-2023
#

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;

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));

#=========================================================================================
#pSAR direction coloring

parSAR.DefineColor("Up", Color.DARK_GREEN);
parSAR.DefineColor("Down", Color.RED);
parSAR.DefineColor("Flat", Color.GRAY);

parSAR.AssignValueColor(if (SAR < low) then parSAR.Color("Up") else parSAR.Color("Down") );



#=========================================================================================
# shows percentage distance of initial psar change to close to serve as reference of the gap
# and price level at that change. also plot a price level for the initial sar of each sar state

input ShowLabel = yes;

def StateChange = if state == state.long and state[1] == state.short then 1 else if state == state.short and state[1] == state.long then -1 else 0;

def sar_level = if StateChange <> 0 then SAR else sar_level[1];
plot level = if ShowLabel then sar_level else Double.NaN;


AddChartBubble(StateChange == 1 and ShowLabel, SAR * 1.000, (SAR - close) / close * 100 + "% $" + level, Color.UPTICK, no);
AddChartBubble(StateChange == -1 and ShowLabel, SAR * 1.000, (SAR - close) / close * 100 + "% $" + level, Color.DOWNTICK , yes);

#=========================================================================================
def longcount = if StateChange == 1 then 1 else if state == state.long then longcount[1] + 1 else 0 ;
AddChartBubble(state==state.long and !isnan(close) and isnan(close[-1]) or state == state.long and state[-1] == state.short, level, longcount, Color.UPTICK);
def shortcount = if StateChange == -1 then 1 else if state == state.short then shortcount[1] + 1 else 0 ;
AddChartBubble(state==state.short and !isnan(close) and isnan(close[-1]) or state == state.short and state[-1] == state.long, level, shortcount, Color.DOWNTICK);
 
Last edited:
The count code and bubbles are at the bottom of this script
Excellent. Thanks for the help. 👋 👋

substituted the line to avoid the extension of the line where there are no prices:
"plot level = if ShowLabel and !IsNaN(close) then sar_level else Double.Nan;"

Is there a way to allow also for current state periods count and not only the past ones?

Just for context why I am going after those additions, I look for pSAR as a help for selling credit spreads as compared for using for example Supertrend (ATR based) as, in addition to consider price levels it also considers the time factor, which is relevant to options.
The additional information helps me define in a more precise way the short strike and the initial DTE.
That said, additional considerations are to be checked, but pSAR gives a very good visual context.
 
Last edited:
with the help of google and @MerryDay ( https://usethinkscript.com/threads/only-display-on-current-candle.6343/ ) I got a solution to my question adding some code to @SleepyZ lines, with some slight repositioning of the counting bubbles:

def longcount = if StateChange == 1 then 1 else if state == state.long then longcount[1] + 1 else 0 ;
AddChartBubble(state == state.long and state[-1] == state.short, level, longcount, Color.UPTICK,yes);
def shortcount = if StateChange == -1 then 1 else if state == state.short then shortcount[1] + 1 else 0 ;
AddChartBubble(state == state.short and state[-1] == state.long, level, shortcount, Color.DOWNTICK,no);


AddChartBubble(state == state.long and isnan(close[-1]), level, longcount, Color.UPTICK,yes);
AddChartBubble(state == state.short and isnan(close[-1]), level, shortcount, Color.DOWNTICK,no);


so now I can get the counting of past and present trend state as signaled by pSAR

View attachment 19965
this is my polished version of the addition to pSAR:

#============ PLOT OF INFORMATION REGARDING pSAR AND PRICE RELATION ============================

input ShowLabel = yes;

# PAST STATES pSAR LEVELS AND PERCENTAGE DISTANCE OF CLOSE TO THEM AT STATE CHANGE TIME*******************

def StateChange = if state == state.long and state[1] == state.short then 1 else if state == state.short and state[1] == state.long then -1 else 0;

def sar_level = if statechange <> 0 then sar else sar_level[1];
plot level = if ShowLabel and !IsNaN(close) then sar_level else Double.Nan;


AddChartBubble(StateChange == 1 and ShowLabel, sar*1.000, round(-(level-close)/level*100,2) +"% $"+ round(level,2), Color.UPTICK, no);
AddChartBubble(StateChange == -1 and ShowLabel,sar*1.000, round(-(level-close)/level*100,2) +"% $"+round(level,2),Color.DOWNTICK ,yes);


# COUNT OF PERIODS AT EACH OF PAST STATES ***************************************************************

def longcount = if StateChange == 1 then 1 else if state == state.long then longcount[1] + 1 else 0 ;
AddChartBubble(state == state.long and state[-1] == state.short, level, longcount+" "+round((close - level)/level*100,2)+"%", Color.UPTICK,yes);
def shortcount = if StateChange == -1 then 1 else if state == state.short then shortcount[1] + 1 else 0 ;
AddChartBubble(state == state.short and state[-1] == state.long, level, shortcount+" "+round((close - level)/level*100,2)+"%", Color.DOWNTICK,no);


# COUNT OF PERIODS AT CURRENT STATE ***************************************************************

AddChartBubble(state == state.long and isnan(close[-1]), level, longcount, Color.CYAN,yes);
AddChartBubble(state == state.short and isnan(close[-1]), level, shortcount, Color.YELLOW,no);


# CURRENT pSAR LEVEL AND PERCENTAGE DISTANCE OF CLOSE TO IT ****************************************

AddChartBubble(state == state.long and isnan(close[-1]), parsar, round(-(sar-close)/sar*100,2) +"% $"+round(parsar,2), Color.CYAN,no);
AddChartBubble(state == state.short and isnan(close[-1]), parsar, round(-(sar-close)/sar*100,2) +"% $"+round(parsar,2), Color.YELLOW,yes);


1697992835473.png




1697992905549.png
 
  • Like
Reactions: ALV

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Thread starter Similar threads Forum Replies Date
F Repaints Multi-Time Frame MTF PSAR for ThinkorSwim Indicators 60
T PSAR Transition Indicator for ThinkorSwim Indicators 30

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
359 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top