Multi Time Frame Normalized Price
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © peacefulLizard50262

//@version=5
indicator("Multi Time Frame Normalized Price", "MTFNP", false, max_lines_count = 500)

import peacefulLizard50262/Spider_Plot/2 as s

length = input.int(20, "STDEV LENGTH", 1)
multiplier = input.float(1, "STDEV MULTIPLIER")
axes_color = input.color(color.new(color.gray, 90), "Axes Color")
bottom_color = input.color(color.new(color.red, 10) , "Bottom Color")
top_color = input.color(color.new(color.blue, 10), "Top Color")
xpos = input.float(2, "X Position")
ypos = input.float(0, "Y Position")
scale = input.float(30, "Scale")

cosh(float x) =>
    (math.exp(x) + math.exp(-x)) / 2

// Custom acosh function
acosh(float x) =>
    x < 1 ? na : math.log(x + math.sqrt(x * x - 1))

// Custom sinh function
sinh(float x) =>
    (math.exp(x) - math.exp(-x)) / 2

// Custom asinh function
asinh(float x) =>
    math.log(x + math.sqrt(x * x + 1))

// Custom inverse tangent function
atan(float x) =>
    math.pi / 2 - math.atan(1 / x)
// Chebyshev Type I Moving Average
chebyshevI(float src, float len, float ripple) =>
    a = 0.
    b = 0.
    g = 0.
    chebyshev = 0.
    
    a := cosh(1 / len * acosh(1 / (1 - ripple)))
    b := sinh(1 / len * asinh(1 / ripple))
    g := (a - b) / (a + b)
    chebyshev := (1 - g) * src + g * nz(chebyshev[1])
    chebyshev

normalizedPrice(int length, float multiplier) =>
    upper = chebyshevI(high, 62, 0.01)
    lower = chebyshevI(low, 62, 0.01) 

    mean = math.avg(upper, lower)

    stdev = math.sqrt(math.sum(math.pow(close - mean, 2), length) / length - 1)

    price = chebyshevI(close, 26, 0.01) - mean

    bot = lower - mean - stdev * multiplier
    top = upper - mean + stdev * multiplier

    normalized = (price - bot) / (top - bot)
    math.max(math.min(nz(normalized, nz(normalized[1])), 1), 0)

time_1 = normalizedPrice(length, multiplier)
time_2 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 2)), normalizedPrice(length, multiplier))
time_3 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 3)), normalizedPrice(length, multiplier))
time_4 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 4)), normalizedPrice(length, multiplier))
time_5 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 5)), normalizedPrice(length, multiplier))
time_6 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 6)), normalizedPrice(length, multiplier))
time_7 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 7)), normalizedPrice(length, multiplier))
time_8 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 8)), normalizedPrice(length, multiplier))
time_9 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 9)), normalizedPrice(length, multiplier))
time_10 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 10)), normalizedPrice(length, multiplier))
time_11 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 11)), normalizedPrice(length, multiplier))
time_12 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 12)), normalizedPrice(length, multiplier))
time_13 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 13)), normalizedPrice(length, multiplier))
time_14 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 14)), normalizedPrice(length, multiplier))
time_15 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 15)), normalizedPrice(length, multiplier))
time_16 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 16)), normalizedPrice(length, multiplier))
time_17 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 17)), normalizedPrice(length, multiplier))
time_18 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 18)), normalizedPrice(length, multiplier))
time_19 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 19)), normalizedPrice(length, multiplier))
time_20 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 20)), normalizedPrice(length, multiplier))
time_21 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 21)), normalizedPrice(length, multiplier))
time_22 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 22)), normalizedPrice(length, multiplier))
time_23 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 23)), normalizedPrice(length, multiplier))
time_24 = request.security(syminfo.tickerid, str.tostring(int(str.tonumber(timeframe.period) * 24)), normalizedPrice(length, multiplier))

color_1 = color.from_gradient(time_1, 0, 1, bottom_color, top_color)
color_2 = color.from_gradient(time_2, 0, 1, bottom_color, top_color)
color_3 = color.from_gradient(time_3, 0, 1, bottom_color, top_color)
color_4 = color.from_gradient(time_4, 0, 1, bottom_color, top_color)
color_5 = color.from_gradient(time_5, 0, 1, bottom_color, top_color)
color_6 = color.from_gradient(time_6, 0, 1, bottom_color, top_color)
color_7 = color.from_gradient(time_7, 0, 1, bottom_color, top_color)
color_8 = color.from_gradient(time_8, 0, 1, bottom_color, top_color)
color_9 = color.from_gradient(time_9, 0, 1, bottom_color, top_color)
color_10 = color.from_gradient(time_10, 0, 1, bottom_color, top_color)
color_11 = color.from_gradient(time_11, 0, 1, bottom_color, top_color)
color_12 = color.from_gradient(time_12, 0, 1, bottom_color, top_color)
color_13 = color.from_gradient(time_13, 0, 1, bottom_color, top_color)
color_14 = color.from_gradient(time_14, 0, 1, bottom_color, top_color)
color_15 = color.from_gradient(time_15, 0, 1, bottom_color, top_color)
color_16 = color.from_gradient(time_16, 0, 1, bottom_color, top_color)
color_17 = color.from_gradient(time_17, 0, 1, bottom_color, top_color)
color_18 = color.from_gradient(time_18, 0, 1, bottom_color, top_color)
color_19 = color.from_gradient(time_19, 0, 1, bottom_color, top_color)
color_20 = color.from_gradient(time_20, 0, 1, bottom_color, top_color)
color_21 = color.from_gradient(time_21, 0, 1, bottom_color, top_color)
color_22 = color.from_gradient(time_22, 0, 1, bottom_color, top_color)
color_23 = color.from_gradient(time_23, 0, 1, bottom_color, top_color)
color_24 = color.from_gradient(time_24, 0, 1, bottom_color, top_color)

data = array.from(
   time_1
 , time_2
 , time_3
 , time_4
 , time_5
 , time_6
 , time_7
 , time_8
 , time_9
 , time_10
 , time_11
 , time_12
 , time_13
 , time_14
 , time_15
 , time_16
 , time_17
 , time_18
 , time_19
 , time_20
 , time_21
 , time_22
 , time_23
 , time_24
 , time_23
 , time_22
 , time_21
 , time_20
 , time_19
 , time_18
 , time_17
 , time_16
 , time_15
 , time_14
 , time_13
 , time_12
 , time_11
 , time_10
 , time_9
 , time_8
 , time_7
 , time_6
 , time_5
 , time_4
 , time_3
 , time_2
 )

color_data = array.from(
   color_1
 , color_2
 , color_3
 , color_4
 , color_5
 , color_6
 , color_7
 , color_8
 , color_9
 , color_10
 , color_11
 , color_12
 , color_13
 , color_14
 , color_15
 , color_16
 , color_17
 , color_18
 , color_19
 , color_20
 , color_21
 , color_22
 , color_23
 , color_24
 , color_23
 , color_22
 , color_21
 , color_20
 , color_19
 , color_18
 , color_17
 , color_16
 , color_15
 , color_14
 , color_13
 , color_12
 , color_11
 , color_10
 , color_9
 , color_8
 , color_7
 , color_6
 , color_5
 , color_4
 , color_3
 , color_2
 )

s.draw_spider_plot(data, color_data, axes_color, scale, xpos, ypos)
