# RSI Prediction!

#### Butler

##### Member
Does anyone know of a thinkscript that will show you what the price would have to be in order for the RSI to be less than 30 on the current candle? Example... The RSI is currently 42 but i dont want to place an order until the RSI is 30 on the same candle. If I am trading a 4 hour candle I dont really want to wait an entire 4 hours watching until it maybe hits my area of interest for a starter position. Using a standard 14 period RSI. I would like to set my orders ahead of time. I dont really want to have to sit there and physically watch until it gets there. In theory i would like to place several orders on different stocks while i am doing other things then i can check on them every now and then and revise the orders with the new predictive RSI values. I think this would help a lot of people on this forum if someone is feeling up to the challenge. Thank you

Last edited:
Does anyone know of a thinkscript that will show you what the price would have to be in order for the RSI to be less than 30 on the current candle? Example... The RSI is currently 42 but i dont want to place an order until the RSI is 30 on the same candle. If I am trading a 4 hour candle I dont really want to wait an entire 4 hours watching until it maybe hits my area of interest for a starter position. Using a standard 14 period RSI. I would like to set my orders ahead of time. I dont really want to have to sit there and physically watch until it gets there. In theory i would like to place several orders on different stocks while i am doing other things then i can check on them every now and then and revise the orders with the new predictive RSI values. I think this would help a lot of people on this forum if someone is feeling up to the challenge. Thank you

this version requires the user to change an input number , on the edit studies window.

input a % price factor number,
on the last bar,
calculate a price that will produce the desired RSI number.

draw labels of values
on the last bar,
..draw a new line for the desired RSI
..draw a bubble with values

Code:
``````# rsi_predict_price_00c2

# calc a price, that will produce the desired RSI number.
# input a % factor number, to change the price.

input price_factor_percent = 99.0;
input desired_rsi_low_level = 30;
input show_labels = yes;
input values_bubble = yes;

# ---------------------------------------
# RSI
# TD Ameritrade IP Company, Inc. (c) 2007-2021
declare lower;
input length = 14;
input over_Bought = 70;
input over_Sold = 30;
input price = close;
input averageType = AverageType.WILDERS;
#input showBreakoutSignals = no;

