# Break Price Momentum BPM For ThinkOrSwim

#### This first post contains the most updated code​

BPM is base in my way of trading every day, I never fight again the price movement with specific exceptions that I learned over time. I do combine this BPM with a Double Bollinger Band

I thanks this site for the contribution that it has giving me to put all these ideas together, help from members like SleepyZ, MarryDay, BenTen, barbaros, they help me to visualize, improve and optimize my daily work, thanks big time!

Any improvement idea is more than welcome!

Code:
``````# Break Price Momentum "BPM" by mbarcala and usethinkscript.com on 12/21/21(18)

declare lower;

input length = 20;
input lowlength = 5;
input lookForward = yes;
input reverType = {default "Momentum", "MultiMomentum", "temaMomentum"};

def exitLevelBeg = 1.5;
def calDays = 0.5;
def mLev = 1.1;
def nDev = 2.0;

def AvgExp = ExpAverage(close, length);
def UpSignal = close crosses above AvgExp;
def DnSignal = close crosses below AvgExp;
def SignUpDn = UpSignal or DnSignal;

def slength = 17;
def lowest_k = Lowest(low, slength);
def c1 = close - lowest_k;
def c2 = Highest(high, slength) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;
def FullK = MovAvgExponential(FastK, lowlength);
def FullD = Max(-100, Min(100, (MovAvgExponential(FullK, 1))) - 50) / 50;
def flen = 0.5 * (Log((1 + FullD) / (1 - FullD)) + flen[1]);

plot BPM = flen;
BPM.SetDefaultColor(CreateColor(0, 101, 255));
BPM.SetLineWeight(2);
BPM.HideBubble();
BPM.HideTitle();

plot cLine = 0;
cLine.SetPaintingStrategy(PaintingStrategy.LINE);
cLine.SetDefaultColor(Color.GRAY);
cLine.SetLineWeight(1);
cLine.HideTitle();
cLine.HideTitle();

plot oBl = mLev;
oBl.SetPaintingStrategy(PaintingStrategy.LINE);
oBl.SetDefaultColor(CreateColor(22, 42, 115));
oBl.SetLineWeight(1);
oBl.HideTitle();

plot oSl = -mLev;
oSl.SetPaintingStrategy(PaintingStrategy.LINE);
oSl.SetDefaultColor(CreateColor(22, 42, 115));
oSl.SetLineWeight(1);
oSl.HideTitle();

plot centlev = 0.2;
centlev.SetDefaultColor(Color.BLACK);
centlev.HideBubble();
centlev.HideTitle();
plot centLev2 = -centlev;
centLev2.SetDefaultColor(Color.BLACK);
centLev2.HideBubble();
centLev2.HideTitle();
AddCloud(BPM, centlev, CreateColor(15, 50, 108), CreateColor(27, 27, 27));#GREEN
AddCloud(BPM, -centlev, CreateColor(27, 27, 27), CreateColor(99, 17, 73));#RED

def extValue = if BPM >= exitLevelBeg then RoundDown((BPM - exitLevelBeg) / calDays, 0) + 1 else if BPM <= -exitLevelBeg then RoundDown((-exitLevelBeg - BPM) / calDays, 0) + 1 else 0;

#def ema1 = ExpAverage(close, length);
def ema2 = ExpAverage(AvgExp, length);
def ema3 = ExpAverage(ema2, length);
def TEMA = 3 * AvgExp - 3 * ema2 + ema3;

plot upArrow;
plot dnArrow;
plot trendUp;
plot trendDn;
plot exts;
plot dnSell;
plot temaUp;

