Fx Session Range
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © hiimannshu

//@version=5


indicator(title='Fx Session Range', shorttitle=' Session Range', overlay=true)

string tip = "The timing of the sessions follows NewYork Timezone and taken from www.forex.timezoneconverter.com "
//------------------Genral Settings------------------------//
type = input.string("Range Box","Session Style",options = ["Range Box","BG Highlightlight"],group="General Settings",tooltip = tip)
fil = input.bool(true,"Fill session box ",group="General Settings")
br = input.bool(true,"Show box Borders ",group="General Settings")
show_lbl = input.bool(true,"",inline = "lbl",group="General Settings")
size = input.string("Normal","Label Size",options=["Tiny","Small","Normal","Huge"],inline = "lbl",group="General Settings")
show_day = input.bool(true,"Show day of the week",group="General Settings")

//------------------Asia session Inputs------------------------//


show_asian_range = input.bool(true, title='',inline="asian",group="Asia")
_asianSess =input.string("Asian Range","Assian Session ",options=["Sydney","Tokyo","Both","Asian Range"],inline="asian",group="Asia")
asia = input.session('1800-0301',"Asian Session",group="Asia")
asiabox_col = input.color(color.new(color.aqua, 90), '     ',inline="_ab",group="Asia")
asiaboxborder_col = input.color(color.new(color.black, 70), '',inline="_ab",group="Asia")
asiabrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_ab",group="Asia")

//------------------Sydney session Inputs------------------------//



sydney = input.session('1800-0201',"Sydney",group="Asia")
sydneybox_col = input.color(color.new(color.aqua, 90), '     ',inline="_sb",group="Asia")
sydneyboxborder_col = input.color(color.new(color.black, 70), '',inline="_sb",group="Asia")
sydneybrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_sb",group="Asia")



//------------------Tokyo session Inputs------------------------//


tokyo = input.session('1900-0301',"Tokyo",group="Asia")
tokyobox_col = input.color(color.new(color.aqua, 90), '     ',inline="_tb",group="Asia")
tokyoboxborder_col = input.color(color.new(color.black, 70), '',inline="_tb",group="Asia")
tokyobrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_tb",group="Asia")

//------------------Frankfurt session Inputs------------------------//


show_frankfurt_range = input.bool(false, title='',inline="frankfurt",group="Frankfurt")
frankfurt = input.session('0200-1001',"Frankfurt",inline="frankfurt",group="Frankfurt")
frankfurtbox_col = input.color(color.new(color.blue, 90), '     ',inline="_fb",group="Frankfurt")
frankfurtboxborder_col = input.color(color.new(color.black, 70), '',inline="_fb",group="Frankfurt")
frankfurtbrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_fb",group="Frankfurt")


//------------------London session Inputs------------------------//


show_london_range = input.bool(true, title='',inline="london",group="London")
london = input.session('0300-1101',"London",inline="london",group="London")
londonbox_col = input.color(color.new(color.rgb(102,187,106,0),90), '     ',inline="_lb",group="London")
londonboxborder_col = input.color(color.new(color.black, 70),'',inline="_lb",group="London")
londonbrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_lb",group="London")


//------------------New York session Inputs------------------------//


show_newyork_range = input.bool(true, title='',inline="ny",group="New York")
newyork = input.session('0800-1601',"New York",inline="ny",group="New York")
newyorkbox_col = input.color(color.new(color.rgb(250,161,164, 0),90), '     ',inline="_nyb",group="New York")
newyorkboxborder_col = input.color(color.new(color.black, 70), '',inline="_nyb",group="New York")
nybrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_nyb",group="New York")

//------------------Custom session Inputs------------------------//


show_custom_range = input.bool(false, title='',inline="cu",group="Custom Range")
custom = input.session('1700-1645',"Custom Range",inline="cu",group="Custom Range")
custom_col = input.color(color.new(color.rgb(250,161,164, 0),90), '     ',inline="_cub",group="Custom Range")
customboxborder_col = input.color(color.new(color.black, 70), '',inline="_cub",group="Custom Range")
custombrtype =input.string("Dotted"," ",options=["No border","Solid","Dashed","Dotted"],inline="_cub",group="Custom Range")

//------------------Genral Functions------------------------//

in_session(sess) =>
    not na(time(timeframe.period, sess))

start_time(sess) =>
    int startTime = na
    startTime := in_session(sess) and not in_session(sess)[1] ? time : startTime[1]
    startTime

is_new_session(sess) =>
    t = time("D", sess)
    na(t[1]) and not na(t) or t[1] < t


br_styl(string style)=>
    switch style
	    "No border" => line.style_solid
	    "Solid" => line.style_solid
    	"Dashed" => line.style_dashed
    	"Dotted" => line.style_dotted
    	=>line.style_dotted


