Crypto VCR 
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Vikashprajapati


 
//Session	            Local Time	                   DST OFF (UCT+0)	DST ON (UTC+0)	DST ON 2022	  DST OFF 2022	DST ON 2023	  DST OFF 2023	  DST ON 2024	DST OFF 2024
//London	            8am-430pm	                   0800-1630	    0700-1530	    March, 27	  October, 30	March, 26	  October, 29	  March, 31	    October, 27
//NewYork	            930am-4pm	                   1430-2100	    1330-2000	    March, 13	  November, 6	March, 12	  November, 5	  March, 10	    November, 3
//Tokyo	                9am-3pm	                       0000-0600	    0000-0600	    N/A	          N/A	        N/A	          N/A	          N/A	        N/A


//@version=5
indicator('Vikash VCR', overlay=true, max_bars_back=300,max_boxes_count=500, max_lines_count=500, max_labels_count=500)


// Config
label_offset_input = input.int(group='Label offsets', title='General', defval=5, inline='labeloffset1')
pivot_offset_input = input.int(group='Label offsets', title='Pivots', defval=-5, inline='labeloffset1')
adr_offset_input = input.int(group='Label offsets', title='ADR', defval=25, inline='labeloffset1')
adr_offset_input_50 = input.int(group='Label offsets', title='50% ADR', defval=85, inline='labeloffset1')
rd_offset_input = input.int(group='Label offsets', title='RD/W', defval=45, inline='labeloffset1')
rd_offset_input_50 = input.int(group='Label offsets', title='50% RD/W', defval=85, inline='labeloffset1')


showEmas = input.bool(group='EMAs', title='Show EMAs?', defval=true, inline='showemas')
labelEmas = input.bool(group='EMAs', title='EMA Labels?', defval=false, inline='showemas')
oneEmaColor = input.color(group='EMAs', title='50', defval=color.rgb(31, 188, 211, 0), inline='emacolors')
twoEmaColor = input.color(group='EMAs', title='200', defval=color.rgb(255, 255, 255, 0), inline='emacolors')

