twopirllc / pandas-ta

Technical Analysis Indicators - Pandas TA is an easy to use Python 3 Pandas Extension with 150+ Indicators
https://twopirllc.github.io/pandas-ta/
MIT License
5.22k stars 1.02k forks source link

Trend Regularity Adaptive Moving Average [LUX] #603

Open Jacks349 opened 1 year ago

Jacks349 commented 1 year ago

Would be awesome to see this indicator on pandas_ta! It's a moving average that adapts to the current trend by taking into account the average of high/lows during a selected period. Link: https://www.tradingview.com/v/p8wGCPi6/

Pinescript code:

// This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo

//@version=4
study("Trend Regularity Adaptive Moving Average","TRAMA",overlay=true)
length=input(99),src = input(close)
//----
ama = 0.
hh = max(sign(change(highest(length))),0)
ll = max(sign(change(lowest(length))*-1),0)
tc = pow(sma(hh or ll ? 1 : 0,length),2)
ama := nz(ama[1]+tc*(src-ama[1]),src)
plot(ama,"Plot",#ff1100,2)

My attempt: i'm not so good at pinescript, and i'm having a lot of troubles understanding how to translate the lines tc = pow(sma(hh or ll ? 1 : 0,length),2) and ama := nz(ama[1]+tc*(src-ama[1]),src) to Python.

Until now i managed to convert the first lines to Python, but i'm not sure if i'm doing it right:

#for each row's close, get the highest value in the last n rows
ohlcv['hh'] = ohlcv['close'].rolling(window=99).max().shift(1).fillna(0)
ohlcv['ll'] = ohlcv['close'].rolling(window=99).min().shift(1).fillna(0)
ohlcv['ll'] = ohlcv['ll']*-1

#diff between current hh row and previous row
ohlcv['hh'] = ohlcv['hh'].diff()
ohlcv['ll'] = ohlcv['hh'].diff()

#set ohlcv['hh'] to 1 if it's greater than 0, 0 if equal to zero else -1
ohlcv['hh'] = np.where(ohlcv['hh'] > 0, 1, np.where(ohlcv['hh'] == 0, 0, -1))
ohlcv['ll'] = np.where(ohlcv['ll'] > 0, 1, np.where(ohlcv['ll'] == 0, 0, -1))

#set ohlcv['hh'] to ohlcv['hh'] if higher than 0, else 0
ohlcv['hh'] = np.where(ohlcv['hh'] > 0, ohlcv['hh'], 0)
ohlcv['ll'] = np.where(ohlcv['ll'] > 0, ohlcv['ll'], 0)
twopirllc commented 1 year ago

Hello @Jacks349,

Sure it could be added. However if you or someone would like to make a PR, that would be the fastest way to get it included. 😎 I am currently blocked on existing PRs and outstanding bugs.

Kind Regards KJ

d1210182010 commented 1 year ago

@twopirllc @Jacks349

Here is my python implementation of TRAMA modified from C# version.

I hope it shall be helpful to you.

def trama(close, length=100):
    high = pd.Series(close).rolling(window=length, min_periods=1).max().values
    low = pd.Series(close).rolling(window=length, min_periods=1).min().values

    hh = (high - np.roll(high, 1)) > 0
    ll = (low - np.roll(low, 1)) < 0
    hl = np.logical_or(hh, ll).astype(float)

    sma = talib.SMA(hl, length)

    tc = np.power(sma, 2)

    result = np.empty(len(close))
    result[:] = np.nan

    for i in range(1, len(close)):
        if np.isnan(result[i-1]):
            result[i] = close[i]
        else:
            result[i] = result[i-1] + tc[i] * (close[i] - result[i-1])

    return result