switch (reverType) {
case "Momentum":
upArrow = if BPM crosses above cLine then BPM else Double.NaN;
dnArrow = if BPM crosses below cLine then BPM else Double.NaN;
trendUp = if BPM > centlev and BPM crosses above BPM[1] then BPM + -0.1 else Double.NaN;
trendDn = if BPM < -centlev and BPM crosses below BPM[1] then BPM + 0.1 else Double.NaN;
exts = if extValue > 0 and extValue[1] != extValue then BPM else Double.NaN;
dnSell = Double.NaN;
temaUp = Double.NaN;
case "MultiMomentum":
upArrow = if BPM crosses above cLine then BPM else Double.NaN;
dnArrow = if BPM crosses below cLine then BPM else Double.NaN;
trendUp = Double.NaN;
trendDn = Double.NaN;
exts = Double.NaN;
upBuy = if flen crosses above flen[1] then flen[1] else Double.NaN;
dnSell = if flen crosses below flen[1] then flen[1] else Double.NaN;
temaUp = Double.NaN;
case "temaMomentum":
upArrow = Double.NaN;
dnArrow = Double.NaN;
trendUp = Double.NaN;
trendDn = Double.NaN;
exts = Double.NaN;
dnSell = Double.NaN;
temaUp = if TEMA crosses above TEMA[1] then BPM + -0.1 else Double.NaN;
temaDn = if TEMA crosses below TEMA[1] then BPM + 0.1 else Double.NaN;
}

############### BPM Crossing cLine ################
upArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
upArrow.SetDefaultColor(Color.GREEN);
upArrow.SetLineWeight(3);
upArrow.HideBubble();
upArrow.HideTitle();
dnArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
dnArrow.SetDefaultColor(Color.RED);
dnArrow.SetLineWeight(3);
dnArrow.HideBubble();
dnArrow.HideTitle();

############### Price Reversals ################
trendUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
trendUp.SetDefaultColor(Color.WHITE);
trendUp.SetLineWeight(1);
trendUp.HideBubble();
trendUp.HideTitle();
trendDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
trendDn.SetDefaultColor(Color.WHITE);
trendDn.SetLineWeight(1);
trendDn.HideBubble();
trendDn.HideTitle();
############## Possible Exit Levels #################
exts.SetPaintingStrategy(PaintingStrategy.POINTS);
exts.SetDefaultColor(Color.MAGENTA);
exts.SetLineWeight(3);
exts.HideBubble();
exts.HideTitle();

############## Multi Revertion Points #################
dnSell.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
dnSell.SetDefaultColor(Color.MAGENTA);
dnSell.SetLineWeight(1);
dnSell.HideBubble();
dnSell.HideTitle();

############## TEMA Arrows #################
temaUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
temaUp.SetDefaultColor(Color.MAGENTA);
temaUp.SetLineWeight(1);
temaUp.HideBubble();
temaUp.HideTitle();

############## Vertical Lines #################
AddVerticalLine(if lookForward then UpSignal and !SignUpDn[-1] else UpSignal and !UpSignal[1], "Up", Color.DARK_GREEN, Curve.SHORT_DASH);
AddVerticalLine(if lookForward then DnSignal and !SignUpDn[-1] else DnSignal and !UpSignal[1], "Down", Color.DARK_RED, Curve.SHORT_DASH);

########## BB Squeeze ###########
def sDev = StDev(close, length);
def MidLine = MovAvgExponential(close, length);
def LowerBand = MidLine + -nDev * sDev;
def UpperBand = MidLine + nDev * sDev;

def shhigh = 1.0 * MovAvgExponential(TrueRange(high, close, low), length);
def shMid = 1.5 * MovAvgExponential(TrueRange(high, close, low), length);
def shlow = 2.0 * MovAvgExponential(TrueRange(high, close, low), length);
def average =  MovAvgExponential(close, length);

def UpperBandKCLow = average + shlow;
def LowerBandKCLow = average - shlow;
def UpperBandKCMid = average + shMid;
def LowerBandKCMid = average - shMid;
def UpperBandKCHigh = average + shhigh;
def LowerBandKCHigh = average - shhigh;

def preSqueeze = LowerBand > LowerBandKCLow and UpperBand < UpperBandKCLow;
def oriSqueeze = LowerBand > LowerBandKCMid and UpperBand < UpperBandKCMid;
def ExtSqueeze = LowerBand > LowerBandKCHigh and UpperBand < UpperBandKCHigh;

