4C Options Expected Move (Weekly + 0DTE)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FourC
//This indicator plots lines for BOTH the Weekly and 0DTE options expected moves. This version is different than the original script "4C Expected Move (Weekly Options)" where only the weekly expected move could be plotted.

//@version=5
indicator("4C Options Expected Move (Weekly + 0DTE)", shorttitle="4C ExpectedMove", overlay=true)

var grweekem = "Weekly Option Expected Move"
emweeklyinfo = input.text_area(defval="Input next week's expected move value based on weekly option pricing. \nUse your broker or other resource to find the expected move +/- value for your symbol. \nIt is typically best to use the EM for the next week expiration that is generated AFTER the Friday close and/or before the Monday open of the upcoming week. \nThis will give the full expected range for the week.", title="Weekly Expected Move Inputs", group=grweekem)
tickerweek = input.symbol(defval="SPX", title="Input Weekly EM Symbol (for your reference)", group=grweekem)
emweek = input.price(1, "Input Weekly Option Expected Move +/-", group=grweekem)
showweekem = input(title='Show Weekly Option Expected Move', defval=true, group=grweekem)
show2sigmaem = input(title='Show 2 Standard Deviation Weekly EM', defval=false, group=grweekem)
posemcolor = input(title='Upper Weekly Expected Move', defval=color.rgb(0,255,0,0), group=grweekem)
wclosecolor = input(title='Last Week Close', defval=color.rgb(0,255,255,0), group=grweekem)
negemcolor = input(title='Lower Weekly Expected Move', defval=color.rgb(255,0,0,0), group=grweekem)
styleOptionem = input.string(title="Weekly EM Line Style", options=["solid (─)", "dashed (╌)", "dotted (┈)"], defval="solid (─)", group=grweekem)

var gr0dte = "0DTE Option Expected Move"
em0dteinfo = input.text_area(defval="Input 0DTE expected move value based on daily option pricing. \nUse your broker or other resource to find the expected move +/- value for your symbol. \nIt is typically best to use the EM value for the 0DTE option that is generated the night before (after market close), or before the market opens for that 0DTE. \nThis will give the full expected range for the day.", title="0DTE Expected Move Inputs", group=gr0dte)
tickerodte = input.symbol(defval="SPX", title="Input 0DTE Symbol (for your reference)", group=gr0dte)
em0dte = input.price(1, "Input 0DTE Option Expected Move +/-", group=gr0dte)
show0dteem = input(title='Show 0DTE Expected Move', defval=false, group=gr0dte)
show2sigma0dte = input(title='Show 2 Standard Deviation 0DTE EM', defval=false, group=gr0dte)
pos0dtecolor = input(title='Upper 0DTE Expected Move', defval=color.rgb(0,255,0,0), group=gr0dte)
dclosecolor = input(title='Prior Day Close', defval=color.rgb(0,255,255,0), group=gr0dte)
neg0dtecolor = input(title='Lower 0DTE Expected Move', defval=color.rgb(255,0,0,0), group=gr0dte)
styleOption0dte = input.string(title="0DTE EM Line Style", options=["solid (─)", "dashed (╌)", "dotted (┈)"], defval="solid (─)", group=gr0dte)

var settings = "Plot Settings"
linesright = input(title='Extend Lines Right', defval=true, group=settings)
linewidth = input(1, "Line Thickness", group=settings)
styleOptionx2 = input.string(title="2 Standard Deviation Line Style ", options=["solid (─)", "dashed (╌)", "dotted (┈)"], defval= "dashed (╌)", group=settings)
labelcolor = input(title='Expected Move Label Color', defval=color.white, group=settings)


var labels = "Label Settings"
showlabels = input(title='Show Labels', defval=true, group=labels)
labelposition = input(5,'Label Postion (Higher Value = Further Right)', group=labels)

lineStyleem = (styleOptionem == "dotted (┈)") ? line.style_dotted :
     (styleOptionem == "dashed (╌)") ? line.style_dashed :
         line.style_solid

lineStyle0dte = (styleOption0dte == "dotted (┈)") ? line.style_dotted :
     (styleOption0dte == "dashed (╌)") ? line.style_dashed :
         line.style_solid

lineStyle2 = (styleOptionx2 == "dotted (┈)") ? line.style_dotted :
     (styleOptionx2 == "dashed (╌)") ? line.style_dashed :
         line.style_solid


////Weekly EM////

wclose = request.security(syminfo.tickerid, "W", close[1], barmerge.gaps_off, barmerge.lookahead_on)

var line wcloseline = na
var line posemline = na
var line negemline = na
var line posemlinex2 = na
var line negemlinex2 = na

var label wcloselabel = na
var label wemposlabel = na
var label wemneglabel = na
var label wemposlabelx2 = na
var label wemneglabelx2 = na

weekposemcalc = wclose + emweek
weeknegemcalc = wclose - emweek
weekposemx2calc = wclose + (2*emweek)
weeknegemx2calc = wclose - (2*emweek)

//Weekly EM Plots//