lbl_size(string size)=>
    switch size
	    "Tiny" => size.tiny
    	"Small" => size.small
    	"Normal" => size.normal
    	"Huge" => size.huge
    	=>size.small
	    
nofil(ses) => 
    int ret = 0
    
    if(ses == "No border" or br == false) 
        ret:=100
        ret
    else
        ret


sessToShow(sess) => 
    int ret = 0
    
    if(sess == "Sydney") 
        ret:=1
        ret
    else if (sess == "Tokyo")
        ret:=2
        ret
    else if (sess == "Both")
        ret:=3
        ret
    else
        ret


timeinrange(res, sess) => time(res, sess) != 0

_dow() =>
    string day = "  Monday"
    
    if (dayofweek(time('D')) == dayofweek.monday and close )
        day := "  Tuesday"
        day
    else if(dayofweek(time('D')) == dayofweek.tuesday and close )
        day := "  Wednesday"
        day
    else if(dayofweek(time('D')) == dayofweek.wednesday and close)
        day := "  Thursday"
        day
    else if(dayofweek(time('D')) == dayofweek.thursday and close )
        day := "  Friday"
        day
    else if(dayofweek(time('D')) == dayofweek.friday and close )
        day := "  Saturday"
        day
    else if(dayofweek(time('D')) == dayofweek.saturday and close )
        day :="  Sunday"
        day
    else if(dayofweek(time('D')) == dayofweek.sunday and close )
        day

//------------------Variables------------------------//

current_tf = str.tonumber(timeframe.period)
bool valid_tf = current_tf <= 60
bool boxType = (type == "Range Box")

_lblSize = lbl_size(size)
_showLabel = ((show_lbl) and (fil or br)) ? 0:100
_sessToShow = sessToShow(_asianSess)
day = _dow()
//--------------------Asia Session---------------------//


asia_session = is_new_session(asia)


box _asiabox = box(na)
float _asialow = na
float _asiahigh = na
label _asialbl=label(na)

_asiastart = start_time(asia)

_asialow := asia_session ? low : in_session(asia) ? math.min(low, _asialow[1]) : na
_asiahigh := asia_session ? high : in_session(asia) ? math.max(high, _asiahigh[1]) : na

_asiabrtype = br_styl(asiabrtype)

_inasia = in_session(asia) and valid_tf

bool _show_asianRange = ((_sessToShow == 0) and show_asian_range )
int asbr = nofil(asiabrtype)

color _asiabox_col = fil?asiabox_col:color.new(color.black,100)
string _astxt = (_show_asianRange and show_lbl )? ((show_day)?"AS "+day:"AS") :""


if _inasia and boxType
    if in_session(asia)[1]
        label.delete(_asialbl[1])
        box.delete(_asiabox[1])

    if low < _asialow
        _asialow := low

    if high > _asiahigh
        _asiahigh := high

    if  _show_asianRange
        _asiabox := box.new(_asiastart, _asiahigh, time, _asialow, xloc=xloc.bar_time, bgcolor=_asiabox_col, border_color=color.new(asiaboxborder_col,asbr), border_style=_asiabrtype)
        _asialbl:= label.new( x= _asiastart,y=_asiahigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(asiaboxborder_col,_showLabel),text= _astxt)
        _asiabox

bgcolor(_show_asianRange and not(boxType) and timeinrange(timeframe.period, asia) ?_asiabox_col : na)

//--------------------Sydney Session---------------------//


sydney_session = is_new_session(sydney)


box _sydneybox = box(na)
float _sydneylow = na
float _sydneyhigh = na
label _sydneylbl=label(na)

_sydneystart = start_time(sydney)

_sydneylow := sydney_session ? low : in_session(sydney) ? math.min(low, _sydneylow[1]) : na
_sydneyhigh := sydney_session ? high : in_session(sydney) ? math.max(high, _sydneyhigh[1]) : na

_sydneybrtype = br_styl(sydneybrtype)

_insydney = in_session(sydney) and valid_tf

bool _show_sydneyRange = (((_sessToShow == 1) or (_sessToShow == 3)) and show_asian_range )
int sybr = nofil(sydneybrtype)

color _sydneybox_col = fil?sydneybox_col:color.new(color.black,100)
string _sytxt = (_show_sydneyRange and show_lbl )? ((show_day)?"SY "+day:"SY") :""