plot squeezeline = if IsNaN(close) then Double.NaN else if ExtSqueeze or oriSqueeze or preSqueeze then cLine else Double.NaN;
squeezeline.AssignValueColor(if ExtSqueeze then CreateColor(155, 83, 21) else if oriSqueeze then CreateColor(122, 22, 46) else if preSqueeze then Color.DARK_GRAY else Color.GREEN);
squeezeline.SetPaintingStrategy(PaintingStrategy.SQUARES);
squeezeline.SetLineWeight(4);
squeezeline.HideTitle();

Last edited by a moderator:
My few cents...I wouldn't use `[-1]` anywhere. This is the value of the next bar that the current plot is going to show, meaning it looks ahead.

My few cents...I wouldn't use `[-1]` anywhere. This is the value of the next bar that the current plot is going to show, meaning it looks ahead.
if you refer to the reversal part, that reversal is base in the signal reversal no about the price reversal

if you refer to the reversal part, that reversal is base in the signal reversal no about the price reversal
Correct, so if you look at the following line,
Code:
``plot trendUp = if mSig[-1] crosses above mSig and mSig > trendL then mSig else Double.NaN;``
it is contructed in a way that the next mSig that doesn't exist will need to cross above current mSig, and current mSig needs to be greater than trendL. The way thinkscript works, potentially, trendUp arrows might show up in the previous candle as it keeps re-evaluating for each tick. If you rely on these arrow for your trades, you just need to know that they might appear and disappear in the previous candle depending on the current candle, aka re-painting.

if you want to move it to non-repainting, you would shift everything over like,
Code:
``plot trendUp = if mSig crosses above mSig[1] and mSig[1] > trendL[1] then mSig else Double.NaN;``
No need to move the plot value.

Also, I am wondering why this line is so complicated?
Code:
``def flen = CompoundValue(1, if IsNaN(0.5 * (Log((1 + FullD) / (1 - FullD)) + flen[1])) then flen[1] else 0.5 * (Log((1 + FullD) / (1 - FullD)) + flen[1]), 0);``

It should be able to work like this too.
Code:
``def flen = 0.5 * (Log((1 + FullD) / (1 - FullD)) + flen[1]);``

You usually want to write the most simple code as possible. It help for maintenance, execution speed, etc.

Correct, so if you look at the following line,
Code:
``plot trendUp = if mSig[-1] crosses above mSig and mSig > trendL then mSig else Double.NaN;``
it is contructed in a way that the next mSig that doesn't exist will need to cross above current mSig, and current mSig needs to be greater than trendL. The way thinkscript works, potentially, trendUp arrows might show up in the previous candle as it keeps re-evaluating for each tick. If you rely on these arrow for your trades, you just need to know that they might appear and disappear in the previous candle depending on the current candle, aka re-painting.

if you want to move it to non-repainting, you would shift everything over like,
Code:
``plot trendUp = if mSig crosses above mSig[1] and mSig[1] > trendL[1] then mSig else Double.NaN;``
No need to move the plot value.
that work the same way, thanks for the help! I already corrected that line

Does the indicator / signals repaint?

that work the same way, thanks for the help! I already corrected that line
Same with this one

Code:
``````def SignUpDt = if UpSignal and SignUpDn[-1] == 0 then UpSignal else Double.NaN;
def SignDnDt = if DnSignal and SignUpDn[-1] == 0 then DnSignal else Double.NaN;``````

To remove the repainting
Code:
``````def SignUpDt = if UpSignal[1] and SignUpDn == 0 then UpSignal else Double.NaN;
def SignDnDt = if DnSignal[1] and SignUpDn == 0 then DnSignal else Double.NaN;``````

Another one...sorry, I have OCD when it comes to code.

