Z-Score Heikin-Ashi Transformed
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © QuantiLuxe

//@version=5
indicator("Z-Score Heikin Ashi Transformed", "[Ʌ] - 𝘡 𝘏-𝘈", false)

type bar
    float o = open
    float h = high
    float l = low
    float c = close

method src(bar b, simple string src) =>
    float x = switch src
        'oc2'   => math.avg(b.o, b.c          )
        'hl2'   => math.avg(b.h, b.l          )
        'hlc3'  => math.avg(b.h, b.l, b.c     )
        'ohlc4' => math.avg(b.o, b.h, b.l, b.c)
        'hlcc4' => math.avg(b.h, b.l, b.c, b.c)

    x

method ha(bar b, simple bool p = true) =>
    var bar x = bar.new(       )
    x.c      := b  .src('ohlc4')
    x        := bar.new(
         na(x.o[1]) ? 
             b.src('oc2') : nz(x.src('oc2')[1]),
         math.max(b.h, math.max(x.o, x.c))     ,
         math.min(b.l, math.min(x.o, x.c))     ,
         x.c                                   )

    p ? x : b

f_z(float src, simple int len) =>

    (src - ta.sma(src, len)) / ta.stdev(src, len)

method z(bar b, simple int len) =>
    bar x = bar.new(
         f_z(b.o, len),
         f_z(b.h, len),
         f_z(b.l, len),
         f_z(b.c, len))

    x


var string gz = "Z-Score", var string ge = "EMAs"
len  = input.int (21   , "Z Period"      ,                          group = gz)
revs = input.bool(true , "Reversions"    ,            inline = '0', group = gz)
revt = input.int (2    , "Threshold"     , [1, 2, 3], inline = '0', group = gz)
hol  = input.bool(true , "Hollow Candles",                          group = gz)
ma1  = input.bool(true , "EMA  |"        ,            inline = '1', group = ge)
len1 = input.int (20   , "Length"        ,            inline = '1', group = ge)
ma2  = input.bool(false, "EMA  |"        ,            inline = '2', group = ge)
len2 = input.int (50   , "Length"        ,            inline = '2', group = ge)


bar score = bar.new().ha().z(len)


var color colup   = #fff2cc
var color coldn   = #6fa8dc
var color colema1 = #FFD6E8
var color colema2 = #9a9adf

color haColor = switch
    score.c > score.o => colup
    score.c < score.o => coldn

plotcandle(score.o, score.h, score.l, score.c, "𝘚𝘤𝘰𝘳𝘦",
     hol ? score.c < score.o ? haColor : na : haColor, haColor, bordercolor = haColor)

plot(ma1 ? ta.ema(score.c, len1) : na, "𝘌𝘔𝘈 1", colema1)
plot(ma2 ? ta.ema(score.c, len2) : na, "𝘌𝘔𝘈 2", colema2)

hline(0, "Mid Line", chart.fg_color, hline.style_solid)

min = hline(-4, display = display.none)
ll  = hline(-3, display = display.none)
hl  = hline(-2, display = display.none)
max = hline(4 , display = display.none)
hh  = hline(3 , display = display.none)
lh  = hline(2 , display = display.none)

fill(lh, hh , color = #9a9adf2a)
fill(hh, max, color = #9a9adf4d)
fill(ll, hl , color = #ffd6e83b)
fill(ll, min, color = #ffd6e85e)

plotshape(revs ? score.h >  revt and score.h < score.h[1] and not (score.h[1] < score.h[2]) ? score.h + 0.75 : na : na, "OB", shape.triangledown, location.absolute, colema1, size = size.tiny)
plotshape(revs ? score.l < -revt and score.l > score.l[1] and not (score.l[1] > score.l[2]) ? score.l - 0.75 : na : na, "OS", shape.triangleup  , location.absolute, colema2, size = size.tiny)

//Source Construction For Indicator\Strategy Exports
plot(score.o           , "open" , editable = false, display = display.none)
plot(score.h           , "high" , editable = false, display = display.none)
plot(score.l           , "low"  , editable = false, display = display.none)
plot(score.c           , "close", editable = false, display = display.none)
plot(score.src('hl2'  ), "hl2"  , editable = false, display = display.none)
plot(score.src('hlc3' ), "hlc3" , editable = false, display = display.none)
plot(score.src('ohlc4'), "ohlc4", editable = false, display = display.none)
plot(score.src('hlcc4'), "hlcc4", editable = false, display = display.none)