Heikin ashi Doji
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © K_M_M

//@version=5
indicator("Heikin ashi Doji", shorttitle = "HA_Doji", overlay=true)
C_Len = 14 // ta.ema depth for bodyAvg
C_ShadowPercent = 5.0 // size of shadows
C_ShadowEqualsPercent = 100.0
C_DojiBodyPercent = 5.0
C_Factor = 2.0 // shows the number of times the shadow dominates the candlestick body

//Heikin Ashi
ha_t = ticker.heikinashi(syminfo.tickerid)
ha_open = request.security(ha_t, timeframe.period, open)
ha_high = request.security(ha_t, timeframe.period, high)
ha_low = request.security(ha_t, timeframe.period, low)
ha_close = request.security(ha_t, timeframe.period, close)

C_BodyHi = math.max(ha_close, ha_open)
C_BodyLo = math.min(ha_close, ha_open)
C_Body = C_BodyHi - C_BodyLo
C_BodyAvg = ta.ema(C_Body, C_Len)
C_SmallBody = C_Body < C_BodyAvg
C_LongBody = C_Body > C_BodyAvg
C_UpShadow = ha_high - C_BodyHi
C_DnShadow = C_BodyLo - ha_low
C_HasUpShadow = C_UpShadow > C_ShadowPercent / 100 * C_Body
C_HasDnShadow = C_DnShadow > C_ShadowPercent / 100 * C_Body
C_WhiteBody = ha_open < ha_close
C_BlackBody = ha_open > ha_close
C_Range = ha_high-ha_low
C_IsInsideBar = C_BodyHi[1] > C_BodyHi and C_BodyLo[1] < C_BodyLo
C_BodyMiddle = C_Body / 2 + C_BodyLo
C_ShadowEquals = C_UpShadow == C_DnShadow or (math.abs(C_UpShadow - C_DnShadow) / C_DnShadow * 100) < C_ShadowEqualsPercent and (math.abs(C_DnShadow - C_UpShadow) / C_UpShadow * 100) < C_ShadowEqualsPercent
C_IsDojiBody = C_Range > 0 and C_Body <= C_Range * C_DojiBodyPercent / 100
C_Doji = C_IsDojiBody and C_ShadowEquals

patternLabelPosLow = ha_low - (ta.atr(30) * 0.6)
patternLabelPosHigh = ha_high + (ta.atr(30) * 0.6)

label_color_neutral = input(color.gray, "Label Color Neutral")
C_DojiNumberOfCandles = 1
C_DragonflyDoji = C_IsDojiBody and C_UpShadow <= C_Body
C_GravestoneDojiOne = C_IsDojiBody and C_DnShadow <= C_Body
alertcondition(C_Doji and not C_DragonflyDoji and not C_GravestoneDojiOne, title = "New pattern detected", message = "New Doji pattern detected")
if C_Doji and not C_DragonflyDoji and not C_GravestoneDojiOne
    var ttDoji = "Doji\nWhen the open and close of a security are essentially equal to each other, a doji candle forms. The length of both upper and lower shadows may vary, causing the candlestick you are left with to either resemble a cross, an inverted cross, or a plus sign. Doji candles show the playout of buyer-seller indecision in a tug-of-war of sorts. As price moves either above or below the opening level during the session, the close is either at or near the opening level."
    label.new(bar_index, patternLabelPosLow, text="D", style=label.style_label_up, color = label_color_neutral, textcolor=color.white, tooltip = ttDoji)
bgcolor(ta.highest(C_Doji?1:0, C_DojiNumberOfCandles)!=0 ? color.new(color.gray, 90) : na, offset=-(C_DojiNumberOfCandles-1))