T3 JMA KAMA VWMA
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © simwai

//@version=5
indicator('T3 JMA KAMA VWMA', shorttitle='C_VWMA', overlay=true)
// C_ -> Custom

// -- Inputs --
string indicatorMaType = input.string(defval='T3', title='Choose MA', options=['KAMA', 'T3', 'JMA'], group='General', inline='1')
string resolution = input.timeframe('', 'Choose Resolution', group='General', inline='2')
int length = input.int(3, 'Length', group='General', inline='2')
float t3Hot = input.float(title='T3 – Smoothing Factor (hot)', defval=0.5, step=0.1, minval=0.00001, group='General', inline='2')
string t3Type = input.string(title='T3 – Type', defval='T3 New', options=['T3 Normal', 'T3 New'], group='General', inline='2')
int jmaPhase = input.int(title='JMA – Phase', defval=50, minval=-100, maxval=100, tooltip='The phase is used to shift the input data before applying the smoothing algorithm. The phase shift can help to identify the turning points of the data.', group='General', inline='3')
int jmaPower = input.int(title='JMA – Power', defval=2, minval=2, tooltip='The power is used to adjust the sensitivity of the JMA to changes in the input data. Higher values of the power will make the JMA more sensitive to changes in the data.', group='General', inline='3')

// -- Colors --
color myGreen = color.rgb(0, 183, 165)
color myPurple = color.rgb(172, 78, 255)

// -- Global State --
[_close, _volume, _high, _low] = request.security(syminfo.tickerid, resolution, expression=[close[1], volume[1], high[1], low[1]], lookahead=barmerge.lookahead_on, gaps=barmerge.gaps_off)

// -- Functions --
tr() => 
    math.max(math.max(_high - _low, math.abs(_high - _close[1])), math.abs(_low - _close[1]))

// Jurik Moving Average (JMA) - Credits to @everget
jma(float _src, int _length, int _phase=50, int _power=2) => 
    phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5
    beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2)
    alpha = math.pow(beta, _power)
    jma = 0.0
    e0 = 0.0
    e0 := (1 - alpha) * _src + alpha * nz(e0[1])
    e1 = 0.0
    e1 := (_src - e0) * (1 - beta) + beta * nz(e1[1])
    e2 = 0.0
    e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1])
    jma := e2 + nz(jma[1])    

// Kaufman's Adaptive Moving Average (KAMA)
kama(float _src, int _period) =>
    if (bar_index > _period)
        tmpVal = 0.0
        tmpVal := nz(tmpVal[1]) +  math.pow(((math.sum(math.abs(_src - _src[1]), _period) != 0) ? (math.abs(_src - _src[_period]) / math.sum(math.abs(_src - _src[1]), _period)) : 0) * (0.666 - 0.0645) + 0.0645, 2) * (_src - nz(tmpVal[1]))
        tmpVal

// T3 - Credits to @loxx
t3(float _src, float _length, float hot=1, string clean='T3')=>
    a = hot
    _c1 = -a * a * a
    _c2 = 3 * a * a + 3 * a * a * a
    _c3 = -6 * a * a - 3 * a - 3 * a * a * a
    _c4 = 1 + 3 * a + a * a * a + 3 * a * a
    
    alpha = 0.
    
    if (clean == 'T3 New')
        alpha := 2.0 / (2.0 + (_length - 1.0) / 2.0)
    else 
        alpha := 2.0 / (1.0 + _length)
    
    _t30 = _src, _t31 = _src
    _t32 = _src, _t33 = _src
    _t34 = _src, _t35 = _src
    
    _t30 := nz(_t30[1]) + alpha * (_src -  nz(_t30[1]))
    _t31 := nz(_t31[1]) + alpha * (_t30 - nz(_t31[1]))
    _t32 := nz(_t32[1]) + alpha * (_t31 - nz(_t32[1]))
    _t33 := nz(_t33[1]) + alpha * (_t32 - nz(_t33[1]))
    _t34 := nz(_t34[1]) + alpha * (_t33 - nz(_t34[1]))
    _t35 := nz(_t35[1]) + alpha * (_t34 - nz(_t35[1]))
    out =
         _c1 * _t35 + _c2 * _t34 +
         _c3 * _t33 +  _c4 * _t32
    out

// Volume Weighted Custom Moving Averages
t3Vwma(float _src, float _volume, int _period, float _t3Hot=0.5, _t3Type='T3 Normal') =>
    t3(_src * _volume, _period, _t3Hot, _t3Type) / t3(_volume, _period, _t3Hot, _t3Type)

jmaVwma(float _src, float _volume, int _period, int _phase=50, int _power=2) =>
    jma(_src * _volume, _period, _phase, _power) / jma(_volume, _period, _phase, _power)

kamaVwma(float _src, float _volume, int _period) =>
    kama(_src * _volume, _period) / kama(_volume, _period)

// Hann Window Smoothing – Credits to @cheatcountry
doHannWindow(float _series, float _hannWindowLength) =>
    sum = 0.0, coef = 0.0
    for i = 1 to _hannWindowLength
        cosine = 1 - math.cos(2 * math.pi * i / (_hannWindowLength + 1))
        sum := sum + (cosine * nz(_series[i - 1]))
        coef := coef + cosine
    h = coef != 0 ? sum / coef : 0

atr(atrLength) => 
    float tr = tr()
    // jma(tr, atrLength)
    doHannWindow(tr, atrLength)

normalize(float _src, int _min, int _max) =>
    var float _historicMin = 1.0
    var float _historicMax = -1.0
    _historicMin := math.min(nz(_src, _historicMin), _historicMin)
    _historicMax := math.max(nz(_src, _historicMax), _historicMax)
    _min + (_max - _min) * (_src - _historicMin) / math.max(_historicMax - _historicMin, 1)

angle(_src) =>
    rad2degree=180/3.14159265359  //pi 
    ang=rad2degree*math.atan((_src[0] - _src[1])/atr(14)) 
    nAngle = normalize(ang, 0, 1)
    nAngle

// -- Calculation --
t3Vwma = t3Vwma(_close, _volume, length, t3Hot, t3Type)
jmaVwma = jmaVwma(_close, _volume, length)
kamaVwma = kamaVwma(_close, _volume, length)

float myVwma = switch indicatorMaType
    'T3' => t3Vwma
    'JMA' => jmaVwma
    'KAMA' => kamaVwma

maAngle = angle(myVwma)
angleGradient = color.from_gradient(maAngle, 0.1, 0.9, myPurple, myGreen)
plot(myVwma, 'C_VWMA', linewidth=2, color=angleGradient)

barcolor(maAngle > 0.7 ? myGreen : maAngle < 0.3 ? myPurple : color.new(color.silver, 25))