Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please add OTT (Optimized trend tracker) to Pandas_TA #387

Open
mhgutier opened this issue Sep 4, 2021 · 4 comments
Open

Please add OTT (Optimized trend tracker) to Pandas_TA #387

mhgutier opened this issue Sep 4, 2021 · 4 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@mhgutier
Copy link

mhgutier commented Sep 4, 2021

Hi Kevin,

Please help to add OTT to pandas_ta by KivancOzbilgicin trading view.

i converted the pinescript to python, it has correct output though my logic seems to be not efficient as it takes 10 seconds or so to calculate.
i think it has almost similar logic with QQE. Thanks in advance

=================
my version

   #OTT variables
    pds = 2
   percent = 1.4
    alpha = 2 / (pds + 1)
    df['atr'] = talib.ATR(df['high'], df['low'], df['close'], timeperiod=14)
    np_atr = np.array(df['atr'])
    ratr = format(np_atr[-2], '.4f')

    df['ud1'] = np.where(df['close'] > df['close'].shift(1), (df['close'] - df['close'].shift()) , 0)
    df['dd1'] = np.where(df['close'] < df['close'].shift(1), (df['close'].shift() - df['close']) , 0)
    df['UD'] = talib.SUM(df['ud1'], timeperiod=9)
    df['DD'] = talib.SUM(df['dd1'], timeperiod=9)
    df['CMO'] = ((df['UD'] - df['DD']) / (df['UD'] + df['DD'])).fillna(0).abs()
    
    # df['Var'] = talib.EMA(df['close'], timeperiod=5)
    df['Var'] = 0.0
    for i in range(pds, len(df)):
        df['Var'].iat[i] = (alpha * df['CMO'].iat[i] * df['close'].iat[i]) + (1 - alpha * df['CMO'].iat[i]) * df['Var'].iat[i-1]

    df['fark'] = df['Var'] * percent * 0.01
    df['newlongstop'] = df['Var'] - df['fark']
    df['newshortstop'] = df['Var'] + df['fark']
    df['longstop'] = 0.0
    df['shortstop'] = 999999999999999999
    # df['dir'] = 1
    for i in df['RSI_MA']:

        def maxlongstop():
            df.loc[(df['newlongstop'] > df['longstop'].shift(1)) , 'longstop'] = df['newlongstop']
            df.loc[(df['longstop'].shift(1) > df['newlongstop']), 'longstop'] = df['longstop'].shift(1) 
            
            return df['longstop']

        def minshortstop():
            df.loc[(df['newshortstop'] < df['shortstop'].shift(1)), 'shortstop'] = df['newshortstop']
            df.loc[(df['shortstop'].shift(1) < df['newshortstop']), 'shortstop'] = df['shortstop'].shift(1)
            
            return df['shortstop']

        df['longstop']= np.where (
            (
                (df['Var'] > df['longstop'].shift(1))
            ),maxlongstop(),df['newlongstop']
        )


        df['shortstop'] = np.where(
            (
                (df['Var'] < df['shortstop'].shift(1))
            ), minshortstop(), df['newshortstop'])

    #get xover
  
    df['xlongstop'] = np.where (
        (
            (df['Var'].shift(1) > df['longstop'].shift(1)) & 
            (df['Var'] < df['longstop'].shift(1))
        ), 1,0)

    df['xshortstop'] =np.where(
        (
            (df['Var'].shift(1) < df['shortstop'].shift(1)) & 
            (df['Var'] > df['shortstop'].shift(1))
        ), 1,0)

    df['trend']=0
    df['dir'] = 0
    for i in df['RSI_MA']:
            df['trend'] = np.where(
            (
                (df['xshortstop'] == 1)
            ),1, (np.where((df['xlongstop'] == 1),-1,df['trend'].shift(1)))
        )

            df['dir'] = np.where(
            (
                (df['xshortstop'] == 1)
            ),1, (np.where((df['xlongstop'] == 1),-1,df['dir'].shift(1).fillna(1)))
        )


    #get OTT

    df['MT'] = np.where(df['dir'] == 1, df['longstop'], df['shortstop'])
    df['OTT'] = np.where(df['Var'] > df['MT'], (df['MT'] * (200 + percent) / 200), (df['MT'] * (200 - percent) / 200))
    df['OTT'] = df['OTT'].shift(2) 