Why -0?
Code:
``````def UpperBandKCLow = average[-0] + shlow[-0];
def LowerBandKCLow = average[-0] - shlow[-0];
def UpperBandKCMid = average[-0] + shMid[-0];
def LowerBandKCMid = average[-0] - shMid[-0];
def UpperBandKCHigh = average[-0] + shhigh[-0];
def LowerBandKCHigh = average[-0] - shhigh[-0];``````

Same with this one

Code:
``````def SignUpDt = if UpSignal and SignUpDn[-1] == 0 then UpSignal else Double.NaN;
def SignDnDt = if DnSignal and SignUpDn[-1] == 0 then DnSignal else Double.NaN;``````

To remove the repainting
Code:
``````def SignUpDt = if UpSignal[1] and SignUpDn == 0 then UpSignal else Double.NaN;
def SignDnDt = if DnSignal[1] and SignUpDn == 0 then DnSignal else Double.NaN;``````
not, I can't change this one because this line is base in if the price cross the 20 ema or mid line in the bollinger band and the next day do the same just mark the last day. I include in lower indicator because some time I change my chart and at least I can see it on the bottom indicator too.
if you look in the 2 picture you can see the blue candles but the my lower indicator do not repaint, the one repaint is different that I have only on the top chart

Another one...sorry, I have OCD when it comes to code.

Why -0?
Code:
``````def UpperBandKCLow = average[-0] + shlow[-0];
def LowerBandKCLow = average[-0] - shlow[-0];
def UpperBandKCMid = average[-0] + shMid[-0];
def LowerBandKCMid = average[-0] - shMid[-0];
def UpperBandKCHigh = average[-0] + shhigh[-0];
def LowerBandKCHigh = average[-0] - shhigh[-0];``````
that's ok I do appreciate all help possible. I'm like you about OCD but the big difference is that you know thinkscript and me not. I can read code, I understand a lot but I can't freely write all I want so I take from here and there and put all together plus the help from others from the forum like you right now.

This part here Is from Mobius squeeze middle line that I use to visualize the squeezing moment, I took that part from the code it was already like that

@mbarcala, you did a pretty good job putting this together.
Here is a reworked version that cleans up a few items and removes the repainting code.

Code:
``````# Break Price Momentum, BPM by mbarcala and usethinkscript.com on 12/21/21(9)
# StochasticFull

# 20211229 - barbaros - rework

declare lower;

input length = 17;
input smlength = 6;

def slength = 20;
def mLev = 1.1;
def trendL = 0.3;
def obL1 = 1.8;
def obL2 = 2.3;
def obL3 = 2.8;
def obL4 = 3.3;
def nDev = 2.0;

def AvgExp = ExpAverage(close, slength);
def UpSignal = close crosses above AvgExp;
def DnSignal = close crosses below AvgExp;
def SignUpDn = UpSignal or DnSignal;

def lowest_k = Lowest(low, length);
def c1 = close - lowest_k;
def c2 = Highest(high, length) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

def FullK = MovAvgExponential(FastK, smlength);
def FullD = Max(-100, Min(100, (MovAvgExponential(FullK, 1))) - 50) / 50;
def flen = 0.5 * (Log((1 + FullD) / (1 - FullD)) + flen[1]);

plot mSig = flen;
mSig.SetDefaultColor(Color.MAGENTA);
mSig.SetLineWeight(2);
mSig.HideBubble();
mSig.HideTitle();

AddCloud(mSig,  mLev,  Color.GREEN,  CreateColor(27, 27, 27));
AddCloud(mSig, -mLev, CreateColor(27, 27, 27), Color.RED);

plot cLine = 0;
cLine.SetPaintingStrategy(PaintingStrategy.LINE);
cLine.SetDefaultColor(Color.GRAY);
cLine.SetLineWeight(2);
cLine.HideTitle();

plot oBl = mLev;
oBl.SetPaintingStrategy(PaintingStrategy.LINE);
oBl.SetDefaultColor(CreateColor(0, 155, 255));
oBl.SetLineWeight(1);
oBl.HideTitle();

