Odd_Custom Candle Calendar Day
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © OddLogic1618

//@version=5
//Create candles based on calendar days, not market days
indicator("Odd_Custom Candle Calendar Day", max_lines_count = 500, max_boxes_count = 500)


in_tf_multi         = input.int(13, "Custom Candle Day Multiplier")
in_start_date       = input.time(timestamp("01 Jan 2022 00:00 +0500"), "Start Date")
in_candle_margin    = input.int(1, "Margin between candles", tooltip = "Creates margins based on calendar time, so if bar opens or closes during off days, margin may have no or reduced effect.")
in_candle_up_c      = input.color(color.green, "Up Color")
in_candle_dw_c      = input.color(color.red, "Down Color")

if in_tf_multi % timeframe.multiplier != 0
    o = "1"
    for i = 2 to in_tf_multi
        if in_tf_multi % i == 0
            o := o + ", " + str.tostring(i)
    runtime.error("Timeframe must be a factor of the Custom TF Period, try " + o)

if not str.contains(timeframe.period, "D")
    runtime.error("Switch to a Day Resolution")

u_period = 86400000 * in_tf_multi
c_margin = 86400000 * in_candle_margin


var float c_open    = na
var float c_high    = na
var float c_low     = na
var float c_close   = na

var bar_start       = in_start_date
var mid_point       = bar_start + (u_period / 2)

var box cur_box     = na
var line cur_line   = na

color cur_color = na

if time >= in_start_date
    var next_start = bar_start + u_period
    if time >= next_start
        bar_start   := next_start
        next_start  := next_start + u_period
        mid_point   := bar_start + (u_period / 2)
        c_open      := na
        c_high      := na
        c_low       := na
        c_close     := na
        cur_box     := na
        cur_line    := na

    if na(c_open)
        c_open := open
    if c_high < high or na(c_high)
        c_high := high
    if c_low > low or na(c_low)
        c_low := low
    c_close := close

    cur_color := c_close < c_open ? in_candle_dw_c : in_candle_up_c

    if na(cur_box)
        cur_box     := box.new(bar_start + c_margin, c_close, next_start - c_margin, c_open, border_color = cur_color, border_width = 1, xloc = xloc.bar_time, bgcolor = cur_color)
        cur_line    := line.new(mid_point, c_high, mid_point, c_low, xloc = xloc.bar_time, color = cur_color, width = 1)
    else
        box.set_top(cur_box, c_close)
        box.set_bgcolor(cur_box, cur_color)
        box.set_border_color(cur_box, cur_color)
        line.set_y1(cur_line, c_high)
        line.set_y2(cur_line, c_low)
        line.set_color(cur_line, cur_color)

//Invisible plots to display values
p_color = color.new(cur_color, 100)

plot(c_open , "Open"    , color = p_color)
plot(c_high , "High"    , color = p_color)
plot(c_low  , "Low"     , color = p_color)
plot(c_close, "Close"   , color = p_color)