trading/docs/plans/remaining-work-plan.md
Viktor Barzin a3cdd0f1a5
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: resolve all remaining TODOs, add dev mode auth bypass
- 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
2026-02-25 22:02:25 +00:00

5.9 KiB

Trading Bot — Remaining Work Plan

Created: 2026-02-25 Status: Complete

Overview

This plan addresses all remaining TODOs, placeholders, and incomplete features in the trading bot. Tasks are ordered by dependency — earlier tasks unblock later ones.


Task 1: Learning engine — expand default weights to all 9 strategies

Status: [x] Complete Files: services/learning_engine/main.py

Problem: _load_strategy_weights() defaults to 3 strategies (momentum, mean_reversion, news_driven) but the signal generator uses all 9. When Redis has no cached weights, the learning engine operates on a stale subset.

Fix: Change the default fallback to all 9 strategies with equal weights (~0.111 each), matching scripts/seed_strategies.py.


Task 2: Portfolio sync — compute actual daily P&L

Status: [x] Complete Files: services/api_gateway/tasks/portfolio_sync.py

Problem: daily_pnl is hardcoded to 0.0 in _sync_once() (line 60).

Fix: Before inserting the new snapshot, query the most recent prior snapshot for today. Compute daily_pnl = current_total_value - day_start_total_value. If no prior snapshot exists for today, the first snapshot's daily_pnl is 0.0.


Task 3: Portfolio API — cumulative P&L from first snapshot

Status: [x] Complete Files: services/api_gateway/routes/portfolio.py

Problem: total_pnl on line 90 just returns latest.daily_pnl instead of the cumulative P&L since inception.

Fix: Query the earliest PortfolioSnapshot and compute:

  • total_pnl = latest.total_value - earliest.total_value
  • total_pnl_pct = total_pnl / earliest.total_value * 100

Task 4: Portfolio API — read trading pause flag from Redis

Status: [x] Complete Files: services/api_gateway/routes/portfolio.py

Problem: trading_active is hardcoded to True (line 92).

Fix: Read the trading:paused key from Redis (same key used by services/api_gateway/routes/controls.py). Return trading_active = not paused.


Task 5: Portfolio metrics — compute max drawdown from snapshots

Status: [x] Complete Files: services/api_gateway/routes/portfolio.py

Problem: max_drawdown is hardcoded to 0.0 (line 170).

Fix: Query all PortfolioSnapshot rows, compute the running peak and maximum percentage drop from peak. Return as a positive decimal (e.g. 0.12 = 12% drawdown).


Task 6: Portfolio metrics — compute avg hold duration from trade outcomes

Status: [x] Complete Files: services/api_gateway/routes/portfolio.py

Problem: avg_hold_duration is hardcoded to "0h" (line 172).

Fix: Query TradeOutcome rows, average the hold_duration_seconds column, and format as a human-readable string (e.g. "4h 30m", "2d 6h").


Task 7: Trade executor — respect the trading pause flag

Status: [x] Complete Files: services/trade_executor/risk_manager.py

Problem: The controls API sets/clears trading:paused in Redis, but the trade executor's RiskManager.check_risk() never checks it. Pausing has no effect.

Fix: Accept a Redis client in RiskManager.__init__(). Add a check at the top of check_risk() that reads trading:paused and rejects with "trading_paused" if set. Wire the Redis client through from trade_executor/main.py.


Task 8: Learning engine — resolve placeholder strategy_id

Status: [x] Complete Files: services/learning_engine/main.py

Problem: WeightAdjustment on line 207 uses strategy_id=UUID(int=0) as a placeholder. This means weight history records can't be linked to the correct strategy.

Fix: On startup, load the strategies table into a name -> UUID lookup dict. Use this lookup when building WeightAdjustment records. Fall back to UUID(int=0) only if the strategy name isn't in the DB.


Task 9: Pass strategy_sources from signal through to learning engine

Status: [x] Complete Files: services/trade_executor/main.py, services/learning_engine/main.py

Problem: TradeExecution doesn't carry strategy_sources. When the learning engine stores the opening trade (line 136), strategy_sources is always []. This means credit attribution (evaluator.attribute_credit()) has no strategies to reward.

Fix:

  1. Add strategy_sources: list[str] = [] to the TradeExecution schema.
  2. In the trade executor's process_signal(), copy signal.strategy_sources into the execution message.
  3. In the learning engine, read trade.strategy_sources (via the extended schema) and store them in the opening trade record.

Task 10: Update CLAUDE.md and add top-level README

Status: [x] Complete Files: .claude/CLAUDE.md, README.md

Fix:

  • Remove "No CI/CD pipeline yet" from Known Issues (Woodpecker exists).
  • Update strategy count references (3 → 9) in Project Structure section.
  • Update model count (14 → 16 tables).
  • Create a concise top-level README.md with: project description, architecture diagram (text), quickstart (docker compose up), dev setup, and test commands.

Execution Order

Tasks are grouped by dependency:

Group A (independent, do first):

  • Task 1 (learning engine weights)
  • Task 7 (trade executor pause flag)
  • Task 9 (strategy_sources passthrough)

Group B (depends on nothing, can parallel with A):

  • Task 2 (portfolio sync daily P&L)
  • Task 8 (learning engine strategy_id lookup)

Group C (depends on Task 2):

  • Task 3 (cumulative P&L API)
  • Task 4 (trading_active flag API)
  • Task 5 (max drawdown API)
  • Task 6 (avg hold duration API)

Group D (after all code changes):

  • Task 10 (documentation)

Test Strategy

After each task, run the relevant unit tests:

python -m pytest tests/ -v -m "not integration" --tb=short

Existing tests should continue to pass. New tests may be needed for:

  • Task 7: risk manager pause check
  • Task 9: strategy_sources in TradeExecution schema