Session Levels
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ajithcpas
//
// This indicator plots important session (intraday) levels for the day.
// It plots high and low of previous day, week, month, 52 week and all time.
// Also plots the vix range which shows the daily expected trading range of the instrument.
// These levels acts as important support/resistance for the day.
//
// For example, if price closes above previous day, week, or month high/low
// it indicates bullish sentiment and vice versa for bearish.
//
// Vix Range plots top and bottom line for expected trading range for the day.
// It is calculated based on the volatility index selected (NSE:India VIX is used by default).
// Checkout this link for vix range indicator: https://in.tradingview.com/script/DnCO9jly-VIX-Range/
//
// ATR Range plots high, low line for expected trading range for the day based on ATR.
// Percentage Range plots high, low line based on given percentage input from the previous day close.

//@version=5
indicator("Session Levels", overlay=true)

// Inputs
show_labels = input.bool(defval=true, title="Show Labels", group="General")
show_prices = input.bool(defval=true, title="Show Prices", group="General")
extend_option = input.string(defval="None", title="Extend Line", options=["None", "Left", "Right", "Both"], group="General")

show_day_open = input.bool(defval=true, title="Show Current Day", group="Session Open")
show_week_open = input.bool(defval=true, title="Show Current Week", group="Session Open")
show_month_open = input.bool(defval=true, title="Show Current Month", group="Session Open")
session_open_color = input.color(defval=color.purple, title="Line Color", group="Session Open")
session_open_line_style = input.string(defval="Dashed", title="Line Style", options=["Solid", "Dotted", "Dashed"], group="Session Open")

show_day = input.bool(true, title="Show Previous Day", group="Session High Low")
show_n_days = input.bool(true, title="Show Previous N Days", inline="N Days", group="Session High Low")
n_days_input = input.int(5, minval=2, step=1, title="", inline="N Days", group="Session High Low")
show_week = input.bool(true, title="Show Previous Week", group="Session High Low")
show_month = input.bool(true, title="Show Previous Month", group="Session High Low")
show_52_week = input.bool(true, title="Show 52 Week", group="Session High Low")
show_all_time = input.bool(true, title="Show All Time", group="Session High Low")
session_high_color = input.color(defval=color.green, title="High Line Color", group="Session High Low")
session_low_color = input.color(defval=color.red, title="Low Line Color", group="Session High Low")
session_hl_line_style = input.string(defval="Solid", title="Line Style", options=["Solid", "Dotted", "Dashed"], group="Session High Low")

show_vix = input.bool(true, title="Show Vix Range", group="Vix Range", tooltip="Vix Range plots top and bottom line for expected trading range for the day. It is calculated based on the volatility index selected.")
vol_symbol = input.symbol("NSE:INDIAVIX", "Volatility Index", group="Vix Range")
vix_color = input.color(defval=color.blue, title="Line Color", group="Vix Range")
vix_line_style = input.string(defval="Solid", title="Line Style", options=["Solid", "Dotted", "Dashed"], group="Vix Range")

show_atr = input.bool(true, title="Show ATR Range", group="ATR Range")
atr_len = input.int(14, minval=1, title="ATR Length", group="ATR Range")
atr_high_color = input.color(defval=color.green, title="High Line Color", group="ATR Range")
atr_low_color = input.color(defval=color.red, title="Low Line Color", group="ATR Range")
atr_hl_line_style = input.string(defval="Solid", title="Line Style", options=["Solid", "Dotted", "Dashed"], group="ATR Range")

show_percentage = input.bool(true, title="Show Percentage Range", group="Percentage Range", tooltip="Plots range based on given percentage from previous day close.")
percentage_input = input.float(1, minval=0.05, step=0.05, title="Percentage", group="Percentage Range")
percentage_high_color = input.color(defval=color.green, title="High Line Color", group="Percentage Range")
percentage_low_color = input.color(defval=color.red, title="Low Line Color", group="Percentage Range")
percentage_hl_line_style = input.string(defval="Solid", title="Line Style", options=["Solid", "Dotted", "Dashed"], group="Percentage Range")

// Functions
getAllTimeHigh() =>
    h  = 0.0
    h := bar_index == 0 ? high : high > h[1] ? high : h[1]

getAllTimeLow() =>
    l = 0.0
    l := bar_index == 0 ? low  : low < l[1] ? low  : l[1]

get_resolution() =>
    resolution = "M"
    if timeframe.isintraday
        resolution := timeframe.multiplier <= 15 ? "D" : "W"
    else if timeframe.isweekly or timeframe.ismonthly
        resolution := "12M"
    resolution

drawLine(price, _text, lineColor, lineStyle, lineExtend, showLabels, showPrices) =>
    fLineStyle = switch lineStyle
        "Dotted" => line.style_dotted
        "Dashed" => line.style_dashed
        => line.style_solid

    fLineExtend = switch lineExtend
        "Left" => extend.left
        "Right" => extend.right
        "Both" => extend.both
        => extend.none

    endOfDay = time_tradingday + 105000000 // used for positioning line, labels
    aLine = line.new(x1=time_tradingday, y1=price, x2=endOfDay, y2=price, xloc=xloc.bar_time, color=lineColor, style=fLineStyle, extend=fLineExtend)
    line.delete(aLine[1])

    fText = _text
    if showLabels and showPrices
        fText := str.format("{0} - {1}", _text, math.round_to_mintick(price))
    else if showPrices
        fText := str.format("{0}", math.round_to_mintick(price))
    if showLabels or showPrices
        aLabel = label.new(endOfDay, price, xloc=xloc.bar_time, text=str.format("                                {0}", fText), textcolor=lineColor, style=label.style_none)
        label.delete(aLabel[1])

