Igniting Candles
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © syntaxgeek

//@version=5
indicator("Igniting Candles", shorttitle="Igniters", overlay=true, max_labels_count=500)

// <inputs>
i_strengthFilter = input.float(2.5, 'Strength Filter', minval=0.5, step=0.1, tooltip='Set to desired strength of ignition for display.', group='Basic')
i_avgVolumeMode = input.bool(false, 'Use average volume?', 'Sets current candle volume comparision against previous average or not.', inline='Average', group='Average Mode')
i_avgVolumeType = input.string('HMA', '', options=["SMA", "EMA", "SMMA (RMA)", "WMA", "HMA", "DEMA", "TEMA", "ZLEMA"])
i_avgVolumeModeBarPeriod = input.int(20, 'Lookback period', minval=2, step=1, group='Average Mode', tooltip='Only applies to average volume mode.')
i_icon = input.string('🚀', 'Icon', options=['🚀', '🧨', '🎆', '💥', '💣', '✨'], group='Style')
i_labelBgColor = input.color(color.white, title='Label Color', inline='Label', group='Style')
i_labelTextColor = input.color(color.black, title='Label Text Color', inline='Label', group='Style')
// </inputs>

// <consts>
v_y1 = low - (ta.atr(30) * 2)
v_y1B = low - ta.atr(30)
v_y2 = high + (ta.atr(30) * 2)
v_y2B = high + ta.atr(30)
// </consts>

// <funcs>
f_zlema(source, length) =>
    v_lag = math.round((length - 1) / 2)
    v_emaData = source + (source - source[v_lag])
    ta.ema(v_emaData, length)

f_dema(source, length) =>
    v_ema1 = ta.ema(source, length)
    (2 * v_ema1) - ta.ema(v_ema1, length)

f_tema(source, length) =>
    v_ema1 = ta.ema(source, length)
    v_ema2 = ta.ema(v_ema1, length)
    v_ema3 = ta.ema(v_ema2, length)
    (3 * v_ema1) - (3 * v_ema2) + v_ema3

f_ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "HMA" => ta.hma(source, length)
        "DEMA" => f_dema(source, length)
        "TEMA" => f_tema(source, length)
        "ZLEMA" => f_zlema(source, length)

f_newLabel(_text, _bias) =>
    v_labelColor = color.green
    v_labelTextColor = color.white
    v_labelPosition = v_y1
    v_labelStyle = label.style_label_up

    if _bias == 'bullish'
        v_labelColor := color.green
        v_labelPosition := v_y1
        v_labelTextColor := color.white
        v_labelStyle := label.style_label_up
    else if _bias == 'bearish'
        v_labelColor := color.red
        v_labelPosition := v_y2
        v_labelTextColor := color.white
        v_labelStyle := label.style_label_down
    else if _bias == 'neutral'
        v_direction = close[1] > close
        v_labelColor := color.white
        v_labelPosition := v_direction ? v_y2 : v_y1
        v_labelTextColor := color.black
        v_labelStyle := v_direction ? label.style_label_down : label.style_label_up

    label.new(bar_index, v_labelPosition, _text, xloc.bar_index, yloc.price, i_labelBgColor, v_labelStyle, i_labelTextColor)
// </funcs>

// <vars>
v_volDiff = 0.0
v_hasCandleIgnited = false

if not i_avgVolumeMode
    v_volDiff := volume / volume[1]
    v_hasCandleIgnited := v_volDiff >= i_strengthFilter
else
    v_avgVolume = f_ma(volume, i_avgVolumeModeBarPeriod, i_avgVolumeType)
    v_volDiff := volume / v_avgVolume
    v_hasCandleIgnited := v_volDiff >= i_strengthFilter
// </vars>

// <plots>
plotchar(v_volDiff, 'Vol Diff', display=display.data_window, editable=false)
plotchar(v_hasCandleIgnited, 'Candle Ignited', display=display.data_window, editable=false)

if v_hasCandleIgnited
    f_newLabel(i_icon + ' (' + str.tostring(v_volDiff, '#.#') + ')', 'neutral')
// </plots>

// <alerts>
if v_hasCandleIgnited
    alert(i_icon + ' (' + str.tostring(v_volDiff, '#.#') + ')', alert.freq_once_per_bar_close)
// <alerts>