MESA Stochastic Multi Length
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © veryfid
// Uses MESA Stochastic code published by @blackcat1402 as open source under the terms of the Mozilla Public License 2.0
//####################
// optimized by  jojogoop
//  - converted to v5
//  - modified smoothing, now indicator reacting faster to price change
//  - rewrote code and functions, now just 1 function handles all lengths, and is called only once

//@version=5

indicator(title='MESA Stochastic Multi Length', shorttitle='MESAStochML', overlay=false)

PI = float(3.14)

//=============== MESA Function 
_mesa(len,src, PI) =>
    a1 = 0.00
    b1 = 0.00
    c1 = 0.00
    c2 = 0.00
    c3 = 0.00
    alpha1 = 0.00
    HP = 0.00
    Filt = 0.00
    HighestC = 0.00
    LowestC = 0.00
    Stoc = 0.00
    MESAStochastic = 0.00
    Trigger = 0.00
    pi = PI


    alpha1 := (math.cos(0.707 * 2 * pi / 48) + math.sin(0.707 * 2 * pi / 48) - 1) / math.cos(0.707 * 2 * pi / 48)
    HP := (1 - alpha1 / 2) * (1 - alpha1 / 2) * (src - 2 * nz(src[1]) + nz(src[2])) + 2 * (1 - alpha1) * nz(HP[1]) - (1 - alpha1) * (1 - alpha1) * nz(HP[2])

    a1 := math.exp(-1.414 * pi / 10)
    b1 := 2 * a1 * math.cos(1.414 * pi / 10)
    c2 := b1
    c3 := -a1 * a1
    c1 := 1 - c2 - c3
    Filt := c1 * (HP + nz(HP)) / 2 + c2 * nz(Filt[1]) + c3 * nz(Filt[2])

    HighestC := Filt
    LowestC := Filt

    for count = 0 to len - 1 by 1
        if nz(Filt[count]) > HighestC
            HighestC := nz(Filt[count])
            HighestC
        if nz(Filt[count]) < LowestC
            LowestC := nz(Filt[count])
            LowestC

    Stoc := (Filt - LowestC) / (HighestC - LowestC)
    //MESAStochastic := c1 * (Stoc + nz(Stoc[1])) / 2 + c2 * nz(MESAStochastic[1]) + c3 * nz(MESAStochastic[2])
    MESAStochastic := c1 * (Stoc + nz(Stoc)) / 2 + c2 * nz(MESAStochastic[1]) + c3 * nz(MESAStochastic[2])
    MESAStochastic


//==================Inputs
Price = input.source(close, title='Source')
Length1 = input.int(48, title='Length #1', group='MESA Stochastic')
Length2 = input.int(21, title='Length #2', group='MESA Stochastic')
Length3 = input.int(9,  title='Length #3', group='MESA Stochastic')
Length4 = input.int(6,  title='Length #4', group='MESA Stochastic')

show_trigger = input(false, title='Show Trigger', group='Trigger')
trig = input.int(2, title='Trigger Length', group='Trigger')


poscol = input.color(color.blue, title='Positive Color', group='Colors')
negcol = input.color(color.red, title='Negative Color', group='Colors')
ncol = input.color(color.red, title='Neutral Color', group='Colors')


//================ Calculations

ms1 = _mesa(Length1, Price, PI)
ms2 = _mesa(Length2, Price, PI)
ms3 = _mesa(Length3, Price, PI)
ms4 = _mesa(Length4, Price, PI)

trigger1 = ta.sma(ms1, trig)
trigger2 = ta.sma(ms2, trig)
trigger3 = ta.sma(ms3, trig)
trigger4 = ta.sma(ms4, trig)

col1 = ta.change(ms1) > 0 ? poscol : ta.change(ms1) < 0 ? negcol : ncol
col2 = ta.change(ms2) > 0 ? poscol : ta.change(ms2) < 0 ? negcol : ncol
col3 = ta.change(ms3) > 0 ? poscol : ta.change(ms3) < 0 ? negcol : ncol
col4 = ta.change(ms4) > 0 ? poscol : ta.change(ms4) < 0 ? negcol : ncol

//===============Plotting
plot1 = plot(ms1, 'MESAStochastic 1', color=col1, linewidth=1)
plot2 = plot(show_trigger ? trigger1 : na, 'Trigger 1', color=color.new(#2962ff, 0), linewidth=1)

plot3 = plot(ms2, 'MESAStochastic 2', color=col2, linewidth=1)
plot4 = plot(show_trigger ? trigger2 : na, 'Trigger 2', color=color.new(#2962ff, 0), linewidth=1)

plot5 = plot(ms3, 'MESAStochastic 3', color=col3, linewidth=1)
plot6 = plot(show_trigger ? trigger3 : na, 'Trigger 3', color=color.new(#2962ff, 0), linewidth=1)

plot7 = plot(ms4, 'MESAStochastic 4', color=col4, linewidth=1)
plot8 = plot(show_trigger ? trigger4 : na, 'Trigger 4', color=color.new(#2962ff, 0), linewidth=1)

