Caleb's Supply and Demand Zones
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © CarreyTrades

//@version=5
indicator("Caleb Zones", overlay=true, max_bars_back=1000)

numbox  = input.int(10, title="Number of Zones", minval=0, maxval=10)
efma    = input.bool(false, title=" ", inline="fma", group="ma")
fma     = input.int(9, title="Fast EMA", inline="fma", group="ma")
fmac    = input.color(color.new(color.yellow, 50), title="Fast MA Color", inline="fma", group="ma")
esma    = input.bool(false, title=" ", inline="sma", group="ma")
sma     = input.int(21, title="Slow EMA", inline="sma", group="ma")
smac    = input.color(color.new(color.orange, 50), title="Slow MA Color", inline="sma", group="ma")
vw      = input.bool(false, title=" ", inline="vw", group="ma")
vwapc   = input.color(color.new(color.aqua, 50), title="VWAP Color", inline="vw", group="ma")
src     = input.source(ohlc4, title="EMA Source", group="ma")

ohour   = input.int(9, title="Start Time", minval=0, maxval=23, step=1, tooltip="Hour values greater than 16 will push into the next day's session and will be off by one hour due to market settlement hour.", inline="a", group="Time")
ominute = input.int(30, title=" ", minval=0, maxval=59, step=1, inline="a", group="Time")
chour   = input.int(16, title="End Time", minval=0, maxval=23, step=1, tooltip="Hour values greater than 16 will push into the next day's session and will be off by one hour due to market settlement hour.", inline="b", group="Time")
cminute = input.int(0, title=" ", minval=0, maxval=59, step=1, inline="b", group="Time")
ext    = input.bool(false, title="Extend Zones Right?", inline="c")
extl   = input.bool(false, title="Extend Zones Left?", inline="c")
extend = ext ? extend.right : extl ? extend.left : extend.none

//Logic
IsSPY  = syminfo.root == "SPY"
IsQQQ  = syminfo.root == "QQQ"
IsES   = (syminfo.root == "ES" or syminfo.root == "MES" or syminfo.root == "US500" or syminfo.root == "SPX")
IsNQ   = (syminfo.root == "NQ" or syminfo.root == "MNQ" or syminfo.root == "US100")

m      = IsSPY ? 1 : IsQQQ ? 1 : IsES ? 10 : IsNQ ? 40 : na

// SPY Boxes
s1t = 447.08
s1b = 446.03
s2t = 444.16
s2b = 442.99
s3t = 440.50
s3b = 439.66
s4t = 437.27
s4b = 436.03
s5t = 434.35
s5b = 433.49
s6t = 431.49
s6b = 430.41
s7t = 428.83
s7b = 427.79   
s8t = 425.90
s8b = 424.92
s9t = 422.32
s9b = 421.33   
s10t = 420.17
s10b = 419.57

// QQQ Boxes
q1t = 341.85 
q1b = 340.99
q2t = 338.13
q2b = 336.27
q3t = 334.22
q3b = 333.10   
q4t = 331.15
q4b = 329.82  
q5t = 327.52 
q5b = 326.56
q6t = 323.33
q6b = 322.07 
q7t = 320.15 
q7b = 319.66  
q8t = 318.10 
q8b = 317.52
q9t = 316.21
q9b = 315.61
q10t = 314.45
q10b = 313.73   

// Timeframe Logic

openTime = hour == ohour and minute == ominute
left = ta.barssince(openTime)
closeTime = hour == chour and minute == cminute
timerange = (chour - ohour - 1)*60 + math.abs(cminute - ominute)

tfcheck = timeframe.period 
mult = timeframe.multiplier
right = timerange / mult

// Box 1

b1t = IsSPY or IsES ? s1t * m : IsQQQ or IsNQ ? q1t * m : na
b1b = IsSPY or IsES ? s1b * m : IsQQQ or IsNQ ? q1b * m : na

bc1 = close > b1t ? color.green : close < b1b ? color.red : color.white

bgc1 = close > b1t ? color.new(color.green, 99) : close < b1b ? color.new(color.red, 99) : color.new(color.white,99)

b1 = numbox >= 9 ? (box.new(bar_index[left], b1t, bar_index[left] + right, b1b, border_color = bc1, extend=extend, bgcolor=bgc1, text_color=color.white)) : na

// Box 2

b2t = IsSPY or IsES ? s2t * m : IsQQQ or IsNQ ? q2t * m : na
b2b = IsSPY or IsES ? s2b * m : IsQQQ or IsNQ ? q2b * m : na

bc2 = close > b2t ? color.green : close < b2b ? color.red : color.white

bgc2 = close > b2t ? color.new(color.green, 99) : close < b2b ? color.new(color.red, 99) : color.new(color.white,99)

b2 = numbox >= 7 ? (box.new(bar_index[left], b2t, bar_index[left] + right, b2b, border_color = bc2, extend=extend, bgcolor = bgc2, text_color=color.white)) : na

// Box 3

b3t = IsSPY or IsES ? s3t * m : IsQQQ or IsNQ ? q3t * m : na
b3b = IsSPY or IsES ? s3b * m : IsQQQ or IsNQ ? q3b * m : na

bc3 = close > b3t ? color.green : close < b3b ? color.red : color.white

