feat: wire live decision loop and enable paper trading

Phase 2 of the autonomous trading engine:

- Replace start()/stop() stubs with real async implementations
- Decision loop: polls recommendations from PostgreSQL, deduplicates
  via Redis, evaluates through the full pipeline, submits orders to
  stonks:queue:broker_orders
- Stop-loss monitor: fetches prices from Polygon API, checks crossings,
  submits immediate sell orders, safety sell after 15 min without data
- Performance loop: computes metrics every 5 min during market hours,
  persists daily snapshots at market close
- Risk tier scheduler: evaluates daily at 16:00 ET, persists tier changes
- Rebalance scheduler: evaluates Monday 09:45 ET, respects circuit breaker
- Notification dispatch: SNS + Gmail with rate limiting and retry
- Backtest replay: fetches historical data, simulates decisions, persists
- Real asyncpg/redis connections in FastAPI lifespan (graceful degradation)
- Migration 019: enable paper trading with conservative tier, 5 cap
- Added max_open_positions to TradingConfig with env var loading
- Phase 2 tasks added to autonomous-trading-engine spec
This commit is contained in:
Celes Renata
2026-04-15 20:52:28 +00:00
parent c4b90a5224
commit 70bad7709a
8 changed files with 2159 additions and 28 deletions
+2
View File
@@ -191,6 +191,7 @@ class TradingConfig:
micro_trading_allocation_cap_pct: float = 0.03
micro_trading_max_daily: int = 10
micro_trading_max_hold_minutes: int = 120
max_open_positions: int = 10
sns_topic_arn: str = ""
sns_phone_number: str = ""
gmail_sender: str = ""
@@ -326,6 +327,7 @@ def load_config() -> AppConfig:
micro_trading_allocation_cap_pct=float(os.getenv("TRADING_MICRO_TRADING_ALLOCATION_CAP_PCT", "0.03")),
micro_trading_max_daily=int(os.getenv("TRADING_MICRO_TRADING_MAX_DAILY", "10")),
micro_trading_max_hold_minutes=int(os.getenv("TRADING_MICRO_TRADING_MAX_HOLD_MINUTES", "120")),
max_open_positions=int(os.getenv("TRADING_MAX_OPEN_POSITIONS", "10")),
sns_topic_arn=os.getenv("TRADING_SNS_TOPIC_ARN", ""),
sns_phone_number=os.getenv("TRADING_SNS_PHONE_NUMBER", ""),
gmail_sender=os.getenv("TRADING_GMAIL_SENDER", ""),