I am trying to code the following algorithm for SuperTrend indicator in python using pandas.
BASIC UPPERBAND = (HIGH + LOW) / 2 + Multiplier * ATR
BASIC LOWERBAND = (HIGH + LOW) / 2 - 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)
SUPERTREND = IF((Previous SUPERTREND = Previous FINAL UPPERBAND) and (Current Close <= Current FINAL UPPERBAND)) THEN
Current FINAL UPPERBAND
ELSE
IF((Previous SUPERTREND = Previous FINAL UPPERBAND) and (Current Close > Current FINAL UPPERBAND)) THEN
Current FINAL LOWERBAND
ELSE
IF((Previous SUPERTREND = Previous FINAL LOWERBAND) and (Current Close >= Current FINAL LOWERBAND)) THEN
Current FINAL LOWERBAND
ELSE
IF((Previous SUPERTREND = Previous FINAL LOWERBAND) and (Current Close < Current FINAL LOWERBAND)) THEN
Current FINAL UPPERBAND
Here is the code that I wrote and tested:
# Compute basic upper and lower bands
df['basic_ub'] = (df['high'] + df['low']) / 2 + multiplier * df[atr]
df['basic_lb'] = (df['high'] + df['low']) / 2 - multiplier * df[atr]
# Compute final upper and lower bands
for i in range(0, len(df)):
if i < period:
df.set_value(i, 'basic_ub', 0.00)
df.set_value(i, 'basic_lb', 0.00)
df.set_value(i, 'final_ub', 0.00)
df.set_value(i, 'final_lb', 0.00)
else:
df.set_value(i, 'final_ub', (df.get_value(i, 'basic_ub')
if df.get_value(i, 'basic_ub') < df.get_value(i-1, 'final_ub') or df.get_value(i-1, 'close') > df.get_value(i-1, 'final_ub')
else df.get_value(i-1, 'final_ub')))
df.set_value(i, 'final_lb', (df.get_value(i, 'basic_lb')
if df.get_value(i, 'basic_lb') > df.get_value(i-1, 'final_lb') or df.get_value(i-1, 'close') < df.get_value(i-1, 'final_lb')
else df.get_value(i-1, 'final_lb')))
# Set the Supertrend value
for i in range(0, len(df)):
if i < period:
df.set_value(i, st, 0.00)
else:
df.set_value(i, 'st', (df.get_value(i, 'final_ub')
if ((df.get_value(i-1, 'st') == df.get_value(i-1, 'final_ub')) and (df.get_value(i, 'close') <= df.get_value(i, 'final_ub')))
else (df.get_value(i, 'final_lb')
if ((df.get_value(i-1, 'st') == df.get_value(i-1, 'final_ub')) and (df.get_value(i, 'close') > df.get_value(i, 'final_ub')))
else (df.get_value(i, 'final_lb')
if ((df.get_value(i-1, 'st') == df.get_value(i-1, 'final_lb')) and (df.get_value(i, 'close') >= df.get_value(i, 'final_lb')))
else (df.get_value(i, 'final_ub')
if((df.get_value(i-1, 'st') == df.get_value(i-1, 'final_lb')) and (df.get_value(i, 'close') < df.get_value(i, 'final_lb')))
else 0.00
)
)
)
)
)
# Mark the trend direction up/down
df['stx'] = np.where((df['st'] > 0.00), np.where((df['close'] < df['st']), 'down', 'up'), np.NaN)
I works, but I am not happy with the for loop. Can anyone help optimise it?
You can find the released code on Github!
SuperTrend Indicator is included in pandas_ta
where you can simply:
import pandas_ta as ta
sti = ta.supertrend(df['High'], df['Low'], df['Close'], length=7, multiplier=3)
Given that df
is a pandas DataFrame with OHLC prices, the result sti
is a DataFrame with 4 columns:
where the trend is a concatenation of the long and short lines. Note that column captions are dynamic and contain the length and multiplier parameter values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With