if _insydney and boxType
    if in_session(sydney)[1]
        label.delete(_sydneylbl[1])
        box.delete(_sydneybox[1])

    if low < _sydneylow
        _sydneylow := low

    if high > _sydneyhigh
        _sydneyhigh := high

    if _show_sydneyRange
        _sydneybox := box.new(_sydneystart, _sydneyhigh, time, _sydneylow, xloc=xloc.bar_time, bgcolor=_sydneybox_col, border_color=color.new(sydneyboxborder_col,sybr), border_style=_sydneybrtype)
        _sydneylbl:= label.new( x= _sydneystart,y=_sydneyhigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(sydneyboxborder_col,_showLabel),text= _sytxt )
        _sydneybox

bgcolor(_show_sydneyRange and not(boxType) and timeinrange(timeframe.period, sydney) ?_sydneybox_col : na)


//--------------------Tokyo Session---------------------//


tokyo_session = is_new_session(tokyo)


box _tokyobox = box(na)
float _tokyolow = na
float _tokyohigh = na
label _tokyolbl=label(na)

_tokyostart = start_time(tokyo)

_tokyolow := tokyo_session ? low : in_session(tokyo) ? math.min(low, _tokyolow[1]) : na
_tokyohigh := tokyo_session ? high : in_session(tokyo) ? math.max(high, _tokyohigh[1]) : na

_tokyobrtype = br_styl(tokyobrtype)

_intokyo = in_session(tokyo) and valid_tf

bool _show_tokyoRange = (((_sessToShow == 2) or (_sessToShow == 3)) and  show_asian_range )
int tybr = nofil(tokyobrtype)

color _tokyobox_col = fil?tokyobox_col:color.new(color.black,100)
string _tytxt = (_show_tokyoRange and show_lbl and not(_show_sydneyRange) )? ((show_day)?"TY "+day:"TY") :"TY"


if _intokyo and boxType
    if in_session(tokyo)[1]
        label.delete(_tokyolbl[1])
        box.delete(_tokyobox[1])

    if low < _tokyolow
        _tokyolow := low

    if high > _tokyohigh
        _tokyohigh := high

    if _show_tokyoRange
        _tokyobox := box.new(_tokyostart, _tokyohigh, time, _tokyolow, xloc=xloc.bar_time, bgcolor=_tokyobox_col, border_color=color.new(tokyoboxborder_col,tybr), border_style=_tokyobrtype)
        _tokyolbl:= label.new( x= _tokyostart,y=_tokyohigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(tokyoboxborder_col,_showLabel),text= _tytxt)
        _tokyobox

bgcolor(_show_tokyoRange and not(boxType) and timeinrange(timeframe.period, tokyo) ?_tokyobox_col : na)
//--------------------Frankfurt Session---------------------//


frankfurt_session = is_new_session(frankfurt)


box _frankfurtbox = box(na)
float _frankfurtlow = na
float _frankfurthigh = na
label _frankfurtlbl=label(na)

_frankfurtstart = start_time(frankfurt)

_frankfurtlow := frankfurt_session ? low : in_session(frankfurt) ? math.min(low, _frankfurtlow[1]) : na
_frankfurthigh := frankfurt_session ? high : in_session(frankfurt) ? math.max(high, _frankfurthigh[1]) : na

_frankfurtbrtype = br_styl(frankfurtbrtype)

_infrankfurt= in_session(frankfurt) and valid_tf


int frbr = nofil(frankfurtbrtype)

color _frankfurtbox_col = fil?frankfurtbox_col:color.new(color.black,100)
string _frtxt = (show_frankfurt_range and show_lbl and not(show_asian_range))? ((show_day)?"FR "+day:"FR") :"FR"


if _infrankfurt and boxType
    if in_session(frankfurt)[1]
        label.delete(_frankfurtlbl[1])
        box.delete(_frankfurtbox[1])

    if low < _frankfurtlow
        _frankfurtlow := low

    if high > _frankfurthigh
        _frankfurthigh := high

    if show_frankfurt_range
        _frankfurtbox := box.new(_frankfurtstart, _frankfurthigh, time, _frankfurtlow, xloc=xloc.bar_time, bgcolor=_frankfurtbox_col, border_color=color.new(frankfurtboxborder_col,frbr), border_style=_frankfurtbrtype)
        _frankfurtlbl:= label.new( x= _frankfurtstart,y=_frankfurthigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(frankfurtboxborder_col,_showLabel),text= _frtxt)
        _frankfurtbox

bgcolor(show_frankfurt_range and not(boxType) and timeinrange(timeframe.period, frankfurt) ?_frankfurtbox_col : na)
//--------------------London Session---------------------//


london_session = is_new_session(london)

box _londonbox = box(na)
float _londonlow = na
float _londonhigh = na
label _londonlbl=label(na)

_londonstart = start_time(london)

_londonlow := london_session ? low : in_session(london) ? math.min(low, _londonlow[1]) : na
_londonhigh := london_session ? high : in_session(london) ? math.max(high, _londonhigh[1]) : na


