CandleLib
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Hamster-Coder

//@version=5

// @description TODO: add library description here
library("CandleLib", overlay = true)

export candle_body() => 
    math.abs(open-close)

// @variable Size of the candle body
candle_body = candle_body()

export candle_shadow_top() => 
    high - math.max(open, close)

// @variable Size of the candle top shadow
candle_shadow_top = candle_shadow_top()

export candle_shadow_bottom() => 
    math.min(open, close) - low

// @variable Size of the candle bottom shadow
candle_shadow_bottom = candle_shadow_bottom()

export candle_body_sma(int length = 50) => 
    ta.sma(candle_body, length)

// @variable Size of the candle top shadow
candle_body_sma = candle_body_sma()

// @function Get approximate candle zero size
// @param maxSize mitiplier to avarage body size of the candle 
export zero(float maxSize = 0.02) =>
    candle_body_sma * maxSize
zero = zero()

// @variable Is candle is 'Dodge'
export candle_type_dodge() =>
    candle_body <= zero and candle_shadow_top > zero and candle_shadow_bottom > zero
candle_type_dodge = candle_type_dodge()

export candle_type_spin() =>
    candle_type_dodge == false and candle_shadow_top > candle_body * 3 and candle_shadow_bottom > candle_body * 3
candle_type_spin = candle_type_spin()



export candle_type_marubotsu() =>
    candle_shadow_top <= zero and candle_shadow_bottom <= zero
candle_type_marubotsu = candle_type_marubotsu()

export candle_type_hammer() =>
    candle_shadow_top < zero and candle_body > zero and candle_shadow_bottom > candle_body * 3
candle_type_hammer = candle_type_hammer()

export candle_type_hammer_inverted() =>
    candle_shadow_top > candle_body * 3 and candle_body > zero and candle_shadow_bottom < zero
candle_type_hammer_inverted = candle_type_hammer_inverted()

// trends 

export trend_candle() =>
    float result = 0
    if (candle_body > zero)
        result := math.sign(close - open)
    result
trend_candle = trend_candle()

export trend_volume() =>
    math.sign(volume - volume[1])

export trend_candle_changed() =>    
    result = false
    if (trend_candle[0] != 0)
        idx = 1
        while (true)
            if (trend_candle[idx] == 0)
                idx += 1
                continue
            result := trend_candle[0] != trend_candle[idx] 
            break
    result
trend_candle_changed = trend_candle_changed()

export trend_reversal_trough_dodge() =>
    candle_type_dodge[1] and trend_candle() != trend_candle()[2] and candle_body > candle_body[2] * 0.618 and (trend_candle() ? candle_shadow_top < candle_body : candle_shadow_bottom < candle_body)

export trend_reversal_trough_hammer_inverted() =>
    trend_candle()[0] < 0 and candle_type_hammer_inverted[1] and trend_candle()[1] < 0 and trend_candle()[2] > 0 and candle_body > zero

export trend_reversal_trough_hammer() =>
    trend_candle()[0] > 0 and candle_type_hammer[1] and trend_candle()[1] > 0 and trend_candle()[2] < 0 and candle_body > zero

export trend_reversal() =>
    candle_body[1] > zero[1] and candle_body[0] > zero[0] and trend_candle_changed[0] and candle_body[0] + zero[0] > candle_body[1]