//Daily Pivot Points
showLevelOnePivotPoints = input.bool(group='Pivot Points', title='Show Level: 1 R/S?', defval=false, inline='pivotlevels')
showLevelTwoPivotPoints = input.bool(group='Pivot Points', title='2 R/S?', defval=false, inline='pivotlevels')
showLevelThreePivotPoints = input.bool(group='Pivot Points', title=' 3 R/S?', defval=false, inline='pivotlevels')
showPivotLabels = input.bool(group='Pivot Points', title='Show labels?', defval=true, inline='pivotlevels')
string rsStyleX = input.string(group='Pivot Points', defval='Dashed', title='R/S Levels Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='pivotcolorsRS')
rsStyle = rsStyleX == 'Dotted' ? line.style_dotted : (rsStyleX == 'Dashed' ? line.style_dashed : (rsStyleX == 'Solid' ? line.style_solid : line.style_dashed))

activeM = input.bool(group='Pivot Points', title='Show M levels?', defval=true, inline='mlevels')
showMLabels = input.bool(group='Pivot Points', title='Labels?', defval=true, inline='mlevels')
extendPivots = input.bool(group='Pivot Points', title='Extend lines in both directions?', defval=false)
pivotColor = input.color(group='Pivot Points', title='Colors: Pivot Point', defval=color.rgb(254, 234, 78, 50), inline='pivotcolors')
pivotLabelColor = input.color(group='Pivot Points', title='Pivot Point Label', defval=color.rgb(254, 234, 78, 50), inline='pivotcolors')
mColor = input.color(group='Pivot Points', title='Colors: M Levels', defval=color.rgb(255, 255, 255, 50), inline='pivotcolors1')
mLabelColor = input.color(group='Pivot Points', title='M Levels Label', defval=color.rgb(255, 255, 255, 50), inline='pivotcolors1')
string mStyleX = input.string(group='Pivot Points', defval='Dashed', title='M Levels Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='pivotcolors2')
mStyle = mStyleX == 'Dotted' ? line.style_dotted : (mStyleX == 'Dashed' ? line.style_dashed : (mStyleX == 'Solid' ? line.style_solid : line.style_dashed))


showDayHighLow = input.bool(group="Yesterday's and Last Week's High/low", title='Show Hi/Lo: Daily?', defval=true, inline='highlow')
showWeekHighLow = input.bool(group="Yesterday's and Last Week's High/low", title='Weekly?', defval=true, inline='highlow')
showDayHighLowLabels = input.bool(group="Yesterday's and Last Week's High/low", title='Show labels?', defval=true, inline='highlow')

showADR = input.bool(group='Average Daily Range - ADR', title='Show ADR?', defval=true, inline='adr')
showADR_DO = input.bool(group='Average Daily Range - ADR', title='Use Daily Open (DO) calc?', defval=false, inline='adr', tooltip='Measure the ADR from the daily open. This will make the ADR static throughout the day. ADR is usually measured taking today high and low. Since todays high and low will change throughout the day, some might prefer to have a static range instead.')
showADRLabels = input.bool(group='Average Daily Range - ADR', title='Labels?', defval=true, inline='adr1')
showADRRange = input.bool(group='Average Daily Range - ADR', title='Range label?', defval=false, inline='adr1')
showADR_50 = input.bool(group='Average Daily Range - ADR', title='Show 50% ADR?', defval=false, inline='adr1')
aDRRange = input.int(group='Average Daily Range - ADR', title='ADR length (days)?', defval=14, minval=1, maxval=31, step=1, inline='adr2', tooltip="Defaults taken from mt4. This defines how many days back to take into consideration when calculating the ADR")
adrColor = input.color(group='Average Daily Range - ADR', title='ADR Color', defval=color.new(color.silver, 50), inline='adr3')
string adrStyleX = input.string(group='Average Daily Range - ADR', defval='Dotted', title='ADR Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='adr3')
adrStyle = adrStyleX == 'Dotted' ? line.style_dotted : (adrStyleX == 'Dashed' ? line.style_dashed : (adrStyleX == 'Solid' ? line.style_solid : line.style_dotted))

showAWR = input.bool(group='Average Weekly Range - AWR', title='Show AWR?', defval=false, inline='awr')
showAWR_WO = input.bool(group='Average Weekly Range - AWR', title='Use Weekly Open (WO) calc?', defval=false, inline='awr', tooltip='Measure the AWR from the weekly open. This will make the AWR static throughout the week. AWR is usually measured taking this weeks high and low. Since this weeks high and low will change throughout the week, some might prefer to have a static range instead.')
showAWRLabels = input.bool(group='Average Weekly Range - AWR', title='Labels?', defval=true, inline='awr1')
showAWRRange = input.bool(group='Average Weekly Range - AWR', title='Range label?', defval=false, inline='awr1')
showAWR_50 = input.bool(group='Average Weekly Range - AWR', title='Show 50% AWR?', defval=false, inline='awr1')
aWRRange = input.int(group='Average Weekly Range - AWR', title='AWR length (weeks)?', defval=4, minval=1, maxval=52, step=1, inline='awr2', tooltip="Defaults taken from mt4. This defines how many weeks back to take into consideration when calculating the AWR")
awrColor = input.color(group='Average Weekly Range - AWR', title='AWR Color', defval=color.new(color.orange, 50), inline='awr3')
string awrStyleX = input.string(group='Average Weekly Range - AWR', defval='Dotted', title='AWR Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='awr3')
awrStyle = awrStyleX == 'Dotted' ? line.style_dotted : (awrStyleX == 'Dashed' ? line.style_dashed : (awrStyleX == 'Solid' ? line.style_solid : line.style_dotted))


showAMR = input.bool(group='Average Monthly Range - AMR', title='Show AMR?', defval=false, inline='amr')
showAMR_MO = input.bool(group='Average Monthly Range - AMR', title='Use Monthly Open (MO) calc?', defval=false, inline='amr',tooltip='Measure the AMR from the monthly open. This will make the AMR static throughout the month. AMR is usually measured taking this months high and low. Since this months high and low will change throughout the month, some might prefer to have a static range instead.')
showAMRLabels = input.bool(group='Average Monthly Range - AMR', title='Labels?', defval=true, inline='amr1')
showAMRRange = input.bool(group='Average Monthly Range - AMR', title='Range label?', defval=false, inline='amr1')
showAMR_50 = input.bool(group='Average Monthly Range - AMR', title='Show 50% AMR?', defval=false, inline='amr1')
aMRRange = input.int(group='Average Monthly Range - AMR', title='AMR length (months)?', defval=6, minval=1, maxval=12, step=1, inline='amr2', tooltip="Defaults taken from mt4. This defines how many months back to take into consideration when calculating the AMR")
amrColor = input.color(group='Average Monthly Range - AMR', title='AMR Color', defval=color.new(color.red, 50), inline='amr3')
string amrStyleX = input.string(group='Average Monthly Range - AMR', defval='Dotted', title='AMR Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='amr3')
amrStyle = amrStyleX == 'Dotted' ? line.style_dotted : (amrStyleX == 'Dashed' ? line.style_dashed : (amrStyleX == 'Solid' ? line.style_solid : line.style_dotted))

showRD = input.bool(group='Range Daily Hi/Lo - RD Hi/Lo', title='Show RD?', defval=false, inline='rd')
showRD_DO = input.bool(group='Range Daily Hi/Lo - RD Hi/Lo', title='Use Daily Open (DO) calc?', defval=false, inline='rd',tooltip='Measure the RD from the daily open. This will make the RD static throughout the day. RD is usually measured taking todays high and low. Since today high and low will change throughout the day, some might prefer to have a static range instead.')
showRDLabels = input.bool(group='Range Daily Hi/Lo - RD Hi/Lo', title='Labels?', defval=true, inline='rd1')
showRDRange = input.bool(group='Range Daily Hi/Lo - RD Hi/Lo', title='Range label?', defval=false, inline='rd1')
showRD_50 = input.bool(group='Range Daily Hi/Lo - RD Hi/Lo', title='Show 50% RD?', defval=false, inline='rd1')
rdRange = input.int(group='Range Daily Hi/Lo - RD Hi/Lo', title='RD length (days)?', defval=15, minval=1, maxval=31, step=1, inline='rd2', tooltip="Defaults taken from Trader At Home PVSRA documentation. This defines how many days back to take into consideration when calculating the RD")
rdColor = input.color(group='Range Daily Hi/Lo - RD Hi/Lo', title='RD Color', defval=color.new(color.red, 30), inline='rd3')
string rdStyleX = input.string(group='Range Daily Hi/Lo - RD Hi/Lo', defval='Solid', title='RD Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='rd3')
rdStyle = rdStyleX == 'Dotted' ? line.style_dotted : (rdStyleX == 'Dashed' ? line.style_dashed : (rdStyleX == 'Solid' ? line.style_solid : line.style_dotted))

showRW = input.bool(group='Range Weekly Hi/Lo - RW Hi/Lo', title='Show RW?', defval=false, inline='rw')
showRW_WO = input.bool(group='Range Weekly Hi/Lo - RW Hi/Lo', title='Use Weekly Open (WO) calc?', defval=false, inline='rw', tooltip='Measure the RW from the weekly open. This will make the RW static throughout the week. RW is usually measured taking this weeks high and low. Since this weeks high and low will change throughout the week, some might prefer to have a static range instead.')
showRWLabels = input.bool(group='Range Weekly Hi/Lo - RW Hi/Lo', title='Labels?', defval=true, inline='rw1')
showRWRange = input.bool(group='Range Weekly Hi/Lo - RW Hi/Lo', title='Range label?', defval=false, inline='rw1')
showRW_50 = input.bool(group='Range Weekly Hi/Lo - RW Hi/Lo', title='Show 50% RW?', defval=false, inline='rw1')
rwRange = input.int(group='Range Weekly Hi/Lo - RW Hi/Lo', title='RW length (weeks)?', defval=13, minval=1, maxval=52, step=1, inline='rw2', tooltip="Defaults taken from Trader At Home PVSRA documentation. This defines how many weeks back to take into consideration when calculating the RW")
rwColor = input.color(group='Range Weekly Hi/Lo - RW Hi/Lo', title='RW Color', defval=color.new(color.blue, 30), inline='rw3')
string rwStyleX = input.string(group='Range Weekly Hi/Lo - RW Hi/Lo', defval='Solid', title='RW Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='rw3')
rwStyle = rwStyleX == 'Dotted' ? line.style_dotted : (rwStyleX == 'Dashed' ? line.style_dashed : (rwStyleX == 'Solid' ? line.style_solid : line.style_dotted))

showAdrTable = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show ADR Table', inline='adrt', defval=true)
showAdrPips = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show ADR PIPS', inline='adrt', defval=true) and showAdrTable
showAdrCurrency = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show ADR Currency', inline='adrt', defval=false) and showAdrTable
showRDPips = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show RD PIPS', inline='adrt', defval=false) and showAdrTable
showRDCurrency = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show RD Currency', inline='adrt', defval=false) and showAdrTable
choiceAdrTable = input.string(group='ADR/ADRx3/AWR/AMR Table', title='ADR Table postion', inline='adrt', defval='top_right', options=['top_right', 'top_left', 'top_center', 'bottom_right', 'bottom_left', 'bottom_center'])
adrTableBgColor = input.color(group='ADR/ADRx3/AWR/AMR Table', title='ADR Table: Background Color', inline='adrtc', defval=color.rgb(93, 96, 107, 70))
adrTableTxtColor = input.color(group='ADR/ADRx3/AWR/AMR Table', title='Text Color', inline='adrtc', defval=color.rgb(31, 188, 211, 0))


/// market boxes and daily open only on intraday
bool show = timeframe.isminutes and timeframe.multiplier <= 240 and timeframe.multiplier >= 1
time_now_exchange = timestamp(year, month, dayofmonth, hour, minute, second)
bool show_dly = timeframe.isminutes  //and timeframe.multiplier < 240
bool show_rectangle9 = input.bool(group='Daily Open', defval=true, title='Show: line ?', inline='dopenconf') and show_dly
bool show_label9 = input.bool(group='Daily Open', defval=true, title='Label?', inline='dopenconf') and show_rectangle9 and show_dly
bool showallDly = input.bool(group='Daily Open', defval=false, title='Show historical daily opens?', inline='dopenconf')
color sess9col = input.color(group='Daily Open', title='Daily Open Color', defval=color.rgb(254, 234, 78, 0), inline='dopenconf1')

bool overridesym = input.bool(group='PVSRA', title='Override chart symbol?', defval=false, inline='pvsra')
string pvsra_sym = input.symbol(group='PVSRA', title='', defval='INDEX:BTCUSD', tooltip='You can use INDEX:BTCUSD or you can combine multiple feeds, for example \'(BINANCE:BTCUSDT+COINBASE:BTCUSD)\'. Note that adding too many will slow things down.', inline='pvsra')

string rectStyle = input.string(group='Market sessions', defval='Dashed', title='Line style of Market Session hi/lo line', options=['Dashed', 'Solid'])
sessLineStyle = line.style_dashed
bool show_markets = input.bool(true, group='Market sessions', title='Show Market Sessions?', tooltip='Turn on or off all market sessions') and show
bool show_markets_weekends = input.bool(false, group='Market sessions', title='Show Market Session on Weekends?', tooltip='Turn on or off market sessions in the weekends. Note do not turn this on for exchanges that dont have weekend data like OANDA') and show
string weekend_sessions = ':1234567'
string no_weekend_sessions = ':23456'

bool show_rectangle1 = input.bool(group='Market session: London (0800-1630 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session1conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label1 = input.bool(group='Market session: London (0800-1630 UTC+0) - DST Aware', defval=true, title='Label?', inline='session1conf') and show_rectangle1 and show_markets
bool show_or1 = input.bool(group='Market session: London (0800-1630 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session1conf', tooltip='This controls the shaded area for the session') and show_rectangle1 and show_markets
string sess1Label = input.string(group='Market session: London (0800-1630 UTC+0) - DST Aware', defval='London', title='Name:', inline='session1style')
color sess1col = input.color(group='Market session: London (0800-1630 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(120, 123, 134, 75), inline='session1style')
color sess1colLabel = input.color(group='Market session: London (0800-1630 UTC+0) - DST Aware', title='Label', defval=color.rgb(120, 123, 134, 0), inline='session1style')
string sess1TimeX = '0800-1630'//input.session(group='Market session: London (0800-1630 UTC+0)', defval='0800-1630', title='Time (UTC+0):', inline='session1style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST and times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess1Time = show_markets_weekends ? sess1TimeX + weekend_sessions : sess1TimeX + no_weekend_sessions


bool show_rectangle2 = input.bool(group='Market session: New York (1430-2100 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session2conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label2 = input.bool(group='Market session: New York (1430-2100 UTC+0) - DST Aware', defval=true, title='Label?', inline='session2conf') and show_rectangle2 and show_markets
bool show_or2 = input.bool(group='Market session: New York (1430-2100 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session2conf', tooltip='This controls the shaded area for the session') and show_rectangle2 and show_markets
string sess2Label = input.string(group='Market session: New York (1430-2100 UTC+0) - DST Aware', defval='NewYork', title='Name:', inline='session2style')
color sess2col = input.color(group='Market session: New York (1430-2100 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(251, 86, 91, 75), inline='session2style')
color sess2colLabel = input.color(group='Market session: New York (1430-2100 UTC+0) - DST Aware', title='Label', defval=color.rgb(253, 84, 87, 25), inline='session2style')
string sess2TimeX = '1430-2100'//input.session(group='Market session: New York (1430-2100 UTC+0)', defval='1430-2100', title='Time (UTC+0):', inline='session2style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess2Time = show_markets_weekends ? sess2TimeX + weekend_sessions : sess2TimeX  + no_weekend_sessions


bool show_rectangle3 = input.bool(group='Market session: Tokyo (0000-0600 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session3conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label3 = input.bool(group='Market session: Tokyo (0000-0600 UTC+0) - DST Aware', defval=true, title='Label?', inline='session3conf') and show_rectangle3 and show_markets
bool show_or3 = input.bool(group='Market session: Tokyo (0000-0600 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session3conf', tooltip='This controls the shaded area for the session') and show_rectangle3 and show_markets
string sess3Label = input.string(group='Market session: Tokyo (0000-0600 UTC+0) - DST Aware', defval='Tokyo', title='Name:', inline='session3style')
color sess3col = input.color(group='Market session: Tokyo (0000-0600 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(80, 174, 85, 75), inline='session3style')
color sess3colLabel = input.color(group='Market session: Tokyo (0000-0600 UTC+0) - DST Aware', title='Label', defval=color.rgb(80, 174, 85, 25), inline='session3style')
string sess3TimeX = '0000-0600'//input.session(group='Market session: Tokyo (0000-0600 UTC+0)', defval='0000-0600', title='Time (UTC+0):', inline='session3style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess3Time = show_markets_weekends ? sess3TimeX + weekend_sessions : sess3TimeX + no_weekend_sessions


bool show_rectangle4 = input.bool(group='Market session: Hong Kong (0130-0800 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session4conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label4 = input.bool(group='Market session: Hong Kong (0130-0800 UTC+0) - DST Aware', defval=true, title='Label?', inline='session4conf') and show_rectangle4 and show_markets
bool show_or4 = input.bool(group='Market session: Hong Kong (0130-0800 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session4conf', tooltip='This controls the shaded area for the session') and show_rectangle4 and show_markets
string sess4Label = input.string(group='Market session: Hong Kong (0130-0800 UTC+0) - DST Aware', defval='HongKong', title='Name:', inline='session4style')
color sess4col = input.color(group='Market session: Hong Kong (0130-0800 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(128, 127, 23, 75), inline='session4style')
color sess4colLabel = input.color(group='Market session: Hong Kong (0130-0800 UTC+0) - DST Aware', title='Label', defval=color.rgb(128, 127, 23, 25), inline='session4style')
string sess4TimeX = '0130-0800'//input.session(group='Market session: Hong Kong (0130-0800 UTC+0)', defval='0130-0800', title='Time (UTC+0):', inline='session4style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess4Time = show_markets_weekends ? sess4TimeX + weekend_sessions : sess4TimeX + no_weekend_sessions

bool show_rectangle5 = input.bool(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session5conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label5 = input.bool(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0) - DST Aware', defval=true, title='Label?', inline='session5conf') and show_rectangle5 and show_markets
bool show_or5 = input.bool(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session5conf', tooltip='This controls the shaded area for the session') and show_rectangle5 and show_markets
string sess5Label = input.string(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0) - DST Aware', defval='Sydney', title='Name:', inline='session5style')
color sess5col = input.color(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(37, 228, 123, 75), inline='session5style')
color sess5colLabel = input.color(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0) - DST Aware', title='Label', defval=color.rgb(37, 228, 123, 25), inline='session5style')
string sess5TimeX = '2200-0600'//input.session(group='Market session: Sydney (NZX+ASX 2200-0600 UTC+0)', defval='2200-0600', title='Time (UTC+0):', inline='session5style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess5Time = show_markets_weekends ? sess5TimeX + weekend_sessions : sess5TimeX + no_weekend_sessions

bool show_rectangle6 = input.bool(group='Market session: EU Brinks (0800-0900 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session6conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label6 = input.bool(group='Market session: EU Brinks (0800-0900 UTC+0) - DST Aware', defval=true, title='Label?', inline='session6conf') and show_rectangle6 and show_markets
bool show_or6 = input.bool(group='Market session: EU Brinks (0800-0900 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session6conf', tooltip='This controls the shaded area for the session') and show_rectangle6 and show_markets
string sess6Label = input.string(group='Market session: EU Brinks (0800-0900 UTC+0) - DST Aware', defval='EU Brinks', title='Name:', inline='session6style')
color sess6col = input.color(group='Market session: EU Brinks (0800-0900 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(255, 255, 255, 65), inline='session6style')
color sess6colLabel = input.color(group='Market session: EU Brinks (0800-0900 UTC+0) - DST Aware', title='Label', defval=color.rgb(255, 255, 255, 25), inline='session6style')
string sess6TimeX = '0800-0900'//input.session(group='Market session: EU Brinks (0800-0900 UTC+0)', defval='0800-0900', title='Time (UTC+0):', inline='session6style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess6Time = show_markets_weekends ? sess6TimeX + weekend_sessions : sess6TimeX + no_weekend_sessions

bool show_rectangle7 = input.bool(group='Market session: US Brinks (1400-1500 UTC+0) - DST Aware', defval=true, title='Show: session?', inline='session7conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label7 = input.bool(group='Market session: US Brinks (1400-1500 UTC+0) - DST Aware', defval=true, title='Label?', inline='session7conf') and show_rectangle7 and show_markets
bool show_or7 = input.bool(group='Market session: US Brinks (1400-1500 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session7conf', tooltip='This controls the shaded area for the session') and show_rectangle7 and show_markets
string sess7Label = input.string(group='Market session: US Brinks (1400-1500 UTC+0) - DST Aware', defval='US Brinks', title='Name:', inline='session7style')
color sess7col = input.color(group='Market session: US Brinks (1400-1500 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(255, 255, 255, 65), inline='session7style')
color sess7colLabel = input.color(group='Market session: US Brinks (1400-1500 UTC+0) - DST Aware', title='Label', defval=color.rgb(255, 255, 255, 25), inline='session7style')
string sess7TimeX = '1400-1500'//input.session(group='Market session: US Brinks (1400-1500 UTC+0)', defval='1400-1500', title='Time (UTC+0):', inline='session7style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess7Time = show_markets_weekends ? sess7TimeX + weekend_sessions : sess7TimeX + no_weekend_sessions

bool show_rectangle8 = input.bool(group='Market session: Frankfurt (0700-1630 UTC+0) - DST Aware', defval=false, title='Show: session?', inline='session8conf', tooltip='If this checkbox is off, Label and Open Range have no effect') and show_markets
bool show_label8 = input.bool(group='Market session: Frankfurt (0700-1630 UTC+0) - DST Aware', defval=true, title='Label?', inline='session8conf') and show_rectangle8 and show_markets
bool show_or8 = input.bool(group='Market session: Frankfurt (0700-1630 UTC+0) - DST Aware', defval=true, title='Opening Range?', inline='session8conf', tooltip='This controls the shaded area for the session') and show_rectangle8 and show_markets
string sess8Label = input.string(group='Market session: Frankfurt (0700-1630 UTC+0) - DST Aware', defval='Frankfurt', title='Name:', inline='session8style')
color sess8col = input.color(group='Market session: Frankfurt (0700-1630 UTC+0) - DST Aware', title='Color: Box', defval=color.rgb(253, 152, 39, 75), inline='session8style')
color sess8colLabel = input.color(group='Market session: Frankfurt (0700-1630 UTC+0) - DST Aware', title='Label', defval=color.rgb(253, 152, 39, 25), inline='session8style')
string sess8TimeX = '0700-1630'//input.session(group='Market session: Frankfurt (0700-1630 UTC+0)', defval='0700-1630', title='Time (UTC+0):', inline='session8style', tooltip='Normally you will not want to adjust these times. Defaults are taken as if the session is NOT in DST times must be in UTC+0. Note due to limitations of pinescript some values sellected here other than the default might not work correctly on all exchanges.')
sess8Time = show_markets_weekends ? sess8TimeX + weekend_sessions : sess8TimeX + no_weekend_sessions


bool showPsy = timeframe.isminutes and (timeframe.multiplier == 60 or timeframe.multiplier == 30 or timeframe.multiplier == 15 or timeframe.multiplier == 5 or timeframe.multiplier == 3 or timeframe.multiplier == 1)   
bool show_psylevels = input.bool(group='Weekly Psy Levels (valid tf 1h/30min/15min/5min/3min/1min)', defval=true, title='Show: Levels?', inline='psyconf') and showPsy
bool show_psylabel = input.bool(group='Weekly Psy Levels (valid tf 1h/30min/15min/5min/3min/1min)', defval=true, title='Labels?', inline='psyconf', tooltip="The Psy High/Low will only show on these timeframes: 1h/30min/15min/5min/3min/1min. It is disabled on all others. This is because the calculation requires a candle to start at the correct time for Sydney/Tokyo but in other timeframes the data does not have values at the designated time for the Sydney/Tokyo sessions.") and show_psylevels
bool showallPsy = input.bool(group='Weekly Psy Levels (valid tf 1h/30min/15min/5min/3min/1min)', defval=false, title='Show historical psy levels?', inline='psyconf') and show_psylevels
color psycolH = input.color(group='Weekly Psy Levels (valid tf 1h/30min/15min/5min/3min/1min)', title='Psy Hi Color', defval=color.new(color.orange, 30), inline='psyconf1') 
color psycolL = input.color(group='Weekly Psy Levels (valid tf 1h/30min/15min/5min/3min/1min)', title='Psy Low Color', defval=color.new(color.orange, 30), inline='psyconf1') 
string psyType = input.string(group='Weekly Psy Levels (valid tf 1h/30min/15min/5min/3min/1min)', defval='crypto', title='Psy calc type', options=['crypto', 'forex'], inline='psyconf12', tooltip="Are you looking at Crypto or Forex? Crypto calculations start with the Sydney session on Saturday night. Forex calculations start with the Tokyo session on Monday morning. Note some exchanges like Oanda do not have sessions on the weekends so you might be forced to select Forex for exchanges like Oanda even when looking at symbols like BITCOIN on Oanda.")

showDstTable = input.bool(group='Daylight Saving Time Info (DST)', title='Show DST Table : ', inline='dstt', defval=false)
choiceDstTable = input.string(group='Daylight Saving Time Info (DST)', title='DST Table postion', inline='dstt', defval='bottom_center', options=['top_right', 'top_left', 'top_center', 'bottom_right', 'bottom_left', 'bottom_center'])
dstTableBgColor = input.color(group='Daylight Saving Time Info (DST)', title='DST Table: Background Color', inline='dsttc', defval=color.rgb(93, 96, 107, 70))
dstTableTxtColor = input.color(group='Daylight Saving Time Info (DST)', title='Text Color', inline='dsttc', defval=color.rgb(31, 188, 211, 0))



//Non repainting security
f_security(_symbol, _res, _src, _repaint) =>
    request.security(_symbol, _res, _src[_repaint ? 0 : barstate.isrealtime ? 1 : 0])[_repaint ? 0 : barstate.isrealtime ? 0 : 1]


// Basic vars (needed in functions)

// Only render intraday
validTimeFrame = timeframe.isintraday == true

// If above the 5 minute, we start drawing yesterday. below, we start today
levelsstart = timeframe.isseconds == true or timeframe.isminutes == true and timeframe.multiplier < 5 ? time('D') : time('D') - 86400 * 1000
//levelsstartbar = ta.barssince(levelsstart)


// Functions
// new_bar: check if we're on a new bar within the session in a given resolution
new_bar(res) =>
    ta.change(time(res)) != 0

// adr: Calculate average daily range for a given length
adr(length, barsBack) =>
    // This is effectively an atr, which is what is used in MT4 to get those levels. FWIW, true range can be also calculated with tr(true)
    trueRange = na(high[1]) ? high - low : math.max(math.max(high - low, math.abs(high - close[1])), math.abs(low - close[1]))
    // Switched to SMA from RMA because somehow it matches MT4 better
    ta.sma(trueRange[barsBack], length)
    
    

// adr_high: Calculate the ADR high given an ADR
adr_high(adr, from_do) =>
    retVal = 0.0
    if not from_do
        retVal := high - low < adr ? low + adr : close >= open ? low + adr : high
    else
        retVal := open + adr
    retVal

// adr_low: Calculate the ADR low given an ADR
adr_low(adr, from_do) =>
    retVal = 0.0
    if not from_do
        retVal := high - low < adr ? high - adr : close >= open ? low : high - adr
    else
        retVal := open - adr
    retVal
    
    

// to_pips: Convert to pips
to_pips(val) =>
    pipSizeCalc = syminfo.mintick * (syminfo.type == "forex" ? 10 : 1)
    returnVal = val/pipSizeCalc
    returnVal
    

pivot_label_x_offset = time_close + pivot_offset_input * timeframe.multiplier * 60 * 1000
label_x_offset = time_close + label_offset_input * timeframe.multiplier * 60 * 1000
adr_label_x_offset = time_close + adr_offset_input * timeframe.multiplier * 60 * 1000
adr_label_x_offset_50 = time_close + adr_offset_input_50 * timeframe.multiplier * 60 * 1000
rd_label_x_offset = time_close + rd_offset_input * timeframe.multiplier * 60 * 1000
rd_label_x_offset_50 = time_close + rd_offset_input_50 * timeframe.multiplier * 60 * 1000

//Right_Label
r_label(ry, rtext, rstyle, rcolor, valid) =>
    var label rLabel = na
    if valid and barstate.isrealtime
        rLabel := label.new(x=label_x_offset, y=ry, text=rtext, xloc=xloc.bar_time, style=rstyle, textcolor=rcolor, textalign=text.align_right)
        label.delete(rLabel[1])
    rLabel

//Right_Label
r_label_offset(ry, rtext, rstyle, rcolor, valid, labelOffset) =>
    if valid and barstate.isrealtime
        rLabel = label.new(x=labelOffset, y=ry, text=rtext, xloc=xloc.bar_time, style=rstyle, textcolor=rcolor, textalign=text.align_right)
        label.delete(rLabel[1])

draw_line(x_series, res, tag, xColor, xStyle, xWidth, xExtend, isLabelValid, xLabelOffset) =>
    var line x_line = na

    if validTimeFrame and new_bar(res) //and barstate.isnew
        x_line := line.new(bar_index, x_series, bar_index+1, x_series, extend=xExtend, color=xColor, style=xStyle, width=xWidth)
        line.delete(x_line[1])

    if not na(x_line) and not new_bar(res)//and line.get_x2(x_line) != bar_index
        line.set_x2(x_line, bar_index)
        line.set_y1(x_line,x_series)
        line.set_y2(x_line,x_series)

    if isLabelValid  //showADRLabels and validTimeFrame
        x_label = label.new(xLabelOffset, x_series, tag, xloc=xloc.bar_time, style=label.style_none, textcolor=xColor)
        label.delete(x_label[1])

draw_line_DO(x_series, res, tag, xColor, xStyle, xWidth, xExtend, isLabelValid, xLabelOffset) =>
    var line x_line = na

    if new_bar(res) and validTimeFrame
        line.set_x2(x_line, bar_index)
        line.set_extend(x_line, extend.none)

        x_line := line.new(bar_index, x_series, bar_index, x_series, extend=xExtend, color=xColor, style=xStyle, width=xWidth)
        line.delete(x_line[1])

    if not na(x_line) and line.get_x2(x_line) != bar_index
        line.set_x2(x_line, bar_index)

    if isLabelValid  //showADRLabels and validTimeFrame
        x_label = label.new(xLabelOffset, x_series, tag, xloc=xloc.bar_time, style=label.style_none, textcolor=xColor)
        label.delete(x_label[1])
        
draw_pivot(pivot_level, res, tag, pivotColor, pivotLabelColor, pivotStyle, pivotWidth, pivotExtend, isLabelValid) =>
    var line pivot_line = na

    // Start drawing yesterday
    if validTimeFrame and new_bar(res)//and barstate.isnew
        //line.set_x2(pivot_line, bar_index)
        //line.set_extend(pivot_line, extend.none)
        pivot_line := line.new(bar_index, pivot_level, bar_index, pivot_level, extend=pivotExtend, color=pivotColor, style=pivotStyle, width=pivotWidth)
        line.delete(pivot_line[1])
    if not na(pivot_line) and not new_bar(res)//line.get_x2(pivot_line) != bar_index
        line.set_x2(pivot_line, bar_index)
        line.set_y1(pivot_line,pivot_level)
        line.set_y2(pivot_line,pivot_level)
    if isLabelValid  //showADRLabels and validTimeFrame
        pivot_label = label.new(pivot_label_x_offset, pivot_level, tag, xloc=xloc.bar_time, style=label.style_none, textcolor=pivotLabelColor, textalign=text.align_right)

        label.delete(pivot_label[1])
    if not barstate.islast
        line.set_x2(pivot_line, x=bar_index)
    else
        line.set_xloc(pivot_line, levelsstart, time_close + 1 * 86400000, xloc=xloc.bar_time)
    pivot_line
    




//Emas
oneEmaLength = 50
twoEmaLength = 200



oneEma = ta.ema(close, oneEmaLength)
plot(showEmas ? oneEma : na, color=oneEmaColor, title='50 Ema')

twoEma = ta.ema(close, twoEmaLength)
plot(showEmas ? twoEma : na, color=twoEmaColor, title='200 Ema')


//Label emas


r_label(oneEma, '50 Ema', label.style_none, oneEmaColor, labelEmas)  //ry, rtext, rstyle, rcolor,valid
r_label(twoEma, '200 Ema', label.style_none, twoEmaColor, labelEmas)




// Get Daily price data
dayHigh = f_security(syminfo.tickerid, 'D', high, false)
dayLow = f_security(syminfo.tickerid, 'D', low, false)
dayOpen = f_security(syminfo.tickerid, 'D', open, false)
dayClose = f_security(syminfo.tickerid, 'D', close, false)

//Compute Values
pivotPoint = (dayHigh + dayLow + dayClose) / 3

// Updated 2021-03-25 by infernix
pivR1 = 2 * pivotPoint - dayLow
pivS1 = 2 * pivotPoint - dayHigh
pivR2 = pivotPoint - pivS1 + pivR1
pivS2 = pivotPoint - pivR1 + pivS1
pivR3 = 2 * pivotPoint + dayHigh - 2 * dayLow
pivS3 = 2 * pivotPoint - (2 * dayHigh - dayLow)

//Plot Values
//plot(validTimeFrame and showLevelOnePivotPoints? pivotPoint : na, linewidth = 1, color = color.yellow, style = plot.style_circles, transp = 25, title = "Daily Pivot Point", show_last = plot_bars)

pivline = draw_pivot(validTimeFrame and (showLevelOnePivotPoints or showLevelTwoPivotPoints or showLevelThreePivotPoints or activeM) ? pivotPoint : na, 'D', 'PP', pivotColor, pivotLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showPivotLabels and validTimeFrame)
pivr1line = draw_pivot(validTimeFrame and showLevelOnePivotPoints ? pivR1 : na, 'D', 'R1', color.new(color.green, 50), color.new(color.green, 50), rsStyle, 1, extendPivots ? extend.both : extend.right, showLevelOnePivotPoints and showPivotLabels and validTimeFrame)
pivs1line = draw_pivot(validTimeFrame and showLevelOnePivotPoints ? pivS1 : na, 'D', 'S1', color.new(color.red, 50), color.new(color.red, 50), rsStyle, 1, extendPivots ? extend.both : extend.right, showLevelOnePivotPoints and showPivotLabels and validTimeFrame)
pivr2line = draw_pivot(validTimeFrame and showLevelTwoPivotPoints ? pivR2 : na, 'D', 'R2', color.new(color.green, 50), color.new(color.green, 50), rsStyle, 1, extendPivots ? extend.both : extend.right, showLevelTwoPivotPoints and showPivotLabels and validTimeFrame)
pivs2line = draw_pivot(validTimeFrame and showLevelTwoPivotPoints ? pivS2 : na, 'D', 'S2', color.new(color.red, 50), color.new(color.red, 50), rsStyle, 1, extendPivots ? extend.both : extend.right, showLevelTwoPivotPoints and showPivotLabels and validTimeFrame)
pivr3line = draw_pivot(validTimeFrame and showLevelThreePivotPoints ? pivR3 : na, 'D', 'R3', color.new(color.green, 50), color.new(color.green, 50), rsStyle, 1, extendPivots ? extend.both : extend.right, showLevelThreePivotPoints and showPivotLabels and validTimeFrame)
pivs3line = draw_pivot(validTimeFrame and showLevelThreePivotPoints ? pivS3 : na, 'D', 'S3', color.new(color.red, 50), color.new(color.red, 50), rsStyle, 1, extendPivots ? extend.both : extend.right, showLevelThreePivotPoints and showPivotLabels and validTimeFrame)


// Daily H/L 

weekHigh = f_security(syminfo.tickerid, 'W', high, false)
weekLow = f_security(syminfo.tickerid, 'W', low, false)

validDHLTimeFrame = timeframe.isintraday == true
validWHLTimeFrame = timeframe.isintraday == true or timeframe.isdaily == true
isToday = year(timenow) == year(time) and month(timenow) == month(time) and dayofmonth(timenow) == dayofmonth(time)
isThisWeek = year(timenow) == year(time) and weekofyear(timenow) == weekofyear(time)


plot(validDHLTimeFrame and showDayHighLow and (showDayHighLow ? true : isToday) ? dayHigh : na, linewidth=2, color=color.new(color.blue, 50), style=plot.style_stepline, title="YDay Hi")
plot(validDHLTimeFrame and showDayHighLow and (showDayHighLow ? true : isToday) ? dayLow : na, linewidth=2, color=color.new(color.blue, 50), style=plot.style_stepline, title="YDay Lo")
r_label(dayHigh, 'YDay Hi', label.style_none, color.blue, validDHLTimeFrame and showDayHighLow and showDayHighLowLabels)  //ry, rtext, rstyle, rcolor, valid
r_label(dayLow, 'YDay Lo', label.style_none, color.blue, validDHLTimeFrame and showDayHighLow and showDayHighLowLabels)

plot(validWHLTimeFrame and showWeekHighLow and (showWeekHighLow ? true : isThisWeek) ? weekHigh : na, linewidth=2, color=color.new(color.green, 60), style=plot.style_stepline, title="LWeek Hi")
plot(validWHLTimeFrame and showWeekHighLow and (showWeekHighLow ? true : isThisWeek) ? weekLow : na, linewidth=2, color=color.new(color.green, 60), style=plot.style_stepline, title="LWeek Lo")

r_label(weekHigh, 'LWeek Hi', label.style_none, color.green, validWHLTimeFrame and showWeekHighLow and showDayHighLowLabels)  //ry, rtext, rstyle, rcolor, valid
r_label(weekLow, 'LWeek Lo', label.style_none, color.green, validWHLTimeFrame and showWeekHighLow and showDayHighLowLabels)

// PVSRA
// From MT4 source:

//   Situation "Climax"
//   Bars with volume >= 200% of the average volume of the 10 previous chart TFs, and bars
//   where the product of candle spread x candle volume is >= the highest for the 10 previous
//   chart time TFs.
//   Default Colors:  Bull bars are green and bear bars are red.

//   Situation "Volume Rising Above Average"
//   Bars with volume >= 150% of the average volume of the 10 previous chart TFs.
//   Default Colors:  Bull bars are blue and bear are blue-violet.

// We want to be able to override where we get the volume data for the candles.


pvsra_security(sresolution, sseries) =>
    request.security(overridesym ? pvsra_sym : syminfo.tickerid, sresolution, sseries[barstate.isrealtime ? 1 : 0], barmerge.gaps_off, barmerge.lookahead_off)
pvsra_security_1 = pvsra_security('', volume)
pvsra_volume = overridesym == true ? pvsra_security_1 : volume
pvsra_security_2 = pvsra_security('', high)
pvsra_high = overridesym == true ? pvsra_security_2 : high
pvsra_security_3 = pvsra_security('', low)
pvsra_low = overridesym == true ? pvsra_security_3 : low
pvsra_security_4 = pvsra_security('', close)
pvsra_close = overridesym == true ? pvsra_security_4 : close
pvsra_security_5 = pvsra_security('', open)
pvsra_open = overridesym == true ? pvsra_security_5 : open


r_label(high - (high - low) / 2, 'PVSRA Override Active!', label.style_none, color.orange, overridesym)  //ry, rtext, rstyle, rcolor, valid

//label.new(overridesym ? 0 : na, low, text = "PVSRA Override: " + pvsra_sym, xloc = xloc.bar_index, yloc=yloc.belowbar,style=label.style_label_down, size=size.huge)

// The below math matches MT4 PVSRA indicator source
// average volume from last 10 candles
sum_1 = math.sum(pvsra_volume, 10)
sum_2 = math.sum(volume, 10)
av = overridesym == true ? sum_1 / 10 : sum_2 / 10
//climax volume on the previous candle
value2 = overridesym == true ? pvsra_volume * (pvsra_high - pvsra_low) : volume * (high - low)
// highest climax volume of the last 10 candles
hivalue2 = ta.highest(value2, 10)
// VA value determines the bar color. va = 0: normal. va = 1: climax.  va = 2: rising
iff_1 = pvsra_volume >= av * 1.5 ? 2 : 0
iff_2 = pvsra_volume >= av * 2 or value2 >= hivalue2 ? 1 : iff_1
iff_3 = volume >= av * 1.5 ? 2 : 0
iff_4 = volume >= av * 2 or value2 >= hivalue2 ? 1 : iff_3
va = overridesym == true ? iff_2 : iff_4

// Bullish or bearish coloring
isBull = overridesym == true ? pvsra_close > pvsra_open : close > open

CUColor = color.lime  // Climax up (bull) bull and bear both start with b so it would be weird hence up down
CDColor = color.red  // Climax down (bear)

AUColor = color.blue  //Avobe average up (bull)
ADColor = color.fuchsia  //Above average down (bear))

NUColor = #999999
NDColor = #4d4d4d



// candleColor = iff(climax,iff(isBull,CUColor,CDColor),iff(aboveA,iff(isBull,AUColor,ADColor),iff(isBull,NUColor,NDColor)))
iff_5 = va == 2 ? AUColor : NUColor
iff_6 = va == 1 ? CUColor : iff_5
iff_7 = va == 2 ? ADColor : NDColor
iff_8 = va == 1 ? CDColor : iff_7
candleColor = isBull ? iff_6 : iff_8
barcolor(candleColor)

alertcondition(va > 0, title='Alert on Any Vector Candle', message='{{ticker}} Vector Candle on the {{interval}}')

alertcondition(candleColor == color.lime, title='Green Vector Candle', message='{{ticker}} Green Vector Candle on the {{interval}} Note: alert triggers in real time before the candle is closed unless you choose "once per bar close" option - ie the alert might trigger at some point and the pa after that could change the vector color completely. Use with caution.')
alertcondition(candleColor == color.red, title='Red Vector Candle', message='{{ticker}} Red Vector Candle on the {{interval}} Note: alert triggers in real time before the candle is closed unless you choose "once per bar close" option- ie the alert might trigger at some point and the pa after that could change the vector color completely. Use with caution.')
alertcondition(candleColor == color.blue, title='Blue Vector Candle', message='{{ticker}} Blue Vector Candle on the {{interval}} Note: alert triggers in real time before the candle is closed unless you choose "once per bar close" option- ie the alert might trigger at some point and the pa after that could change the vector color completely. Use with caution.')
alertcondition(candleColor == color.fuchsia, title='Purple Vector Candle', message='{{ticker}} Purple Vector Candle on the {{interval}} Note: alert triggers in real time before the candle is closed unless you choose "once per bar close" option- ie the alert might trigger at some point and the pa after that could change the vector color completely. Use with caution.')

redGreen = candleColor ==  color.lime and candleColor[1] == color.red
greenRed = candleColor ==  color.red and candleColor[1] == color.lime
redBlue = candleColor ==  color.blue and candleColor[1] == color.red
blueRed = candleColor ==  color.red and candleColor[1] == color.blue
greenPurpule = candleColor ==  color.fuchsia and candleColor[1] == color.lime
purpleGreen = candleColor ==  color.lime and candleColor[1] == color.fuchsia
bluePurpule = candleColor ==  color.fuchsia and candleColor[1] == color.blue
purpleBlue = candleColor ==  color.blue and candleColor[1] == color.fuchsia
alertcondition(redGreen, title='Red/Green Vector Candle Pattern', message='{{ticker}} Red/Green Vector Candle Pattern on the {{interval}}')
alertcondition(greenRed, title='Green/Red Vector Candle Pattern', message='{{ticker}} Green/Red Vector Candle Pattern on the {{interval}}')
alertcondition(redBlue, title='Red/Blue Vector Candle Pattern', message='{{ticker}} Red/Blue Vector Candle Pattern on the {{interval}}')
alertcondition(blueRed, title='Blue/Red Vector Candle Pattern', message='{{ticker}} Blue/Red Vector Candle Pattern on the {{interval}}')
alertcondition(greenPurpule, title='Green/Purple Vector Candle Pattern', message='{{ticker}} Green/Purple Vector Candle Pattern on the {{interval}}')
alertcondition(purpleGreen, title='Purple/Green Vector Candle Pattern', message='{{ticker}} Purple/Green Vector Candle Pattern on the {{interval}}')
alertcondition(bluePurpule, title='Blue/Purple Vector Candle Pattern', message='{{ticker}} Blue/Purple Vector Candle Pattern on the {{interval}}')
alertcondition(purpleBlue, title='Purple/Blue Vector Candle Pattern', message='{{ticker}} Purple/Blue Vector Candle Pattern on the {{interval}}')


//ADR
// Daily ADR

day_adr = request.security(syminfo.tickerid, 'D', adr(aDRRange,1), lookahead=barmerge.lookahead_on)
day_adr_high = request.security(syminfo.tickerid, 'D', showADR_DO ? adr_high(day_adr, true) : adr_high(day_adr, false), lookahead=barmerge.lookahead_on)
day_adr_low = request.security(syminfo.tickerid, 'D',  showADR_DO ? adr_low(day_adr, true) : adr_low(day_adr, false), lookahead=barmerge.lookahead_on)
day_adr_high_50 = day_adr_high - (day_adr/2)
day_adr_low_50 = day_adr_low + (day_adr/2)
    
if showADR
    string hl = 'Hi-ADR'+ (showADR_DO?'(DO)':'')
    string ll = 'Lo-ADR'+ (showADR_DO?'(DO)':'')
    draw_line(day_adr_high, 'D', hl, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset)
    draw_line(day_adr_low, 'D', ll, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset)
    r_label_offset((day_adr_high + day_adr_low) / 2, 'ADR ' + str.format('{0,number,#.##}', to_pips(day_adr)) + 'PIPS|' + str.tostring(day_adr, format.mintick) + syminfo.currency, label.style_none, adrColor, showADRLabels and validTimeFrame and showADRRange, adr_label_x_offset)  //ry, rtext, rstyle, rcolor, valid

if showADR and showADR_50
    string hl = '50% Hi-ADR'+ (showADR_DO?'(DO)':'')
    string ll = '50% Lo-ADR'+ (showADR_DO?'(DO)':'')
    draw_line(day_adr_high_50, 'D', hl, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset_50)
    draw_line(day_adr_low_50, 'D', ll, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset_50)
    r_label_offset((day_adr_high_50 + day_adr_low_50) / 2, '50% ADR ' + str.format('{0,number,#.##}', to_pips(day_adr/2)) + 'PIPS|' + str.tostring(day_adr/2, format.mintick) + syminfo.currency, label.style_none, adrColor, showADRLabels and validTimeFrame and showADRRange, adr_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid
    
alertcondition(close >= day_adr_high and day_adr_high != 0.0 , "ADR High reached", "PA has reached the calculated ADR High")
alertcondition(close <= day_adr_low and day_adr_low != 0.0 , "ADR Low reached", "PA has reached the calculated ADR Low")
alertcondition(close >= day_adr_high_50 and day_adr_high_50 != 0.0 , "50% of ADR High reached", "PA has reached 50% of the calculated ADR High")
alertcondition(close <= day_adr_low_50 and day_adr_low_50 != 0.0 , "50% ADR Low reached", "PA has reached 50% the calculated ADR Low")


//Weekly ADR    
week_adr = request.security(syminfo.tickerid, 'W', adr(aWRRange,1), lookahead=barmerge.lookahead_on)
week_adr_high = request.security(syminfo.tickerid, 'W', showAWR_WO ? adr_high(week_adr, true) : adr_high(week_adr, false), lookahead=barmerge.lookahead_on)
week_adr_low = request.security(syminfo.tickerid, 'W', showAWR_WO ?  adr_low(week_adr, true) : adr_low(week_adr, false), lookahead=barmerge.lookahead_on)
week_adr_high_50 = week_adr_high - (week_adr/2)
week_adr_low_50 = week_adr_low + (week_adr/2)

if showAWR
    string hl = 'Hi-AWR'+ (showAWR_WO?'(WO)':'')
    string ll = 'Lo-AWR'+ (showAWR_WO?'(WO)':'')
    draw_line(week_adr_high, 'W', hl, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset)
    draw_line(week_adr_low, 'W', ll, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset)
    r_label_offset((week_adr_high + week_adr_low) / 2, 'AWR ' + str.format('{0,number,#.##}', to_pips(week_adr)) + 'PIPS|' + str.tostring(week_adr, format.mintick) + syminfo.currency, label.style_none, awrColor, showAWRLabels and validTimeFrame and showAWRRange, adr_label_x_offset)  //ry, rtext, rstyle, rcolor, valid
if showAWR and showAWR_50
    string hl = '50% Hi-AWR'+ (showAWR_WO?'(WO)':'')
    string ll = '50% Lo-AWR'+ (showAWR_WO?'(WO)':'')
    draw_line(week_adr_high_50, 'W', hl, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset_50)
    draw_line(week_adr_low_50, 'W', ll, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset_50)
    r_label_offset((week_adr_high_50 + week_adr_low_50) / 2, '50% AWR ' + str.format('{0,number,#.##}', to_pips(week_adr/2)) + 'PIPS|' + str.tostring(week_adr/2, format.mintick) + syminfo.currency, label.style_none, awrColor, showAWRLabels and validTimeFrame and showAWRRange, adr_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid

alertcondition(close >= week_adr_high and week_adr_high != 0 , "AWR High reached", "PA has reached the calculated AWR High")
alertcondition(close <= week_adr_low and week_adr_low != 0 , "AWR Low reached", "PA has reached the calculated AWR Low")
alertcondition(close >= week_adr_high_50 and week_adr_high_50 != 0 , "50% of AWR High reached", "PA has reached 50% of the calculated AWR High")
alertcondition(close <= week_adr_low_50 and week_adr_low_50 != 0 , "50% AWR Low reached", "PA has reached 50% of the calculated AWR Low")


//Monthly ADR 
month_adr = request.security(syminfo.tickerid, 'M', adr(aMRRange,1), lookahead=barmerge.lookahead_on)
month_adr_high = request.security(syminfo.tickerid, 'M', showAMR_MO ? adr_high(month_adr, true) : adr_high(month_adr, false), lookahead=barmerge.lookahead_on)
month_adr_low = request.security(syminfo.tickerid, 'M', showAMR_MO ? adr_low(month_adr, true) : adr_low(month_adr, false), lookahead=barmerge.lookahead_on)
month_adr_high_50 = month_adr_high - (month_adr/2)
month_adr_low_50 = month_adr_low + (month_adr/2)

if showAMR and timeframe.isminutes and timeframe.multiplier >= 3
    string hl = 'Hi-AMR'+ (showAMR_MO?'(MO)':'')
    string ll = 'Lo-AMR'+ (showAMR_MO?'(MO)':'')
    draw_line(month_adr_high, 'M', hl, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset)
    draw_line(month_adr_low, 'M', ll, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset)
    r_label_offset((month_adr_high + month_adr_low) / 2, 'AMR ' + str.format('{0,number,#.##}', to_pips(month_adr)) + 'PIPS|' + str.tostring(month_adr, format.mintick) + syminfo.currency, label.style_none, amrColor, showAMRLabels and validTimeFrame and showAMRRange,adr_label_x_offset)  //ry, rtext, rstyle, rcolor, valid
if showAMR and showAMR_50 and timeframe.isminutes and timeframe.multiplier >= 3
    string hl = '50% Hi-AMR'+ (showAMR_MO?'(MO)':'')
    string ll = '50% Lo-AMR'+ (showAMR_MO?'(MO)':'')
    draw_line(month_adr_high_50, 'M', hl, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset_50)
    draw_line(month_adr_low_50, 'M', ll, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset_50)
    r_label_offset((month_adr_high_50 + month_adr_low_50) / 2, '50% AMR ' + str.format('{0,number,#.##}', to_pips(month_adr/2)) + 'PIPS|' + str.tostring(month_adr/2, format.mintick) + syminfo.currency, label.style_none, amrColor, showAMRLabels and validTimeFrame and showAMRRange,adr_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid

alertcondition(close >= month_adr_high and month_adr_high != 0 , "AMR High reached", "PA has reached the calculated AMR High")
alertcondition(close <= month_adr_low and month_adr_low != 0 , "AMR Low reached", "PA has reached the calculated AMR Low")
alertcondition(close >= month_adr_high_50 and month_adr_high_50 != 0 , "50% of AMR High reached", "PA has reached 50% of the calculated AMR High")
alertcondition(close <= month_adr_low_50 and month_adr_low_50 != 0 , "50% of AMR Low reached", "PA has reached 50% of the calculated AMR Low")


//Range Daily Hi/Lo
day_rd = request.security(syminfo.tickerid, 'D', adr(rdRange, 1), lookahead=barmerge.lookahead_on)
day_range_high = request.security(syminfo.tickerid, 'D', showRD_DO ? adr_high(day_rd, true) : adr_high(day_rd, false), lookahead=barmerge.lookahead_on)
day_range_low = request.security(syminfo.tickerid, 'D', showRD_DO ? adr_low(day_rd, true) : adr_low(day_rd, false), lookahead=barmerge.lookahead_on)
day_range_high_50 = day_range_high - (day_rd/2)
day_range_low_50 = day_range_low + (day_rd/2)

if showRD
    string hl = 'RD-Hi'+ (showRD_DO?'(DO)':'')
    string ll = 'RD-Lo'+ (showRD_DO?'(DO)':'')
    draw_line(day_range_high, 'D', hl, rdColor, rdStyle, 2, extend.right, showRDLabels and validTimeFrame, rd_label_x_offset)
    draw_line(day_range_low, 'D', ll, rdColor, rdStyle, 2, extend.right, showRDLabels and validTimeFrame, rd_label_x_offset)
    r_label_offset((day_range_high + day_range_low) / 2, 'RD ' + str.format('{0,number,#.##}', to_pips(day_rd)) + 'PIPS|' + str.tostring(day_rd/2, format.mintick) + syminfo.currency, label.style_none, rdColor, showRDLabels and validTimeFrame and showRDRange, rd_label_x_offset)  //ry, rtext, rstyle, rcolor, valid
if showRD and showRD_50
    string hl = '50% RD-Hi'+ (showRD_DO?'(DO)':'')
    string ll = '50% RD-Lo'+ (showRD_DO?'(DO)':'')
    draw_line(day_range_high_50, 'D', hl, rdColor, rdStyle, 2, extend.right, showRDLabels and validTimeFrame, rd_label_x_offset_50)
    draw_line(day_range_low_50, 'D', ll, rdColor, rdStyle, 2, extend.right, showRDLabels and validTimeFrame, rd_label_x_offset_50)
    r_label_offset((day_range_high_50 + day_range_high_50) / 2, '50% RD ' + str.format('{0,number,#.##}', to_pips(day_rd/2)) + 'PIPS|' + str.tostring(day_rd/2, format.mintick) + syminfo.currency, label.style_none, rdColor, showRDLabels and validTimeFrame and showRDRange, rd_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid
  
alertcondition(close >= day_range_high and day_range_high != 0 , "Range Daily High reached", "PA has reached the calculated Range Daily High")
alertcondition(close <= day_range_low and day_range_low != 0 , "Range Daily Low reached", "PA has reached the calculated Range Daily Low")
alertcondition(close >= day_range_high_50 and day_range_high_50 != 0 , "50% of Range Daily High reached", "PA has reached 50% of the calculated Range Daily High")
alertcondition(close <= day_range_low_50 and day_range_low_50 != 0 , "50% of Range Daily Low reached", "PA has reached 50% of the calculated Range Daily Low")


//Range Weekly Hi/Lo
week_rd = request.security(syminfo.tickerid, 'W', adr(rwRange, 1), lookahead=barmerge.lookahead_on)
week_range_high = request.security(syminfo.tickerid, 'W', showRW_WO ? adr_high(week_rd, true) : adr_high(week_rd, false), lookahead=barmerge.lookahead_on)
week_range_low = request.security(syminfo.tickerid, 'W', showRW_WO ? adr_low(week_rd, false) : adr_low(week_rd, false), lookahead=barmerge.lookahead_on)
week_range_high_50 = week_range_high - (week_rd/2)
week_range_low_50 = week_range_low + (week_rd/2)

if showRW
    string hl = 'RW-Hi'+ (showRW_WO?'(WO)':'')
    string ll = 'RW-Lo'+ (showRW_WO?'(WO)':'')
    draw_line(week_range_high, 'D', hl, rwColor, rwStyle, 2, extend.right, showRWLabels and validTimeFrame, rd_label_x_offset)
    draw_line(week_range_low, 'D', ll, rwColor, rwStyle, 2, extend.right, showRWLabels and validTimeFrame, rd_label_x_offset)
    r_label_offset((week_range_high + week_range_low) / 2, 'RW ' + str.format('{0,number,#.##}', to_pips(week_rd)) + 'PIPS|' + str.tostring(week_rd/2, format.mintick) + syminfo.currency, label.style_none, rwColor, showRWLabels and validTimeFrame and showRWRange,rd_label_x_offset)  //ry, rtext, rstyle, rcolor, valid
if showRW and showRW_50
    string hl = '50% RW-Hi'+ (showRW_WO?'(WO)':'')
    string ll = '50% RW-Lo'+ (showRW_WO?'(WO)':'')
    draw_line(week_range_high_50, 'D', hl, rwColor, rwStyle, 2, extend.right, showRWLabels and validTimeFrame, rd_label_x_offset_50)
    draw_line(week_range_low_50, 'D', ll, rwColor, rwStyle, 2, extend.right, showRWLabels and validTimeFrame, rd_label_x_offset_50)
    r_label_offset((week_range_high_50 + week_range_low_50) / 2, '50% RW ' + str.format('{0,number,#.##}', to_pips(week_rd/2)) + 'PIPS|' + str.tostring(week_rd/2, format.mintick) + syminfo.currency, label.style_none, rwColor, showRWLabels and validTimeFrame and showRWRange, rd_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid
 
alertcondition(close >= week_range_high and week_range_high != 0 , "Range Weekly High reached", "PA has reached the calculated Range Weekly High")
alertcondition(close <= week_range_low and week_range_low != 0 , "Range Weekly Low reached", "PA has reached the calculated Range Weekly Low")
alertcondition(close >= week_range_high_50 and week_range_high_50 != 0 , "50% of Range Weekly High reached", "PA has reached 50% of the calculated Range Weekly High")
alertcondition(close <= week_range_low_50 and week_range_low_50 != 0 , "50% of Range Weekly Low reached", "PA has reached 50% of the calculated Range Weekly Low")



if barstate.islast and showAdrTable and validTimeFrame

    if showAdrPips or showAdrCurrency
        var table panel = table.new(choiceAdrTable, 2, 16, bgcolor=adrTableBgColor)
        // Table header.
        table.cell(panel, 0, 0, '')
        table.cell(panel, 1, 0, '')
        
        if showAdrPips
            table.cell(panel, 0, 2, 'ADR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 2, str.format('{0,number,#.##}', to_pips(day_adr)) + "PIPS" , text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 3, 'ADRx3', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 3, str.format('{0,number,#.##}', to_pips(day_adr) * 3)+ "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 4, 'AWR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 4, str.format('{0,number,#.##}', to_pips(week_adr)) + "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 5, 'AMR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 5, str.format('{0,number,#.##}', to_pips(month_adr)) + "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
        
        if showAdrCurrency  
            table.cell(panel, 0, 6, 'ADR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 6, str.tostring(day_adr, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 7, 'ADRx3', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 7, str.tostring(day_adr * 3, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 8, 'AWR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 8, str.tostring(week_adr, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 9, 'AMR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 9, str.tostring(month_adr, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
        
        if showRDPips
            table.cell(panel, 0, 10, 'RD', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 10, str.format('{0,number,#.##}', to_pips(day_rd)) + "PIPS" , text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 11, 'RDx3', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 11, str.format('{0,number,#.##}', to_pips(day_rd) * 3)+ "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 12, 'RW', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 12, str.format('{0,number,#.##}', to_pips(week_adr)) + "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
            
        if showRDCurrency  
            table.cell(panel, 0, 13, 'RD', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 13, str.tostring(day_rd, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 14, 'RDx3', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 14, str.tostring(day_rd * 3, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 15, 'RW', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 15, str.tostring(week_rd, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            
   




// M - Levels


//Calculate Pivot Point
// 2021-03025 updated by infernix 
//M calculations
m0C = (pivS2 + pivS3) / 2
m1C = (pivS1 + pivS2) / 2
m2C = (pivotPoint + pivS1) / 2
m3C = (pivotPoint + pivR1) / 2
m4C = (pivR1 + pivR2) / 2
m5C = (pivR2 + pivR3) / 2


m0line = draw_pivot(validTimeFrame and activeM and m0C ? m0C : na, 'D', 'M0', mColor, mLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showMLabels and validTimeFrame)
m1line = draw_pivot(validTimeFrame and activeM and m1C ? m1C : na, 'D', 'M1', mColor, mLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showMLabels and validTimeFrame)
m2line = draw_pivot(validTimeFrame and activeM and m2C ? m2C : na, 'D', 'M2', mColor, mLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showMLabels and validTimeFrame)
m3line = draw_pivot(validTimeFrame and activeM and m3C ? m3C : na, 'D', 'M3', mColor, mLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showMLabels and validTimeFrame)
m4line = draw_pivot(validTimeFrame and activeM and m4C ? m4C : na, 'D', 'M4', mColor, mLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showMLabels and validTimeFrame)
m5line = draw_pivot(validTimeFrame and activeM and m5C ? m5C : na, 'D', 'M5', mColor, mLabelColor, mStyle, 1, extendPivots ? extend.both : extend.right, showMLabels and validTimeFrame)


//*****************
// Market sessions
//*****************
splitSessionString(sessXTime) =>
    //session stirng looks like this: 0000-0000:1234567 ie start time, end time, day of the week
    //we need to parse the sessXTime string into hours and min for start and end times so we can use those in the timestampfunction below

    //string times contains "0000-2300" as an example
    string times = array.get(str.split(sessXTime, ':'), 0)

    //string startTime contains "0000"
    string startTime = array.get(str.split(times, '-'), 0)
    //string endTime contains "2300"
    string endTime = array.get(str.split(times, '-'), 1)

    //now we need to get the start hour and start min, sing 0 index - hour is the characters in index 0 and index 1 while min is the chars at index 2 and 3
    string[] startTimeChars = str.split(startTime, '')
    string[] endTimeChars = str.split(endTime, '')

    //so now startHour contains 00 and start min contains 00
    string startHour = array.get(startTimeChars, 0) + array.get(startTimeChars, 1)
    string startMin = array.get(startTimeChars, 2) + array.get(startTimeChars, 3)

    //so now endHour contains 23 and end min contains 00
    string endHour = array.get(endTimeChars, 0) + array.get(endTimeChars, 1)
    string endMin = array.get(endTimeChars, 2) + array.get(endTimeChars, 3)
    [startHour, startMin, endHour, endMin]
    
calc_session_startend(sessXTime, gmt) =>
    [startHour, startMin, endHour, endMin] = splitSessionString(sessXTime)
    targetstartTimeX = timestamp(gmt, year, month, dayofmonth, math.round(str.tonumber(startHour)), math.round(str.tonumber(startMin)), 00)
    targetendTimeX = timestamp(gmt, year, month, dayofmonth, math.round(str.tonumber(endHour)), math.round(str.tonumber(endMin)), 00)
    time_now = timestamp(year, month, dayofmonth, hour, minute, 00) 
    midnight_exchange = timestamp(year, month, dayofmonth, 00, 00, 00)  


    //if start hour is greater than end hour we are dealing with a session that starts towards the end of one day 
    //and ends the next day. ie advance the end time by 24 hours - its the next day
    bool adjusted = false
    if gmt == 'GMT+0'
        if math.round(str.tonumber(startHour)) > math.round(str.tonumber(endHour))
            if time_now - targetstartTimeX >= 0
                targetendTimeX := targetendTimeX + 24 * 60 * 60 * 1000
                adjusted := true
                targetendTimeX
    if gmt == 'GMT+1'
        if math.round(str.tonumber(startHour)) == 0
            startHour := '24'
        if math.round(str.tonumber(endHour)) == 0
            endHour := '24'    
        if math.round(str.tonumber(startHour))-1 > math.round(str.tonumber(endHour))-1
            if time_now - targetstartTimeX >= 0
                targetendTimeX := targetendTimeX + 24 * 60 * 60 * 1000
                adjusted := true
                targetendTimeX
    
    //now is the exchange is at some utc offset and the market session crosses days even when start hour is not greater than end hour
    //we still need to adjust the end time. 
    
    if targetstartTimeX < midnight_exchange and midnight_exchange < targetendTimeX and not adjusted
        targetendTimeX := targetendTimeX + 24 * 60 * 60 * 1000
        targetendTimeX                
            
    [targetstartTimeX,targetendTimeX]
                

draw_open_range(sessXTime, sessXcol, show_orX, gmt)=>
    if show_orX
        // Initialize variables on bar zero only, so they preserve their values across bars.
        var hi = float(na)
        var lo = float(na)
        var box hiLoBox = na
        // Detect changes in timeframe.
        session = time(timeframe.period, sessXTime, gmt)
        bool newTF = session and not session[1]
        if newTF
            // New bar in higher timeframe; reset values and create new lines and box.
            [targetstartTimeX,targetendTimeX] = calc_session_startend(sessXTime, gmt)
            sessionDuration = math.round(math.abs(time  - targetendTimeX)/(timeframe.multiplier*60*1000))
   
            hi := high
            lo := low
            hiLoBox := box.new(bar_index, hi, timeframe.multiplier == 1? bar_index : bar_index+sessionDuration, lo, border_color = na, bgcolor = sessXcol)
            int(na)
        else
            if timeframe.multiplier == 1 and (na(session[1]) and not na(session) or session[1] < session)
                box.set_right(hiLoBox, bar_index+1)
            int(na)
draw_session_hilo(sessXTime, show_rectangleX, show_labelX, sessXcolLabel, sessXLabel, gmt)=>
    if show_rectangleX
        // Initialize variables on bar zero only, so they preserve their values across bars.
        var hi = float(0)
        var lo = float(10000000000.0)
       
        var line line_t = na
        var line line_b = na
        var label line_label = na
        // var box hiLoBox = na
        // Detect changes in timeframe.
        session = time(timeframe.period, sessXTime, gmt)
        sessLineStyleX = rectStyle == 'Solid' ? line.style_solid : line.style_dashed
        bool newTF = session and not session[1]
        hi := newTF ? high : session ? math.max(high, hi[1]) : hi[1]
        lo := newTF ? low : session ? math.min(low, lo[1]) : lo[1]
          
        if newTF
            beginIndex = bar_index 
            [targetstartTimeX,targetendTimeX] = calc_session_startend(sessXTime, gmt)
            sessionDuration = math.round(math.abs(time  - targetendTimeX)/(timeframe.multiplier*60*1000))
        
            line_t := line.new(beginIndex, hi, timeframe.multiplier == 1? bar_index : bar_index+sessionDuration, hi, xloc=xloc.bar_index, style=sessLineStyleX, color=sessXcolLabel)
            line_b := line.new(beginIndex, lo, timeframe.multiplier == 1? bar_index : bar_index+sessionDuration, lo, xloc=xloc.bar_index, style=sessLineStyleX, color=sessXcolLabel)
            line.delete(line_t[1])
            line.delete(line_b[1])
            if show_labelX
                line_label := label.new(beginIndex, hi, sessXLabel, xloc=xloc.bar_index, textcolor=sessXcolLabel, style=label.style_none, size=size.normal, textalign=text.align_right)
                label.delete(line_label[1])
  
            int(na)
        else
            if na(session[1]) and not na(session) or session[1] < session
                if timeframe.multiplier == 1
                    line.set_x2(line_t,bar_index+1)
                    line.set_x2(line_b,bar_index+1)
                line.set_y1(line_t,hi)
                line.set_y2(line_t,hi)
                line.set_y1(line_b,lo)
                line.set_y2(line_b,lo)
                if show_labelX and not na(line_label)
                    label.set_y(line_label, hi)
            int(na)




//*****************************//
// Daylight Savings Time Flags //
//*****************************//

int previousSunday = dayofmonth - dayofweek + 1
bool nyDST = na
bool ukDST = na
bool sydDST = na

if month < 3 or month > 11
    nyDST := false
    ukDST := false
    sydDST := true
else if month > 4 and month < 10
    nyDST := true
    ukDST := true
    sydDST := false
else if month == 3
    nyDST := previousSunday >= 8
    ukDST := previousSunday >= 24
    sydDST := true
else if month == 4
    nyDST := true
    ukDST := true
    sydDST := previousSunday <= 0
else if month == 10
    nyDST := true
    ukDST := previousSunday <= 24
    sydDST := previousSunday >= 0
else // month == 11
    nyDST := previousSunday <= 0
    ukDST := false
    sydDST := true
    


            
if ukDST
    draw_open_range(sess1Time,sess1col,show_or1,'GMT+1')
    draw_session_hilo(sess1Time, show_rectangle1, show_label1, sess1colLabel, sess1Label, 'GMT+1')
else
    draw_open_range(sess1Time,sess1col,show_or1,'GMT+0')
    draw_session_hilo(sess1Time, show_rectangle1, show_label1, sess1colLabel, sess1Label, 'GMT+0')

if nyDST
    draw_open_range(sess2Time,sess2col,show_or2,'GMT+1')
    draw_session_hilo(sess2Time, show_rectangle2, show_label2, sess2colLabel, sess2Label, 'GMT+1')
else
    draw_open_range(sess2Time,sess2col,show_or2,'GMT+0')
    draw_session_hilo(sess2Time, show_rectangle2, show_label2, sess2colLabel, sess2Label, 'GMT+0')

// Tokyo
draw_open_range(sess3Time,sess3col,show_or3,'GMT+0')
draw_session_hilo(sess3Time, show_rectangle3, show_label3, sess3colLabel, sess3Label, 'GMT+0')

// Hong Kong
draw_open_range(sess4Time,sess4col,show_or4,'GMT+0')
draw_session_hilo(sess4Time, show_rectangle4, show_label4, sess4colLabel, sess4Label, 'GMT+0')

if sydDST
    draw_open_range(sess5Time,sess5col,show_or5,'GMT+1')
    draw_session_hilo(sess5Time, show_rectangle5, show_label5, sess5colLabel, sess5Label, 'GMT+1')
else
    draw_open_range(sess5Time,sess5col,show_or5,'GMT+0')
    draw_session_hilo(sess5Time, show_rectangle5, show_label5, sess5colLabel, sess5Label, 'GMT+0')

//eu brinks is for london
if ukDST
    draw_open_range(sess6Time,sess6col,show_or6,'GMT+1')
    draw_session_hilo(sess6Time, show_rectangle6, show_label6, sess6colLabel, sess6Label, 'GMT+1')
else
    draw_open_range(sess6Time,sess6col,show_or6,'GMT+0')
    draw_session_hilo(sess6Time, show_rectangle6, show_label6, sess6colLabel, sess6Label, 'GMT+0')

//us brinks is ny
if nyDST
    draw_open_range(sess7Time,sess7col,show_or7,'GMT+1')
    draw_session_hilo(sess7Time, show_rectangle7, show_label7, sess7colLabel, sess7Label, 'GMT+1')
else
    draw_open_range(sess7Time,sess7col,show_or7,'GMT+0')
    draw_session_hilo(sess7Time, show_rectangle7, show_label7, sess7colLabel, sess7Label, 'GMT+0')

//becuase frankfurt changes with london
if ukDST
    draw_open_range(sess8Time,sess8col,show_or8,'GMT+1')
    draw_session_hilo(sess8Time, show_rectangle8, show_label8, sess8colLabel, sess8Label, 'GMT+1')
else
    draw_open_range(sess8Time,sess8col,show_or8,'GMT+0')
    draw_session_hilo(sess8Time, show_rectangle8, show_label8, sess8colLabel, sess8Label, 'GMT+0')


//************//
// Psy Levels //
//************//
var int oneWeekMillis = (7 * 24 * 60 * 60 * 1000)

// Timestamp any of the 6 previous days in the week (such as last Wednesday at 21 hours GMT)
timestampPreviousDayOfWeek(previousDayOfWeek, hourOfDay, GMTOffset) =>
    int dayofweekOffset = na
    int previousDayOfMonth = na
    int psySessionStartTime = na
    int returnValue = na
    //today we onlu care about Monday - forec and Saturday for crypto - if that changes in the future this code will need to be updated
    if previousDayOfWeek == "Monday"
        dayofweekOffset := (dayofweek(time, GMTOffset) - 1 + 6) % 7
    
    if previousDayOfWeek == "Saturday"
        dayofweekOffset := (dayofweek(time, GMTOffset) - 1 + 1) % 7


    previousDayOfMonth := dayofmonth(time, GMTOffset) - dayofweekOffset
    
    //based on time we are on the day where the psy levels will change - now we need to determine if we are before or after the 
    //time when the psy levels will chnge
    
    //today is Saturday or Monday dayofweekOffset will be equal to zero and we are checking if the current time is before the psy level change
    //we also need to be minful of GMTOffset. using  and hourOfDay != 00 because if we switch at midnight we dont have to do anything
    if dayofweekOffset == 0 and GMTOffset == "GMT" and hourOfDay >= hour(time,GMTOffset) and hourOfDay != 00
        //even thou today is saturday we are still not past the change time - subract a week because it is not time to change yet
        returnValue := timestamp(GMTOffset, year, month, previousDayOfMonth, hourOfDay, 00, 00) - oneWeekMillis
    //same as previous but handling GMT+1
    else if dayofweekOffset == 0 and GMTOffset == "GMT+1" and hourOfDay -1 >= hour(time,GMTOffset) //and 0 != minute(time,GMTOffset)
        returnValue := timestamp(GMTOffset, year, month, previousDayOfMonth, hourOfDay, 00, 00) - oneWeekMillis
    //default - we have already switched some time ago
    else
        returnValue := timestamp(GMTOffset, year, month, previousDayOfMonth, hourOfDay, 00, 00)
    returnValue



int psySession = na 
int psySessionStartDay = na
int psySessionStartTime = na
bool inPsySession = na
float psyHi = na
float psyLo = na
string psyHiLabel = na
string psyLoLabel = na
//only do the calc if the user has not disabled the psy levels
if show_psylevels
    //4 hour res based on how mt4 does it
    //mt4 code
    //int Li_4 = iBarShift(NULL, PERIOD_H4, iTime(NULL, PERIOD_W1, Li_0)) - 2 - Offset;
    //ObjectCreate("PsychHi", OBJ_TREND, 0, Time[0], iHigh(NULL, PERIOD_H4, iHighest(NULL, PERIOD_H4, MODE_HIGH, 2, Li_4)), iTime(NULL, PERIOD_W1, 0), iHigh(NULL, PERIOD_H4,
    //iHighest(NULL, PERIOD_H4, MODE_HIGH, 2, Li_4)));
        
    //so basically because the session is 8 hours and we are looking at a 4 hour resolution we only need to take the highest high an lowest low of 2 bars
    //we use the gmt offset to adjust the 0000-0800 session to Sydney open which is at 2100 during dst and at 2200 otherwize. (dst - spring foward, fall back)
    //keep in mind sydney is in the souther hemisphere so dst is oposite of when london and new york go into dst
    if psyType == 'crypto'
        if sydDST
            psySession := time('240', '2200-0600:1', "GMT+1")
            psySessionStartTime := timestampPreviousDayOfWeek('Saturday', 22, 'GMT+1')
        else
            psySession := time('240', '2200-0600:1', "GMT")
            psySessionStartTime := timestampPreviousDayOfWeek('Saturday', 22, 'GMT')
    else
        psySession := time('240', '0000-0800:2', "GMT")
        psySessionStartTime := timestampPreviousDayOfWeek('Monday', 00, 'GMT')
        
    inPsySession := na(psySession) ? false : true
    if inPsySession
        // When entering a new psy session, initialize hi/lo
        if not inPsySession[1]
            psyHi := high
            psyLo := low
            psyHiLabel := 'Psy-Hi calculating...'
            psyLoLabel := 'Psy-Lo calculating...'
        // After initialization, calculate psy hi/lo
        else
            psyHi := math.max(high, psyHi[1])
            psyLo := math.min(low, psyLo[1])
            //stylePsy := line.style_dashed //this does not work for style correctly but it does for the label which is odd
            psyHiLabel := 'Psy-Hi calculating...'
            psyLoLabel := 'Psy-Lo calculating...'
    // When not in the psy session, use the last value of psyHi and psyLo
    else
        psyHi := psyHi[1]
        psyLo := psyLo[1]
        psyHiLabel := 'Psy-Hi'
        psyLoLabel := 'Psy-Lo'



    

// Draw Psy Level Lines
if (barstate.islast) and not showallPsy and show_psylevels
    
    // Extend line back to the previous start time (after Psy-Hi/Lo have been calculated)
    psyHiLine = line.new(time, psyHi, psySessionStartTime, psyHi, xloc.bar_time, extend.none, psycolH)
    line.delete(psyHiLine[1])
    psyLoLine = line.new(time, psyLo, psySessionStartTime, psyLo, xloc.bar_time, extend.none, psycolL)
    line.delete(psyLoLine[1])

// Write Psy Level Labels - same label regardless if line.new or plot used
r_label(psyHi, psyHiLabel, label.style_none, psycolH, show_psylabel)
r_label(psyLo, psyLoLabel, label.style_none, psycolL, show_psylabel) 

// Plot Historical Psy Level
plot(showPsy and show_psylevels and showallPsy ? psyHi : na, color=psycolH, style=plot.style_stepline, linewidth=2, editable=false, title="Psy-Hi")  //, offset=psy_plot_offset)
plot(showPsy and show_psylevels and showallPsy ? psyLo : na, color=psycolL, style=plot.style_stepline, linewidth=2, editable=false, title="Psy-Lo")  //, offset=psy_plot_offset)



//***********
// Daily open
//***********
getdayOpen()=>
    in_sessionDly = time('D', '24x7')
    bool isDly = ta.change(time('D'))//ta.change(in_sessionDly)//in_sessionDly and not in_sessionDly[1]
    var dlyOpen = float(na)
    if isDly
        dlyOpen := open
    dlyOpen
daily_open = getdayOpen()
//this plot is only to show historical values when the option is selected.
plot(show_rectangle9 and validTimeFrame and showallDly ? daily_open : na, color=sess9col, style=plot.style_stepline, linewidth=2, editable=false, title="Daily Open")
if showallDly
    //if historical values are selected to be shown - then add a label to the plot
    r_label(daily_open, 'Daily Open', label.style_none, sess9col, validTimeFrame and show_label9)
    showallDly
else
    if show_rectangle9
        //othewise we draw the line and label together - showing only todays line.
        draw_line_DO(daily_open, 'D', 'Daily Open', sess9col, line.style_solid, 1, extend.none, validTimeFrame and show_label9, label_x_offset)
    
//London DST Starts Last Sunday of March DST Edns Last Sunday of October
//New York DST Starts 2nd Sunday of March DST Edns 1st Sunday of November
//Sydney DST Start on 1st Sunday of October DST ends 1st Sunday of Arpil
//Frankfurt DST Starts Last Sunday of March DST Edns Last Sunday of October

 
if barstate.islast and showDstTable


    var table dstTable = table.new(choiceDstTable, 2, 8, bgcolor=dstTableBgColor)

    //general
    table.cell(dstTable, 0, 0, 'London DST Starts Last Sunday of March | DST Ends Last Sunday of October', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 1, 'New York DST Starts 2nd Sunday of March | DST Ends 1st Sunday of November', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 2, 'Tokyo does not observe DST', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 3, 'Hong Kong does not observe DST', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 4, 'Sydney DST Start on 1st Sunday of October | DST Ends 1st Sunday of Arpil', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 5, 'EU Brinks DST Starts Last Sunday of March | DST Ends Last Sunday of October', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 6, 'US Brinks DST Starts 2nd Sunday of March | DST Ends 1st Sunday of November', text_color=adrTableTxtColor, text_halign=text.align_left)
    table.cell(dstTable, 0, 7, 'Frankfurt DST Starts Last Sunday of March | DST Ends Last Sunday of October', text_color=adrTableTxtColor, text_halign=text.align_left)