technical
technical copied to clipboard
New version of PMAX and Supertrend
I propose a new version for PMAX and Supertrend with loop. Same result but really faster
def PMAX(dataframe, period, multiplier,length):
start_time = time.time()
df = dataframe.copy()
last_row = dataframe.tail(1).index.item()
mavalue = 'MA_' + str(length)
df[mavalue] = ta.EMA(df , length)
df['ATR'] = ta.ATR(df, period)
pm = 'PM_' + str(period) + '_' + str(multiplier)
pmx = 'PMX_' + str(period) + '_' + str(multiplier)
# Compute basic upper and lower bands
BASIC_UB = (df[mavalue] + multiplier * df['ATR']).values
BASIC_LB = (df[mavalue] - multiplier * df['ATR']).values
FINAL_UB = np.zeros(last_row + 1)
FINAL_LB = np.zeros(last_row + 1)
PM = np.zeros(last_row + 1)
MAVALUE = df[mavalue].values
# Compute final upper and lower bands
for i in range(period, last_row):
FINAL_UB[i] = BASIC_UB[i] if BASIC_UB[i] < FINAL_UB[i - 1] or MAVALUE[i - 1] > FINAL_UB[i - 1] else FINAL_UB[i - 1]
FINAL_LB[i] = BASIC_LB[i] if BASIC_LB[i] > FINAL_LB[i - 1] or MAVALUE[i - 1] < FINAL_LB[i - 1] else FINAL_LB[i - 1]
# Set the Supertrend value
for i in range(period, last_row):
PM[i] = FINAL_UB[i] if PM[i - 1] == FINAL_UB[i - 1] and MAVALUE[i] <= FINAL_UB[i] else \
FINAL_LB[i] if PM[i - 1] == FINAL_UB[i - 1] and MAVALUE[i] > FINAL_UB[i] else \
FINAL_LB[i] if PM[i - 1] == FINAL_LB[i - 1] and MAVALUE[i] >= FINAL_LB[i] else \
FINAL_UB[i] if PM[i - 1] == FINAL_LB[i - 1] and MAVALUE[i] < FINAL_LB[i] else 0.00
df_PM = pd.DataFrame(PM, columns=[pm])
df = pd.concat([df, df_PM],axis=1)
# Mark the trend direction up/down
df[pmx] = np.where((df[pm] > 0.00), np.where((df['close'] < df[pm]), 'down', 'up'), np.NaN)
df.fillna(0, inplace=True)
end_time = time.time()
# print("total time taken this loop: ", end_time - start_time)
return df
def supertrend(self, dataframe: DataFrame, multiplier, period):
start_time = time.time()
df = dataframe.copy()
last_row = dataframe.tail(1).index.item()
df['TR'] = ta.TRANGE(df)
df['ATR'] = ta.SMA(df['TR'], period)
st = 'ST_' + str(period) + '_' + str(multiplier)
stx = 'STX_' + str(period) + '_' + str(multiplier)
# Compute basic upper and lower bands
BASIC_UB = ((df['high'] + df['low']) / 2 + multiplier * df['ATR']).values
BASIC_LB = ((df['high'] + df['low']) / 2 - multiplier * df['ATR']).values
FINAL_UB = np.zeros(last_row + 1)
FINAL_LB = np.zeros(last_row + 1)
ST = np.zeros(last_row + 1)
CLOSE = df['close'].values
# Compute final upper and lower bands
for i in range(period, last_row):
FINAL_UB[i] = BASIC_UB[i] if BASIC_UB[i] < FINAL_UB[i - 1] or CLOSE[i - 1] > FINAL_UB[i - 1] else FINAL_UB[i - 1]
FINAL_LB[i] = BASIC_LB[i] if BASIC_LB[i] > FINAL_LB[i - 1] or CLOSE[i - 1] < FINAL_LB[i - 1] else FINAL_LB[i - 1]
# Set the Supertrend value
for i in range(period, last_row):
ST[i] = FINAL_UB[i] if ST[i - 1] == FINAL_UB[i - 1] and CLOSE[i] <= FINAL_UB[i] else \
FINAL_LB[i] if ST[i - 1] == FINAL_UB[i - 1] and CLOSE[i] > FINAL_UB[i] else \
FINAL_LB[i] if ST[i - 1] == FINAL_LB[i - 1] and CLOSE[i] >= FINAL_LB[i] else \
FINAL_UB[i] if ST[i - 1] == FINAL_LB[i - 1] and CLOSE[i] < FINAL_LB[i] else 0.00
df_ST = pd.DataFrame(ST, columns=[st])
df = pd.concat([df, df_ST],axis=1)
# Mark the trend direction up/down
df[stx] = np.where((df[st] > 0.00), np.where((df['close'] < df[st]), 'down', 'up'), np.NaN)
df.fillna(0, inplace=True)
end_time = time.time()
# print("total time taken this loop: ", end_time - start_time)
return DataFrame(index=df.index, data={
'ST' : df[st],
'STX' : df[stx]
})
Please provide code contributions as Pull request - not as text in an issue.
That way we can review and merge the changes directly, without the need of manual work from our side. Thanks.
Closing this for the reasons above.
Feel free to submit this as Pull request however.