-
Notifications
You must be signed in to change notification settings - Fork 218
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
Optimized Trend Tracker OTT indicator #97
Comments
Hi ! I would also be very interested to have this OTT indicator integrated into Freqtrade. |
and also this indicator.. |
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. |
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 |
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']
|
Interresting
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 Might be this should be calculated in a loop - but i'm not sure if that's how pinescript does it. |
i couldnt find the bug where is... some pairs work correctly..some pairs not.. |
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. 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 |
@xmatthias you right that... Pmax is also an indicator that works well.... you should take a look at it too |
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? |
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.. |
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 |
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? |
this is the definition.. How you use it is up to you... (qtpylib.crossed_above(dataframe[mavalue] , dataframe[f'pm_{pmaxperiod}_{pmaxmulti}_{pmaxl}_{pmaxtype}'])) |
pmax.zip |
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 |
i am glad you succeeded.. your strategy seems so good.. I've tried something like this...you should also try with inverse fisher average... |
@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. |
i will try thank you so much again. @tarantula3535 |
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. |
you probably right..its no magic,I am already using it...The point is for more people to use it.. |
pmaxmulti.zip |
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. |
how to you configure the smooth in the inverse fisher, @Cuzeppe ? |
I guess
should be
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.
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] ){ } } |
Thank you, I'll give it a try. What is exactly maxNo? Is it the period of OTT? |
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). |
This works for me |
Can you send the complete code that works ? |
Hi, I came on this site while looking for an OTT indicator in Python, thanks to @tarantula3535 for inspiring me with his efforts. |
this is working have fun :) def OTT(df):
|
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 |
Could you please create a PR to tecnical repository ? and also simple usage ? |
düzgün çalışan ott var mı ? |
Hello everyone, first of all thx for OTT and Pmax indicator. But I used for backtest I need Kıvanç Özbilic's 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 """for stoch %K with vidya" """for smooting %K with vidya" and df["k"] return NaN all time. |
Is there any one who tested this ? |
This comment was marked as duplicate.
This comment was marked as duplicate.
Hi, is there someone who can adjust the OTT to SOTT indicator? |
Hi, can you please modify the code to the Stochastic OTT? (https://www.tradingview.com/script/BK45kYNB-Stochastic-OTT/) |
Did minor modifications like rounding off, added final buy/sell signal...here is the working & tested code (data matches with TV) !
|
@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. |
TV indicators might well not be the same as other TA libraries so you probably will see different results for more complex calculations. |
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 |
Hi guys! can someone explain why in PMAX for loop starting from ATR period instead of 1? |
most likely, because ATR will be empty (NaN) for the first |
@ahmedevv i'm interested in your implementation of OTT and Supertrend. Can you share please ? |
https://github.com/OnlyFibonacci/AlgoSeyri/blob/main/indicators/indicators.py I guess y'all found this already but just in case I'll leave this here. |
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? |
hi i want to write this indicator in python but i dont have much time.. here is the tradingview's url
https://tr.tradingview.com/script/zVhoDQME/
this indicator is very helpfull the filtering in the buy signals conditions..
I would be glad if you could write this indicator in Python
The text was updated successfully, but these errors were encountered: