Giter Site home page Giter Site logo

Comments (53)

ysdede avatar ysdede commented on August 14, 2024 4

Hi, I came on this site while looking for an OTT indicator in Python, thanks to @tarantula3535 for inspiring me with his efforts.
I've built a Numpy/Numba-based version as well. At the time, just VAR is supported (EDIT: I've added Kaufman's Adaptive Moving Average (KAMA) and WMA), but adding ta-lib moving averages is straightforward. You can use it with freqtrade or the other frameworks relies on Pandas dataframe by converting pandas dfs to numpy array and vice versa. You can disable, remove, or install the part that uses Jesse's split tool.
Var indicator is currently incompatible with Numba and performs slowly, but it works; I've validated OTT output with Tradingview version.
custom_indicators
Suggestions and pull requests are welcome.

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024 3

hi... i use basic PMAX indicator.. here is the code.. anyone want to use it..

def PMAX(dataframe, period = 10, multiplier = 3, length=12, MAtype=1 ):
    """
    Function to compute SuperTrend
    
    Args :
        df : Pandas DataFrame which contains ['date', 'open', 'high', 'low', 'close', 'volume'] columns
        period : Integer indicates the period of computation in terms of number of candles
        multiplier : Integer indicates value to multiply the ATR
        length: moving averages length
        MAtype: type of the moving averafe 1 EMA 2 DEMA 3 T3 4 SMA 5 VIDYA
        
    Returns :
        df : Pandas DataFrame with new columns added for 
            True Range (TR), ATR (ATR_$period)
            PMAX (pm_$period_$multiplier_$length_$Matypeint)
            PMAX Direction (pmX_$period_$multiplier_$length_$Matypeint)
    """
    import talib.abstract as ta
    df = dataframe.copy()
    mavalue = 'MA_' + str(length)
    atr = 'ATR_' + str(period)
    df[atr]=ta.ATR(df , timeperiod = period)
    pm = 'pm_' + str(period) + '_' + str(multiplier) + '_' + str(length) + '_' + str(MAtype)
    pmx = 'pmX_' + str(period) + '_' + str(multiplier) + '_' + str(length) + '_' + str(MAtype)   
    """
    Pmax Algorithm :

        BASIC UPPERBAND = MA + Multiplier * ATR
        BASIC LOWERBAND = MA - Multiplier * ATR
        
        FINAL UPPERBAND = IF( (Current BASICUPPERBAND < Previous FINAL UPPERBAND) or (Previous Close > Previous FINAL UPPERBAND))
                            THEN (Current BASIC UPPERBAND) ELSE Previous FINALUPPERBAND)
        FINAL LOWERBAND = IF( (Current BASIC LOWERBAND > Previous FINAL LOWERBAND) or (Previous Close < Previous FINAL LOWERBAND)) 
                            THEN (Current BASIC LOWERBAND) ELSE Previous FINAL LOWERBAND)
        
        PMAX = IF((Previous PMAX = Previous FINAL UPPERBAND) and (Current Close <= Current FINAL UPPERBAND)) THEN
                        Current FINAL UPPERBAND
                    ELSE
                        IF((Previous PMAX = Previous FINAL UPPERBAND) and (Current Close > Current FINAL UPPERBAND)) THEN
                            Current FINAL LOWERBAND
                        ELSE
                            IF((Previous PMAX = Previous FINAL LOWERBAND) and (Current Close >= Current FINAL LOWERBAND)) THEN
                                Current FINAL LOWERBAND
                            ELSE
                                IF((Previous PMAX = Previous FINAL LOWERBAND) and (Current Close < Current FINAL LOWERBAND)) THEN
                                    Current FINAL UPPERBAND
    
    """
    # MAtype==1 --> EMA
    # MAtype==2 --> DEMA
    # MAtype==3 --> T3
    # MAtype==4 --> SMA
    # MAtype==5 --> VIDYA
    # MAtype==6 --> TEMA
    # MAtype==7 --> WMA
    # MAtype==8 --> VWMA
    # Compute basic upper and lower bands
    if MAtype==1:
        df[mavalue]=ta.EMA(df , timeperiod = length)
    elif MAtype==2:
        df[mavalue]=ta.DEMA(df , timeperiod = length)
    elif MAtype==3:
        df[mavalue]=ta.T3(df , timeperiod = length)
    elif MAtype==4:
        df[mavalue]=ta.SMA(df , timeperiod = length)
    elif MAtype==5:
        df[mavalue]= VIDYA(df , length= length)
    elif MAtype==6:
        df[mavalue]= ta.TEMA(df , timeperiod = length)
    elif MAtype==7:
        df[mavalue]= ta.WMA(df , timeperiod = length)
    elif MAtype==8:
        df[mavalue]= vwma(df , length)                        
    # Compute basic upper and lower bands
    df['basic_ub'] = df[mavalue] + multiplier * df[atr]
    df['basic_lb'] = df[mavalue] - multiplier * df[atr]
    # Compute final upper and lower bands
    df['final_ub'] = 0.00
    df['final_lb'] = 0.00
    for i in range(period, len(df)):
        df['final_ub'].iat[i] = df['basic_ub'].iat[i] if df['basic_ub'].iat[i] < df['final_ub'].iat[i - 1] or df[mavalue].iat[i - 1] > df['final_ub'].iat[i - 1] else df['final_ub'].iat[i - 1]
        df['final_lb'].iat[i] = df['basic_lb'].iat[i] if df['basic_lb'].iat[i] > df['final_lb'].iat[i - 1] or df[mavalue].iat[i - 1] < df['final_lb'].iat[i - 1] else df['final_lb'].iat[i - 1]
       
    # Set the Pmax value
    df[pm] = 0.00
    for i in range(period, len(df)):
        df[pm].iat[i] = df['final_ub'].iat[i] if df[pm].iat[i - 1] == df['final_ub'].iat[i - 1] and df[mavalue].iat[i] <= df['final_ub'].iat[i] else \
                        df['final_lb'].iat[i] if df[pm].iat[i - 1] == df['final_ub'].iat[i - 1] and df[mavalue].iat[i] >  df['final_ub'].iat[i] else \
                        df['final_lb'].iat[i] if df[pm].iat[i - 1] == df['final_lb'].iat[i - 1] and df[mavalue].iat[i] >= df['final_lb'].iat[i] else \
                        df['final_ub'].iat[i] if df[pm].iat[i - 1] == df['final_lb'].iat[i - 1] and df[mavalue].iat[i] <  df['final_lb'].iat[i] else 0.00 
                 
    # Mark the trend direction up/down
    df[pmx] = np.where((df[pm] > 0.00), np.where((df['close'] < df[pm]), 'down',  'up'), np.NaN)

    # Remove basic and final bands from the columns
    df.drop(['basic_ub', 'basic_lb', 'final_ub', 'final_lb'], inplace=True, axis=1)
    
    df.fillna(0, inplace=True)

    return df

from technical.

ibrahimclk avatar ibrahimclk commented on August 14, 2024 2

this is working have fun :)

def OTT(df):

pds = 2
percent = 1.4
alpha = 2 / (pds + 1)

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'] = df['ud1'].rolling(9).sum()
df['DD'] = df['dd1'].rolling(9).sum()
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['UD']:

    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['UD']:
        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) 

return df['OTT'], df['Var']

from technical.

TomPer avatar TomPer commented on August 14, 2024

Hi ! I would also be very interested to have this OTT indicator integrated into Freqtrade.

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

and also this indicator..
https://tr.tradingview.com/script/sU9molfV/
Pmax profit maximizer
can anyone write this code and implement in it the freqtrade?

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

If I can take a little time out, it's like I figured out the logic. It can be solved by something like adding a moving average to Supertrend.

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

This should work for OTT:

Would be great if you could have a look at it too - i'm no pinescript expert - but would be great if we can include this in the technical module.

def OTT(dataframe, *, pds = 2, percent = 1.4):
    """
    Source: https://www.tradingview.com/script/zVhoDQME/
    Author: Anıl Özekşi
    
    Pinescript Developer: KivancOzbilgic
    
    Idea: 
        Buy when Signal line crosses above OTT
        Sell when signal crosses below OTT
        
    usage:
      dataframe['OTT'], dataframe['OTTSignal'] = OTT(dataframe)
    """
    df = dataframe.copy()
    alpha = 2 / (pds + 1)
    
    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'] = df['ud1'].rolling(9).sum()
    df['DD'] = df['dd1'].rolling(9).sum()
    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['longStop'] = df['Var'] - df['fark']
    df['longStopPrev'] = df['longStop'].shift(1).ffill(limit=1)
    
    df['longStop'] = np.where(df['Var'] > df['longStopPrev'], df[['longStop', 'longStopPrev']].max(axis=1), df['longStop'])
    
    df['shortStop'] = df['Var'] + df['fark']
    df['shortStopPrev'] = df['shortStop'].shift(1).ffill(limit=1)
    df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])

    df['dir'] = 1
    # dir = 1
    # dir := nz(dir[1], dir)
    # dir := dir == -1 and Var > shortStopPrev ? 1 : dir == 1 and Var < longStopPrev ? -1 : dir
    df['dir'] = np.where(df['Var'] > df['shortStopPrev'], 1, np.where(df['Var'] < df['longStopPrev'], -1, df['dir']))
    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)
    
    
    return df['OTT'], df['Var']
    

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

in the OTT
If the calculations compare correctly with tradingview, different results come out..
I could not find the reason for this.. e.g. ARDR USDT
image
image

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

Interresting
the point i'm not confident is the dir calculation.

    # dir = 1
    # dir := nz(dir[1], dir)
    # dir := dir == -1 and Var > shortStopPrev ? 1 : dir == 1 and Var < longStopPrev ? -1 : dir

In my understanding, dir will be assigned 1 - will be assigned to all rows with 1 by using the previous row - making the comparisons to dir below (if it's 1 or -1) irrelevant.

Might be this should be calculated in a loop - but i'm not sure if that's how pinescript does it.

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

i couldnt find the bug where is... some pairs work correctly..some pairs not..

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

One big problem with these indicators is always the starting point (this is fully based on the result of the previous row - so a change 2000 lines ago will (very slightly) change the result in the last candle.
It's usually not visible as it's in the 10th decimal place (or wherever) - but slight change nonetheless.

Obviously, this error will then depend on the price of the coin (a coin priced 0.00005 is more likely to have a "visible" error than one priced 200.05)...

It should however be similar with other indicators as well (like VIDYA) - which also has a similar calculation

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

@xmatthias you right that... Pmax is also an indicator that works well.... you should take a look at it too

from technical.

Cuzeppe avatar Cuzeppe commented on August 14, 2024

Hi @tarantula3535 I'm a newbie and don't know how to add this indicator. but my favorite indicator on tradingview is pmax. Is there any documentation that explains how to do this?

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024
def PMAX(dataframe, period = 10, multiplier = 3, length=12, MAtype=1, src=1):
    """
    Function to compute PMAX
    
    Args :
        df : Pandas DataFrame which contains ['date', 'open', 'high', 'low', 'close', 'volume'] columns
        period : Integer indicates the period of computation in terms of number of candles
        multiplier : Integer indicates value to multiply the ATR
        length: moving averages length
        MAtype: type of the moving averafe 1 EMA 2 DEMA 3 T3 4 SMA 5 VIDYA
        
    Returns :
        df : Pandas DataFrame with new columns added for 
            True Range (TR), ATR (ATR_$period)
            PMAX (pm_$period_$multiplier_$length_$Matypeint)
            PMAX Direction (pmX_$period_$multiplier_$length_$Matypeint)
    """
    import talib.abstract as ta
    df = dataframe.copy()
    mavalue = 'MA_' + str(MAtype) + '_' + str(length)
    atr = 'ATR_' + str(period)
    df[atr]=ta.ATR(df , timeperiod = period)
    pm = 'pm_' + str(period) + '_' + str(multiplier) + '_' + str(length) + '_' + str(MAtype)
    pmx = 'pmX_' + str(period) + '_' + str(multiplier) + '_' + str(length) + '_' + str(MAtype)
    """
    Pmax Algorithm :

        BASIC UPPERBAND = MA + Multiplier * ATR
        BASIC LOWERBAND = MA - Multiplier * ATR
        
        FINAL UPPERBAND = IF( (Current BASICUPPERBAND < Previous FINAL UPPERBAND) or (Previous Close > Previous FINAL UPPERBAND))
                            THEN (Current BASIC UPPERBAND) ELSE Previous FINALUPPERBAND)
        FINAL LOWERBAND = IF( (Current BASIC LOWERBAND > Previous FINAL LOWERBAND) or (Previous Close < Previous FINAL LOWERBAND)) 
                            THEN (Current BASIC LOWERBAND) ELSE Previous FINAL LOWERBAND)
        
        PMAX = IF((Previous PMAX = Previous FINAL UPPERBAND) and (Current Close <= Current FINAL UPPERBAND)) THEN
                        Current FINAL UPPERBAND
                    ELSE
                        IF((Previous PMAX = Previous FINAL UPPERBAND) and (Current Close > Current FINAL UPPERBAND)) THEN
                            Current FINAL LOWERBAND
                        ELSE
                            IF((Previous PMAX = Previous FINAL LOWERBAND) and (Current Close >= Current FINAL LOWERBAND)) THEN
                                Current FINAL LOWERBAND
                            ELSE
                                IF((Previous PMAX = Previous FINAL LOWERBAND) and (Current Close < Current FINAL LOWERBAND)) THEN
                                    Current FINAL UPPERBAND
    
    """
    # MAtype==1 --> EMA
    # MAtype==2 --> DEMA
    # MAtype==3 --> T3
    # MAtype==4 --> SMA
    # MAtype==5 --> VIDYA
    # MAtype==6 --> TEMA
    # MAtype==7 --> WMA
    # MAtype==8 --> VWMA
    # Compute basic upper and lower bands
    if src == 1:
        masrc=df["close"]
    elif src == 2:
        masrc = (df["high"] + df["low"]) / 2
    elif src == 3:
        masrc = (df["high"] + df["low"]+ df["close"] + df["open"]) / 4
    if MAtype==1:
        df[mavalue]= ta.EMA(masrc , timeperiod = length)
    elif MAtype==2:
        df[mavalue]= ta.DEMA(masrc , timeperiod = length)
    elif MAtype==3:
        df[mavalue]= ta.T3(masrc , timeperiod = length)
    elif MAtype==4:
        df[mavalue]= ta.SMA(masrc , timeperiod = length)
    elif MAtype==5:
        df[mavalue]= VIDYA(df , length= length)
    elif MAtype==6:
        df[mavalue]= ta.TEMA(masrc , timeperiod = length)
    elif MAtype==7:
        df[mavalue]= ta.WMA(df , timeperiod = length)
    elif MAtype==8:
        df[mavalue]= vwma(df , length)
    elif MAtype==9:
        df[mavalue]= zema(df , period=length)
    # Compute basic upper and lower bands
    df['basic_ub'] = df[mavalue] + (multiplier * df[atr])
    df['basic_lb'] = df[mavalue] - (multiplier * df[atr])
    # Compute final upper and lower bands
    df['final_ub'] = 0.00
    df['final_lb'] = 0.00
    for i in range(period, len(df)):
        df['final_ub'].iat[i] = df['basic_ub'].iat[i] if df['basic_ub'].iat[i] < df['final_ub'].iat[i - 1] or df[mavalue].iat[i - 1] > df['final_ub'].iat[i - 1] else df['final_ub'].iat[i - 1]
        df['final_lb'].iat[i] = df['basic_lb'].iat[i] if df['basic_lb'].iat[i] > df['final_lb'].iat[i - 1] or df[mavalue].iat[i - 1] < df['final_lb'].iat[i - 1] else df['final_lb'].iat[i - 1]
       
    # Set the Pmax value
    df[pm] = 0.00
    for i in range(period, len(df)):
        df[pm].iat[i] = df['final_ub'].iat[i] if df[pm].iat[i - 1] == df['final_ub'].iat[i - 1] and df[mavalue].iat[i] <= df['final_ub'].iat[i] else \
                        df['final_lb'].iat[i] if df[pm].iat[i - 1] == df['final_ub'].iat[i - 1] and df[mavalue].iat[i] >  df['final_ub'].iat[i] else \
                        df['final_lb'].iat[i] if df[pm].iat[i - 1] == df['final_lb'].iat[i - 1] and df[mavalue].iat[i] >= df['final_lb'].iat[i] else \
                        df['final_ub'].iat[i] if df[pm].iat[i - 1] == df['final_lb'].iat[i - 1] and df[mavalue].iat[i] <  df['final_lb'].iat[i] else 0.00 
                 
    # Mark the trend direction up/down
    df[pmx] = np.where((df[pm] > 0.00), np.where((df[mavalue] < df[pm]), 'down',  'up'), np.NaN)

    # Remove basic and final bands from the columns
    df.drop(['basic_ub', 'basic_lb', 'final_ub', 'final_lb'], inplace=True, axis=1)
    
    df.fillna(0, inplace=True)

    return df

This is the function i upgrade it..

        pmdf2 = PMAX(dataframe, period=10, multiplier=3, length=9, MAtype=2, src=3)
        dataframe['pmX_10_3_9_2'] = pmdf2['pmX_10_3_9_2']

i use in the strategy just like that...i hopefully helped you..
e.g. trend is "up" look other indicators...
e.g. ema crossover pmax value..

from technical.

Cuzeppe avatar Cuzeppe commented on August 14, 2024

Actually i couldnt find where to add the indicator codes and which part of its and how to implement indicator to my strategy file. can u share ur strategy file and indicators file pls? [email protected] I would be grateful

from technical.

Cuzeppe avatar Cuzeppe commented on August 14, 2024

when i try to download "technical" from git it downloads all the files into .local/lib/python3.8/site-packages am i doing something wrong?

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

if you don't use virtual env , you are doing right..

when i try to download "technical" from git it downloads all the files into .local/lib/python3.8/site-packages am i doing something wrong?
i am copy and paste the function in this file...
technical-->indicator-->indcators.py
and
call in the strategy file
image
just like that..

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

this is the definition.. How you use it is up to you...
for example
ema cross pmax value --> You can use it as in the populate_buy_trend

(qtpylib.crossed_above(dataframe[mavalue] , dataframe[f'pm_{pmaxperiod}_{pmaxmulti}_{pmaxl}_{pmaxtype}']))

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

pmax.zip
I hope it helps to give an idea..
i am using it this way...

from technical.

Cuzeppe avatar Cuzeppe commented on August 14, 2024

omg thank you so much finally it works. I've been trying to run this for days and thanks to you it is working now. Thank you very much I am grateful. my tradingview btcusdt pmax strategy is 1min timeframe atr:14 mult:4 ma:VAR ma lenght:25 and im using it with inverse fisher rsi lenght :10 smooth: 9
if pmax goes for buy wait for price retest. if iftrsi goes below -0.50 go long from pmax or ma200. im trading with this setup. i will try freqtrade for futures trade if it works

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

omg thank you so much finally it works. I've been trying to run this for days and thanks to you it is working now. Thank you very much I am grateful. my tradingview btcusdt pmax strategy is 1min timeframe atr:14 mult:4 ma:VAR ma lenght:25 and im using it with inverse fisher rsi lenght :10 smooth: 9
if pmax goes for buy wait for price retest. if iftrsi goes below -0.50 go long from pmax or ma200. im trading with this setup. i will try freqtrade for futures trade if it works

i am glad you succeeded.. your strategy seems so good.. I've tried something like this...you should also try with inverse fisher average...

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

@xmatthias i may close the issue..I would be glad if you add the PMAX indicator with the necessary explanations.You can check it too.

from technical.

Cuzeppe avatar Cuzeppe commented on August 14, 2024

i will try thank you so much again. @tarantula3535

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

i may close the issue..I would be glad if you add the PMAX indicator with the necessary explanations.

then leave it open ... otherwise it'll "disappear" into the "closed issues" list ... and unless i explicitly remember (which i probably won't) - it'll not be added.
on the other hand, nothing prevents you from attempting a Pull request adding this :)
it's no magic... :)

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

