Implied Range from Options [SS]
// 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("Implied Range from Options [SS]", overlay=true)

g1 = "Call Data" 
g2 = "Put Data" 
g3 = "Range Analytics"
g4 = "Settings"

showirlbl = input.bool(true, "Show Implied Range Labels", group = g4)
showplts = input.bool(true, "Show Median and Midline Plots", group = g4)
offseta = input.int(0, "Offset", group=g4) 
strike = input.float(100, "Strike Price", group = g1) 
iv = input.float(27.20, "Implied Volatility", group=g1) 
days = input.int(7, "Days to Expiry", group = g1) 

strike2 = input.float(100, "Strike Price", group = g2)
iv2 = input.float(27.20, "Implied Volatility", group=g2) 
days2 = input.int(7, "Days to Expiry", group = g2) 

showlbl = input.bool(true, "Show Range Labels", group=g3)
len = input.int(14, "Length", group=g3, tooltip = "Determines the lookback length for the average high to open and open to low.")
timeframe = input.timeframe("D", group = g3, tooltip = "Timeframe will determine the average range based on the desired timeframe outlook.")

em1 = (strike * iv * math.sqrt(days/252)) / 100 
em2 = (strike2 * iv2 * math.sqrt(days/252)) / 100 

em_ucl = strike + em1
em_lcl = strike - em1 

em2_ucl = strike2 + em2
em2_lcl = strike2 - em2 
a = plot(em_ucl, color=color.green, offset = offseta,  linewidth=3)  
b = plot(em_lcl, color=color.red, offset = offseta, linewidth=3) 

c = plot(em2_ucl, color=color.green, offset=offseta, linewidth=3) 
d = plot(em2_lcl, color=color.red, offset=offseta, linewidth=3) 

// Additional Colours and fills
color redfill = color.new(color.red, 85) 
color greenfill = color.new(color.lime, 85) 
color bluefill = color.new(color.blue, 85) 
color white = color.white
color purple = color.purple 
color transp = color.new(color.white, 100) 
fill(b, d, color = redfill) 
fill(a, c, color = greenfill) 



// Range analytics 

[op, avg_hi_to_op, prev_hi_to_op, avg_lo_to_op, prev_lo_to_op] = request.security(syminfo.ticker, timeframe, [close, ta.sma(high-open, len), (high[1] - low[1]), ta.sma(open - low, 14), (open[1] - low[1])], lookahead = barmerge.lookahead_on)


// Avg Baseline 

avg_base = (em_ucl + em2_lcl) / 2 
hi_mid = (em_ucl + avg_base) / 2 
lo_mid = (em2_lcl + avg_base) / 2 

hi_perc_dif = (em_ucl - op) / op * 100 
hi_mid_perc_dif = (hi_mid - op) / op * 100 
lo_mid_perc_dif = (lo_mid - op) / op * 100 
lo_perc_dif = (em_lcl - op) / op * 100 

hi_midmid = (em2_ucl - hi_mid) / 2 
avghi_mid = (hi_mid - avg_base) / 2 
lo_midmid = (lo_mid - em2_lcl) / 2 

plot(showplts ? hi_mid : na, color=color.aqua, style=plot.style_cross, offset = offseta, linewidth=2) 
plot(showplts ? lo_mid : na, color=color.aqua, style=plot.style_cross, offset = offseta, linewidth=2) 
plot(showplts ? avg_base : na, color=purple, style=plot.style_circles, offset = offseta, linewidth=3)


var label callucl = na 
var label putucl = na 
var label calllcl = na 
var label putlcl = na 
var label hidiflbl = na 
var label himidlbl = na 
var label lomidlbl = na 
var label lodiflbl = na 



if barstate.islast and showirlbl
    label.delete(callucl) 
    label.delete(putucl) 
    label.delete(calllcl) 
    label.delete(putlcl) 
    callucl := label.new(bar_index + offseta, y=em_ucl, text = "Implied High Range from Calls: " + str.tostring(math.round(em_ucl, 2)), style=label.style_label_down, color=greenfill, textcolor=white)
    putucl := label.new(bar_index + offseta, y=em2_ucl, text = "Implied High Range from Puts: " + str.tostring(math.round(em2_ucl, 2)), style=label.style_label_up, color=greenfill, textcolor=white)
    calllcl := label.new(bar_index + offseta, y=em_lcl, text = "Implied Low Range from Calls: " + str.tostring(math.round(em_lcl, 2)), style=label.style_label_up, color=redfill, textcolor=white)
    putlcl := label.new(bar_index + offseta, y=em2_lcl, text = "Implied Low Range from Puts: " + str.tostring(math.round(em2_lcl, 2)), style=label.style_label_down, color=redfill, textcolor=white)
if barstate.islast and showlbl 
    label.delete(himidlbl) 
    label.delete(hidiflbl) 
    label.delete(lomidlbl) 
    label.delete(lodiflbl) 
    hidiflbl := label.new(bar_index + offseta, y = hi_mid + hi_midmid, text = str.tostring(math.round(hi_perc_dif,2)) + "% \n Average High to Open: " + str.tostring(math.round(avg_hi_to_op,2)) + "\n Previous High to Open: " + str.tostring(prev_hi_to_op), color = transp, textcolor = white)
    himidlbl := label.new(bar_index + offseta, y = avg_base + avghi_mid, text = str.tostring(math.round(hi_mid_perc_dif,2)) + "%", color = transp, textcolor = white)
    lomidlbl := label.new(bar_index + offseta, y = avg_base - avghi_mid, text = str.tostring(math.round(lo_mid_perc_dif,2)) + "%", color = transp, textcolor = white)
    lodiflbl := label.new(bar_index + offseta, y = lo_mid - lo_midmid, text = str.tostring(math.round(lo_perc_dif,2)) + "%" + "\n Average Open to Low: " + str.tostring(math.round(avg_lo_to_op,2)) + "\n Previous Open to Low: " + str.tostring(prev_lo_to_op), color = transp, textcolor = white)



