RSI and Stochastic Probability Based Price Target Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Steversteves

//@version=5
indicator("RSI and Stochastic Probability Based Price Target Indicator", overlay=true, max_labels_count=500)

// Bell Cruve Levels
length = input.int(75, title="Bell Curve Lookback Period") 

// Calculation
basis = ta.sma(close, length)
dev = ta.stdev(close, length)
upper1 = basis + 3 * dev 
upper2 = basis + 2 * dev
upper13 = basis + 1.5 * dev
upper68 = basis + dev
lower1 = basis - 3 * dev 
lower2 = basis - 2 * dev
lower13 = basis - 1.5 * dev
lower68 = basis - dev


// Datatable
string rng = na 
string uprng = na
string downrng = na  

var bulltarget = 0.0 
var beartarget = 0.0 

bool u12 = close < upper1 and close > upper2 

bool u13 = close > upper13 and close < upper2 

bool u3 = close < upper13 and close > upper68 

bool neut = close >= lower68 and close <= upper68 
 
bool l13 = close < lower68 and close > lower13  

bool l2 = close < lower13 and close > lower2

bool l1 = close < lower2 

// Bear Target 
if u12 
    beartarget := upper2 

if u13 
    beartarget := upper13 

if u3 
    beartarget := upper68

if neut 
    beartarget := lower68 

if l13
    beartarget := lower13

if l2 
    beartarget := lower2 



// Bull target 

if neut 
    bulltarget := upper68 

if u3 
    bulltarget := upper13

if u13 
    bulltarget := upper2 

if u12 
    bulltarget := upper1 

if l13 
    bulltarget := lower68 

if l2 
    bulltarget := lower13 

if l1 
    bulltarget := lower2 

// Range assessment 

if u12 or l1
    rng := "0.1%"

if u13 or l2 
    rng := "2.1%"

if u3 or l13 
    rng := "13%"

if neut 
    rng := "68%" 

// Probability up 

if neut 
    uprng := "13%" 

if u3
    uprng := "2.1%" 

if u13 or u12 
    uprng := "0.1%" 

if l13 or l2 or l1 
    uprng := "68%" 

// Probability Down

if neut 
    downrng := "13%" 

if l13 
    downrng := "2.1%" 

if l2 or l1 
    downrng := "0.1%" 

if u3 or u13 or u12 
    downrng := "68%" 

// RSI and Stochastic Regression Based Analyses 
len = input.int(75, title="Regression Lookback", tooltip = "This is the lookback period for price prediction. Reccomended to leave at no less than 75 for best results.")
sm = input.int(14, title="Smoothing Length", group="Technicals")

rsilen = input.int(14, title="RSI Length", group="Technicals") 
stolen = input.int(14, title="Stochastic Length", group="Technicals")
timeframe = input.timeframe("", title="RSI and Stochastic Timeframe")

stosmooth = input.bool(true, title="Stochastic Smoothing?", group="Technicals", tooltip = "This will smooth the price prediction for stochastics. Unsmoothing will help you identify divergences but is not reccomended as default.")
rsismooth = input.bool(true, title="RSI Smoothing", group="Technicals", tooltip = "This will smoothe the price prediction for RSI. Unsmoothing will help you identify divergences but is not reccomended as default.")

today_close = request.security(syminfo.tickerid, timeframe, close, lookahead=barmerge.lookahead_on)

linregs(y, x, len) =>
    ybar = math.sum(y, len)/len
    xbar = math.sum(x, len)/len
    b = math.sum((x - xbar)*(y - ybar), len)/math.sum((x - xbar)*(x - xbar), len)
    a = ybar - b*xbar
    [a, b]

// Historical stock price data
o = ta.rsi(close, rsilen)
s = ta.stoch(close, high, low, stolen)
l = today_close

// Calculate linear regression for stock price based on open price
[a, b] = linregs(l, o, len)
[c, d] = linregs(l, s, len)

rsiprice = a + b * o
stoprice = c + d * s

// Smoothing 
rsism = ta.sma(rsiprice, sm) 
stosm = ta.sma(stoprice, sm) 

// Conditions 
rsicross = ta.crossover(rsism, stosm)
stocross = ta.crossover(stosm, rsism) 

// Variables
var label_triggered = false
var label_time = 0

var rsi = 0.0 
var sto = 0.0 

// Assessments 

if stocross and close > upper68 and bar_index - label_time >= 10 
    label_triggered := true
    label_time := bar_index
    rsilabel = label.new(x=bar_index, y=high, color=color.black, textcolor=color.white, style=label.style_label_center, size=size.normal)
    label.set_text(id=rsilabel, text="Pullback to: " + str.tostring(math.round(basis, 2)))

if rsicross and bar_index - label_time >= 10 and close < lower68 
    label_triggered := true
    label_time := bar_index
    rsilabel = label.new(x=bar_index, y=high, color=color.black, textcolor=color.white, style=label.style_label_center, size=size.normal)
    label.set_text(id=rsilabel, text="Pullup to: " + str.tostring(math.round(basis, 2)))

if stosmooth 
    sto := stosm 

else
    sto := stoprice 

if rsismooth
    rsi := rsism 

else 
    rsi := rsiprice


// plot functions 

plot(rsi, title="RSI Line", color=color.white, linewidth=3) 

plot(sto, title="Stochastic line", color=color.yellow, linewidth=3) 

plotshape(rsicross ? low : na, title = "Bullish Cross", style=shape.triangleup, color=color.green, size=size.small)
plotshape(stocross ? high : na, "Bearish Cross", style=shape.triangledown, color=color.red, size=size.small)

// Data Table 
showTable     = input.bool(true, "Show Table")

tablePosInput = input.string(title="Position", defval="Top Right", options=["Bottom Left", "Bottom Right", "Top Left", "Top Right"], tooltip="Select where you want the table to draw.")
var tablePos  = tablePosInput == "Bottom Left" ? position.bottom_left : tablePosInput == "Bottom Right" ? position.bottom_right : tablePosInput == "Top Left" ? position.top_left : tablePosInput == "Top Right" ? position.top_right : na

var dataTable = table.new(tablePos, columns = 9, rows = 7, border_color = color.black, border_width = 2)

if showTable
    table.cell(dataTable, 1, 1, text = "Data Table", bgcolor = color.black, text_color = color.white) 
    table.cell(dataTable, 2, 1, text = "Variables", bgcolor = color.black, text_color = color.white) 
    table.cell(dataTable, 1, 2, text = "Probability Range", bgcolor = color.black, text_color = color.white) 
    table.cell(dataTable, 2, 2, text = str.tostring(rng), bgcolor = color.blue, text_color = color.white) 
    table.cell(dataTable, 1, 3, text = "Probability Up Move", bgcolor = color.black, text_color = color.white) 
    table.cell(dataTable, 2, 3, text = str.tostring(uprng), bgcolor = color.blue, text_color = color.white) 
    table.cell(dataTable, 1, 4, text = "Probability Down Move", bgcolor = color.black, text_color = color.white) 
    table.cell(dataTable, 2, 4, text = str.tostring(downrng), bgcolor = color.blue, text_color = color.white)
    table.cell(dataTable, 1, 5, text = "Next Bull Target", bgcolor = color.black, text_color = color.white)
    table.cell(dataTable, 2, 5, text = str.tostring(math.round(bulltarget,2)), bgcolor = color.blue, text_color = color.white)
    table.cell(dataTable, 1, 6, text = "Next Bear Target", bgcolor = color.black, text_color = color.white)
    table.cell(dataTable, 2, 6, text = str.tostring(math.round(beartarget,2)), bgcolor = color.blue, text_color = color.white)