i may close the issue..I would be glad if you add the PMAX indicator with the necessary explanations.

then leave it open ... otherwise it'll "disappear" into the "closed issues" list ... and unless i explicitly remember (which i probably won't) - it'll not be added.
on the other hand, nothing prevents you from attempting a Pull request adding this :)
it's no magic... :)

you probably right..its no magic,I am already using it...The point is for more people to use it..
Thanks for all your hard work and time

from technical.

tarantula3535 avatar tarantula3535 commented on August 14, 2024

pmax.zip
I hope it helps to give an idea..
i am using it this way...

Merhabalar.Rica etsem Pmax için kullandığınız hyperopt dosyasını da paylaşır mısınız?

pmaxmulti.zip
ufak tefek ayarlamalarla kullanabilirsiniz..fakat uzun aralık tanımlarsanız çok fazla ram kullanır ve işlemi iptal edebilir..
çalışma mantığını anlayıp fikir vermesi için kullanabilirsiniz..umarım işinize yara sonuçları paylaşırsınız..

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

I'd apreciate if we could keep the issues in english ... otherwise it'll exclude most of the remaining comunity from contributing (or benefitting) from the discussions.

from technical.

manvalorian avatar manvalorian commented on August 14, 2024

omg thank you so much finally it works. I've been trying to run this for days and thanks to you it is working now. Thank you very much I am grateful. my tradingview btcusdt pmax strategy is 1min timeframe atr:14 mult:4 ma:VAR ma lenght:25 and im using it with inverse fisher rsi lenght :10 smooth: 9
if pmax goes for buy wait for price retest. if iftrsi goes below -0.50 go long from pmax or ma200. im trading with this setup. i will try freqtrade for futures trade if it works

how to you configure the smooth in the inverse fisher, @Cuzeppe ?

from technical.

quents avatar quents commented on August 14, 2024

This should work for OTT:

Would be great if you could have a look at it too - i'm no pinescript expert - but would be great if we can include this in the technical module.

def OTT(dataframe, *, pds = 2, percent = 1.4):
    """
    Source: https://www.tradingview.com/script/zVhoDQME/
    Author: Anıl Özekşi
    
    Pinescript Developer: KivancOzbilgic
    
    Idea: 
        Buy when Signal line crosses above OTT
        Sell when signal crosses below OTT
        
    usage:
      dataframe['OTT'], dataframe['OTTSignal'] = OTT(dataframe)
    """
    df = dataframe.copy()
    alpha = 2 / (pds + 1)
    
    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'] = df['ud1'].rolling(9).sum()
    df['DD'] = df['dd1'].rolling(9).sum()
    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['longStop'] = df['Var'] - df['fark']
    df['longStopPrev'] = df['longStop'].shift(1).ffill(limit=1)
    
    df['longStop'] = np.where(df['Var'] > df['longStopPrev'], df[['longStop', 'longStopPrev']].max(axis=1), df['longStop'])
    
    df['shortStop'] = df['Var'] + df['fark']
    df['shortStopPrev'] = df['shortStop'].shift(1).ffill(limit=1)
    df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])

    df['dir'] = 1
    # dir = 1
    # dir := nz(dir[1], dir)
    # dir := dir == -1 and Var > shortStopPrev ? 1 : dir == 1 and Var < longStopPrev ? -1 : dir
    df['dir'] = np.where(df['Var'] > df['shortStopPrev'], 1, np.where(df['Var'] < df['longStopPrev'], -1, df['dir']))
    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)
    
    
    return df['OTT'], df['Var']
    

I guess

df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])

should be

df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].min(axis=1), df['shortStop'])

but it did not change the result, it still plots a different graph from the TradingView's OTT with the same parameters. I think you are right, there must be some for loop at the calculation of df['dir'] because at first glance it seems meaningless to define at as 1, and then assign it to the previous dir and check if it is -1 or 1 at the following line.

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir

Anyone to help?

from technical.

rafadan2 avatar rafadan2 commented on August 14, 2024

This should work for OTT:
Would be great if you could have a look at it too - i'm no pinescript expert - but would be great if we can include this in the technical module.

def OTT(dataframe, *, pds = 2, percent = 1.4):
    """
    Source: https://www.tradingview.com/script/zVhoDQME/
    Author: Anıl Özekşi
    
    Pinescript Developer: KivancOzbilgic
    
    Idea: 
        Buy when Signal line crosses above OTT
        Sell when signal crosses below OTT
        
    usage:
      dataframe['OTT'], dataframe['OTTSignal'] = OTT(dataframe)
    """
    df = dataframe.copy()
    alpha = 2 / (pds + 1)
    
    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'] = df['ud1'].rolling(9).sum()
    df['DD'] = df['dd1'].rolling(9).sum()
    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['longStop'] = df['Var'] - df['fark']
    df['longStopPrev'] = df['longStop'].shift(1).ffill(limit=1)
    
    df['longStop'] = np.where(df['Var'] > df['longStopPrev'], df[['longStop', 'longStopPrev']].max(axis=1), df['longStop'])
    
    df['shortStop'] = df['Var'] + df['fark']
    df['shortStopPrev'] = df['shortStop'].shift(1).ffill(limit=1)
    df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])

    df['dir'] = 1
    # dir = 1
    # dir := nz(dir[1], dir)
    # dir := dir == -1 and Var > shortStopPrev ? 1 : dir == 1 and Var < longStopPrev ? -1 : dir
    df['dir'] = np.where(df['Var'] > df['shortStopPrev'], 1, np.where(df['Var'] < df['longStopPrev'], -1, df['dir']))
    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)
    
    
    return df['OTT'], df['Var']
    

I guess

df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])

should be

df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].min(axis=1), df['shortStop'])

but it did not change the result, it still plots a different graph from the TradingView's OTT with the same parameters. I think you are right, there must be some for loop at the calculation of df['dir'] because at first glance it seems meaningless to define at as 1, and then assign it to the previous dir and check if it is -1 or 1 at the following line.

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir

Anyone to help?

I am trying to write the same code in R without much Pinescript knowledge. https://www.tradingview.com/pine-script-docs/en/v4/Quickstart_guide.html#execution-model-of-pine-scripts

Pine script seems to be running recuvrsively or similar to a loop.

I think below code gives something similar for the dir part. Maybe it needs a lag here and there but basically, what it does is if there is a change in dir, for all the next values it is also changed.

`for(i in 1:maxNo) {

if(dir[i] == -1 & MAvg[i]>shortStopPrev[i] ){
dir[i] <- 1
dir[i:maxNo] <- 1
}
else if(dir[i] == 1 & MAvg[i]<longStopPrev[i]){
dir[i:maxNo] <- -1

}

}
`

from technical.

quents avatar quents commented on August 14, 2024

This should work for OTT:

Would be great if you could have a look at it too - i'm no pinescript expert - but would be great if we can include this in the technical module.

def OTT(dataframe, *, pds = 2, percent = 1.4):

"""
Source: https://www.tradingview.com/script/zVhoDQME/
Author: Anıl Özekşi
Pinescript Developer: KivancOzbilgic
Idea: 
    Buy when Signal line crosses above OTT
    Sell when signal crosses below OTT
usage:
  dataframe['OTT'], dataframe['OTTSignal'] = OTT(dataframe)
"""
df = dataframe.copy()
alpha = 2 / (pds + 1)
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'] = df['ud1'].rolling(9).sum()
df['DD'] = df['dd1'].rolling(9).sum()
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['longStop'] = df['Var'] - df['fark']
df['longStopPrev'] = df['longStop'].shift(1).ffill(limit=1)
df['longStop'] = np.where(df['Var'] > df['longStopPrev'], df[['longStop', 'longStopPrev']].max(axis=1), df['longStop'])
df['shortStop'] = df['Var'] + df['fark']
df['shortStopPrev'] = df['shortStop'].shift(1).ffill(limit=1)
df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])
df['dir'] = 1
# dir = 1
# dir := nz(dir[1], dir)
# dir := dir == -1 and Var > shortStopPrev ? 1 : dir == 1 and Var < longStopPrev ? -1 : dir
df['dir'] = np.where(df['Var'] > df['shortStopPrev'], 1, np.where(df['Var'] < df['longStopPrev'], -1, df['dir']))
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)
return df['OTT'], df['Var']

I guess

df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].max(axis=1), df['shortStop'])

should be

df['shortStop'] = np.where(df['Var'] < df['shortStopPrev'], df[['shortStop', 'shortStopPrev']].min(axis=1), df['shortStop'])

but it did not change the result, it still plots a different graph from the TradingView's OTT with the same parameters. I think you are right, there must be some for loop at the calculation of df['dir'] because at first glance it seems meaningless to define at as 1, and then assign it to the previous dir and check if it is -1 or 1 at the following line.

dir = 1

dir := nz(dir[1], dir)

dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir

Anyone to help?

I am trying to write the same code in R without much Pinescript knowledge. https://www.tradingview.com/pine-script-docs/en/v4/Quickstart_guide.html#execution-model-of-pine-scripts

Pine script seems to be running recuvrsively or similar to a loop.

I think below code gives something similar for the dir part. Maybe it needs a lag here and there but basically, what it does is if there is a change in dir, for all the next values it is also changed.

`for(i in 1:maxNo) {

if(dir[i] == -1 & MAvg[i]>shortStopPrev[i] ){

dir[i] <- 1

dir[i:maxNo] <- 1

}

else if(dir[i] == 1 & MAvg[i]<longStopPrev[i]){

dir[i:maxNo] <- -1

}

}

`

Thank you, I'll give it a try. What is exactly maxNo? Is it the period of OTT?

from technical.

rafadan2 avatar rafadan2 commented on August 14, 2024

I used maxNo for the number of bars, or how long the data is. So the loop iterates from the beginning until maxNo(end of data).

from technical.

sirichoke-kunwed avatar sirichoke-kunwed commented on August 14, 2024

dir = np.where(Var>shortStopPrev, 1, np.where(Var<longStopPrev, -1, 0)

This works for me

from technical.

Orhan972 avatar Orhan972 commented on August 14, 2024

dir = np.where(Var>shortStopPrev, 1, np.where(Var<longStopPrev, -1, 0)

This works for me

Can you send the complete code that works ?

from technical.

froggleston avatar froggleston commented on August 14, 2024

Don't these implementations lookahead?

for i in range(period, len(df)):

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

Don't these implementations lookahead?

no - not because of this, anyway - this is simply a loop accessing all columns. It would lookahead if you'd use a "total" (or last row) within the loop - but it doesn't, only access is to i and i-1

from technical.

KaanRF avatar KaanRF commented on August 14, 2024

this is working have fun :)

def OTT(df):

pds = 2
percent = 1.4
alpha = 2 / (pds + 1)

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'] = df['ud1'].rolling(9).sum()
df['DD'] = df['dd1'].rolling(9).sum()
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['UD']:

    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['UD']:
        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) 

return df['OTT'], df['Var']

Could you please create a PR to tecnical repository ? and also simple usage ?

from technical.

equinox794 avatar equinox794 commented on August 14, 2024

düzgün çalışan ott var mı ?

from technical.

svsvfx avatar svsvfx commented on August 14, 2024

Hello everyone, first of all thx for OTT and Pmax indicator. But I used for backtest I need Kıvanç Özbilic's Stochastic OTT.
https://tr.tradingview.com/script/BK45kYNB-Stochastic-OTT/

This indicator works great for 1m charts. I'm not good for programing but i tired few things but when I try to smooting stochastic %K with "vidya" it's return NaN. I'm used pandas_ta library. Here is my simple code;

periodK = 600
period_d = 33
smoothK = 500

"""for stoch %K with vidya"
df["stoch"] = df.ta.stoch(k=periodK,d=period_d,smooth_k=smoothK, mamode = "vidya")[f"STOCHk_{periodK}{period_d}{smoothK}"]

"""for smooting %K with vidya"
df["k"] = ta.ma("vidya", source = df["stoch"], length = smoothK)

and df["k"] return NaN all time.
Thanks for helping.

from technical.

KaanRF avatar KaanRF commented on August 14, 2024

this is working have fun :)

def OTT(df):

pds = 2
percent = 1.4
alpha = 2 / (pds + 1)

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'] = df['ud1'].rolling(9).sum()
df['DD'] = df['dd1'].rolling(9).sum()
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['UD']:

    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['UD']:
        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) 

return df['OTT'], df['Var']

Is there any one who tested this ?

from technical.

dpanday77 avatar dpanday77 commented on August 14, 2024

Hello everyone, first of all thx for OTT and Pmax indicator. But I used for backtest I need Kıvanç Özbilic's Stochastic OTT. https://tr.tradingview.com/script/BK45kYNB-Stochastic-OTT/

This indicator works great for 1m charts. I'm not good for programing but i tired few things but when I try to smooting stochastic %K with "vidya" it's return NaN. I'm used pandas_ta library. Here is my simple code;

periodK = 600 period_d = 33 smoothK = 500

"""for stoch %K with vidya" df["stoch"] = df.ta.stoch(k=periodK,d=period_d,smooth_k=smoothK, mamode = "vidya")[f"STOCHk_{periodK}{period_d}{smoothK}"]

"""for smooting %K with vidya" df["k"] = ta.ma("vidya", source = df["stoch"], length = smoothK)

and df["k"] return NaN all time. Thanks for helping.

Hi any progress on this or is there somebody who can adjust the OTT to SOTT indicator?

from technical.

dpanday77 avatar dpanday77 commented on August 14, 2024

Hi, is there someone who can adjust the OTT to SOTT indicator?

from technical.

dpanday77 avatar dpanday77 commented on August 14, 2024

this is working have fun :)

def OTT(df):

pds = 2
percent = 1.4
alpha = 2 / (pds + 1)

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'] = df['ud1'].rolling(9).sum()
df['DD'] = df['dd1'].rolling(9).sum()
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['UD']:

    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['UD']:
        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) 

return df['OTT'], df['Var']

Hi, can you please modify the code to the Stochastic OTT? (https://www.tradingview.com/script/BK45kYNB-Stochastic-OTT/)

from technical.

magrawalgit avatar magrawalgit commented on August 14, 2024

Did minor modifications like rounding off, added final buy/sell signal...here is the working & tested code (data matches with TV) !


def OTT(df):
    pds = 2
    percent = 1.4
    alpha = 2 / (pds + 1)

    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'] = df['ud1'].rolling(9).sum()
    df['DD'] = df['dd1'].rolling(9).sum()
    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['UD']:

        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['UD']:
            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))
    # round the numeric columns
    df = df.round(2)
    
    #this OTT2 column now is to be shifted by 2 prev values
    df['OTT2'] = df['OTT'].shift(2)
    df['OTT3'] = df['OTT'].shift(3)
    
    df['buySignalk'] = np.where(df['Var'] > df['OTT2'], 1, 0)
    df['buySignalr'] = np.where(df['OTT2'] > df['OTT3'], 1, 0)
    df['buySignalc'] = np.where(df['close'] > df['OTT2'], 1, 0)
    
    df['sellSignallk'] = np.where(df['Var'] < df['OTT2'], 1, 0)
    df['sellSignallc'] = np.where(df['Var'] < df['OTT3'], 1, 0)
    df['sellSignallr'] = np.where(df['Var'] < df['OTT2'], 1, 0)
    
    condn = ( ( df['buySignalk'] == 1) | (df['buySignalr'] == 1) | (df['buySignalc'] == 1 ) )
    
    df['buy'] = np.where( condn, 1, 0)
    
    condn = ( ( df['sellSignallk'] == 1) | (df['sellSignallc'] == 1 ) | ( df['sellSignallr'] == 1 ) )
    
    df['sell'] = np.where( condn, 1, 0)
    
    #print(df.dtypes)
    #return df['OTT'], df['Var']
    return df

from technical.

dpanday77 avatar dpanday77 commented on August 14, 2024

@mata1234 When i print out the df of OTT and Var then the values are not the same as with TV. I tested several settings by changing the pds and percent variables. Also when using another timeframe.
Maybe you can have a look at it.
Besides that i wonder if you are able to convert this indicator as well: https://www.tradingview.com/script/BK45kYNB-Stochastic-OTT/

from technical.

froggleston avatar froggleston commented on August 14, 2024

TV indicators might well not be the same as other TA libraries so you probably will see different results for more complex calculations.

from technical.

ahmedevv avatar ahmedevv commented on August 14, 2024

If you guys haven't figured out the OTT indicator in Python then I've implemented it a few weeks back in my BOT which is working with SuperTrend, ADX, EMA and OTT. I can give you guys the implementation of OTT. Let me know if I can be of any help.

from technical.

dpanday77 avatar dpanday77 commented on August 14, 2024

If you guys haven't figured out the OTT indicator in Python then I've implemented it a few weeks back in my BOT which is working with SuperTrend, ADX, EMA and OTT. I can give you guys the implementation of OTT. Let me know if I can be of any help.

@ahmedevv I'm interested on how you have implemented the indicator and also which version because the ones i have used doesn't match exactly with the values of Tradingview

from technical.

amalysh avatar amalysh commented on August 14, 2024
def PMAX(dataframe, period = 10, multiplier = 3, length=12, MAtype=1, src=1):
    """
    Function to compute PMAX
    
    Args :
        df : Pandas DataFrame which contains ['date', 'open', 'high', 'low', 'close', 'volume'] columns
        period : Integer indicates the period of computation in terms of number of candles
        multiplier : Integer indicates value to multiply the ATR
        length: moving averages length
        MAtype: type of the moving averafe 1 EMA 2 DEMA 3 T3 4 SMA 5 VIDYA
        
    Returns :
        df : Pandas DataFrame with new columns added for 
            True Range (TR), ATR (ATR_$period)
            PMAX (pm_$period_$multiplier_$length_$Matypeint)
            PMAX Direction (pmX_$period_$multiplier_$length_$Matypeint)
    """
    import talib.abstract as ta
    df = dataframe.copy()
    mavalue = 'MA_' + str(MAtype) + '_' + str(length)
    atr = 'ATR_' + str(period)
    df[atr]=ta.ATR(df , timeperiod = period)
    pm = 'pm_' + str(period) + '_' + str(multiplier) + '_' + str(length) + '_' + str(MAtype)
    pmx = 'pmX_' + str(period) + '_' + str(multiplier) + '_' + str(length) + '_' + str(MAtype)
    """
    Pmax Algorithm :

        BASIC UPPERBAND = MA + Multiplier * ATR
        BASIC LOWERBAND = MA - Multiplier * ATR
        
        FINAL UPPERBAND = IF( (Current BASICUPPERBAND < Previous FINAL UPPERBAND) or (Previous Close > Previous FINAL UPPERBAND))
                            THEN (Current BASIC UPPERBAND) ELSE Previous FINALUPPERBAND)
        FINAL LOWERBAND = IF( (Current BASIC LOWERBAND > Previous FINAL LOWERBAND) or (Previous Close < Previous FINAL LOWERBAND)) 
                            THEN (Current BASIC LOWERBAND) ELSE Previous FINAL LOWERBAND)
        
        PMAX = IF((Previous PMAX = Previous FINAL UPPERBAND) and (Current Close <= Current FINAL UPPERBAND)) THEN
                        Current FINAL UPPERBAND
                    ELSE
                        IF((Previous PMAX = Previous FINAL UPPERBAND) and (Current Close > Current FINAL UPPERBAND)) THEN
                            Current FINAL LOWERBAND
                        ELSE
                            IF((Previous PMAX = Previous FINAL LOWERBAND) and (Current Close >= Current FINAL LOWERBAND)) THEN
                                Current FINAL LOWERBAND
                            ELSE
                                IF((Previous PMAX = Previous FINAL LOWERBAND) and (Current Close < Current FINAL LOWERBAND)) THEN
                                    Current FINAL UPPERBAND
    
    """
    # MAtype==1 --> EMA
    # MAtype==2 --> DEMA
    # MAtype==3 --> T3
    # MAtype==4 --> SMA
    # MAtype==5 --> VIDYA
    # MAtype==6 --> TEMA
    # MAtype==7 --> WMA
    # MAtype==8 --> VWMA
    # Compute basic upper and lower bands
    if src == 1:
        masrc=df["close"]
    elif src == 2:
        masrc = (df["high"] + df["low"]) / 2
    elif src == 3:
        masrc = (df["high"] + df["low"]+ df["close"] + df["open"]) / 4
    if MAtype==1:
        df[mavalue]= ta.EMA(masrc , timeperiod = length)
    elif MAtype==2:
        df[mavalue]= ta.DEMA(masrc , timeperiod = length)
    elif MAtype==3:
        df[mavalue]= ta.T3(masrc , timeperiod = length)
    elif MAtype==4:
        df[mavalue]= ta.SMA(masrc , timeperiod = length)
    elif MAtype==5:
        df[mavalue]= VIDYA(df , length= length)
    elif MAtype==6:
        df[mavalue]= ta.TEMA(masrc , timeperiod = length)
    elif MAtype==7:
        df[mavalue]= ta.WMA(df , timeperiod = length)
    elif MAtype==8:
        df[mavalue]= vwma(df , length)
    elif MAtype==9:
        df[mavalue]= zema(df , period=length)
    # Compute basic upper and lower bands
    df['basic_ub'] = df[mavalue] + (multiplier * df[atr])
    df['basic_lb'] = df[mavalue] - (multiplier * df[atr])
    # Compute final upper and lower bands
    df['final_ub'] = 0.00
    df['final_lb'] = 0.00
    for i in range(period, len(df)):
        df['final_ub'].iat[i] = df['basic_ub'].iat[i] if df['basic_ub'].iat[i] < df['final_ub'].iat[i - 1] or df[mavalue].iat[i - 1] > df['final_ub'].iat[i - 1] else df['final_ub'].iat[i - 1]
        df['final_lb'].iat[i] = df['basic_lb'].iat[i] if df['basic_lb'].iat[i] > df['final_lb'].iat[i - 1] or df[mavalue].iat[i - 1] < df['final_lb'].iat[i - 1] else df['final_lb'].iat[i - 1]
       
    # Set the Pmax value
    df[pm] = 0.00
    for i in range(period, len(df)):
        df[pm].iat[i] = df['final_ub'].iat[i] if df[pm].iat[i - 1] == df['final_ub'].iat[i - 1] and df[mavalue].iat[i] <= df['final_ub'].iat[i] else \
                        df['final_lb'].iat[i] if df[pm].iat[i - 1] == df['final_ub'].iat[i - 1] and df[mavalue].iat[i] >  df['final_ub'].iat[i] else \
                        df['final_lb'].iat[i] if df[pm].iat[i - 1] == df['final_lb'].iat[i - 1] and df[mavalue].iat[i] >= df['final_lb'].iat[i] else \
                        df['final_ub'].iat[i] if df[pm].iat[i - 1] == df['final_lb'].iat[i - 1] and df[mavalue].iat[i] <  df['final_lb'].iat[i] else 0.00 
                 
    # Mark the trend direction up/down
    df[pmx] = np.where((df[pm] > 0.00), np.where((df[mavalue] < df[pm]), 'down',  'up'), np.NaN)

    # Remove basic and final bands from the columns
    df.drop(['basic_ub', 'basic_lb', 'final_ub', 'final_lb'], inplace=True, axis=1)
    
    df.fillna(0, inplace=True)

    return df

This is the function i upgrade it..

        pmdf2 = PMAX(dataframe, period=10, multiplier=3, length=9, MAtype=2, src=3)
        dataframe['pmX_10_3_9_2'] = pmdf2['pmX_10_3_9_2']

i use in the strategy just like that...i hopefully helped you.. e.g. trend is "up" look other indicators... e.g. ema crossover pmax value..

Hi guys! can someone explain why in PMAX for loop starting from ATR period instead of 1?
for i in range(period, len(df)):

from technical.

xmatthias avatar xmatthias commented on August 14, 2024

Hi guys! can someone explain why in PMAX for loop starting from ATR period instead of 1?
for i in range(period, len(df)):

most likely, because ATR will be empty (NaN) for the first period candles. This makes all calculations based off of it either NaN or wrong.
starting from period is a micro-optimization (it'll avoid a few loops) - but not doing it would be pointless, too.

from technical.

BlueDigitalWizard avatar BlueDigitalWizard commented on August 14, 2024

@ahmedevv i'm interested in your implementation of OTT and Supertrend. Can you share please ?

from technical.

pongpom avatar pongpom commented on August 14, 2024

https://github.com/OnlyFibonacci/AlgoSeyri/blob/main/indicators/indicators.py
This is exactly the same as the tradingview version of OTT.
However, there is a slight difference in ohlcv data (in my case, using binance api data) between tradingview and the exchange, so don't expect perfect compatibility. From what I've experienced, if you want perfect compatibility, you can use tradingview api to get tradingview ohlcv data and use it, but I don't recommend this.

I guess y'all found this already but just in case I'll leave this here.

from technical.

acemi1 avatar acemi1 commented on August 14, 2024

I tried all the codes above. OTT is calculated incorrectly in all but one case. Only https://github.com/OnlyFibonacci/AlgoSeyri/blob/main/indicators/indicators.py is correct. But this code runs incredibly slow. Is it possible to share the correctly calculated OTT indicator?

from technical.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.