from core.models import Signal from strategies.base import Strategy from utils.indicators import atr class SessionBreakout(Strategy): name = "session_breakout" def __init__(self, timeframe, params): super().__init__(timeframe, params) self.traded_day = {} def on_bar(self, symbol, df): p = self.p last = df.iloc[-1] day, h = last.time.date(), last.time.hour if not (p["range_end"] <= h < p["trade_until"]) or self.traded_day.get(symbol) == day: return None today = df[df.time.dt.date == day] rng = today[(today.time.dt.hour >= p["range_start"]) & (today.time.dt.hour < p["range_end"])] if len(rng) < 4: return None hi, lo = rng.high.max(), rng.low.min() a = atr(df, 14).iloc[-1] side = "buy" if last.close > hi else "sell" if last.close < lo else None if side: self.traded_day[symbol] = day sl = p["sl_atr"] * a return Signal(symbol, side, sl, sl * p["rr"], self.name, "Range breakout")