fix: resolve all remaining TODOs, add dev mode auth bypass
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

- Learning engine: expand default weights from 3 to all 9 strategies
- Learning engine: resolve placeholder strategy_id with DB lookup
- Learning engine: pass strategy_sources from trade execution
- Trade executor: respect trading:paused Redis flag in RiskManager
- Portfolio sync: compute actual daily P&L from day-start snapshot
- Portfolio API: cumulative P&L from first snapshot, read pause flag
- Portfolio metrics: compute max drawdown and avg hold duration
- Add strategy_sources field to TradeExecution schema
- Add dev_mode config (TRADING_DEV_MODE) to bypass auth for local dev
- Dashboard: VITE_DEV_MODE bypasses ProtectedRoute and 401 redirects
- Vite proxy target configurable via VITE_API_TARGET
- Add top-level README.md and remaining-work-plan.md
- Update CLAUDE.md with correct counts and remove stale TODOs
- 404 tests passing

Made-with: Cursor
This commit is contained in:
Viktor Barzin 2026-02-25 22:02:25 +00:00
parent 4094e4b10f
commit a3cdd0f1a5
No known key found for this signature in database
GPG key ID: 0EB088298288D958
16 changed files with 511 additions and 45 deletions

View file

@ -103,6 +103,7 @@ async def process_signal(
status=result.status,
signal_id=signal.signal_id,
strategy_id=None,
strategy_sources=signal.strategy_sources,
timestamp=result.timestamp,
)
@ -193,7 +194,7 @@ async def run(config: TradeExecutorConfig | None = None) -> None:
)
# --- Risk manager ---
risk_manager = RiskManager(config, broker)
risk_manager = RiskManager(config, broker, redis=redis)
# --- Database (for persisting trades) ---
db_session_factory = None

View file

@ -10,6 +10,8 @@ import logging
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from redis.asyncio import Redis
from services.trade_executor.config import TradeExecutorConfig
from shared.broker.base import BaseBroker
from shared.schemas.trading import AccountInfo, PositionInfo, SignalDirection, TradeSignal
@ -24,6 +26,8 @@ _MARKET_OPEN_MINUTE = 30
_MARKET_CLOSE_HOUR = 16
_MARKET_CLOSE_MINUTE = 0
TRADING_PAUSED_KEY = "trading:paused"
class RiskManager:
"""Performs pre-trade risk checks and calculates position sizes.
@ -34,11 +38,19 @@ class RiskManager:
Trade executor configuration with risk parameters.
broker:
Broker instance for querying current positions and account info.
redis:
Redis client for checking the trading pause flag.
"""
def __init__(self, config: TradeExecutorConfig, broker: BaseBroker) -> None:
def __init__(
self,
config: TradeExecutorConfig,
broker: BaseBroker,
redis: Redis | None = None,
) -> None:
self.config = config
self.broker = broker
self.redis = redis
# ticker -> last exit timestamp
self._cooldowns: dict[str, datetime] = {}
@ -55,6 +67,12 @@ class RiskManager:
``(approved, reason)`` ``approved`` is ``True`` when
all checks pass, otherwise ``reason`` explains the failure.
"""
# 0. Trading pause flag
if self.redis is not None:
paused = await self.redis.get(TRADING_PAUSED_KEY)
if paused:
return False, "trading_paused"
# 1. Market hours
now_et = datetime.now(tz=_ET)
if not self._is_market_hours(now_et):