4C Daily Levels Suite + Premarket High/Low
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FourC 
//Some parts of this code were adapted from 'pd Levels' by CryptoCurl
//03/07/23 - This script has had a complete overahaul, with many changes and improvements. 

//@version=5
indicator('4C Daily Levels Suite + Premarket High/Low', shorttitle='4C Levels',overlay=true)

////Inputs////

var options = "Chart Customization"
OnlyLastPeriod = input(title='Show Current Levels Only?', defval=true, group=options)
linesright = input(title='Extend Lines Right (Current Levels Only) ', defval=false, group=options)
linesfull = input(title='Extend Lines Full Screen (Current Levels Only)', defval=false, group=options)

var pdhi = "Prior Day High"
showpriorhigh = input(title="Show Prior Day High?", defval=true, group=pdhi)
highColor = input(title='Prior Day High', defval=color.rgb(0,255,0,0), group=pdhi)
priorHighStyleOption = input.string('solid (─)', title='Prior Day High Line Style', options=['solid (─)', 'dotted (┈)', 'dashed (╌)'], group=pdhi)
priorHighLineStyle = priorHighStyleOption == 'solid (╌)' ? line.style_solid : priorHighStyleOption == 'dotted (┈)' ? line.style_dotted : priorHighStyleOption == 'dashed (╌)' ? line.style_dashed : line.style_solid 
pdhilineWidth = input(1, 'Line Thickness', group=pdhi)

var pdlo = "Prior Day Low"
showpriorlow = input(title="Show Prior Day Low?", defval=true, group=pdlo)
lowColor = input(title='Prior Day Low ', defval=color.rgb(255,0,0,0), group=pdlo)
priorLowStyleOption = input.string('solid (─)', title='Prior Day Low Line Style', options=['solid (─)', 'dotted (┈)', 'dashed (╌)'], group=pdlo)
priorLowLineStyle = priorLowStyleOption == 'solid (╌)' ? line.style_solid : priorLowStyleOption == 'dotted (┈)' ? line.style_dotted : priorLowStyleOption == 'dashed (╌)' ? line.style_dashed : line.style_solid 
pdlolineWidth = input(1, 'Line Thickness', group=pdlo)

var pdclose = "Prior Day Close"
showpriorclose = input(title="Show Prior Day Close?", defval=true, group=pdclose)
closecolor = input(title='Prior Day Close', defval=color.rgb(0,255,255,0), group=pdclose)
priorCloseStyleOption = input.string('solid (─)', title='Prior Day Close Line Style', options=['solid (─)', 'dotted (┈)', 'dashed (╌)'], group=pdclose)
priorCloseLineStyle = priorCloseStyleOption == 'solid (╌)' ? line.style_solid : priorCloseStyleOption == 'dotted (┈)' ? line.style_dotted : priorCloseStyleOption == 'dashed (╌)' ? line.style_dashed : line.style_solid 
pdcloselineWidth = input(1, 'Line Thickness', group=pdclose)

var pmlevels = "Premarket High/Low"
showpmlevels = input(title='Show Premarket Levels? (Extended Hours Only)', defval=true, group=pmlevels)
pmhighcolor = input(title='Premarket High', defval=color.rgb(255, 0, 255,0), group=pmlevels)
pmlowcolor = input(title='Premarket Low', defval=color.rgb(255, 0, 255,0), group=pmlevels)
pmStyleOption = input.string('solid (─)', title='Pre-market Line Style', options=['solid (─)', 'dotted (┈)', 'dashed (╌)'], group=pmlevels)
pmLineStyle = pmStyleOption == 'solid (╌)' ? line.style_solid : pmStyleOption == 'dotted (┈)' ? line.style_dotted : pmStyleOption == 'dashed (╌)' ? line.style_dashed : line.style_solid 
pmlevelslineWidth = input(1, 'Line Thickness', group=pmlevels)

