ALMA Trendline
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © syamsularifinirpan

//@version=5
indicator(title='ALMA Trendline', shorttitle='ALMA Trendline', overlay=true, format=format.price, precision=3)

// Price Source with Kalman Filter
    //value1 = swma(p-p[1])
    //value1 = Movement Uncertainty
    //0.8 = Kalman Gain 1 (The 'Kalman Gain' allows the user to choose how much error to let into the calculation. The smaller this number is the quicker the moving average will approach price action. setting from 0.01-1.1)
    //0.2 = Ratio of uncertainties 1 (The 'Ratio of Uncertainties' controls how adaptive the moving averages are, increasing this number will increase adaptivity and vice versa for decreasing. setting from 0.01 and above)
    //value2 = swma(tr)
    //value2 = Measurement Uncertainty
    //0.8 = Kalman Gain 2 (The 'Kalman Gain' allows the user to choose how much error to let into the calculation. The smaller this number is the quicker the moving average will approach price action. setting from 0.01-1.1)

k_gain1 = input.float(title="k Gain 1", defval=0.8, minval = 0.01, step = 0.01)
k_gain2 = input.float(title="k Gain 2", defval=0.8, minval = 0.01, step = 0.01)
u_ratio1 = input.float(title="u Ratio 1", defval=0.2, minval = 0.01, step = 0.01)
u_ratio2 = input.float(title="u Ratio 2", defval=0.1, minval = 0.01, step = 0.01)

f_klmf(_src) =>
    p = _src
    value1 = float(na)
    value1 := u_ratio1 * (p - p[1]) + k_gain1 * nz(value1[1])
    value2 = float(na)
    value2 := u_ratio2 * ta.tr + k_gain2 * nz(value2[1])
    lambda = math.abs(value1 / value2)
    alpha = (-math.pow(lambda, 2) + math.sqrt(math.pow(lambda, 4) + 16 * math.pow(lambda, 2)))/8
    klmf = float(na)
    klmf := alpha * p + (1 - alpha) * nz(klmf[1])
    klmf

kalman_close =f_klmf(close)
kalman_open =f_klmf(open)
kalman_high =f_klmf(high)
kalman_low =f_klmf(low)
kalman_hl2 =f_klmf(hl2)
kalman_hlc3 =f_klmf(hlc3)
kalman_ohlc4 =f_klmf(ohlc4)

// ALMA Trend
    //Using Fast, Slow and Trend ALMA.
    //Bullish momentum is identified when price is closing above the Dominant Momentum MA, and the Short-term MA is above the Dominant MA. Vice versa for bearish momemntum.
    //There are in-between points when a trend is not identified, and this is when price closes above or below the Trend ma, but the Short-term MA has not crossed it.

//Quick-term ALMA
ALMA2_src = close
ALMA2_length = 6
ALMA2_offset = 0.85
ALMA2_sigma = 6
kalman_ALMA2  = f_klmf(ALMA2_src)
ALMA2 = ta.alma(ALMA2_src, ALMA2_length, ALMA2_offset, ALMA2_sigma)

//ALMA Trendline
Short_TL_display = input(title='Show Traling Line (ALMA Trendline): On/Off', defval=true)
_Short_TL_src = input.string(title=' >>ALMA Trendline Source: default=kalman_close)', defval='kalman_close', options=['Close', 'Open', 'High', 'Low', 'hl2', 'hlc3', 'ohlc4', 'kalman_close', 'kalman_open', 'kalman_low', 'kalman_high', 'kalman_hl2', 'kalman_hlc3', 'kalman_ohlc4'])
Short_TL_src = _Short_TL_src=="Close"?close:
                 _Short_TL_src=="Open"?open:
                     _Short_TL_src=="High"?high:
                         _Short_TL_src=="Low"?low:
                             _Short_TL_src=="hl2"?hl2:
                                 _Short_TL_src=="hlc3"?hlc3:
                                      _Short_TL_src=="ohlc4"?ohlc4:
                                         _Short_TL_src=="kalman_close"?kalman_close:
                                             _Short_TL_src=="kalman_open"?kalman_open:
                                                 _Short_TL_src=="kalman_low"?kalman_low:
                                                     _Short_TL_src=="kalman_high"?kalman_high:
                                                         _Short_TL_src=="kalman_hl2"?kalman_hl2:
                                                             _Short_TL_src=="kalman_hlc3"?kalman_hlc3:kalman_ohlc4
Short_TL_length = input.int(title=" >>ALMA Trendline Length", defval=18, minval=7, maxval=200)
Short_TL_offset = input.float(title=" >>ALMA Trendline Offset", defval=0.85, minval = 0.025, step = 0.025)
Short_TL_sigma = input.float(title=" >>ALMA Trendline Sigma", defval=50, minval = 0.5, step = 0.5)
Short_TL = ta.alma(Short_TL_src, Short_TL_length, Short_TL_offset, Short_TL_sigma)
Short_TL_color = close[1] > Short_TL ? color.new(#66bb6a,50) : color.new(#ef5350,50)

plot(Short_TL, color=Short_TL_color, linewidth=2, title="ALMA Trendline")