if wclose[1] != wclose
    line.set_x2(wcloseline, bar_index)
    line.set_x2(posemline, bar_index)
    line.set_x2(negemline, bar_index)
    line.set_x2(posemlinex2, bar_index)
    line.set_x2(negemlinex2, bar_index)
    line.set_extend(wcloseline, extend.none)
    line.set_extend(posemline, extend.none)
    line.set_extend(negemline, extend.none)
    line.set_extend(posemlinex2, extend.none)
    line.set_extend(negemlinex2, extend.none)
    label.delete(wcloselabel)
    label.delete(wemposlabel)
    label.delete(wemneglabel)
    label.delete(wemposlabelx2)
    label.delete(wemneglabelx2)

    //Expected Move Lines
    wcloseline := line.new(bar_index, wclose, bar_index, wclose, color=wclosecolor, style=lineStyleem, width=linewidth)
    posemline := line.new(bar_index, weekposemcalc, bar_index, weekposemcalc, color=posemcolor, style=lineStyleem, width=linewidth)
    negemline := line.new(bar_index, weeknegemcalc, bar_index, weeknegemcalc, color=negemcolor, style=lineStyleem, width=linewidth)
    posemlinex2 := line.new(bar_index, weekposemx2calc, bar_index, weekposemx2calc, color=posemcolor, style=lineStyle2, width=linewidth)
    negemlinex2 := line.new(bar_index, weeknegemx2calc, bar_index, weeknegemx2calc, color=negemcolor, style=lineStyle2, width=linewidth)
    
    line.delete(wcloseline[1])
    line.delete(posemline[1])
    line.delete(negemline[1])
    line.delete(posemlinex2[1])
    line.delete(negemlinex2[1])
    
    if showweekem != true
        line.delete(wcloseline)
        line.delete(posemline)
        line.delete(negemline)
        line.delete(posemlinex2)
        line.delete(negemlinex2)
    
    if show2sigmaem != true

        line.delete(posemlinex2)
        line.delete(negemlinex2)

    if linesright == true
        line.set_x2(wcloseline, bar_index)
        line.set_x2(posemline, bar_index)
        line.set_x2(negemline, bar_index)
        line.set_x2(posemlinex2, bar_index)
        line.set_x2(negemlinex2, bar_index)
        line.set_extend(wcloseline, extend.right)
        line.set_extend(posemline, extend.right)
        line.set_extend(negemline, extend.right)
        line.set_extend(posemlinex2, extend.right)
        line.set_extend(negemlinex2, extend.right)
    
    //Expected Move Labels
    if showlabels == true
        wcloselabel := label.new(bar_index, wclose, 'WC: ' + str.tostring(wclose, '#.##'), style=label.style_none)
        wemposlabel := label.new(bar_index, weekposemcalc, '+WEM ' + str.tostring(weekposemcalc, '#.##'), style=label.style_none)
        wemneglabel := label.new(bar_index, weeknegemcalc, '-WEM: ' + str.tostring(weeknegemcalc, '#.##'), style=label.style_none)
        wemposlabelx2 := label.new(bar_index, weekposemx2calc, '+2WEM): ' + str.tostring(weekposemx2calc, '#.##'), style=label.style_none)
        wemneglabelx2 := label.new(bar_index, weeknegemx2calc, '-2WEM): ' + str.tostring(weeknegemx2calc, '#.##'), style=label.style_none)
        label.set_textcolor(wcloselabel, labelcolor)
        label.set_textcolor(wemposlabel, labelcolor)
        label.set_textcolor(wemneglabel, labelcolor)
        label.set_textcolor(wemposlabelx2, labelcolor)
        label.set_textcolor(wemneglabelx2, labelcolor)

    if show2sigmaem != true
        label.delete(wemposlabelx2)
        label.delete(wemneglabelx2)

if not na(wcloseline) and line.get_x2(wcloseline) != bar_index
    line.set_x2(wcloseline, bar_index)
    line.set_x2(posemline, bar_index)
    line.set_x2(negemline, bar_index)
    line.set_x2(posemlinex2, bar_index)
    line.set_x2(negemlinex2, bar_index)
    label.set_x(wcloselabel, bar_index + labelposition)
    label.set_x(wemposlabel, bar_index + labelposition)
    label.set_x(wemneglabel, bar_index + labelposition)
    label.set_x(wemposlabelx2, bar_index + labelposition)
    label.set_x(wemneglabelx2, bar_index + labelposition)


////Daily 0DTE EM////

dclose = request.security(syminfo.tickerid, "D", close[1], barmerge.gaps_off, barmerge.lookahead_on)

var line dcloseline = na
var line pos0dteline = na
var line neg0dteline = na
var line pos0dtelinex2 = na
var line neg0dtelinex2 = na

var label dcloselabel = na
var label pos0dtelabel = na
var label neg0dtelabel = na
var label pos0dtelabelx2 = na
var label neg0dtelabelx2 = na

pos0dteemcalc = dclose + em0dte
neg0dteemcalc = dclose - em0dte
pos0dteemx2calc = dclose + (2*em0dte)
neg0dteemx2calc = dclose - (2*em0dte)

