Heikin Ashi Count
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Julien-PH
//@version=5

indicator(title="Heikin Ashi Count", shorttitle="HA Count", overlay=false)

// Input
timeframe       = input.timeframe(defval="", title="Timeframe"                         , group="Heikin Ashi Settings")
lengthHAC       = input.float(defval=1.15, minval=1, step=0.01, title="Counting length", group="Heikin Ashi Settings")

lengthDiv       = input.float(defval=100 , minval=3, step=1   , title="Number of bars where we look for divergences"    , group="Divergence Settings")
confirmedDiv    = input.bool(true, title="Wait confirmation ?", tooltip="Authorize repainting, confirmation periode = 1", group="Divergence Settings")

// Method
isPL(src=close,left=3,right=0) =>
    ta.pivotlow(src,left,right)

isPH(src=close,left=3,right=0) =>
    ta.pivothigh(src,left,right)

haCountMethod(length) =>
    hac = 50.0
    hac := if barstate.isfirst
        50
    else if close > open
        hac[1] / length + (100 * ((length - 1)/length))
    else if close < open
        hac[1] / length
    else
        hac[1]

isInBullDivergence(indicator,price=close,length=100,confirm=true) =>
    isDiv = 0
    confirmOffset = confirm ? 1 : 0
    LL = indicator[0+confirmOffset]
    if (isPL(indicator,right=confirmOffset) and indicator < 50)
        for i = 1+confirmOffset to length+confirmOffset
    		if (LL > indicator[i] and indicator[i] < indicator[i+1])
    		    LL := indicator[i]
    		    if (price[i] > price[confirmOffset] and ta.lowestbars(price,i) < 3)
    		        isDiv := i
    isDiv

isInBearDivergence(indicator,price=close,length=100,confirm=true) =>
    isDiv = 0
    confirmOffset = confirm ? 1 : 0
    HH = indicator[0+confirmOffset]
    if (isPH(indicator,right=confirmOffset) and indicator > 50)
        for i = 1+confirmOffset to length+confirmOffset
    		if (HH < indicator[i] and indicator[i] > indicator[i+1])
    		    HH := indicator[i]
    		    if (price[i] < price[confirmOffset] and ta.highestbars(price,i) < 3)
    		        isDiv := i
    isDiv

findDivergence(indicator,price=close,length=100,confirm=true) =>
    bullDiv = isInBullDivergence(indicator,price,length,confirm)
    bearDiv = isInBearDivergence(indicator,price,length,confirm)
    [bullDiv,bearDiv]


// Heikin Ashi Count and divergences
hac                 = request.security(ticker.heikinashi(syminfo.tickerid), timeframe, haCountMethod(lengthHAC))
[bullDiv,bearDiv]   = request.security(                  syminfo.tickerid , timeframe, findDivergence(hac,close,lengthDiv,confirmedDiv))


// Plot
bandTop     = hline(100 , color=color.new(color.gray,0 ), linestyle=hline.style_solid)
bandMid     = hline(50  , color=color.new(color.gray,50), linestyle=hline.style_solid)
bandBottom  = hline(0   , color=color.new(color.gray,0 ), linestyle=hline.style_solid)

display_divs    = input.bool(true,title="Display divergence signals ?"  , group="Plot")
display_divline = input.bool(true,title="Display divergence lines ?"    , group="Plot")
locOption       = input.string(defval='Absolute', title='Location of the divergence signals', options=['Absolute','Value'], group='Plot')
colorHAC        = input.color(color.new(color.orange,25), title="Heinkin Ashi Count color"  , group="Plot")
colorBullDiv    = input.color(color.new(color.green ,30), title="Bull Divergence color"     , group="Plot")
colorBearDiv    = input.color(color.new(color.red   ,30), title="Bear Divergence color"     , group="Plot")

confirmationOffset = confirmedDiv ? 1 : 0

plot(hac, title="HAC", color=colorHAC, linewidth=1, histbase=50, style=plot.style_area)
plotchar(display_divs and bullDiv ? (locOption == 'Value' ? hac[confirmationOffset] : 0  ) : na, title = 'Bull Divergence signal', char='•', color = colorBullDiv, location = location.absolute, size = size.small, offset = -confirmationOffset)
plotchar(display_divs and bearDiv ? (locOption == 'Value' ? hac[confirmationOffset] : 100) : na, title = 'Bear Divergence signal', char='•', color = colorBearDiv, location = location.absolute, size = size.small, offset = -confirmationOffset)

if display_divline and bullDiv>0
    line.new(x1=bar_index-bullDiv, y1=math.round(hac[bullDiv]), x2=bar_index-confirmationOffset, y2=math.round(hac[confirmationOffset]), color=colorBullDiv, width = 1)
if display_divline and bearDiv>0
    line.new(x1=bar_index-bearDiv, y1=math.round(hac[bearDiv]), x2=bar_index-confirmationOffset, y2=math.round(hac[confirmationOffset]), color=colorBearDiv, width = 1)