var topen = "Today Open - RTH"
showtodayopen = input(title="Show Todays Open?", defval=true, group=topen)
openColor = input(title="Todays Open", defval=color.rgb(255,255,255,0), group=topen)
todayOpenStyleOption = input.string('solid (─)', title="Todays Open Line Style", options=['solid (─)', 'dotted (┈)', 'dashed (╌)'], group=topen)
todayOpenLineStyle = todayOpenStyleOption == 'solid (╌)' ? line.style_solid : todayOpenStyleOption  == 'dotted (┈)' ? line.style_dotted : todayOpenStyleOption == 'dashed (╌)' ? line.style_dashed : line.style_solid 
topenlineWidth = input(1, 'Line Thickness', group=topen)

var weeklevels = "Prior Week High/Low"
showweeklevels = input(title='Show Prior Week Levels?', defval=true, group=weeklevels)
pwhighcolor = input(title='Prior Week High', defval=color.rgb(255,255,0,0), group=weeklevels)
pwlowcolor = input(title='Prior Week Low', defval=color.rgb(255, 100, 0,0), group=weeklevels)
pwclosecolor = input(title='Prior Week Close', defval=color.rgb(255, 155, 0,0), group=weeklevels)
pwStyleOption = input.string('solid (─)', title='Prior Week Line Style', options=['solid (─)', 'dotted (┈)', 'dashed (╌)'], group=weeklevels)
pwLineStyle = pwStyleOption == 'solid (╌)' ? line.style_solid : pwStyleOption == 'dotted (┈)' ? line.style_dotted : pwStyleOption == 'dashed (╌)' ? line.style_dashed : line.style_solid 
pwlevelslineWidth = input(1, 'Line Thickness', group=weeklevels)

//End Inputs//

////Levels////

prevHigh = request.security(syminfo.tickerid, "D", syminfo.session == session.regular ? high[1] : high, lookahead=barmerge.lookahead_on)
prevLow = request.security(syminfo.tickerid, "D", syminfo.session == session.regular ? low[1] : low, lookahead=barmerge.lookahead_on)
yestclose = request.security(syminfo.tickerid, "D", syminfo.session == session.regular ? close[1] : close, lookahead=barmerge.lookahead_on)
pmHigh = float(na)
pmLow = float(na)
pwHigh = request.security(syminfo.tickerid, "W", syminfo.session == session.regular ? high[1] : high, lookahead=barmerge.lookahead_on)
pwLow = request.security(syminfo.tickerid, "W", syminfo.session == session.regular ? low[1] : low, lookahead=barmerge.lookahead_on)
pwClose = request.security(syminfo.tickerid, "W", syminfo.session == session.regular ? close[1] : close, lookahead=barmerge.lookahead_on)

//pdEQ = (prevHigh + prevLow) / 2

var line pHighLine = na
var line pLowLine = na
var line pCloseLine = na
var line pmHighLine = na
var line pmLowLine = na
var line tOpenLine = na
var line pwHighLine = na
var line pwLowLine = na
var line pwCloseLine = na

isNewDay = dayofweek != dayofweek[1]
isNewWeek = weekofyear != weekofyear[1]

////Premarket Calculations and line boundary settings////

if session.isfirstbar and session.ispremarket
    pmHigh := high
    pmLow := low
else
    pmHigh := pmHigh[1]
    pmLow := pmLow[1]

if high > pmHigh and session.ispremarket
    pmHigh := high
    line.set_y1(pmHighLine, pmHigh)
    line.set_y2(pmHighLine, pmHigh)

if low < pmLow and session.ispremarket
    pmLow := low
    line.set_y1(pmLowLine, pmLow)
    line.set_y2(pmLowLine, pmLow)

//End Premarket Calcs//

////Major Levels Line Plots////

line.set_x2(pHighLine, bar_index)
line.set_x2(pLowLine, bar_index)
line.set_x2(pCloseLine, bar_index)
line.set_x2(pmHighLine, bar_index)
line.set_x2(pmLowLine, bar_index)

