Files
stonks-oracle/services/trading/trading_window.py
T
Celes Renata 4ffde8cc06 feat: autonomous trading engine — full implementation
- Database migration 018 with 13 tables for trading engine state
- Trading engine service (services/trading/) with 12 pure computation modules:
  position sizer, stop-loss manager, reserve pool, circuit breaker,
  risk tier controller, correlation matrix, tax lots, trading window,
  gradual entry, notifications, micro-trading, backtester
- Core TradingEngine with pre-trade evaluation pipeline and integration wiring
- FastAPI HTTP service with 14 endpoints (health, config, decisions, metrics, backtest)
- Performance tracker with Sharpe ratio, drawdown, profit factor computation
- 194 Python tests (165 property-based + 29 integration)
- Frontend: 13 TanStack Query hooks, 7 dashboard panels, tabbed Trading Engine page
- Helm chart entry, network policy, nginx proxy, ingress for trading-engine
- Shared infrastructure: enums, Redis keys, TradingConfig in AppConfig
2026-04-15 16:12:22 +00:00

83 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Trading window utilities for the autonomous trading engine.
Pure computation module that determines whether a given timestamp falls
within the allowed trading window (9:45 AM 3:45 PM ET on weekdays),
whether the US market is open, and when the next trading window opens.
Uses ``zoneinfo.ZoneInfo("America/New_York")`` for Eastern Time handling.
Does not check market holidays (simplified).
"""
from __future__ import annotations
from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo
# US Eastern timezone
ET = ZoneInfo("America/New_York")
# Trading window boundaries (excludes first/last 15 min of market hours)
WINDOW_OPEN = time(9, 45)
WINDOW_CLOSE = time(15, 45)
# Full US market hours
MARKET_OPEN = time(9, 30)
MARKET_CLOSE = time(16, 0)
# Weekday range: Monday=0 … Friday=4
_WEEKDAYS = range(0, 5)
def is_within_trading_window(dt: datetime) -> bool:
"""Return True if *dt* is between 9:45 AM ET and 3:45 PM ET on a weekday.
The timestamp is first converted to US/Eastern time. Weekends are
always outside the window. Market holidays are **not** checked
(simplified implementation).
"""
et_dt = dt.astimezone(ET)
if et_dt.weekday() not in _WEEKDAYS:
return False
t = et_dt.time()
return WINDOW_OPEN <= t < WINDOW_CLOSE
def next_window_open(dt: datetime) -> datetime:
"""Return the next datetime when the trading window opens (9:45 AM ET).
If *dt* is before 9:45 AM ET on a weekday the same day's open is
returned. Otherwise the next weekday's 9:45 AM ET is returned.
"""
et_dt = dt.astimezone(ET)
today_open = et_dt.replace(
hour=WINDOW_OPEN.hour,
minute=WINDOW_OPEN.minute,
second=0,
microsecond=0,
)
# If we haven't reached today's open yet and it's a weekday, return today
if et_dt < today_open and et_dt.weekday() in _WEEKDAYS:
return today_open
# Otherwise advance to the next weekday
candidate = et_dt + timedelta(days=1)
candidate = candidate.replace(
hour=WINDOW_OPEN.hour,
minute=WINDOW_OPEN.minute,
second=0,
microsecond=0,
)
while candidate.weekday() not in _WEEKDAYS:
candidate += timedelta(days=1)
return candidate
def is_market_open(dt: datetime) -> bool:
"""Return True if *dt* is during US market hours (9:30 AM 4:00 PM ET) on a weekday."""
et_dt = dt.astimezone(ET)
if et_dt.weekday() not in _WEEKDAYS:
return False
t = et_dt.time()
return MARKET_OPEN <= t < MARKET_CLOSE