plot oSl = -mLev;
oSl.SetPaintingStrategy(PaintingStrategy.LINE);
oSl.SetDefaultColor(CreateColor(0, 155, 255));
oSl.SetLineWeight(1);
oSl.HideTitle();

############### Price Crossing Level ################
plot upArrow = if mSig crosses above 0 then mSig else Double.NaN;
upArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
upArrow.SetDefaultColor(Color.GREEN);
upArrow.SetLineWeight(3);
upArrow.HideBubble();
upArrow.HideTitle();

plot dnArrow = if mSig crosses below 0 then mSig else Double.NaN;
dnArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
dnArrow.SetDefaultColor(Color.RED);
dnArrow.SetLineWeight(3);
dnArrow.HideBubble();
dnArrow.HideTitle();

############### Signal Reversal ################
plot trendUp = if mSig crosses above mSig[1] and mSig[1] > trendL[1] then mSig else Double.NaN;
trendUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
trendUp.SetDefaultColor(Color.CYAN);
trendUp.SetLineWeight(1);
trendUp.HideBubble();
trendUp.HideTitle();
#--------------
plot trendDn = if mSig crosses below mSig[1] and mSig[1] < -trendL[1] then mSig else Double.NaN;
trendDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
trendDn.SetDefaultColor(Color.CYAN);
trendDn.SetLineWeight(1);
trendDn.HideBubble();
trendDn.HideTitle();

############## Exit Levels #################
plot exts = if mSig crosses above obL1    or mSig crosses below -obL1
or mSig crosses above obL2 or mSig crosses below -obL2
or mSig crosses above obL3 or mSig crosses below -obL3
or mSig crosses above obL4 or mSig crosses below -obL4 then mSig else Double.NaN;
exts.SetPaintingStrategy(PaintingStrategy.POINTS);
exts.SetDefaultColor(CreateColor(255,255,0));
exts.SetLineWeight(5);
exts.HideBubble();
exts.HideTitle();