if isNewDay and timeframe.isintraday
    
    pHighLine := line.new(bar_index, prevHigh, bar_index, prevHigh, color=highColor, style=priorHighLineStyle, width=pdhilineWidth)
    pLowLine := line.new(bar_index, prevLow, bar_index, prevLow, color=lowColor, style=priorLowLineStyle, width=pdlolineWidth)
    pCloseLine := line.new(bar_index, yestclose, bar_index, yestclose, color=closecolor, style=priorCloseLineStyle, width=pdcloselineWidth)
    pmHighLine := line.new(bar_index, pmHigh, bar_index, pmHigh, color=pmhighcolor, style=pmLineStyle, width=pmlevelslineWidth)
    pmLowLine := line.new(bar_index, pmLow, bar_index, pmLow, color=pmlowcolor, style=pmLineStyle, width=pmlevelslineWidth)

    if showpriorhigh == false
        line.delete(pHighLine)

    if showpriorlow == false
        line.delete(pLowLine)

    if showpriorclose == false
        line.delete(pCloseLine)
    
    if showpmlevels == false
        line.delete(pmHighLine)
        line.delete(pmLowLine)

    if OnlyLastPeriod
        line.delete(pHighLine[1])
        line.delete(pLowLine[1])
        line.delete(pCloseLine[1])
        line.delete(pmHighLine[1])
        line.delete(pmLowLine[1])
    
    if linesright and OnlyLastPeriod
        line.set_x2(pHighLine, bar_index)
        line.set_x2(pLowLine, bar_index)
        line.set_x2(pCloseLine, bar_index)
        line.set_x2(pmHighLine, bar_index)
        line.set_x2(pmLowLine, bar_index)
        line.set_extend(pHighLine, extend.right)
        line.set_extend(pLowLine, extend.right)
        line.set_extend(pCloseLine, extend.right)
        line.set_extend(pmHighLine, extend.right)
        line.set_extend(pmLowLine, extend.right)
    
    if linesfull and OnlyLastPeriod
        line.set_x2(pHighLine, bar_index)
        line.set_x2(pLowLine, bar_index)
        line.set_x2(pCloseLine, bar_index)
        line.set_x2(pmHighLine, bar_index)
        line.set_x2(pmLowLine, bar_index)
        line.set_extend(pHighLine, extend.both)
        line.set_extend(pLowLine, extend.both)
        line.set_extend(pCloseLine, extend.both)
        line.set_extend(pmHighLine, extend.both)
        line.set_extend(pmLowLine, extend.both)

//Today Open//
todayOpen = request.security(syminfo.tickerid, "D", open, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)

line.set_x2(tOpenLine, bar_index)

if todayOpen[1] != todayOpen and timeframe.isintraday
    
    tOpenLine := line.new(bar_index, todayOpen, bar_index, todayOpen, color=openColor, style=todayOpenLineStyle, width=topenlineWidth)
    
    if showtodayopen == false
        line.delete(tOpenLine)
    
    if OnlyLastPeriod
        line.delete(tOpenLine[1])

    if linesright and OnlyLastPeriod
        line.set_x2(tOpenLine, bar_index)
        line.set_extend(tOpenLine, extend.right)

    if linesfull and OnlyLastPeriod
        line.set_x2(tOpenLine, bar_index)
        line.set_extend(tOpenLine, extend.both)

//Prior Week Levels//

line.set_x2(pwHighLine, bar_index)
line.set_x2(pwLowLine, bar_index)
line.set_x2(pwCloseLine, bar_index)

if isNewWeek
    
    pwHighLine := line.new(bar_index, pwHigh, bar_index, pwHigh, color=pwhighcolor, style=pwLineStyle, width=pwlevelslineWidth)
    pwLowLine := line.new(bar_index, pwLow, bar_index, pwLow, color=pwlowcolor, style=pwLineStyle, width=pwlevelslineWidth)
    pwCloseLine := line.new(bar_index, pwClose, bar_index, pwClose, color=pwclosecolor, style=pwLineStyle, width=pwlevelslineWidth)

    if showweeklevels == false
        line.delete(pwHighLine)
        line.delete(pwLowLine)
        line.delete(pwCloseLine)

    if OnlyLastPeriod
        line.delete(pwHighLine[1])
        line.delete(pwLowLine[1])
        line.delete(pwCloseLine[1])

    if linesright and OnlyLastPeriod
        line.set_x2(pwHighLine, bar_index)
        line.set_x2(pwLowLine, bar_index)
        line.set_x2(pwCloseLine, bar_index)
        line.set_extend(pwHighLine, extend.right)
        line.set_extend(pwLowLine, extend.right)
        line.set_extend(pwCloseLine, extend.right)

    if linesfull and OnlyLastPeriod
        line.set_x2(pwHighLine, bar_index)
        line.set_x2(pwLowLine, bar_index)
        line.set_x2(pwCloseLine, bar_index)
        line.set_extend(pwHighLine, extend.both)
        line.set_extend(pwLowLine, extend.both)
        line.set_extend(pwCloseLine, extend.both)
        