def NetChgAvg = MovingAverage(averageType, price - price[1], length);
def TotChgAvg = MovingAverage(averageType, AbsValue(price - price[1]), length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;

plot RSI = 50 * (ChgRatio + 1);
#plot OverSold = over_Sold;
#plot OverBought = over_Bought;
#plot UpSignal = if RSI crosses above OverSold then OverSold else Double.NaN;
#plot DownSignal = if RSI crosses below OverBought then OverBought else Double.NaN;

#UpSignal.SetHiding(!showBreakoutSignals);
#DownSignal.SetHiding(!showBreakoutSignals);

RSI.DefineColor("OverBought", GetColor(5));
RSI.DefineColor("Normal", GetColor(7));
RSI.DefineColor("OverSold", GetColor(1));
RSI.AssignValueColor(if RSI > over_Bought then RSI.color("OverBought") else if RSI < over_Sold then RSI.color("OverSold") else RSI.color("Normal"));
#OverSold.SetDefaultColor(GetColor(8));
#OverBought.SetDefaultColor(GetColor(8));
#UpSignal.SetDefaultColor(Color.UPTICK);
#UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
#DownSignal.SetDefaultColor(Color.DOWNTICK);
#DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);

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

def na = double.nan;
def bn = barnumber();
def lastbarbn = highestall( if( !isnan(close), bn, 0));
def lastbar = if lastbarbn == bn then 1 else 0;

# on last bar,  calc price for desired rsi #
def NetChgAvg2;
def TotChgAvg2;
def ChgRatio2;
def rsi2;
def i;
if bn == lastbarbn then {
i = price_factor_percent;
#i = 98.0;

NetChgAvg2 = MovingAverage(averageType, (price * (i/100)) - price[1], length);
TotChgAvg2 = MovingAverage(averageType, AbsValue((price * (i/100)) - price[1]), length);
ChgRatio2 = if TotChgAvg2 != 0 then NetChgAvg2 / TotChgAvg2 else 0;
RSI2 = 50 * (ChgRatio2 + 1);

} else {
# don't change this i variable, leave at 100
i = 100.0;
NetChgAvg2 = MovingAverage(averageType, (price * (i/100)) - price[1], length);
TotChgAvg2 = MovingAverage(averageType, AbsValue((price * (i/100)) - price[1]), length);
ChgRatio2 = if TotChgAvg2 != 0 then NetChgAvg2 / TotChgAvg2 else 0;
RSI2 = 50 * (ChgRatio2 + 1);
}

input test1_bubbles = yes;
addchartbubble(test1_bubbles and !isnan(close), 30, rsi2 + "\n\$" + (price * (i/100)) + "\n" + i + "%" , color.yellow, yes);

# show_labels
addlabel(show_labels, "input a % to change the RSI number.  i , " + i + "%" , color.green);
addlabel(show_labels, "desired rsi: " + desired_rsi_low_level , color.cyan);
addlabel(show_labels, "adjusted rsi level " +  round(rsi2, 1), color.yellow);
addlabel(show_labels, "price  \$" + round(price * (i/100),2) , color.yellow);

plot z1 = 0;
z1.SetDefaultColor(Color.gray);
plot z2 = 100;
z2.SetDefaultColor(Color.gray);

# plot a line from prev rsi to alt rsi #

#def last2 = (lastbarbn - bn) >=2  ?

def last = ( !isnan(close[0]) and isnan(close[-1]) );
def prev = ( !isnan(close[-1]) and isnan(close[-2]) );

#def newrsiline = ( last or last[1] );
plot w = if (last or prev) then rsi2 else na;
w.SetDefaultColor(Color.cyan);

addchartbubble(values_bubble and last, rsi2*0.94, round(rsi2,1) + "  / \$" + round(price * (i/100),2) + "  / i  " + i + "%" , color.yellow, no);
#``````

hal_predrsi
-------------

i have started on the next version, using a fold loop, to automatically calculate the required price, for the desired RSI number.
but, so far, it doesn't work.
rsi2 is supposed to equal the count of k's that are < desired RSI #. (similar to i in the first ver.)
------------
this goes in 1st half of if-then ( if bn == lastbarbn then { )
rsi2 = fold k = 1 to 100
with p
do p + (if (50 * ( (( MovingAverage(averageType, ((price * (k/100)) - price[1]), length))/( MovingAverage(averageType, AbsValue( (price * (k/100)) - price[1]), length))) + 1)) < desired_rsi_low_level then 1 else 0);

Last edited:
any luck with the next version?

any luck with the next version?
sorry, i have not. maybe in a week or two i will get back to it.

sorry, i have not. maybe in a week or two i will get back to it.
halcyonguy,

would you code a thinkscript that predicts moving average intersection? for example: ma(9) decreases and crosses below ma(20) but then begins increasing back up toward ma(20). the requested script would alert/identify that ma(9) had stopped decreasing, started increasing, and predicts/projects based on upward movement of potential crossover with ma(20).

one of the most challenging aspects is trying to identify a stock before move up/ and or the bottom. it is very easy to see AFTER the move up/gain that the ma(9) was increasing and crossed over ma(20). the intention of the prediction and/or projection script is to identify that ma(9) has stopped decreasing, turned up, and if it continues increasing it will crossover the ma(20).

great job coding the RSI prediction. this could definitely be applied to other indicators but i do not possess the necessary coding / math skills to make it happen. appreciate any and all assistance regarding moving average crossover prediction.

best regards,

halcyonguy,

would you code a thinkscript that predicts moving average intersection? for example: ma(9) decreases and crosses below ma(20) but then begins increasing back up toward ma(20). the requested script would alert/identify that ma(9) had stopped decreasing, started increasing, and predicts/projects based on upward movement of potential crossover with ma(20).

one of the most challenging aspects is trying to identify a stock before move up/ and or the bottom. it is very easy to see AFTER the move up/gain that the ma(9) was increasing and crossed over ma(20). the intention of the prediction and/or projection script is to identify that ma(9) has stopped decreasing, turned up, and if it continues increasing it will crossover the ma(20).

great job coding the RSI prediction. this could definitely be applied to other indicators but i do not possess the necessary coding / math skills to make it happen. appreciate any and all assistance regarding moving average crossover prediction.

best regards,

this predicts where 2 signals would theoretically cross in the future, not where the price will go to.

find if 2 lines will cross in the future, if they were extended.
. use the difference between the close of 2 bars, to calculate the slope.
. can use an offset to look at a bar farther back, not just previous bar.
. extend dotted lines from the end of 2 signal lines.
. labels display several stats, and the price of crossing, and how many bars out.

Ruby:
``````# predict_crossing_00d

# find if 2 lines will cross in the future, if they were extended.
# halcyonguy  12/2021

def na = double.nan;
def bn = barnumber();

def lastbar = !isnan(close[0]) and isnan(close[-1]);
def lastbarbn = if bn == 1 then na else if lastbar then bn else lastbarbn[1];
# ------------------------------------------------------
# 2 averages for testing

input avg1_len = 9;
input avg1_type =  AverageType.simple;
def ma1 = MovingAverage(avg1_type, close, avg1_len);

input avg2_len = 20;
input avg2_type =  AverageType.simple;
def ma2 = MovingAverage(avg2_type, close, avg2_len);

plot z1 = ma1;
z1.setdefaultcolor(color.cyan);
plot z2 = ma2;
z2.setdefaultcolor(color.yellow);

addlabel(1, "avg1 len " + avg1_len, color.yellow);
addlabel(1, "avg2 len " + avg2_len, color.yellow);
# ------------------------------------------------------
#  set 2 formulas to sig1 and sig2
def sig1 = ma1;
def sig2 = ma2;

# calc close chg from a bar,  x bars back
input  barsback_for_offest_for_slope = 1;
def bb = barsback_for_offest_for_slope;
def s1chg = if !isnan(close) then (sig1[0] - sig1[bb])/bb else s1chg[1];
def s2chg = if !isnan(close) then (sig2[0] - sig2[bb])/bb else s2chg[1];

#check if 2 signals are moving towards each other , consolidating
def consol1 = if (sig1 > sig2 and s1chg < s2chg) then 1 else 0;
def consol2 = if (sig1 < sig2 and s1chg > s2chg) then 1 else 0;
def consol = (consol1 or consol2);
def notconsol = (!consol1 or !consol2);

def consolcnt = if ( !consol[1] and consol) then 1 else (consolcnt[1] + 1);
def wideningcnt = if ( consol[1] and !consol) then 1 else (wideningcnt[1] + 1);

addlabel(1, "bars back for offest for slope " + bb, color.lime);

addlabel(consol, "consolidating for " + consolcnt + " bars", color.yellow);
addlabel(!consol, "widening for " + wideningcnt + " bars", color.magenta);

# ------------------------------------
# bars till a crossing
def bars_x = round( (sig2 - sig1) / (s1chg - s2chg), 0);

# future price levels
def f1 = round((sig1 + ( bars_x * s1chg)), 2);
def f2 = round((sig2 + ( bars_x * s2chg)), 2);

addlabel(1, "#1 chg: " + s1chg, color.yellow);
addlabel(1, "#2 chg: " + s2chg, color.yellow);

addlabel(consol, "#1 cross \$: " + f1, color.cyan);
addlabel(consol, "#2 cross \$: " + f2, color.cyan);
#--------------------

def cross_price = if (!isnan(close[-1]) or notconsol) then na
else if lastbar then (sig1 + ( bars_x * s1chg))
else cross_price[1];

plot z4 = cross_price;
z4.SetStyle(Curve.MEDIUM_DASH);
z4.SetDefaultColor(Color.cyan);
z4.setlineweight(1);
z4.hidebubble();

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

#if last bar then  bn of crossing
def bnx = if lastbar then (bars_x + bn) else bnx[1];

addlabel(consol, "last# " + lastbarbn + " cross # " + bnx , color.pink);

# extended lines , after lastbar
def extline_offset = 1;
def ex1 = if bn == 1 then na else
if lastbar[extline_offset] then sig1[extline_offset] + s1chg[extline_offset]
else (ex1[1] + s1chg);

plot ext1 = ex1;
ext1.SetStyle(Curve.MEDIUM_DASH);
ext1.setdefaultcolor(color.white);
#ext1.setlineweight(1);
ext1.hidebubble();

# start on lastbar
#def ex2 = if bn == 1 then na else
#   if lastbar then sig2
#   else (ex2[1] + s2chg);

# start on a bar after lastbar, so there is a gap between lines
def ex2 = if bn == 1 then na else
if lastbar[extline_offset] then sig2[extline_offset] + s2chg[extline_offset]
else (ex2[1] + s2chg);

plot ext2 = ex2;
ext2.SetStyle(Curve.MEDIUM_DASH);
ext2.setdefaultcolor(color.white);
#ext2.setlineweight(1);
ext2.hidebubble();

# draw vert line at time of lines crossing
addverticalline(bn == bnx , "signal cross", color.yellow);

def bars_xb = round(bars_x,0);
AddLabel(consol, "signals 1 & 2 will cross in " + bars_xb + " bars", Color.YELLOW);
AddLabel(!consol, "signals 1 & 2 will not cross", Color.magenta);

#--------------------------------
# test data
input test1 = no;
addchartbubble( test1, low *0.992, "C " + consolcnt + "\nW " + wideningcnt, color.cyan, no);
input test2 = no;
addchartbubble(test2, cross_price, bn + "\n" + ex1 + "\n" + ex1[1] + "\n" + s1chg , color.cyan, no);
input test3 = no;
addchartbubble(test3, cross_price, bn + "\n" + ex1 + "\n" + ex1[1] + "\n" + s1chg , color.cyan, no);
input test4 = no;
addchartbubble(test4, cross_price, bn + "\n" + bnx + "\n" + 0 , color.cyan, no);

# ==================================

# https://tlc.thinkorswim.com/center/reference/thinkScript/Constants/AverageType
#  EXPONENTIAL
#  HULL
#  SIMPLE
#  WEIGHTED
#  WILDERS

# ==============================
# derive a formula
# ----------------
# this is the result formula from below
#   signal diff is on top and bar to bar changes are on bottom.
#     bars_x = (sig2 - sig1) / (s1chg - s2chg)
# ----------------
#  if sig1 > sig2 then,
#  look for when sig1 < sig2q
#
# (sig1 + ( bars_x * s1chg)) <= (sig2 + ( bars_x * s2chg))
#
# rename vars and simplify
# a=sig1
# b=sig2
# a2=s1chg
# b2=s2chg
# x=bars_x

# (a + ( x * a2)) <= (b + ( x * b2))
# a2*x + a <= b2*x + b
# a2*x - b2*x <= b - a
# (a2 - b2) / x <= b - a
# (a2 - b2)  <= (b - a ) * x
# (a2 - b2) / (b - a ) <= x

# replace var names
# invert formula, so signal diff is on top and bar to bar changes are on bottom.
#def bars_x = round( (sig2 - sig1) / (s1chg - s2chg), 1);
#=============================
#``````

some examples using lengths of 55 and 123

TJX

BABA

hal_cross

Last edited:
halcyonguy,

awesome, thank you.....i liked your post and wanted to say thank you for your work.

regards,

@halcyonguy Were you ever able to create a working version of this RSI Prediction indicator? I've been intraday trading extensions on 1min, 5min, and 15min charts using mainly support/resistance, volume, and time. I would love love love to try using this RSI prediction tool in tandem to help determine possible points of exhaustion and reversal. Thanks in advance!!

@halcyonguy Were you ever able to create a working version of this RSI Prediction indicator? I've been intraday trading extensions on 1min, 5min, and 15min charts using mainly support/resistance, volume, and time. I would love love love to try using this RSI prediction tool in tandem to help determine possible points of exhaustion and reversal. Thanks in advance!!

no , i haven't . i'll put it on my list for winter projects.

no , i haven't . i'll put it on my list for winter projects.
Thank you!! Looking forward to it!

TOS has a indicator already onboard that does this... "ReverseEnginerringRSI"

TOS has a indicator already onboard that does this... "ReverseEnginerringRSI"
Thanks, @TDTOS! I didn't know that existed. I actually started playing around with it and came up with a top and bottom range. I'm still testing it, but it is basically what I wanted. @halcyonguy Not sure if this would be useful to you if you were still interested in playing around with this.

Code:
``````# ReverseEngineeredRSI
# TD Ameritrade IP Company, Inc. (c) 2007-2022

input length = 14;
input price = close;
input rsiValueOverbought = 85.0;
input rsiValueOversold = 15.0;
input smoothingType = {default Wilders, EMA};

########Cloud Top and Bottom
def rsiValueOverboughtTop = 95.0;
def rsiValueOversoldBottom = 5.0;

########Overbought Main Def
def coeffOverboughtTop = rsiValueOverboughtTop / (100 - rsiValueOverboughtTop);
def coeffOverbought = rsiValueOverbought / (100 - rsiValueOverbought);
def coeffOversold = rsiValueOversold / (100 - rsiValueOversold);
def coeffOversoldBottom = rsiValueOversoldBottom / (100 - rsiValueOversoldBottom);
def chg = price - price[1];

########Overbought Top Cloud Def
def diffOverboughtTop;
switch (smoothingType) {
case Wilders:
diffOverboughtTop =  (length - 1) * (WildersAverage(Max(-chg, 0), length) * coeffOverboughtTop - WildersAverage(Max(chg, 0), length));
case EMA:
diffOverboughtTop =  (length - 1) * (ExpAverage(Max(-chg, 0), length) * coeffOverboughtTop - ExpAverage(Max(chg, 0), length)) / 2;}

def valueOverboughtTop = price + if diffOverboughtTop >= 0 then diffOverboughtTop else diffOverboughtTop / coeffOverboughtTop;
plot RevEngRSIOverboughtTop = CompoundValue(1, valueOverboughtTop[1], Double.NaN);

RevEngRSIOverboughtTop.SetDefaultColor(GetColor(9));

########Overbought Case and plot
def diffOverbought;
switch (smoothingType) {
case Wilders:
diffOverbought =  (length - 1) * (WildersAverage(Max(-chg, 0), length) * coeffOverbought - WildersAverage(Max(chg, 0), length));
case EMA:
diffOverbought =  (length - 1) * (ExpAverage(Max(-chg, 0), length) * coeffOverbought - ExpAverage(Max(chg, 0), length)) / 2;}

def valueOverbought = price + if diffOverbought >= 0 then diffOverbought else diffOverbought / coeffOverbought;
plot RevEngRSIOverbought = CompoundValue(1, valueOverbought[1], Double.NaN);

RevEngRSIOverbought.SetDefaultColor(GetColor(9));

########Oversold Case and plot
def diffOversold;
switch (smoothingType) {
case Wilders:
diffOversold =  (length - 1) * (WildersAverage(Max(-chg, 0), length) * coeffOversold - WildersAverage(Max(chg, 0), length));
case EMA:
diffOversold =  (length - 1) * (ExpAverage(Max(-chg, 0), length) * coeffOversold - ExpAverage(Max(chg, 0), length)) / 2;}

def valueOversold = price + if diffOversold >= 0 then diffOversold else diffOversold / coeffOversold;
plot RevEngRSIOversold = CompoundValue(1, valueOversold[1], Double.NaN);

RevEngRSIOversold.SetDefaultColor(GetColor(9));

########Oversold Bottom Cloud Def
def diffOversoldBottom;
switch (smoothingType) {
case Wilders:
diffOversoldBottom =  (length - 1) * (WildersAverage(Max(-chg, 0), length) * coeffOversoldBottom - WildersAverage(Max(chg, 0), length));
case EMA:
diffOversoldBottom =  (length - 1) * (ExpAverage(Max(-chg, 0), length) * coeffOversoldBottom - ExpAverage(Max(chg, 0), length)) / 2;}

def valueOversoldBottom = price + if diffOversoldBottom >= 0 then diffOversoldBottom else diffOversoldBottom / coeffOversoldBottom;
plot RevEngRSIOversoldBottom = CompoundValue(1, valueOversoldBottom[1], Double.NaN);

RevEngRSIOversoldBottom.SetDefaultColor(GetColor(9));

########Labels
AddLabel(yes, if price >= RevEngRSIOverbought then "Overbought!" else "Overbought at "  + RevEngRSIOverbought , Color.cyan);
AddLabel(yes, if price <= RevEngRSIOversold then "Oversold!" else "Oversold at "  + RevEngRSIOversold , Color.cyan);

########Cloud Attempt
AddCloud( RevEngRSIOverboughtTop, RevEngRSIOverbought, Color.WHITE, Color.WHITE);
AddCloud( RevEngRSIOversold, RevEngRSIOversoldBottom, Color.WHITE, Color.WHITE);``````

Last edited:
this predicts where 2 signals would theoretically cross in the future, not where the price will go to.

find if 2 lines will cross in the future, if they were extended.
. use the difference between the close of 2 bars, to calculate the slope.
. can use an offset to look at a bar farther back, not just previous bar.
. extend dotted lines from the end of 2 signal lines.
. labels display several stats, and the price of crossing, and how many bars out.

Ruby:
``````# predict_crossing_00d

# find if 2 lines will cross in the future, if they were extended.
# halcyonguy  12/2021

def na = double.nan;
def bn = barnumber();

def lastbar = !isnan(close[0]) and isnan(close[-1]);
def lastbarbn = if bn == 1 then na else if lastbar then bn else lastbarbn[1];
# ------------------------------------------------------
# 2 averages for testing

input avg1_len = 9;
input avg1_type =  AverageType.simple;
def ma1 = MovingAverage(avg1_type, close, avg1_len);

input avg2_len = 20;
input avg2_type =  AverageType.simple;
def ma2 = MovingAverage(avg2_type, close, avg2_len);

plot z1 = ma1;
z1.setdefaultcolor(color.cyan);
plot z2 = ma2;
z2.setdefaultcolor(color.yellow);

addlabel(1, "avg1 len " + avg1_len, color.yellow);
addlabel(1, "avg2 len " + avg2_len, color.yellow);
# ------------------------------------------------------
#  set 2 formulas to sig1 and sig2
def sig1 = ma1;
def sig2 = ma2;

# calc close chg from a bar,  x bars back
input  barsback_for_offest_for_slope = 1;
def bb = barsback_for_offest_for_slope;
def s1chg = if !isnan(close) then (sig1[0] - sig1[bb])/bb else s1chg[1];
def s2chg = if !isnan(close) then (sig2[0] - sig2[bb])/bb else s2chg[1];

#check if 2 signals are moving towards each other , consolidating
def consol1 = if (sig1 > sig2 and s1chg < s2chg) then 1 else 0;
def consol2 = if (sig1 < sig2 and s1chg > s2chg) then 1 else 0;
def consol = (consol1 or consol2);
def notconsol = (!consol1 or !consol2);

def consolcnt = if ( !consol[1] and consol) then 1 else (consolcnt[1] + 1);
def wideningcnt = if ( consol[1] and !consol) then 1 else (wideningcnt[1] + 1);

addlabel(1, "bars back for offest for slope " + bb, color.lime);

addlabel(consol, "consolidating for " + consolcnt + " bars", color.yellow);
addlabel(!consol, "widening for " + wideningcnt + " bars", color.magenta);

# ------------------------------------
# bars till a crossing
def bars_x = round( (sig2 - sig1) / (s1chg - s2chg), 0);

# future price levels
def f1 = round((sig1 + ( bars_x * s1chg)), 2);
def f2 = round((sig2 + ( bars_x * s2chg)), 2);

addlabel(1, "#1 chg: " + s1chg, color.yellow);
addlabel(1, "#2 chg: " + s2chg, color.yellow);

addlabel(consol, "#1 cross \$: " + f1, color.cyan);
addlabel(consol, "#2 cross \$: " + f2, color.cyan);
#--------------------

def cross_price = if (!isnan(close[-1]) or notconsol) then na
else if lastbar then (sig1 + ( bars_x * s1chg))
else cross_price[1];

plot z4 = cross_price;
z4.SetStyle(Curve.MEDIUM_DASH);
z4.SetDefaultColor(Color.cyan);
z4.setlineweight(1);
z4.hidebubble();

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

#if last bar then  bn of crossing
def bnx = if lastbar then (bars_x + bn) else bnx[1];

addlabel(consol, "last# " + lastbarbn + " cross # " + bnx , color.pink);

# extended lines , after lastbar
def extline_offset = 1;
def ex1 = if bn == 1 then na else
if lastbar[extline_offset] then sig1[extline_offset] + s1chg[extline_offset]
else (ex1[1] + s1chg);

plot ext1 = ex1;
ext1.SetStyle(Curve.MEDIUM_DASH);
ext1.setdefaultcolor(color.white);
#ext1.setlineweight(1);
ext1.hidebubble();

# start on lastbar
#def ex2 = if bn == 1 then na else
#   if lastbar then sig2
#   else (ex2[1] + s2chg);

# start on a bar after lastbar, so there is a gap between lines
def ex2 = if bn == 1 then na else
if lastbar[extline_offset] then sig2[extline_offset] + s2chg[extline_offset]
else (ex2[1] + s2chg);

plot ext2 = ex2;
ext2.SetStyle(Curve.MEDIUM_DASH);
ext2.setdefaultcolor(color.white);
#ext2.setlineweight(1);
ext2.hidebubble();

# draw vert line at time of lines crossing
addverticalline(bn == bnx , "signal cross", color.yellow);

def bars_xb = round(bars_x,0);
AddLabel(consol, "signals 1 & 2 will cross in " + bars_xb + " bars", Color.YELLOW);
AddLabel(!consol, "signals 1 & 2 will not cross", Color.magenta);

#--------------------------------
# test data
input test1 = no;
addchartbubble( test1, low *0.992, "C " + consolcnt + "\nW " + wideningcnt, color.cyan, no);
input test2 = no;
addchartbubble(test2, cross_price, bn + "\n" + ex1 + "\n" + ex1[1] + "\n" + s1chg , color.cyan, no);
input test3 = no;
addchartbubble(test3, cross_price, bn + "\n" + ex1 + "\n" + ex1[1] + "\n" + s1chg , color.cyan, no);
input test4 = no;
addchartbubble(test4, cross_price, bn + "\n" + bnx + "\n" + 0 , color.cyan, no);

# ==================================

# https://tlc.thinkorswim.com/center/reference/thinkScript/Constants/AverageType
#  EXPONENTIAL
#  HULL
#  SIMPLE
#  WEIGHTED
#  WILDERS

# ==============================
# derive a formula
# ----------------
# this is the result formula from below
#   signal diff is on top and bar to bar changes are on bottom.
#     bars_x = (sig2 - sig1) / (s1chg - s2chg)
# ----------------
#  if sig1 > sig2 then,
#  look for when sig1 < sig2q
#
# (sig1 + ( bars_x * s1chg)) <= (sig2 + ( bars_x * s2chg))
#
# rename vars and simplify
# a=sig1
# b=sig2
# a2=s1chg
# b2=s2chg
# x=bars_x

# (a + ( x * a2)) <= (b + ( x * b2))
# a2*x + a <= b2*x + b
# a2*x - b2*x <= b - a
# (a2 - b2) / x <= b - a
# (a2 - b2)  <= (b - a ) * x
# (a2 - b2) / (b - a ) <= x

# replace var names
# invert formula, so signal diff is on top and bar to bar changes are on bottom.
#def bars_x = round( (sig2 - sig1) / (s1chg - s2chg), 1);
#=============================
#``````

some examples using lengths of 55 and 123

TJX
View attachment 12699

BABA
View attachment 12700
hal_cross
Can this script be changed so that there is no gap/space where the extended MA starts to print? Basically looking for one continuous print of the MA with out the space.

this predicts where 2 signals would theoretically cross in the future, not where the price will go to.

find if 2 lines will cross in the future, if they were extended.
. use the difference between the close of 2 bars, to calculate the slope.
. can use an offset to look at a bar farther back, not just previous bar.
. extend dotted lines from the end of 2 signal lines.
. labels display several stats, and the price of crossing, and how many bars out.

Ruby:
``````# predict_crossing_00d

# find if 2 lines will cross in the future, if they were extended.
# halcyonguy  12/2021

def na = double.nan;
def bn = barnumber();

def lastbar = !isnan(close[0]) and isnan(close[-1]);
def lastbarbn = if bn == 1 then na else if lastbar then bn else lastbarbn[1];
# ------------------------------------------------------
# 2 averages for testing

input avg1_len = 9;
input avg1_type =  AverageType.simple;
def ma1 = MovingAverage(avg1_type, close, avg1_len);

input avg2_len = 20;
input avg2_type =  AverageType.simple;
def ma2 = MovingAverage(avg2_type, close, avg2_len);

plot z1 = ma1;
z1.setdefaultcolor(color.cyan);
plot z2 = ma2;
z2.setdefaultcolor(color.yellow);

addlabel(1, "avg1 len " + avg1_len, color.yellow);
addlabel(1, "avg2 len " + avg2_len, color.yellow);
# ------------------------------------------------------
#  set 2 formulas to sig1 and sig2
def sig1 = ma1;
def sig2 = ma2;

# calc close chg from a bar,  x bars back
input  barsback_for_offest_for_slope = 1;
def bb = barsback_for_offest_for_slope;
def s1chg = if !isnan(close) then (sig1[0] - sig1[bb])/bb else s1chg[1];
def s2chg = if !isnan(close) then (sig2[0] - sig2[bb])/bb else s2chg[1];

#check if 2 signals are moving towards each other , consolidating
def consol1 = if (sig1 > sig2 and s1chg < s2chg) then 1 else 0;
def consol2 = if (sig1 < sig2 and s1chg > s2chg) then 1 else 0;
def consol = (consol1 or consol2);
def notconsol = (!consol1 or !consol2);

def consolcnt = if ( !consol[1] and consol) then 1 else (consolcnt[1] + 1);
def wideningcnt = if ( consol[1] and !consol) then 1 else (wideningcnt[1] + 1);

addlabel(1, "bars back for offest for slope " + bb, color.lime);

addlabel(consol, "consolidating for " + consolcnt + " bars", color.yellow);
addlabel(!consol, "widening for " + wideningcnt + " bars", color.magenta);

# ------------------------------------
# bars till a crossing
def bars_x = round( (sig2 - sig1) / (s1chg - s2chg), 0);

# future price levels
def f1 = round((sig1 + ( bars_x * s1chg)), 2);
def f2 = round((sig2 + ( bars_x * s2chg)), 2);

addlabel(1, "#1 chg: " + s1chg, color.yellow);
addlabel(1, "#2 chg: " + s2chg, color.yellow);

addlabel(consol, "#1 cross \$: " + f1, color.cyan);
addlabel(consol, "#2 cross \$: " + f2, color.cyan);
#--------------------

def cross_price = if (!isnan(close[-1]) or notconsol) then na
else if lastbar then (sig1 + ( bars_x * s1chg))
else cross_price[1];

plot z4 = cross_price;
z4.SetStyle(Curve.MEDIUM_DASH);
z4.SetDefaultColor(Color.cyan);
z4.setlineweight(1);
z4.hidebubble();

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

#if last bar then  bn of crossing
def bnx = if lastbar then (bars_x + bn) else bnx[1];

addlabel(consol, "last# " + lastbarbn + " cross # " + bnx , color.pink);

# extended lines , after lastbar
def extline_offset = 1;
def ex1 = if bn == 1 then na else
if lastbar[extline_offset] then sig1[extline_offset] + s1chg[extline_offset]
else (ex1[1] + s1chg);

plot ext1 = ex1;
ext1.SetStyle(Curve.MEDIUM_DASH);
ext1.setdefaultcolor(color.white);
#ext1.setlineweight(1);
ext1.hidebubble();

# start on lastbar
#def ex2 = if bn == 1 then na else
#   if lastbar then sig2
#   else (ex2[1] + s2chg);

# start on a bar after lastbar, so there is a gap between lines
def ex2 = if bn == 1 then na else
if lastbar[extline_offset] then sig2[extline_offset] + s2chg[extline_offset]
else (ex2[1] + s2chg);

plot ext2 = ex2;
ext2.SetStyle(Curve.MEDIUM_DASH);
ext2.setdefaultcolor(color.white);
#ext2.setlineweight(1);
ext2.hidebubble();

# draw vert line at time of lines crossing
addverticalline(bn == bnx , "signal cross", color.yellow);

def bars_xb = round(bars_x,0);
AddLabel(consol, "signals 1 & 2 will cross in " + bars_xb + " bars", Color.YELLOW);
AddLabel(!consol, "signals 1 & 2 will not cross", Color.magenta);

#--------------------------------
# test data
input test1 = no;
addchartbubble( test1, low *0.992, "C " + consolcnt + "\nW " + wideningcnt, color.cyan, no);
input test2 = no;
addchartbubble(test2, cross_price, bn + "\n" + ex1 + "\n" + ex1[1] + "\n" + s1chg , color.cyan, no);
input test3 = no;
addchartbubble(test3, cross_price, bn + "\n" + ex1 + "\n" + ex1[1] + "\n" + s1chg , color.cyan, no);
input test4 = no;
addchartbubble(test4, cross_price, bn + "\n" + bnx + "\n" + 0 , color.cyan, no);

# ==================================

# https://tlc.thinkorswim.com/center/reference/thinkScript/Constants/AverageType
#  EXPONENTIAL
#  HULL
#  SIMPLE
#  WEIGHTED
#  WILDERS

# ==============================
# derive a formula
# ----------------
# this is the result formula from below
#   signal diff is on top and bar to bar changes are on bottom.
#     bars_x = (sig2 - sig1) / (s1chg - s2chg)
# ----------------
#  if sig1 > sig2 then,
#  look for when sig1 < sig2q
#
# (sig1 + ( bars_x * s1chg)) <= (sig2 + ( bars_x * s2chg))
#
# rename vars and simplify
# a=sig1
# b=sig2
# a2=s1chg
# b2=s2chg
# x=bars_x

# (a + ( x * a2)) <= (b + ( x * b2))
# a2*x + a <= b2*x + b
# a2*x - b2*x <= b - a
# (a2 - b2) / x <= b - a
# (a2 - b2)  <= (b - a ) * x
# (a2 - b2) / (b - a ) <= x

# replace var names
# invert formula, so signal diff is on top and bar to bar changes are on bottom.
#def bars_x = round( (sig2 - sig1) / (s1chg - s2chg), 1);
#=============================
#``````

some examples using lengths of 55 and 123

TJX
View attachment 12699

BABA
View attachment 12700
hal_cross
Hey @halcyonguy I like this study! Im having trouble with the extension lines though. For example if you try to use it on a Max 1Day or say you have the chart set for 6yrs 1Day but there is only 5yrs of previous data the extension lines will start at an infinite point below then come up to the moving average, and then continue as normal.

Example 6yr 1d chart with only 5yrs of data:

Same chart 5yr 1d:

Do you know what if anything I can change in the code to fix this? Thank you for your time!

Hey @halcyonguy I like this study! Im having trouble with the extension lines though. For example if you try to use it on a Max 1Day or say you have the chart set for 6yrs 1Day but there is only 5yrs of previous data the extension lines will start at an infinite point below then come up to the moving average, and then continue as normal.

Example 6yr 1d chart with only 5yrs of data:

Same chart 5yr 1d:

Do you know what if anything I can change in the code to fix this? Thank you for your time!

sorry, i am not seeing that.
i see wavy lines below the bars. then in a split second , it moves up to where it should be.

sorry, i am not seeing that.
i see wavy lines below the bars. then in a split second , it moves up to where it should be.
Hmm that's so weird some charts like the /ES E-mini S&P 500 will look like this on Max 1D:

Hmm that's so weird some charts like the /ES E-mini S&P 500 will look like this on Max 1D:

i created a custom time, daily , time interval = max , agg = day.
i see a series of 16 updated images, over 8 seconds,
an image like yours, with dashed lines way below the candles. then the dashed lines move up a little, then up a little more,..... till they are near candles

maybe you have slow internet ? or a poor wifi signal? or a slow computer?
i have an i7 laptop that has hard wired internet
sorry, not sure what is the cause.

i created a custom time, daily , time interval = max , agg = day.
i see a series of 16 updated images, over 8 seconds,
an image like yours, with dashed lines way below the candles. then the dashed lines move up a little, then up a little more,..... till they are near candles

maybe you have slow internet ? or a poor wifi signal? or a slow computer?
i have an i7 laptop that has hard wired internet
sorry, not sure what is the cause.
Actually I experience the same thing depending on the ticker. It’ll start at infinity then over the course of some seconds I’ll get about 4-5 updated images and the extension line will move up closer to the candles to the point where it’ll be tight under the candles. However it won’t get to the point where the extension line starts one bar off from where the moving average end like on the shorter time frames. It’ll remain its own independent line that runs the length of the chart rather than being an extension of the moving average.

How did you incorporate the custom time into the script, and what was the result? Sorry I’m more of a beginner-novice when it comes to writing script. I’m pretty good at reverse engineering but I still struggle with original creation.

Last edited:

### Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
395 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
• 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.