Yes, this happens because of candle instability at market open.
At 9:15 the volatility is very high, candles move very fast, ATR is not stable initially that’s why this happens.
So, the main fix is using only closed candles, wait for enough candles like 20 candles minimum and use proper ATR smoothing/alignment.
After first few candles your super trend will be working great.
def compute_supertrend(candles, period=10, multiplier=3):
if len(candles) < period + 2:
return []
trs = []
for i in range(1, len(candles)):
h = candles[i]["high"]
l = candles[i]["low"]
pc = candles[i - 1]["close"]
tr = max(
h - l,
abs(h - pc),
abs(l - pc)
)
trs.append(tr)
if len(trs) < period:
return []
atr_vals = [sum(trs[:period]) / period]
for i in range(period, len(trs)):
atr = (
(atr_vals[-1] * (period - 1)) + trs[i]
) / period
atr_vals.append(atr)
atr = [None] * period + atr_vals
final_upper = [None] * len(candles)
final_lower = [None] * len(candles)
supertrend = [None] * len(candles)
direction = [None] * len(candles)
result = []
for i in range(len(candles)):
if atr[i] is None:
result.append(None)
continue
h = candles[i]["high"]
l = candles[i]["low"]
c = candles[i]["close"]
hl2 = (h + l) / 2
upper_band = hl2 + (multiplier * atr[i])
lower_band = hl2 - (multiplier * atr[i])
if final_upper[i - 1] is None:
final_upper[i] = upper_band
final_lower[i] = lower_band
else:
prev_upper = final_upper[i - 1]
prev_lower = final_lower[i - 1]
prev_close = candles[i - 1]["close"]
final_upper[i] = (
upper_band
if upper_band < prev_upper or prev_close > prev_upper
else prev_upper
)
final_lower[i] = (
lower_band
if lower_band > prev_lower or prev_close < prev_lower
else prev_lower
)
if supertrend[i - 1] is None:
if c <= final_upper[i]:
supertrend[i] = final_upper[i]
direction[i] = "SELL"
else:
supertrend[i] = final_lower[i]
direction[i] = "BUY"
elif supertrend[i - 1] == final_upper[i - 1]:
if c <= final_upper[i]:
supertrend[i] = final_upper[i]
direction[i] = "SELL"
else:
supertrend[i] = final_lower[i]
direction[i] = "BUY"
else:
if c >= final_lower[i]:
supertrend[i] = final_lower[i]
direction[i] = "BUY"
else:
supertrend[i] = final_upper[i]
direction[i] = "SELL"
result.append({
"supertrend": round(supertrend[i], 2),
"signal": direction[i]
})
return result
# Sample candles - reolace thsi with actual live candle data
candles = [
{"high": 101, "low": 99, "close": 100},
{"high": 102, "low": 100, "close": 101},
{"high": 103, "low": 101, "close": 102},
{"high": 104, "low": 102, "close": 103},
{"high": 105, "low": 103, "close": 104},
{"high": 106, "low": 104, "close": 105},
{"high": 107, "low": 105, "close": 106},
{"high": 108, "low": 106, "close": 107},
{"high": 109, "low": 107, "close": 108},
{"high": 110, "low": 108, "close": 109},
{"high": 111, "low": 109, "close": 110},
{"high": 112, "low": 110, "close": 111},
{"high": 113, "low": 111, "close": 112},
]
result = compute_supertrend(candles)
for row in result:
print(row)