//Daily 0DTE EM Plots//

if dclose[1] != dclose
    line.set_x2(dcloseline, bar_index)
    line.set_x2(pos0dteline, bar_index)
    line.set_x2(neg0dteline, bar_index)
    line.set_x2(pos0dtelinex2, bar_index)
    line.set_x2(neg0dtelinex2, bar_index)
    line.set_extend(dcloseline, extend.none)
    line.set_extend(pos0dteline, extend.none)
    line.set_extend(neg0dteline, extend.none)
    line.set_extend(pos0dtelinex2, extend.none)
    line.set_extend(neg0dtelinex2, extend.none)
    label.delete(dcloselabel)
    label.delete(pos0dtelabel)
    label.delete(neg0dtelabel)
    label.delete(pos0dtelabelx2)
    label.delete(neg0dtelabelx2)

    //Expected Move Lines
    dcloseline := line.new(bar_index, dclose, bar_index, dclose, color=wclosecolor, style=lineStyle0dte, width=linewidth)
    pos0dteline := line.new(bar_index, pos0dteemcalc, bar_index, pos0dteemcalc, color=posemcolor, style=lineStyle0dte, width=linewidth)
    neg0dteline := line.new(bar_index, neg0dteemcalc, bar_index, neg0dteemcalc, color=negemcolor, style=lineStyle0dte, width=linewidth)
    pos0dtelinex2 := line.new(bar_index, pos0dteemx2calc, bar_index, pos0dteemx2calc, color=posemcolor, style=lineStyle2, width=linewidth)
    neg0dtelinex2 := line.new(bar_index, neg0dteemx2calc, bar_index, neg0dteemx2calc, color=negemcolor, style=lineStyle2, width=linewidth)

    line.delete(dcloseline[1])
    line.delete(pos0dteline[1])
    line.delete(neg0dteline[1])
    line.delete(pos0dtelinex2[1])
    line.delete(neg0dtelinex2[1])

    if show0dteem != true

        line.delete(dcloseline)
        line.delete(pos0dteline)
        line.delete(neg0dteline)
        line.delete(pos0dtelinex2)
        line.delete(neg0dtelinex2)

    if show2sigma0dte != true

        line.delete(pos0dtelinex2)
        line.delete(neg0dtelinex2)

    if linesright == true
        line.set_x2(dcloseline, bar_index)
        line.set_x2(pos0dteline, bar_index)
        line.set_x2(neg0dteline, bar_index)
        line.set_x2(pos0dtelinex2, bar_index)
        line.set_x2(neg0dtelinex2, bar_index)
        line.set_extend(dcloseline, extend.right)
        line.set_extend(pos0dteline, extend.right)
        line.set_extend(neg0dteline, extend.right)
        line.set_extend(pos0dtelinex2, extend.right)
        line.set_extend(neg0dtelinex2, extend.right)


        //Expected Move Labels
    if showlabels and show0dteem == true
        dcloselabel := label.new(bar_index, dclose, 'DC: ' + str.tostring(dclose, '#.##'), style=label.style_none)
        pos0dtelabel := label.new(bar_index, pos0dteemcalc, '0DTE +EM: ' + str.tostring(pos0dteemcalc, '#.##'), style=label.style_none)
        neg0dtelabel := label.new(bar_index, neg0dteemcalc, '0DTE -EM: ' + str.tostring(neg0dteemcalc, '#.##'), style=label.style_none)
        pos0dtelabelx2 := label.new(bar_index, pos0dteemx2calc, '0DTE +(2EM): ' + str.tostring(pos0dteemx2calc, '#.##'), style=label.style_none)
        neg0dtelabelx2 := label.new(bar_index, neg0dteemx2calc, '0DTE -(2EM): ' + str.tostring(neg0dteemx2calc, '#.##'), style=label.style_none)
        label.set_textcolor(dcloselabel, labelcolor)
        label.set_textcolor(pos0dtelabel, labelcolor)
        label.set_textcolor(neg0dtelabel, labelcolor)
        label.set_textcolor(pos0dtelabelx2, labelcolor)
        label.set_textcolor(neg0dtelabelx2, labelcolor)

    if show2sigma0dte != true
        label.delete(pos0dtelabelx2)
        label.delete(neg0dtelabelx2)


if not na(dcloseline) and line.get_x2(dcloseline) != bar_index
    line.set_x2(dcloseline, bar_index)
    line.set_x2(pos0dteline, bar_index)
    line.set_x2(neg0dteline, bar_index)
    line.set_x2(pos0dtelinex2, bar_index)
    line.set_x2(neg0dtelinex2, bar_index)
    label.set_x(dcloselabel, bar_index + labelposition)
    label.set_x(pos0dtelabel, bar_index + labelposition)
    label.set_x(neg0dtelabel, bar_index + labelposition)
    label.set_x(pos0dtelabelx2, bar_index + labelposition)
    label.set_x(neg0dtelabelx2, bar_index + labelposition)