technical
technical copied to clipboard
Optimized Trend Tracker 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
Hi ! I would also be very interested to have this OTT indicator integrated into Freqtrade.
and also this indicator.. https://tr.tradingview.com/script/sU9molfV/ Pmax profit maximizer can anyone write this code and implement in it the freqtrade?
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']
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
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.
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. 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
@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.. e.g. trend is "up" look other indicators... e.g. ema crossover pmax value..
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?
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 just like that..
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}']))
pmax.zip I hope it helps to give an idea.. i am using it this way...
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
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...
@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
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... :)
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
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..
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.
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 ?
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?
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
}
} `
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?
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).