Kviateq - Session Opening Ranges
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © hundredtoamillion

//@version=5

indicator("Kviateq - Session Opening Ranges", overlay= true)

ref_res = ""
tmzn = input(defval="GMT+7", title = "Timezone")

bool showSydney  = input.bool(true, "Show Sydney Opening Range?", group = "Opening Ranges ON/OFF")
bool showTokyo   = input.bool(true, "Show Tokyo Opening Range?", group = "Opening Ranges ON/OFF")
bool showLondon  = input.bool(true, "Show London Opening Range?", group = "Opening Ranges ON/OFF")
bool showNewYork = input.bool(true, "Show New York Opening Range?", group = "Opening Ranges ON/OFF")

sydney  = input.session(defval = "0600-1300", title = "Sydney Session", group = "Session Times")
tokyo   = input.session(defval = "0700-1600", title = "Tokyo Session", group = "Session Times")
london  = input.session(defval = "1500-2340", title = "London Session", group = "Session Times")
newyork = input.session(defval = "2030-0400", title = "New York Session", group = "Session Times")

lor = input(20, title = "Opening Range Length in Minutes")

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SY = time(ref_res, sydney, tmzn)
TK = time(ref_res, tokyo, tmzn)
LD = time(ref_res, london, tmzn)
NY = time(ref_res, newyork, tmzn)

open_bar(t) => na(t[1]) and not na(t) or t[1] < t ? 1 : 0
    
ld_switch = ta.change(open_bar(LD)) > 0
ny_switch = ta.change(open_bar(NY)) > 0
tk_switch = ta.change(open_bar(TK)) > 0
sy_switch = ta.change(open_bar(SY)) > 0

get_ohlc(s) =>
    // Assign persisting variables
    var float _open  = na
    var float _high  = na
    var float _low   = na
    var float _close = na
    
    // Update variables if new bar
    _open  := s ? 
         open : nz(_open[1], open)
    _high  := s or high > _high[1] ? 
         high : nz(_high[1], high)
    _low   := s or low < _low[1] ? 
         low : nz(_low[1], low)
    _close := close
     
    // Return variables as a tuple
    [_open, _high, _low, _close]

// Update the current session ohlc values
[sy_o, sy_h, sy_l, sy_c] = get_ohlc(sy_switch)
[tk_o, tk_h, tk_l, tk_c] = get_ohlc(tk_switch)
[ld_o, ld_h, ld_l, ld_c] = get_ohlc(ld_switch)
[ny_o, ny_h, ny_l, ny_c] = get_ohlc(ny_switch)

get_minutes() =>
    m = 
         timeframe.isseconds ? timeframe.multiplier / 60 :
         timeframe.isintraday ? timeframe.multiplier : 
         timeframe.isdaily ? timeframe.multiplier * 1440 : 
         timeframe.isweekly ? timeframe.multiplier * 10080 : 
         timeframe.ismonthly ? timeframe.multiplier * 42800 : 
         na

t = lor / get_minutes() 

var float ld_open_high = na
var float ld_open_low = na
var float ny_open_high = na
var float ny_open_low = na
var float tk_open_high = na
var float tk_open_low = na
var float sy_open_high = na
var float sy_open_low = na

if (ta.barssince(ta.change(open_bar(LD)) > 0) < t)
    ld_open_high := ld_h
    ld_open_low  := ld_l
if (ta.barssince(ta.change(open_bar(NY)) > 0) < t)
    ny_open_high := ny_h
    ny_open_low  := ny_l
if (ta.barssince(ta.change(open_bar(TK)) > 0) < t)
    tk_open_high := tk_h
    tk_open_low  := tk_l
if (ta.barssince(ta.change(open_bar(SY)) > 0) < t)
    sy_open_high := sy_h
    sy_open_low  := sy_l
//

plorh = plot(showLondon and LD ? ld_open_high : na, color = color.new(color.blue,0), style = plot.style_circles, title = "London Opening Range High")
plorl = plot(showLondon and LD ? ld_open_low :na, color = color.new(color.blue,0), style = plot.style_circles, title = "London Opening Range Low")
fill(plorh, plorl, color = color.new(color.blue,55), title = "London Opening Range Fill")
pnorh = plot(showNewYork and NY ? ny_open_high : na, color = color.new(color.red, 0), style = plot.style_circles, title = "New York Opening Range High")
pnorl = plot(showNewYork and NY ? ny_open_low :na, color = color.new(color.red,0) , style = plot.style_circles, title = "New York Opening Range Low")
fill(pnorh, pnorl, color = color.new(color.red,65), title = "New York Opening Range Fill")
ptorh = plot(showTokyo and TK ? tk_open_high : na, color = color.new(color.yellow, 0), style = plot.style_circles, title = "Tokyo Opening Range High")
ptorl = plot(showTokyo and TK ? tk_open_low :na, color = color.new(color.yellow, 0), style = plot.style_circles,  title = "Tokyo Opening Range Low")
fill(ptorh, ptorl, color = color.new(color.yellow,80), title = "Tokyo Opening Range Fill")
psorh = plot(showSydney and SY ? sy_open_high : na, color = color.new(#8e8e8e, 0), style = plot.style_circles, title = "Tokyo Opening Range High")
psorl = plot(showSydney and SY ? sy_open_low : na, color = color.new(#8e8e8e, 0), style = plot.style_circles, title = "Tokyo Opening Range High")
fill(psorh, psorl, color = color.new(#8e8e8e,80), title = "Tokyo Opening Range Fill")