diff --git a/apps/orb_trader/engine.py b/apps/orb_trader/engine.py index 7e75775..cda6a41 100644 --- a/apps/orb_trader/engine.py +++ b/apps/orb_trader/engine.py @@ -63,10 +63,9 @@ class ORBTradingEngine: self._params = params self._log_callback = log_callback # optional scheduler._log for UI visibility - # Force live trading overrides - self._params.compound_returns = True - self._params.settlement_days = 0 - self._params.slippage_bps = 0.0 + # Live trading overrides + self._params.settlement_days = 0 # paper trading; no real T+1 settlement + self._params.slippage_bps = 0.0 # real fills, no simulated slippage # IEX feed has ~1-3% market share vs SIP; RVOL computed from IEX ORB volume # relative to SIP avg_daily_vol would be ~0.01-0.03 (min_rvol=1.0 would filter # everything). Disable the threshold filter; RVOL is still used for ranking. @@ -883,11 +882,20 @@ class ORBTradingEngine: self._session.session_id, date_str, pos.ticker ) - # Cancel any unfilled breakout orders + # Cancel any unfilled breakout candidates (in-memory and DB) for cand in self._pending_cands: self._state.update_candidate_status( self._session.session_id, date_str, cand["ticker"], "timeout" ) + self._pending_cands = [] + + # Also sweep DB for any pending records not in in-memory list (e.g. after restart) + db_cands = self._state.list_candidates(self._session.session_id, date_str) + for c in db_cands: + if c["status"] == "pending": + self._state.update_candidate_status( + self._session.session_id, date_str, c["ticker"], "timeout" + ) return {"closed": closed}