SubCandles-V2
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HeWhoMustNotBeNamed

//   __    __            __       __  __                  __       __                        __      __    __              __      _______             __    __                                          __ 
//  /  |  /  |          /  |  _  /  |/  |                /  \     /  |                      /  |    /  \  /  |            /  |    /       \           /  \  /  |                                        /  |
//  $$ |  $$ |  ______  $$ | / \ $$ |$$ |____    ______  $$  \   /$$ | __    __   _______  _$$ |_   $$  \ $$ |  ______   _$$ |_   $$$$$$$  |  ______  $$  \ $$ |  ______   _____  ____    ______    ____$$ |
//  $$ |__$$ | /      \ $$ |/$  \$$ |$$      \  /      \ $$$  \ /$$$ |/  |  /  | /       |/ $$   |  $$$  \$$ | /      \ / $$   |  $$ |__$$ | /      \ $$$  \$$ | /      \ /     \/    \  /      \  /    $$ |
//  $$    $$ |/$$$$$$  |$$ /$$$  $$ |$$$$$$$  |/$$$$$$  |$$$$  /$$$$ |$$ |  $$ |/$$$$$$$/ $$$$$$/   $$$$  $$ |/$$$$$$  |$$$$$$/   $$    $$< /$$$$$$  |$$$$  $$ | $$$$$$  |$$$$$$ $$$$  |/$$$$$$  |/$$$$$$$ |
//  $$$$$$$$ |$$    $$ |$$ $$/$$ $$ |$$ |  $$ |$$ |  $$ |$$ $$ $$/$$ |$$ |  $$ |$$      \   $$ | __ $$ $$ $$ |$$ |  $$ |  $$ | __ $$$$$$$  |$$    $$ |$$ $$ $$ | /    $$ |$$ | $$ | $$ |$$    $$ |$$ |  $$ |
//  $$ |  $$ |$$$$$$$$/ $$$$/  $$$$ |$$ |  $$ |$$ \__$$ |$$ |$$$/ $$ |$$ \__$$ | $$$$$$  |  $$ |/  |$$ |$$$$ |$$ \__$$ |  $$ |/  |$$ |__$$ |$$$$$$$$/ $$ |$$$$ |/$$$$$$$ |$$ | $$ | $$ |$$$$$$$$/ $$ \__$$ |
//  $$ |  $$ |$$       |$$$/    $$$ |$$ |  $$ |$$    $$/ $$ | $/  $$ |$$    $$/ /     $$/   $$  $$/ $$ | $$$ |$$    $$/   $$  $$/ $$    $$/ $$       |$$ | $$$ |$$    $$ |$$ | $$ | $$ |$$       |$$    $$ |
//  $$/   $$/  $$$$$$$/ $$/      $$/ $$/   $$/  $$$$$$/  $$/      $$/  $$$$$$/  $$$$$$$/     $$$$/  $$/   $$/  $$$$$$/     $$$$/  $$$$$$$/   $$$$$$$/ $$/   $$/  $$$$$$$/ $$/  $$/  $$/  $$$$$$$/  $$$$$$$/ 
//                                                                                                                                                                                                          
//                                                                                                                                                                                                          
//
//@version=5
indicator("SubCandles-V2", overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count=500)

numberOfBacktestBars = 100
import PineCoders/Time/3 as t

[lo, lh, ll, lc] = request.security_lower_tf(syminfo.tickerid, '1', [open, high, low, close], true)
low_indices_sorted = array.sort_indices(ll, order.ascending)
high_indices_sorted = array.sort_indices(lh, order.descending)

ll_index = array.size(lh)>0? array.get(low_indices_sorted, 0) : 0
hh_index = array.size(ll)>0? array.get(high_indices_sorted, 0) : 0

high_after_low = array.size(lh)>0? array.max(array.slice(lh, ll_index, array.size(lh))) : na
low_after_high = array.size(ll)>0? array.min(array.slice(ll, hh_index, array.size(ll))) : na

high_before_low = array.size(lh)>0? array.max(array.slice(lh, 0, ll_index+1)) : na
low_before_high = array.size(ll)>0? array.min(array.slice(ll, 0, hh_index+1)) : na

fSize = math.min(ll_index, hh_index)
sSize = math.max(ll_index, hh_index) - math.min(ll_index, hh_index)
tSize = array.size(lh) - math.max(ll_index, hh_index)
sizeArray = array.from(fSize, sSize, tSize)
sizeArraySortOrder = array.sort_indices(sizeArray, order.ascending)

_first_open = open
_first_high = ll_index < hh_index? high_before_low : high
_first_low = ll_index < hh_index? low : low_before_high
_first_close = ll_index < hh_index? low : high
_first_size = array.get(sizeArraySortOrder, 0)+1

_second_open = _first_close
_second_high = high
_second_low = low
_second_close = ll_index < hh_index? high : low
_second_size = array.get(sizeArraySortOrder, 1)+1

_third_open = _second_close
_third_high = ll_index < hh_index ? high : high_after_low
_third_low = ll_index < hh_index ? low_after_high : low
_third_close = close
_third_size = array.get(sizeArraySortOrder, 2)+1

draw_envelope(candleStart, candleEnd)=>
    var box envelope = na
    box.delete(envelope)
    borderColor = (open > close and close[1] > close) ? color.red : ((open < close and close[1] < close) ? color.green : color.silver)
    envelopeColor = color.new(borderColor, 90)
    diff = 0.2*(high - low)
    envelope := box.new(candleStart, high+diff, candleEnd, low-diff, bgcolor = envelopeColor, border_color=borderColor)

draw_candle(_open, _high, _low, _close, _size, _offset)=>
    var box body = na
    var line upperWick = na
    var line lowerWick = na
    box.delete(body)
    line.delete(upperWick)
    line.delete(lowerWick)
    candleStart = _offset
    candleEnd = _offset+_size*2
    candleColor = _open > _close? color.red : color.green
    body := box.new(candleStart, _open, candleEnd, _close, bgcolor = candleColor, border_color = candleColor)
    upperWick := line.new((candleStart+candleEnd)/2, math.max(_open, _close), (candleStart+candleEnd)/2, _high, color=candleColor)
    lowerWick := line.new((candleStart+candleEnd)/2, math.min(_open, _close), (candleStart+candleEnd)/2, _low, color=candleColor)
    candleEnd+1

initialDistance = bar_index + 10

offset = initialDistance+1
offset := draw_candle(_first_open, _first_high, _first_low, _first_close, _first_size, offset)
offset := draw_candle(_second_open, _second_high, _second_low, _second_close, _second_size, offset)
offset := draw_candle(_third_open, _third_high, _third_low, _third_close, _third_size, offset)

draw_envelope(initialDistance, offset)