############## Vertical Lines #################
AddVerticalLine(UpSignal and !UpSignal[1], "Up", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(DnSignal and !DnSignal[1], "Down", Color.RED, Curve.SHORT_DASH);

########## BB Squeeze ###########
def sDev = StDev(data = close, slength);
def MidLine = MovingAverage(averageType = AverageType.EXPONENTIAL, data = close, slength);
def LowerBand = MidLine + -nDev * sDev;
def UpperBand = MidLine + nDev * sDev;

def shhigh = 1.0 * MovAvgExponential(TrueRange(high, close, low), slength);
def shMid = 1.5 * MovAvgExponential(TrueRange(high, close, low), slength);
def shlow = 2.0 * MovAvgExponential(TrueRange(high, close, low), slength);
def average =  MovAvgExponential(close, slength);

def UpperBandKCLow = average + shlow;
def LowerBandKCLow = average - shlow;
def UpperBandKCMid = average + shMid;
def LowerBandKCMid = average - shMid;
def UpperBandKCHigh = average + shhigh;
def LowerBandKCHigh = average - shhigh;

def preSqueeze = LowerBand > LowerBandKCLow and UpperBand < UpperBandKCLow;
def oriSqueeze = LowerBand > LowerBandKCMid and UpperBand < UpperBandKCMid;
def ExtSqueeze = LowerBand > LowerBandKCHigh and UpperBand < UpperBandKCHigh;

plot squeezeline = if ExtSqueeze or oriSqueeze or preSqueeze then 0 else Double.NaN;
squeezeline.AssignValueColor(if ExtSqueeze then Color.ORANGE else if oriSqueeze then Color.RED else if preSqueeze then Color.BLACK else Color.GREEN);
squeezeline.SetPaintingStrategy(PaintingStrategy.POINTS);
squeezeline.SetLineWeight(4);
squeezeline.HideTitle();``````

Notice the highlighted areas where the reworked script plots the vertical lines vs the original script wouldn't. This is where the original script would be repainting.

Last edited:
@mbarcala, you did a pretty good job putting this together.
Here is a reworked version that cleans up a few items and removes the repainting code.

Code:
``````# Break Price Momentum, BPM by mbarcala and usethinkscript.com on 12/21/21(9)
# StochasticFull

# 20211229 - barbaros - rework

declare lower;

input length = 17;
input smlength = 6;

def slength = 20;
def mLev = 1.1;
def trendL = 0.3;
def obL1 = 1.8;
def obL2 = 2.3;
def obL3 = 2.8;
def obL4 = 3.3;
def nDev = 2.0;

def AvgExp = ExpAverage(close, slength);
def UpSignal = close crosses above AvgExp;
def DnSignal = close crosses below AvgExp;
def SignUpDn = UpSignal or DnSignal;

def lowest_k = Lowest(low, length);
def c1 = close - lowest_k;
def c2 = Highest(high, length) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

def FullK = MovAvgExponential(FastK, smlength);
def FullD = Max(-100, Min(100, (MovAvgExponential(FullK, 1))) - 50) / 50;
def flen = 0.5 * (Log((1 + FullD) / (1 - FullD)) + flen[1]);

plot mSig = flen;
mSig.SetDefaultColor(Color.MAGENTA);
mSig.SetLineWeight(2);
mSig.HideBubble();
mSig.HideTitle();

AddCloud(mSig,  mLev,  Color.GREEN,  CreateColor(27, 27, 27));
AddCloud(mSig, -mLev, CreateColor(27, 27, 27), Color.RED);

plot cLine = 0;
cLine.SetPaintingStrategy(PaintingStrategy.LINE);
cLine.SetDefaultColor(Color.GRAY);
cLine.SetLineWeight(2);
cLine.HideTitle();

plot oBl = mLev;
oBl.SetPaintingStrategy(PaintingStrategy.LINE);
oBl.SetDefaultColor(CreateColor(0, 155, 255));
oBl.SetLineWeight(1);
oBl.HideTitle();

plot oSl = -mLev;
oSl.SetPaintingStrategy(PaintingStrategy.LINE);
oSl.SetDefaultColor(CreateColor(0, 155, 255));
oSl.SetLineWeight(1);
oSl.HideTitle();

############### Price Crossing Level ################
plot upArrow = if mSig crosses above 0 then mSig else Double.NaN;
upArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
upArrow.SetDefaultColor(Color.GREEN);
upArrow.SetLineWeight(3);
upArrow.HideBubble();
upArrow.HideTitle();

plot dnArrow = if mSig crosses below 0 then mSig else Double.NaN;
dnArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
dnArrow.SetDefaultColor(Color.RED);
dnArrow.SetLineWeight(3);
dnArrow.HideBubble();
dnArrow.HideTitle();

############### Signal Reversal ################
plot trendUp = if mSig crosses above mSig[1] and mSig[1] > trendL[1] then mSig else Double.NaN;
trendUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
trendUp.SetDefaultColor(Color.CYAN);
trendUp.SetLineWeight(1);
trendUp.HideBubble();
trendUp.HideTitle();
#--------------
plot trendDn = if mSig crosses below mSig[1] and mSig[1] < -trendL[1] then mSig else Double.NaN;
trendDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
trendDn.SetDefaultColor(Color.CYAN);
trendDn.SetLineWeight(1);
trendDn.HideBubble();
trendDn.HideTitle();

############## Exit Levels #################
plot exts = if mSig crosses above obL1    or mSig crosses below -obL1
or mSig crosses above obL2 or mSig crosses below -obL2
or mSig crosses above obL3 or mSig crosses below -obL3
or mSig crosses above obL4 or mSig crosses below -obL4 then mSig else Double.NaN;
exts.SetPaintingStrategy(PaintingStrategy.POINTS);
exts.SetDefaultColor(CreateColor(255,255,0));
exts.SetLineWeight(5);
exts.HideBubble();
exts.HideTitle();

############## Vertical Lines #################
AddVerticalLine(UpSignal and !UpSignal[1], "Up", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(DnSignal and !DnSignal[1], "Down", Color.RED, Curve.SHORT_DASH);

########## BB Squeeze ###########
def sDev = StDev(data = close, slength);
def MidLine = MovingAverage(averageType = AverageType.EXPONENTIAL, data = close, slength);
def LowerBand = MidLine + -nDev * sDev;
def UpperBand = MidLine + nDev * sDev;

def shhigh = 1.0 * MovAvgExponential(TrueRange(high, close, low), slength);
def shMid = 1.5 * MovAvgExponential(TrueRange(high, close, low), slength);
def shlow = 2.0 * MovAvgExponential(TrueRange(high, close, low), slength);
def average =  MovAvgExponential(close, slength);

def UpperBandKCLow = average + shlow;
def LowerBandKCLow = average - shlow;
def UpperBandKCMid = average + shMid;
def LowerBandKCMid = average - shMid;
def UpperBandKCHigh = average + shhigh;
def LowerBandKCHigh = average - shhigh;

def preSqueeze = LowerBand > LowerBandKCLow and UpperBand < UpperBandKCLow;
def oriSqueeze = LowerBand > LowerBandKCMid and UpperBand < UpperBandKCMid;
def ExtSqueeze = LowerBand > LowerBandKCHigh and UpperBand < UpperBandKCHigh;

plot squeezeline = if ExtSqueeze or oriSqueeze or preSqueeze then 0 else Double.NaN;
squeezeline.AssignValueColor(if ExtSqueeze then Color.ORANGE else if oriSqueeze then Color.RED else if preSqueeze then Color.BLACK else Color.GREEN);
squeezeline.SetPaintingStrategy(PaintingStrategy.POINTS);
squeezeline.SetLineWeight(4);
squeezeline.HideTitle();``````

Notice the highlighted areas where the reworked script plots the vertical lines vs the original script wouldn't. This is where the original script would be repainting.

not, I can't change the one repainting because that line of repainting is base in if the price cross the 20 ema or mid line in the bollinger band and the next day do the same and just mark the last day. I include in lower indicator because some time I change my chart and at least I can see it on the bottom indicator too.

look the idea of the top indicator here

Code:
``````def length = 20;
def displace = 0;
def price = close;

plot AvgExp = ExpAverage(price[-displace], length);
AvgExp.HideTitle();
AvgExp.HideBubble();

def UpSignal = if close[1] crosses below AvgExp and close crosses above AvgExp or close crosses above AvgExp then 1 else 0;
def DnSignal = if close[1] crosses above AvgExp and close crosses below AvgExp or close crosses below AvgExp then 1 else 0;

AssignPriceColor(if UpSignal or DnSignal then CreateColor(0,130,211) else Color.CURRENT);

def prange = high - low;
def phigh = high + prange * .2;
def plow = low - prange * .2;

def SignUpDn = if UpSignal or DnSignal then 1 else if SignUpDn[1] == 1 and UpSignal or DnSignal then 1 else 0;

def debug = yes;
plot x = if !debug then Double.NAN else SignUpDn;
x.Hide();

## Yellow Point Signal ##
plot SignUpDn = if UpSignal and signUpDn[-1] == 0 then plow else
if DnSignal and signUpDn[-1] == 0 then phigh else Double.NaN;
SignUpDn.SetDefaultColor(Color.YELLOW);
SignUpDn.SetStyle(Curve.POINTS);
SignUpDn.SetLineWeight(3);``````

not, I can't change the one repainting because that line of repainting is base in if the price cross the 20 ema or mid line in the bollinger band and the next day do the same and just mark the last day. I include in lower indicator because some time I change my chart and at least I can see it on the bottom indicator too.

look the idea of the top indicator here

Code:
``````def length = 20;
def displace = 0;
def price = close;

plot AvgExp = ExpAverage(price[-displace], length);
AvgExp.HideTitle();
AvgExp.HideBubble();

def UpSignal = if close[1] crosses below AvgExp and close crosses above AvgExp or close crosses above AvgExp then 1 else 0;
def DnSignal = if close[1] crosses above AvgExp and close crosses below AvgExp or close crosses below AvgExp then 1 else 0;

AssignPriceColor(if UpSignal or DnSignal then CreateColor(0,130,211) else Color.CURRENT);

def prange = high - low;
def phigh = high + prange * .2;
def plow = low - prange * .2;

def SignUpDn = if UpSignal or DnSignal then 1 else if SignUpDn[1] == 1 and UpSignal or DnSignal then 1 else 0;

def debug = yes;
plot x = if !debug then Double.NAN else SignUpDn;
x.Hide();

## Yellow Point Signal ##
plot SignUpDn = if UpSignal and signUpDn[-1] == 0 then plow else
if DnSignal and signUpDn[-1] == 0 then phigh else Double.NaN;
SignUpDn.SetDefaultColor(Color.YELLOW);
SignUpDn.SetStyle(Curve.POINTS);
SignUpDn.SetLineWeight(3);``````
I disagree but it’s ok.

I disagree but it’s ok.
I end with this and the signal go exactly

Code:
``````AddVerticalLine(UpSignal and SignUpDn[-1] == 0, "Up", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(DnSignal and SignUpDn[-1] == 0, "Down", Color.RED, Curve.SHORT_DASH);``````

I disagree but it’s ok.
the part that really would like to see is I can get it more dynamically is this one here, in this part the signal after cross obL1 it suppose to show again another signal every 0.5 that the signal go up or down. what I'm trying to ask if the a way to create a calculation that I can set that part automatically every time signal increase more? I have it now more like manually

I end with this and the signal go exactly

Code:
``````AddVerticalLine(UpSignal and SignUpDn[-1] == 0, "Up", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(DnSignal and SignUpDn[-1] == 0, "Down", Color.RED, Curve.SHORT_DASH);``````
Bottom line is, you don't want to have `[-1]` anywhere in your code. When you look ahead in your code, signals shown in bars that have closed already will repaint. Repainting indicators are highly undesirable. Look at the screenshot I posted. All your vertical lines match to what my revision has, but my revision also shows you the vertical lines that would have shown if you were live watching it and then disappeared...or all of a sudden a signal shows up 1 bar ago where you miss the signal. It's up to you. I am just trying to help.

Bottom line is, you don't want to have `[-1]` anywhere in your code. When you look ahead in your code, signals shown in bars that have closed already will repaint. Repainting indicators are highly undesirable. Look at the screenshot I posted. All your vertical lines match to what my revision has, but my revision also shows you the vertical lines that would have shown if you were live watching it and then disappeared...or all of a sudden a signal shows up 1 bar ago where you miss the signal. It's up to you. I am just trying to help.
don't get wrong I know you trying to help and appreciate a lot believe me! what do you think about this line here, can be possible to create this more dynamic, the signal every time increase 0.5 show another signal, right now looks to manual?

Code:
``````plot ext1 = if mSig crosses above obL1 or mSig crosses below -obL1 then mSig else
if mSig crosses above obL2 or mSig crosses below -obL2 then mSig else
if mSig crosses above obL3 or mSig crosses below -obL3 then mSig else
if mSig crosses above obL4 or mSig crosses below -obL4 then mSig else Double.NaN;``````

don't get wrong I know you trying to help and appreciate a lot believe me! what do you think about this line here, can be possible to create this more dynamic, the signal every time increase 0.5 show another signal, right now looks to manual?

Code:
``````plot ext1 = if mSig crosses above obL1 or mSig crosses below -obL1 then mSig else
if mSig crosses above obL2 or mSig crosses below -obL2 then mSig else
if mSig crosses above obL3 or mSig crosses below -obL3 then mSig else
if mSig crosses above obL4 or mSig crosses below -obL4 then mSig else Double.NaN;``````
Yes, I believe that can be done. I’ll post the script tomorrow.

87k+ Posts
361 Online

## The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

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?