drawOpen(show, resolution, labelText, lineColor, lineStyle, lineExtend, showLabels, showPrices) =>
    _open = request.security(syminfo.tickerid, resolution, open)
    if show
        drawLine(_open, labelText, lineColor, lineStyle, lineExtend, showLabels, showPrices)

drawHighLow(show, resolution, labelTextHigh, labelTextLow, highColor, lowColor, lineStyle, lineExtend, showLabels, showPrices) =>
    [_high, _low] = request.security(syminfo.tickerid, resolution, [high[1], low[1]])
    if show and not na(_high)
        drawLine(_high, labelTextHigh, highColor, lineStyle, lineExtend, showLabels, showPrices)
        drawLine(_low, labelTextLow, lowColor, lineStyle, lineExtend, showLabels, showPrices)

drawVixRange(show, resolution, lineColor, lineStyle, lineExtend, showLabels, showPrices) =>
    prevClose = request.security(syminfo.tickerid, resolution, close[1])
    vixClose = request.security(vol_symbol, resolution, close[1])
    if show
        expectedRange = resolution == "D" ? (prevClose * (vixClose / 100) / 16) : resolution == "W" ? (prevClose * (vixClose / 100) * 0.1386) : (prevClose * (vixClose / 100) * 0.2773)
        drawLine(prevClose + expectedRange, "Vix Top", lineColor, lineStyle, lineExtend, showLabels, showPrices)
        drawLine(prevClose - expectedRange, "Vix Bottom", lineColor, lineStyle, lineExtend, showLabels, showPrices)

// Session Open
drawOpen(show_day_open, "D", "     Day Open", session_open_color, session_open_line_style, extend_option, show_labels, show_prices)
drawOpen(show_week_open, "W", "     Week Open", session_open_color, session_open_line_style, extend_option, show_labels, show_prices)
drawOpen(show_month_open, "M", "     Month Open", session_open_color, session_open_line_style, extend_option, show_labels, show_prices)

// Session High Low
drawHighLow(show_day, "D", "PDH", "PDL", session_high_color, session_low_color, session_hl_line_style, extend_option, show_labels, show_prices)
drawHighLow(show_week, "W", "PWH", "PWL", session_high_color, session_low_color, session_hl_line_style, extend_option, show_labels, show_prices)
drawHighLow(show_month, "M", "PMH", "PML", session_high_color, session_low_color, session_hl_line_style, extend_option, show_labels, show_prices)

// N Days High Low
n_days_high = request.security(syminfo.tickerid, "D", ta.highest(high[1], n_days_input))
n_days_low = request.security(syminfo.tickerid, "D", ta.lowest(low[1], n_days_input))
if show_n_days and not na(n_days_high)
    drawLine(n_days_high, "PnDH", session_high_color, session_hl_line_style, extend_option, show_labels, show_prices)
    drawLine(n_days_low, "PnDL", session_low_color, session_hl_line_style, extend_option, show_labels, show_prices)

// 52 Week High Low
_52_week_high = request.security(syminfo.tickerid, "W", ta.highest(high[1], 52))
_52_week_low = request.security(syminfo.tickerid, "W", ta.lowest(low[1], 52))
if show_52_week and not na(_52_week_high)
    drawLine(_52_week_high, "52WH", session_high_color, session_hl_line_style, extend_option, show_labels, show_prices)
    drawLine(_52_week_low, "52WL", session_low_color, session_hl_line_style, extend_option, show_labels, show_prices)

// All Time High Low
ath = request.security(syminfo.tickerid, "M", getAllTimeHigh())
atl = request.security(syminfo.tickerid, "M", getAllTimeLow())
if show_all_time
    drawLine(ath, "ATH", session_high_color, session_hl_line_style, extend_option, show_labels, show_prices)
    drawLine(atl, "ATL", session_low_color, session_hl_line_style, extend_option, show_labels, show_prices)

resolution = get_resolution()

// Vix Range
drawVixRange(show_vix, resolution, vix_color, vix_line_style, extend_option, show_labels, show_prices)

// ATR Range
prevDayATR = request.security(syminfo.tickerid, resolution, ta.atr(atr_len)[1])
prevDayClose = request.security(syminfo.tickerid, resolution, close[1])
if show_atr
    drawLine(prevDayClose + prevDayATR, "ATR High", atr_high_color, atr_hl_line_style, extend_option, show_labels, show_prices)
    drawLine(prevDayClose - prevDayATR, "ATR Low", atr_low_color, atr_hl_line_style, extend_option, show_labels, show_prices)

// Percentage Range
if show_percentage
    percentRange = prevDayClose * percentage_input / 100
    drawLine(prevDayClose + percentRange, "Percentage High", percentage_high_color, percentage_hl_line_style, extend_option, show_labels, show_prices)
    drawLine(prevDayClose - percentRange, "Percentage Low", percentage_low_color, percentage_hl_line_style, extend_option, show_labels, show_prices)