_inlondon = in_session(london) and valid_tf

_londonbrtype = br_styl(londonbrtype)
color _londonbox_col = fil?londonbox_col:color.new(color.black,100)
string _lntxt = (show_london_range and show_lbl and not(show_asian_range) and not(show_frankfurt_range))? ((show_day)?"LN "+day:"LN") :"LN"


int lobr = nofil(londonbrtype)

if _inlondon and boxType
    if in_session(london)[1]
        label.delete(_londonlbl[1])
        box.delete(_londonbox[1])

    if low < _londonlow
        _londonlow := low

    if high > _londonhigh
        _londonhigh := high

    if show_london_range
        _londonbox := box.new(_londonstart, _londonhigh, time, _londonlow, xloc=xloc.bar_time, bgcolor=_londonbox_col, border_color=color.new(londonboxborder_col,lobr), border_style=_londonbrtype)
        _londonlbl:= label.new( x= _londonstart,y=_londonhigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(londonboxborder_col,_showLabel),text= _lntxt)
        _londonbox

bgcolor(show_london_range and not(boxType) and timeinrange(timeframe.period,london) ?_londonbox_col : na)

//--------------------New York Session---------------------//




newyork_session = is_new_session(newyork)

box _newyorkbox = box(na)
float _newyorklow = na
float _newyorkhigh = na
label _nylbl=label(na)

_newyorkstart = start_time(newyork)

_newyorklow := newyork_session ? low : in_session(newyork) ? math.min(low, _newyorklow[1]) : na
_newyorkhigh := newyork_session ? high : in_session(newyork) ? math.max(high, _newyorkhigh[1]) : na


_innewyork = in_session(newyork) and valid_tf

_newyorkbrtype = br_styl(nybrtype)
color _newyorkbox_col = fil?newyorkbox_col:color.new(color.black,100)
string _nytxt = (show_newyork_range and show_lbl and not(show_asian_range) and not(show_frankfurt_range ) and not(show_london_range))? ((show_day)?"NY "+day:"NY") :"NY"

int nybr = nofil(nybrtype)

if _innewyork and boxType
    if in_session(newyork)[1]
        label.delete(_nylbl[1])
        box.delete(_newyorkbox[1])

    if low < _newyorklow
        _newyorklow := low

    if high > _newyorkhigh
        _newyorkhigh := high

    if show_newyork_range
        _newyorkbox := box.new(_newyorkstart, _newyorkhigh, time, _newyorklow, xloc=xloc.bar_time, bgcolor=_newyorkbox_col, border_color=color.new(newyorkboxborder_col,nybr), border_style=_newyorkbrtype)
        _nylbl:= label.new( x= _newyorkstart,y=_newyorkhigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(newyorkboxborder_col,_showLabel),text= _nytxt)
        _newyorkbox

if newyork_session and show_newyork_range
    line.new(x1=_newyorkstart, y1=high, x2=_newyorkstart, y2=low, extend=extend.both,color=color.new(color.white,70), width=1, xloc=xloc.bar_time,style =line.style_dotted )

bgcolor(show_newyork_range and not(boxType) and timeinrange(timeframe.period, newyork) ?_newyorkbox_col : na)

//--------------------Custom Session---------------------//




custom_session = is_new_session(custom)

box _custombox = box(na)
float _customlow = na
float _customhigh = na
label _customlbl=label(na)

_customstart = start_time(custom)

_customlow := custom_session ? low : in_session(custom) ? math.min(low, _customlow[1]) : na
_customhigh := custom_session ? high : in_session(custom) ? math.max(high, _customhigh[1]) : na


_incustom = in_session(custom) and valid_tf

_custombrtype = br_styl(custombrtype)
color _custombox_col = fil?custom_col:color.new(color.black,100)


int cubr = nofil(custombrtype)

if _incustom and boxType
    if in_session(custom)[1]
        label.delete(_customlbl[1])
        box.delete(_custombox[1])

    if low < _customlow
        _customlow := low

    if high > _customhigh
        _customhigh := high

    if show_custom_range
        _custombox := box.new(_customstart, _customhigh, time, _customlow, xloc=xloc.bar_time, bgcolor=custom_col, border_color=color.new(customboxborder_col,cubr), border_style=_custombrtype)
        _customlbl:= label.new( x= _customstart,y=_customhigh,style=label.style_label_lower_left,xloc=xloc.bar_time,size=_lblSize,color=color.new(color.black,100),textcolor=color.new(customboxborder_col,_showLabel),text= day)
        _custombox


bgcolor(show_custom_range and not(boxType) and timeinrange(timeframe.period, custom) ?custom_col : na)

