Session goal: Run existing test suite, measure codebase health, identify integration gaps between design docs and implementation. Prepare for Phase 3 (signal engine V2) implementation.
Progress log:
- 00:00 — Read project index.md, REVIEW.md, signal-engine-v2-design.md, risk-framework-spec.md
- 00:15 — Scanned codebase structure: 5,113 lines across 18 Python files in scripts/paper_trading/
- 00:30 — Identified missing venv dependencies; located existing .venv at /opt/data/.venv with pandas, numpy, pytest installed
- 00:45 — Ran full test suite:
pytest scripts/paper_trading/test_*.py -v
Test results (38 collected):
| Module | Tests | Status |
|---|---|---|
| factor_screen.py (16 tests) | ✅ 16 passed | All screening logic works |
| rebalancer.py (13 tests) | ✅ 13 passed | Scheduler and weight clamping OK |
| test_integration.py (8 tests) | ❌ 8 failed | Integration tests broken — create_fundamentals_from_dict API mismatch |
| test_announcement_signals.py | ⚠️ 1 error, 0 run | Missing tickers fixture |
Key finding: The integration tests fail because factor_screen.py::create_fundamentals_from_dict() expects flat dicts (not nested). The function signature takes ticker_data: Dict[str, Dict] but iterates with data.get('roe') — it treats values as dict when they’re scalars. The root cause is the test fixtures pass nested dicts ({key: {roe_pct: 18.0}}) while the function expects {ticker: {roe: ...}}.
Gap analysis — Design vs Implementation:
| Design Module (signal-engine-v2-design.md) | Exists? | Notes |
|---|---|---|
asx_data_feed.py | ✅ Yes | Basic OHLCV fetch; missing dividend history field, SQLite cache |
factor_engine.py | ❌ No equivalent | Implemented as factor_screen.py (different API). Not a signal engine — it’s a pre-filter |
fee_gate.py | ✅ Yes | 217 lines, tested. Matches design spec for IBKR AU flat fees |
dividend_layer.py | ✅ Yes | 320 lines, tested. DRIP compounding model present |
mock_data.py | ❌ Missing | Design calls for it; no equivalent in codebase |
signal_store (SQLite) | ❌ Missing | No persistent signal store implementation |
Integration gap: runner.py has 10 imports that need wiring:
from signal_engine import SignalEngine # exists ✅
from ibkr_connection import IBKRConnection # exists ✅
from factor_screen import FactorScreen # exists ✅
from rebalancer import RebalanceScheduler # exists ✅
# Missing integrations:
- fee_gate NOT imported or used in runner.py
- position_sizer NOT imported
- drawdown_protection NOT imported
- concentration_guard NOT imported
- dividend_layer NOT importedCritical issues for Phase 3 implementation:
- Integration tests are broken —
test_integration.pyuses wrong fixture format forFactorScreen. Must fix before adding new modules. - No end-to-end pipeline exists — runner.py can fetch data and generate signals, but fee_gate, risk framework, and dividend layer are standalone modules never composed together.
- Design doc references “signal_engine_v2” but actual code uses SMA crossover + Kelly — the SignalEngine class implements technical indicators (SMA cross), NOT the factor/dividend-based signals from the V2 design. The V2 FactorEngine spec has not been implemented.
Outputs: None written today — pure audit/research session.
Issues / Questions for pvs:
- Should I fix the integration test failures first, or start implementing signal_engine_v2 design?
- The
create_fundamentals_from_dictAPI is ambiguous — should the function accept flat dicts{roe: 0.15}or nested with ticker wrapper? Current tests expect one, code expects other. - Priority: mock data pipeline vs persistent signal store? Both needed for V2 but can’t do both in one session.
Status: done (audit complete)