diff --git a/DECISIONS.md b/DECISIONS.md index 55a436c1..92f10194 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -102,6 +102,49 @@ Download 6 months of history via `yf.download()` and compute 1-day, 1-week, 1-mo --- +## Decision 008: Medium-Term Upgrade — Macro Regime via yfinance Only + +**Date**: 2026-03-17 +**Status**: Implemented ✅ + +**Context**: Macro regime classification needs VIX, credit spreads, yield curve, market breadth, sector rotation — all free signals. + +**Decision**: Use yfinance exclusively for all macro regime signals (no Alpha Vantage endpoint for this data). 6 signals from `^VIX`, `^GSPC`, `HYG`, `LQD`, `TLT`, `SHY`, and sector ETFs. No vendor routing needed. + +**Scoring**: Each signal ±1. Total ≥3 = risk-on, ≤-3 = risk-off, else transition. Confidence based on absolute score: |score| ≥4 → high, ≥2 → medium, else low. + +**File**: `tradingagents/dataflows/macro_regime.py` + +--- + +## Decision 009: TTM Tool Prefers Alpha Vantage (More History) + +**Date**: 2026-03-17 +**Status**: Implemented ✅ + +**Context**: yfinance returns only 4-5 quarterly periods. Alpha Vantage `INCOME_STATEMENT` endpoint returns up to 20 quarters. For 8-quarter trend analysis, AV is significantly better. + +**Decision**: `get_ttm_analysis` tool uses `route_to_vendor` with AV as primary, yfinance as fallback. TTM module handles <8 quarters gracefully (computes with what's available, reports `quarters_available`). + +**File**: `tradingagents/dataflows/ttm_analysis.py` + +--- + +## Decision 010: Peer Comparison via Hardcoded Sector Tickers + +**Date**: 2026-03-17 +**Status**: Implemented ✅ + +**Context**: No Alpha Vantage endpoint for peer comparison. yfinance `top_companies` was unreliable (Mistake 3). Need deterministic peer lists. + +**Decision**: Hardcode `_SECTOR_TICKERS` mapping (20 tickers per sector) and `_SECTOR_ETFS` in `peer_comparison.py`. Peer data via `yf.download()` — reliable and fast. Sector ETF used as benchmark for alpha calculation. + +**Trade-off**: Peers don't auto-update if sector composition changes. Acceptable for current use case. + +**File**: `tradingagents/dataflows/peer_comparison.py` + +--- + ## Decision 007: .env Loading Strategy **Date**: 2026-03-17 diff --git a/MISTAKES.md b/MISTAKES.md index b3629182..3b40c839 100644 --- a/MISTAKES.md +++ b/MISTAKES.md @@ -92,6 +92,35 @@ Documenting bugs and wrong assumptions to avoid repeating them. --- +## Mistake 10: Python 3.11 f-string backslash restriction + +**What happened**: `ttm_analysis.py` used a backslash inside an f-string expression: +```python +f"| Debt / Equity | {f\"{ttm['debt_to_equity']:.2f}x\" if ...} |" +``` +Python 3.11 raises `SyntaxError: f-string expression part cannot include a backslash`. + +**Fix**: Pre-compute the string outside the f-string or use string concatenation: +```python +f"| Debt / Equity | {(str(round(ttm['debt_to_equity'], 2)) + 'x') if ... else 'N/A'} |" +``` + +**Lesson**: Python 3.11 does not allow backslashes inside f-string `{}` expressions. Extract to a variable or use string concatenation instead. (Python 3.12+ relaxes this restriction.) + +--- + +## Mistake 11: Mock test data precision — threshold boundary failures + +**What happened**: `test_risk_on_regime` failed because mock risk-on data scored only 2 (needed ≥3). Two signals were inadvertently near-threshold: +1. Flat VIX series → VIX trend signal = 0 (SMA5 == SMA20) +2. `_trending_series(80, 85, 250)` HYG → 21-day change was 0.499%, just under 0.5% threshold → credit spread = 0 + +**Fix**: Made mock data obviously far from thresholds: `_trending_series(30, 12, n)` for VIX (clearly falling), `_trending_series(75, 90, n)` for HYG (clearly improving). + +**Lesson**: When writing signal/threshold tests, make mock data unmistakably one-sided. Near-threshold values cause brittle tests. The mock should test the regime, not the exact threshold boundary. + +--- + ## Mistake 9: Removed top-level `llm_provider` but code still references it **What happened**: Removed `llm_provider` from `default_config.py` (since we have per-tier providers). But `scanner_graph.py` line 78 does `self.config.get(f"{tier}_llm_provider") or self.config["llm_provider"]` — would crash if per-tier provider is ever None. diff --git a/PROGRESS.md b/PROGRESS.md index 8beafb32..625e1b25 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -52,6 +52,48 @@ The 3-phase scanner pipeline runs successfully from `python -m cli.main scan --d --- +## Milestone: Medium-Term Positioning Upgrade ✅ COMPLETE (PR pending) + +Branch: `claude/implement-medium-term-upgrade-VDdph` + +### What Was Added + +| Component | Status | Notes | +|-----------|--------|-------| +| Debate rounds 1→2 | ✅ | `default_config.py`; also fixed ConditionalLogic wiring bug | +| ConditionalLogic config wiring | ✅ | `trading_graph.py` was ignoring config, always using defaults | +| 8-quarter TTM analysis | ✅ | `tradingagents/dataflows/ttm_analysis.py` + `get_ttm_analysis` tool | +| Sector/peer comparison | ✅ | `tradingagents/dataflows/peer_comparison.py` + `get_peer_comparison`, `get_sector_relative` tools | +| Macro regime classifier | ✅ | `tradingagents/dataflows/macro_regime.py` + `get_macro_regime` tool | +| `macro_regime_report` AgentState field | ✅ | `agent_states.py`; fed into research + risk managers | +| New unit tests (88) | ✅ | 5 new test files; 104 passed, 0 failed | + +### New Files + +- `tradingagents/dataflows/ttm_analysis.py` — parse vendor CSVs, compute TTM, QoQ/YoY trends +- `tradingagents/dataflows/peer_comparison.py` — sector peer lookup, 1W/1M/3M/6M/YTD ranking vs ETF +- `tradingagents/dataflows/macro_regime.py` — 6-signal macro regime classifier (yfinance only) +- `tests/test_ttm_analysis.py` (18 tests) +- `tests/test_peer_comparison.py` (11 tests) +- `tests/test_macro_regime.py` (16 tests) +- `tests/test_debate_rounds.py` (17 tests) +- `tests/test_config_wiring.py` (12 tests) + +### Modified Files + +- `tradingagents/default_config.py` — debate rounds 1→2 +- `tradingagents/graph/trading_graph.py` — bug fix + new tools in ToolNodes +- `tradingagents/agents/utils/fundamental_data_tools.py` — 4 new `@tool` functions +- `tradingagents/agents/utils/agent_utils.py` — export 4 new tools +- `tradingagents/agents/utils/agent_states.py` — `macro_regime_report` field +- `tradingagents/agents/analysts/fundamentals_analyst.py` — 3 new tools, 8-quarter prompt +- `tradingagents/agents/analysts/market_analyst.py` — macro regime tool, returns macro_regime_report +- `tradingagents/agents/managers/research_manager.py` — macro regime context +- `tradingagents/agents/managers/risk_manager.py` — macro regime context +- `tradingagents/dataflows/interface.py` — register `get_ttm_analysis` + +--- + ## TODOs / Future Work ### High Priority