bgc3 = close > b3t ? color.new(color.green, 99) : close < b3b ? color.new(color.red, 99) : color.new(color.white,99)

b3 = numbox >= 5 ? (box.new(bar_index[left], b3t, bar_index[left] + right, b3b, border_color = bc3, extend=extend, bgcolor = bgc3, text_color=color.white)) : na

// Box 4

b4t = IsSPY or IsES ? s4t * m : IsQQQ or IsNQ ? q4t * m : na
b4b = IsSPY or IsES ? s4b * m : IsQQQ or IsNQ ? q4b * m : na

bc4 = close > b4t ? color.green : close < b4b ? color.red : color.white

bgc4 = close > b4t ? color.new(color.green, 99) : close < b4b ? color.new(color.red, 99) : color.new(color.white,99)

b4 = numbox >= 3 ? (box.new(bar_index[left], b4t, bar_index[left] + right, b4b, border_color = bc4, extend=extend, bgcolor = bgc4, text_color=color.white)) : na

// Box 5

b5t = IsSPY or IsES ? s5t * m : IsQQQ or IsNQ ? q5t * m : na
b5b = IsSPY or IsES ? s5b * m : IsQQQ or IsNQ ? q5b * m : na

bc5 = close > b5t ? color.green : close < b5b ? color.red : color.white

bgc5 = close > b5t ? color.new(color.green, 99) : close < b5b ? color.new(color.red, 99) : color.new(color.white,99)

b5 = numbox >= 1 ? box.new(bar_index[left], b5t, bar_index[left] + right, b5b, border_color = bc5, extend=extend, bgcolor = bgc5, text_color=color.white) : na

// Box 6

b6t = IsSPY or IsES ? s6t * m : IsQQQ or IsNQ ? q6t * m : na
b6b = IsSPY or IsES ? s6b * m : IsQQQ or IsNQ ? q6b * m : na

bc6 = close > b6t ? color.green : close < b6b ? color.red : color.white

bgc6 = close > b6t ? color.new(color.green, 99) : close < b6b ? color.new(color.red, 99) : color.new(color.white,99)

b6 = numbox >= 2 ? box.new(bar_index[left], b6t, bar_index[left] + right, b6b, border_color = bc6, extend=extend, bgcolor = bgc6, text_color=color.white) : na

// Box 7

b7t = IsSPY or IsES ? s7t * m : IsQQQ or IsNQ ? q7t * m : na
b7b = IsSPY or IsES ? s7b * m : IsQQQ or IsNQ ? q7b * m : na

bc7 = close > b7t ? color.green : close < b7b ? color.red : color.white

bgc7 = close > b7t ? color.new(color.green, 99) : close < b7b ? color.new(color.red, 99) : color.new(color.white,99)

b7 = numbox >= 4 ? box.new(bar_index[left], b7t, bar_index[left] + right, b7b, border_color = bc7, extend=extend, bgcolor = bgc7, text_color=color.white) : na

// Box 8

b8t = IsSPY or IsES ? s8t * m : IsQQQ or IsNQ ? q8t * m : na
b8b = IsSPY or IsES ? s8b * m : IsQQQ or IsNQ ? q8b * m : na

bc8 = close > b8t ? color.green : close < b8b ? color.red : color.white

bgc8 = close > b8t ? color.new(color.green, 99) : close < b8b ? color.new(color.red, 99) : color.new(color.white,99)

b8 = numbox >= 6 ? box.new(bar_index[left], b8t, bar_index[left] + right, b8b, border_color = bc8, extend=extend, bgcolor = bgc8, text_color=color.white) : na

// Box 9

b9t = IsSPY or IsES ? s9t * m : IsQQQ or IsNQ ? q9t * m : na
b9b = IsSPY or IsES ? s9b * m : IsQQQ or IsNQ ? q9b * m : na

bc9 = close > b9t ? color.green : close < b9b ? color.red : color.white

bgc9 = close > b9t ? color.new(color.green, 99) : close < b9b ? color.new(color.red, 99) : color.new(color.white,99)

b9 = numbox >= 8 ? box.new(bar_index[left], b9t, bar_index[left] + right, b9b, border_color = bc9, extend=extend, bgcolor = bgc9, text_color=color.white) : na

// Box 10

b10t = IsSPY or IsES ? s10t * m : IsQQQ or IsNQ ? q10t * m : na
b10b = IsSPY or IsES ? s10b * m : IsQQQ or IsNQ ? q10b * m : na

bc10 = close > b10t ? color.green : close < b10b ? color.red : color.white

bgc10 = close > b10t ? color.new(color.green, 99) : close < b10b ? color.new(color.red, 99) : color.new(color.white,99)

b10 = numbox >= 10 ? box.new(bar_index[left], b10t, bar_index[left] + right, b10b, border_color = bc10, extend=extend, bgcolor = bgc10, text_color=color.white) : na

// EMA Plots

fmap = efma ? ta.ema(src, fma) : na
plot(fmap, title="Fast Moving Average", color=fmac)
smap = esma ? ta.ema(src, sma) : na
plot(smap, title="Slow Moving Average", color=smac)
vwap = vw ? ta.vwap(src) : na
plot(vwap, title="VWAP", color=vwapc)
