End Point Moving Average [EPMA]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © crypteisfuture

//@version=5
indicator("End Point Moving Average [EPMA]", overlay = true)

Get_EPMA(epma_source, epma_length) =>
    epma = ( epma_length * math.sum( ta.cum( 1 ) * epma_source, epma_length ) - math.sum( ta.cum( 1 ), epma_length) * math.sum( epma_source, epma_length) ) / (epma_length * math.sum( math.pow( ta.cum( 1 ), 2), epma_length ) - math.pow( math.sum( ta.cum( 1 ), epma_length ), 2 ) ) * ta.cum( 1 ) + (ta.ema(epma_source, epma_length) - ta.ema( ta.cum( 1 ), epma_length) * (epma_length * math.sum( ta.cum( 1 ) * epma_source, epma_length) - math.sum( ta.cum( 1 ), epma_length ) * math.sum( epma_source, epma_length) ) / (epma_length * math.sum( math.pow( ta.cum( 1 ), 2 ), epma_length) - math.pow( math.sum( ta.cum( 1 ), epma_length ), 2 ) ) )

Get_EPMA_Average(epma) =>
    epma_average = math.avg(epma[0], epma[1], epma[3], epma[5], epma[8], epma[13])



epma_source         = input.source(close, title = 'EPMA Source')
epma_length         = input.int(20, title = 'EPMA Length')

epma                = Get_EPMA(epma_source, epma_length)
epma_avg            = Get_EPMA_Average(epma)


show_high_low_epma  = input.bool(false, 'Show high/low EPMA only?')

epma_high_length     = input.int(50, title = 'High EPMA Length')
epma_high           = Get_EPMA(high, epma_high_length)
epma_high_avg       = Get_EPMA_Average(epma_high)

epma_low_length     = input.int(14, title = 'Low EPMA Length')
epma_low            = Get_EPMA(low, epma_low_length)
epma_low_avg        = Get_EPMA_Average(epma_low)


is_epma_underprice  = epma_avg > close

downtrend_color     = color.red
uptrend_color       = color.lime

epma_color          = is_epma_underprice ? downtrend_color : uptrend_color


plot(show_high_low_epma ? na : epma_avg, color    = color.new(epma_color, 0),     linewidth = 2)
plot(show_high_low_epma ? na : epma_avg[1], color = color.new(epma_color, 50),    linewidth = 2)
plot(show_high_low_epma ? na : epma_avg[2], color = color.new(epma_color, 60),    linewidth = 2)
plot(show_high_low_epma ? na : epma_avg[3], color = color.new(epma_color, 70),    linewidth = 2)
plot(show_high_low_epma ? na : epma_avg[4], color = color.new(epma_color, 80),    linewidth = 2)
plot(show_high_low_epma ? na : epma_avg[5], color = color.new(epma_color, 90),    linewidth = 2)


plot(show_high_low_epma ? epma_high_avg : na, color    = color.new(epma_color, 0),     linewidth = 2)
plot(show_high_low_epma ? epma_high_avg[1] : na, color = color.new(epma_color, 50),    linewidth = 2)
plot(show_high_low_epma ? epma_high_avg[2] : na, color = color.new(epma_color, 60),    linewidth = 2)
plot(show_high_low_epma ? epma_high_avg[3] : na, color = color.new(epma_color, 70),    linewidth = 2)
plot(show_high_low_epma ? epma_high_avg[4] : na, color = color.new(epma_color, 80),    linewidth = 2)
plot(show_high_low_epma ? epma_high_avg[5] : na, color = color.new(epma_color, 90),    linewidth = 2)

plot(show_high_low_epma ? epma_low_avg : na, color    = color.new(epma_color, 0),     linewidth = 2)
plot(show_high_low_epma ? epma_low_avg[1] : na, color = color.new(epma_color, 50),    linewidth = 2)
plot(show_high_low_epma ? epma_low_avg[2] : na, color = color.new(epma_color, 60),    linewidth = 2)
plot(show_high_low_epma ? epma_low_avg[3] : na, color = color.new(epma_color, 70),    linewidth = 2)
plot(show_high_low_epma ? epma_low_avg[4] : na, color = color.new(epma_color, 80),    linewidth = 2)
plot(show_high_low_epma ? epma_low_avg[5] : na, color = color.new(epma_color, 90),    linewidth = 2)