//End Major Levels Line Pots//

////Label Calculations and Scale Plot////

var labels = "Labels In Price Scale"

showlabels = input(title="Show Level Values In Price Scale", defval=true, group=labels)
labelsetting = input.text_area(defval = "To show levels in the price scale, open 'Chart Settings', go to 'Scales', make sure 'Indicators and Financials Value' is checked. \n", title="Label Settings", group=labels)

//labelnote = input.text_area(defval = "PLEASE NOTE: \nIf adjusting the label colors, do it in the area below. \nDo not adjust the colors in the 'Style' tab. \nKeeping the transparency set at 0% is recommended. \nThese suggestions are due to a (code) workaround in the indicator, which enables level values to be plotted in the price scale. If the label color settings are adjusted in the 'Style' tab, unwanted extra plot lines for the levels can appear on the chart. \nIf this happens, reset the indicator by removing it from the chart, and then re-add it.", title = "LABEL COLORS", group=labels)

pdhilabel = input(title='PD High', defval=color.rgb(0,255,0,0), group=labels)
pdlowlabel = input(title='PD Low', defval=color.rgb(255,0,0,0), group=labels)
pdcloselabel= input(title='PD Close', defval=color.rgb(0,255,255,0), group=labels)
pmhighlabel = input(title='PM High', defval=color.rgb(255, 0, 255,0), group=labels)
pmlowlabel = input(title='PM Low', defval=color.rgb(255, 0, 255,0), group=labels)
openlabel = input(title="Open", defval=color.rgb(255,255,255,0), group=labels)
pwhilabel = input(title='PW High', defval=color.rgb(255,255,0,0), group=labels)
pwlowlabel = input(title='PW Low', defval=color.rgb(255,100,0,0), group=labels)
pwcloselabel = input(title='PW Close', defval=color.rgb(255,155,0,0), group=labels)

prevhighlabel = request.security(syminfo.tickerid, "D", high[1], lookahead=barmerge.lookahead_on)
prevlowlabel = request.security(syminfo.tickerid, "D", low[1], lookahead=barmerge.lookahead_on)
prevcloselabel = request.security(syminfo.tickerid, "D", close[1], lookahead=barmerge.lookahead_on)
prevweekhighlabel = request.security(syminfo.tickerid, "W", high[1], lookahead=barmerge.lookahead_on)
prevweeklowlabel = request.security(syminfo.tickerid, "W", low[1], lookahead=barmerge.lookahead_on)
prevweekcloselabel = request.security(syminfo.tickerid, "W", close[1], lookahead=barmerge.lookahead_on)

plot(showlabels and showpriorhigh ? prevhighlabel : na, title="PD High", color=pdhilabel, display=display.price_scale, editable=false)
plot(showlabels and showpriorlow ? prevlowlabel : na, title="PD Low", color=pdlowlabel, display=display.price_scale, editable=false)
plot(showlabels and showpriorclose ? prevcloselabel : na, title="PD Close", color=pdcloselabel, display=display.price_scale, editable=false)
plot(showlabels and showpmlevels ? pmHigh : na, title="PM High", color=pmhighlabel, display=display.price_scale, editable=false)
plot(showlabels and showpmlevels ? pmLow : na, title="PM Low", color=pmlowlabel, display=display.price_scale, editable=false)
plot(showlabels and showtodayopen ? todayOpen : na, title="Open", color=openlabel, display=display.price_scale, editable=false)
plot(showlabels and showweeklevels ? prevweekhighlabel : na, title="PW High", color=pwhilabel, display=display.price_scale, editable=false)
plot(showlabels and showweeklevels ? prevweeklowlabel : na, title="PW Low", color=pwlowlabel, display=display.price_scale, editable=false)
plot(showlabels and showweeklevels ? prevweekcloselabel : na, title="PW Close", color=pwcloselabel, display=display.price_scale, editable=false)

//End Labels//

//////////END SCRIPT//////////