============
Pine version

//@version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © KivancOzbilgic

//created by: @Anil_Ozeksi
//developer: ANIL ÖZEKŞİ
//author: @kivancozbilgic

study("Optimized Trend Tracker","OTT", overlay=true)
src = input(close, title="Source")
length=input(2, "OTT Period", minval=1)
percent=input(1.4, "OTT Percent", type=input.float, step=0.1, minval=0)
showsupport = input(title="Show Support Line?", type=input.bool, defval=true)
showsignalsk = input(title="Show Support Line Crossing Signals?", type=input.bool, defval=true)
showsignalsc = input(title="Show Price/OTT Crossing Signals?", type=input.bool, defval=false)
highlight = input(title="Show OTT Color Changes?", type=input.bool, defval=false)
showsignalsr = input(title="Show OTT Color Change Signals?", type=input.bool, defval=false)
highlighting = input(title="Highlighter On/Off ?", type=input.bool, defval=true)
mav = input(title="Moving Average Type", defval="VAR", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"])
Var_Func(src,length)=>
    valpha=2/(length+1)
    vud1=src>src[1] ? src-src[1] : 0
    vdd1=src<src[1] ? src[1]-src : 0
    vUD=sum(vud1,9)
    vDD=sum(vdd1,9)
    vCMO=nz((vUD-vDD)/(vUD+vDD))
    VAR=0.0
    VAR:=nz(valpha*abs(vCMO)*src)+(1-valpha*abs(vCMO))*nz(VAR[1])
VAR=Var_Func(src,length)
Wwma_Func(src,length)=>
    wwalpha = 1/ length
    WWMA = 0.0
    WWMA := wwalpha*src + (1-wwalpha)*nz(WWMA[1])
WWMA=Wwma_Func(src,length)
Zlema_Func(src,length)=>
    zxLag = length/2==round(length/2) ? length/2 : (length - 1) / 2
    zxEMAData = (src + (src - src[zxLag]))
    ZLEMA = ema(zxEMAData, length)
ZLEMA=Zlema_Func(src,length)
Tsf_Func(src,length)=>
    lrc = linreg(src, length, 0)
    lrc1 = linreg(src,length,1)
    lrs = (lrc-lrc1)
    TSF = linreg(src, length, 0)+lrs
TSF=Tsf_Func(src,length)
getMA(src, length) =>
    ma = 0.0
    if mav == "SMA"
        ma := sma(src, length)
        ma

    if mav == "EMA"
        ma := ema(src, length)
        ma

    if mav == "WMA"
        ma := wma(src, length)
        ma

    if mav == "TMA"
        ma := sma(sma(src, ceil(length / 2)), floor(length / 2) + 1)
        ma

    if mav == "VAR"
        ma := VAR
        ma

    if mav == "WWMA"
        ma := WWMA
        ma

    if mav == "ZLEMA"
        ma := ZLEMA
        ma

    if mav == "TSF"
        ma := TSF
        ma
    ma
    
MAvg=getMA(src, length)
fark=MAvg*percent*0.01
longStop = MAvg - fark
longStopPrev = nz(longStop[1], longStop)
longStop := MAvg > longStopPrev ? max(longStop, longStopPrev) : longStop
shortStop =  MAvg + fark
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := MAvg < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir
MT = dir==1 ? longStop: shortStop
OTT=MAvg>MT ? MT*(200+percent)/200 : MT*(200-percent)/200
@mhgutier mhgutier added the enhancement New feature or request label Sep 4, 2021
@twopirllc twopirllc added the good first issue Good for newcomers label Sep 4, 2021
@twopirllc
Copy link
Owner

Hello @mhgutier,

Added it to the list. ✅

I appreciate that you shared both the source and your Python implementation. 😎

If you are feeling venturous, try the following guide: Creating a Custom Indicator: The Big 4. If not, hopefully someone can help implement this sooner. I'll keep you posted when it's ready on the development branch for testing.

Kind Regards,
KJ

@bibinvargheset
Copy link

@mhgutier
I was trying to run your code but df['RSI_MA']: is not done can share the the complete code?

@mhgutier
Copy link
Author

mhgutier commented Sep 21, 2021

Hi @twopirllc ,

Please see updated code below. please free to modify if needed. i am not a developer, just learned python in youtube , for me the code is slow unlike the way pandas_ta compute for super trend/qqe (super fast)

import pandas as pd
import numpy as np
import talib
import pandas_ta
import schedule
import ccxt

exchange = ccxt.binance()

pair='ETH/USDT'
ohlc = exchange.fetch_ohlcv(pair, timeframe='5m')
df = pd.DataFrame(ohlc, columns = ['time', 'open', 'high', 'low', 'close', 'volume'])


#OTT variables
pds = 2
percent = 1.4
alpha = 2 / (pds + 1)
df['atr'] = talib.ATR(df['high'], df['low'], df['close'], timeperiod=14)

df['ud1'] = np.where(df['close'] > df['close'].shift(1), (df['close'] - df['close'].shift()) , 0)
df['dd1'] = np.where(df['close'] < df['close'].shift(1), (df['close'].shift() - df['close']) , 0)
df['UD'] = talib.SUM(df['ud1'], timeperiod=9)
df['DD'] = talib.SUM(df['dd1'], timeperiod=9)
df['CMO'] = ((df['UD'] - df['DD']) / (df['UD'] + df['DD'])).fillna(0).abs()


df['Var'] = 0.0
for i in range(pds, len(df)):
    df['Var'].iat[i] = (alpha * df['CMO'].iat[i] * df['close'].iat[i]) + (1 - alpha * df['CMO'].iat[i]) * df['Var'].iat[i-1]

df['fark'] = df['Var'] * percent * 0.01
df['newlongstop'] = df['Var'] - df['fark']
df['newshortstop'] = df['Var'] + df['fark']
df['longstop'] = 0.0
df['shortstop'] = 999999999999999999

for i in (df['close']):

    def maxlongstop():
        df.loc[(df['newlongstop'] > df['longstop'].shift(1)) , 'longstop'] = df['newlongstop']
        df.loc[(df['longstop'].shift(1) > df['newlongstop']), 'longstop'] = df['longstop'].shift(1) 
        
        return df['longstop']

    def minshortstop():
        df.loc[(df['newshortstop'] < df['shortstop'].shift(1)), 'shortstop'] = df['newshortstop']
        df.loc[(df['shortstop'].shift(1) < df['newshortstop']), 'shortstop'] = df['shortstop'].shift(1)
        
        return df['shortstop']

    df['longstop']= np.where (
        (
            (df['Var'] > df['longstop'].shift(1))
        ),maxlongstop(),df['newlongstop']
    )


    df['shortstop'] = np.where(
        (
            (df['Var'] < df['shortstop'].shift(1))
        ), minshortstop(), df['newshortstop'])

#get xover

df['xlongstop'] = np.where (
    (
        (df['Var'].shift(1) > df['longstop'].shift(1)) & 
        (df['Var'] < df['longstop'].shift(1))
    ), 1,0)

df['xshortstop'] =np.where(
    (
        (df['Var'].shift(1) < df['shortstop'].shift(1)) & 
        (df['Var'] > df['shortstop'].shift(1))
    ), 1,0)

df['trend']=0
df['dir'] = 0
for i in df['close']:
        df['trend'] = np.where(
        (
            (df['xshortstop'] == 1)
        ),1, (np.where((df['xlongstop'] == 1),-1,df['trend'].shift(1)))
    )

        df['dir'] = np.where(
        (
            (df['xshortstop'] == 1)
        ),1, (np.where((df['xlongstop'] == 1),-1,df['dir'].shift(1).fillna(1)))
    )


#get OTT

df['MT'] = np.where(df['dir'] == 1, df['longstop'], df['shortstop'])
df['OTT'] = np.where(df['Var'] > df['MT'], (df['MT'] * (200 + percent) / 200), (df['MT'] * (200 - percent) / 200))
df['OTT'] = df['OTT'].shift(2) 


#print OTT
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
pd.set_option('display.max_colwidth', None)
print(df[['close','Var','OTT']].round(2))

image

@twopirllc
Copy link
Owner

Hello @mhgutier,

I will look into it as soon as I can. I will let you know when it is available to testing on the development branch.

Kind Regards,
KJ

@twopirllc twopirllc removed their assignment Feb 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants