docs: add implementation plan for medium-term positioning upgrade

Covers 4 objectives: increased debate rounds, 8-quarter TTM fundamentals,
sector/peer relative performance, and macro regime classification.

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH
This commit is contained in:
Claude 2026-03-17 14:15:30 +00:00
parent e448e06b4a
commit 5335bdac37
No known key found for this signature in database
1 changed files with 299 additions and 0 deletions

299
PLAN.md Normal file
View File

@ -0,0 +1,299 @@
# Implementation Plan: Medium-Term Positioning Upgrade
## Lead Architect Overview
Four objectives to upgrade TradingAgents for medium-term (13 month) positioning:
1. **Agentic Debate** — Increase debate rounds to 23
2. **Fundamental Data** — Extend look-back to 8 quarters with TTM trend computation
3. **Relative Performance** — Sector & peer comparison tools
4. **Macro Regime Flag** — Classify market as risk-on / risk-off / transition
---
## Step 1: Agentic Debate — Increase Rounds (Architect + API Integrator)
**Assigned to: API Integrator Agent**
**Risk: LOW** — Config-only change, conditional logic already supports arbitrary round counts.
### Changes:
- **File:** `tradingagents/default_config.py`
- Change `"max_debate_rounds": 1``"max_debate_rounds": 2`
- Change `"max_risk_discuss_rounds": 1``"max_risk_discuss_rounds": 2`
- **File:** `tradingagents/graph/trading_graph.py` (line 146)
- Pass config values to `ConditionalLogic`:
```python
self.conditional_logic = ConditionalLogic(
max_debate_rounds=self.config.get("max_debate_rounds", 2),
max_risk_discuss_rounds=self.config.get("max_risk_discuss_rounds", 2),
)
```
- **NOTE:** Currently `ConditionalLogic()` is called with no args, so it uses its own defaults of 1. The config values are never actually wired in. This is a bug fix.
### Verification:
- Investment debate: count threshold = `2 * 2 = 4` → Bull speaks 2×, Bear speaks 2× before judge
- Risk debate: count threshold = `3 * 2 = 6` → Each of 3 analysts speaks 2× before judge
- `max_recur_limit` of 100 is sufficient (was 100, worst case ~20 graph steps)
---
## Step 2: Fundamental Data — 8-Quarter TTM Trend (API Integrator + Economist)
**Assigned to: API Integrator (data layer) + Economist (TTM computation logic)**
**Risk: MEDIUM** — Requires new data tool + prompt update + TTM computation module.
### 2A: New TTM Computation Module (Economist Agent)
- **New file:** `tradingagents/dataflows/ttm_analysis.py`
- `compute_ttm_metrics(income_df, balance_df, cashflow_df) -> dict`
- Sum last 4 quarters of income stmt for flow items (Revenue, Net Income, EBITDA, Operating Income, Gross Profit)
- Use latest quarter for balance sheet (stock items: Total Assets, Total Debt, Equity)
- Compute key ratios: Revenue Growth (QoQ and YoY), Margin trends (Gross, Operating, Net), ROE trend, Debt/Equity trend, FCF trend
- `format_ttm_report(metrics: dict, ticker: str) -> str`
- Markdown report with 8-quarter trend table + TTM summary + quarter-over-quarter trajectory
### 2B: New Tool — `get_ttm_analysis` (API Integrator Agent)
- **File:** `tradingagents/agents/utils/fundamental_data_tools.py`
- Add new `@tool` function `get_ttm_analysis(ticker, curr_date) -> str`
- Internally calls existing vendor-routed `get_income_statement`, `get_balance_sheet`, `get_cashflow` with `freq="quarterly"`
- Passes raw data to `compute_ttm_metrics()` and `format_ttm_report()`
- **File:** `tradingagents/agents/utils/agent_utils.py`
- Export `get_ttm_analysis` tool
### 2C: Update Fundamentals Analyst Prompt (Economist Agent)
- **File:** `tradingagents/agents/analysts/fundamentals_analyst.py`
- Add `get_ttm_analysis` to tools list
- Update system prompt from "past week" to:
> "You are a researcher tasked with analyzing fundamental information covering the last 8 quarters (2 years) for a company. First call `get_ttm_analysis` to obtain a Trailing Twelve Months (TTM) trend report including revenue growth, margin trajectories, and key ratio trends. Then supplement with `get_fundamentals` for the latest snapshot. Write a comprehensive report covering multi-quarter trends, not just the most recent filing."
- **File:** `tradingagents/graph/trading_graph.py``_create_tool_nodes()`
- Add `get_ttm_analysis` to the `"fundamentals"` ToolNode
### 2D: Data Layer — Ensure 8 Quarters Available
- **yfinance:** `ticker.quarterly_income_stmt` returns up to 5 quarters. To get 8, we need to combine quarterly + annual or make 2 calls. Actually, yfinance returns the last 4-5 quarters by default. We'll need to fetch 2+ years of data.
- Approach: Call `ticker.quarterly_income_stmt` which returns available quarters (typically 4-5). Also call `ticker.income_stmt` (annual) for older periods. Combine to reconstruct 8 quarters.
- **Alternative (preferred):** yfinance `ticker.get_income_stmt(freq="quarterly", as_dict=False)` can return more data. Test this.
- **Fallback:** Alpha Vantage INCOME_STATEMENT endpoint returns up to 20 quarterly reports — use this as the configured vendor for TTM.
- **File:** `tradingagents/default_config.py`
- Add to `tool_vendors`: `"get_ttm_analysis": "alpha_vantage,yfinance"` to prefer Alpha Vantage for richer quarterly history
### Data Source Assessment:
| Source | Quarters Available | Notes |
|--------|-------------------|-------|
| yfinance `quarterly_income_stmt` | 4-5 | Limited but free |
| Alpha Vantage `INCOME_STATEMENT` | Up to 20 quarterly | Best option, needs API key |
| Alpha Vantage `BALANCE_SHEET` | Up to 20 quarterly | Same |
| Alpha Vantage `CASH_FLOW` | Up to 20 quarterly | Same |
---
## Step 3: Relative Performance — Sector & Peer Comparison (API Integrator + Economist)
**Assigned to: API Integrator (tools) + Economist (comparison logic)**
**Risk: MEDIUM** — New tools leveraging existing scanner infrastructure.
### 3A: New Peer Comparison Module (Economist Agent)
- **New file:** `tradingagents/dataflows/peer_comparison.py`
- `get_sector_peers(ticker) -> list[str]`
- Use yfinance `Ticker.info["sector"]` to identify sector
- Return top 5-8 peers from same sector (use existing `_SECTOR_TICKERS` mapping from `alpha_vantage_scanner.py`, or yfinance Sector.top_companies)
- `compute_relative_performance(ticker, peers, period="6mo") -> str`
- Download price history for ticker + peers via `yf.download()`
- Compute: 1-week, 1-month, 3-month, 6-month returns for each
- Rank ticker among peers
- Compute ticker's alpha vs sector ETF
- Return markdown table with relative positioning
### 3B: New Tools — `get_peer_comparison` and `get_sector_relative` (API Integrator)
- **File:** `tradingagents/agents/utils/fundamental_data_tools.py`
- `get_peer_comparison(ticker, curr_date) -> str`@tool
- Calls `get_sector_peers()` and `compute_relative_performance()`
- Returns ranked peer table with ticker highlighted
- `get_sector_relative(ticker, curr_date) -> str`@tool
- Compares ticker vs its sector ETF over multiple time frames
- Returns outperformance/underperformance metrics
- **File:** `tradingagents/agents/utils/agent_utils.py`
- Export both new tools
### 3C: Wire Into Fundamentals Analyst (API Integrator)
- **File:** `tradingagents/agents/analysts/fundamentals_analyst.py`
- Add `get_peer_comparison` and `get_sector_relative` to tools list
- Update prompt to instruct: "Also analyze how the company performs relative to sector peers and its sector ETF benchmark over 1-week, 1-month, 3-month, and 6-month periods."
- **File:** `tradingagents/graph/trading_graph.py``_create_tool_nodes()`
- Add both tools to `"fundamentals"` ToolNode
### 3D: Vendor Routing
- These tools use yfinance directly (no Alpha Vantage endpoint for peer comparison)
- No vendor routing needed — direct yfinance calls inside the module
- Register in `TOOLS_CATEGORIES` under `"fundamental_data"` for consistency
---
## Step 4: Macro Regime Flag (Economist Agent)
**Assigned to: Economist Agent**
**Risk: MEDIUM** — New module + new state field + integration into Research Manager.
### 4A: Macro Regime Classifier Module (Economist)
- **New file:** `tradingagents/dataflows/macro_regime.py`
- `classify_macro_regime(curr_date: str = None) -> dict`
- Returns: `{"regime": "risk-on"|"risk-off"|"transition", "confidence": float, "signals": dict, "summary": str}`
- Signal sources (all via yfinance — free, no API key needed):
1. **VIX level**: `yf.Ticker("^VIX")`<16 risk-on, 16-25 transition, >25 risk-off
2. **VIX trend**: 5-day vs 20-day SMA — rising = risk-off signal
3. **Credit spread proxy**: `yf.Ticker("HYG")` vs `yf.Ticker("LQD")` — HYG/LQD ratio declining = risk-off
4. **Yield curve proxy**: `yf.Ticker("TLT")` (20yr) vs `yf.Ticker("SHY")` (1-3yr) — TLT outperforming = risk-off (flight to safety)
5. **Market breadth**: S&P 500 (`^GSPC`) above/below 200-SMA
6. **Sector rotation signal**: Defensive sectors (XLU, XLP, XLV) outperforming cyclicals (XLY, XLK, XLI) = risk-off
- Scoring: Each signal contributes -1 (risk-off), 0 (neutral), or +1 (risk-on). Aggregate:
- Sum >= 3: "risk-on"
- Sum <= -3: "risk-off"
- Otherwise: "transition"
- `format_macro_report(regime_data: dict) -> str`
- Markdown report with signal breakdown, regime classification, and confidence level
### 4B: New Tool — `get_macro_regime` (API Integrator)
- **File:** `tradingagents/agents/utils/fundamental_data_tools.py` (or new `macro_tools.py`)
- `get_macro_regime(curr_date) -> str`@tool
- Calls `classify_macro_regime()` and `format_macro_report()`
- **File:** `tradingagents/agents/utils/agent_utils.py`
- Export `get_macro_regime`
### 4C: Add Macro Regime to Agent State
- **File:** `tradingagents/agents/utils/agent_states.py`
- Add to `AgentState`:
```python
macro_regime_report: Annotated[str, "Macro regime classification (risk-on/risk-off/transition)"]
```
### 4D: Wire Into Market Analyst (API Integrator)
- **File:** `tradingagents/agents/analysts/market_analyst.py`
- Add `get_macro_regime` to tools list
- Update prompt to include: "Before analyzing individual stock technicals, call `get_macro_regime` to determine the current market environment (risk-on, risk-off, or transition). Interpret all subsequent technical signals through this macro lens."
- Return `macro_regime_report` in output dict
- **File:** `tradingagents/graph/trading_graph.py``_create_tool_nodes()`
- Add `get_macro_regime` to `"market"` ToolNode
### 4E: Feed Macro Regime Into Downstream Agents
- **File:** `tradingagents/agents/managers/research_manager.py`
- Add `macro_regime_report` to the `curr_situation` string that gets passed to the judge
- Update prompt to reference macro regime in decision-making
- **File:** `tradingagents/agents/managers/risk_manager.py`
- Include macro regime context in risk assessment prompt
- **File:** `tradingagents/graph/trading_graph.py``_log_state()`
- Add `macro_regime_report` to logged state
---
## Step 5: Integration Tests (Tester Agent)
**Assigned to: Tester Agent**
### 5A: Test Debate Rounds — `tests/test_debate_rounds.py`
- Test `ConditionalLogic` with `max_debate_rounds=2`:
- Verify bull/bear alternate correctly for 4 turns
- Verify routing to "Research Manager" after count >= 4
- Test `ConditionalLogic` with `max_risk_discuss_rounds=2`:
- Verify aggressive→conservative→neutral rotation for 6 turns
- Verify routing to "Risk Judge" after count >= 6
- Test config values are properly wired from `TradingAgentsGraph` config to `ConditionalLogic`
### 5B: Test TTM Analysis — `tests/test_ttm_analysis.py`
- Unit test `compute_ttm_metrics()` with mock 8-quarter DataFrames
- Verify TTM revenue = sum of last 4 quarters
- Verify margin calculations
- Verify QoQ and YoY growth rates
- Unit test `format_ttm_report()` output contains expected sections
- Integration test `get_ttm_analysis` tool with real ticker (mark `@pytest.mark.integration`)
### 5C: Test Peer Comparison — `tests/test_peer_comparison.py`
- Unit test `get_sector_peers()` returns valid tickers for known sectors
- Unit test `compute_relative_performance()` with mock price data
- Verify correct return calculations
- Verify ranking logic
- Integration test with real ticker (mark `@pytest.mark.integration`)
### 5D: Test Macro Regime — `tests/test_macro_regime.py`
- Unit test `classify_macro_regime()` with mocked yfinance data:
- All risk-on signals → "risk-on"
- All risk-off signals → "risk-off"
- Mixed signals → "transition"
- Unit test `format_macro_report()` output format
- Unit test scoring edge cases (VIX at boundaries, missing data gracefully handled)
- Integration test with real market data (mark `@pytest.mark.integration`)
### 5E: Test Config Wiring — `tests/test_config_wiring.py`
- Test that `TradingAgentsGraph(config={...})` properly passes debate rounds to `ConditionalLogic`
- Test that new tools appear in the correct ToolNodes
- Test that new state fields exist in `AgentState`
---
## File Change Summary
| File | Action | Objective |
|------|--------|-----------|
| `tradingagents/default_config.py` | EDIT | #1 debate rounds, #2 tool vendor |
| `tradingagents/graph/trading_graph.py` | EDIT | #1 wire config, #2/#3/#4 add tools to ToolNodes, #4 log macro |
| `tradingagents/graph/conditional_logic.py` | NO CHANGE | Already supports arbitrary rounds |
| `tradingagents/agents/utils/agent_states.py` | EDIT | #4 add macro_regime_report |
| `tradingagents/agents/analysts/fundamentals_analyst.py` | EDIT | #2/#3 new tools + prompt |
| `tradingagents/agents/analysts/market_analyst.py` | EDIT | #4 macro regime tool + prompt |
| `tradingagents/agents/managers/research_manager.py` | EDIT | #4 include macro in decision |
| `tradingagents/agents/managers/risk_manager.py` | EDIT | #4 include macro in risk assessment |
| `tradingagents/agents/utils/fundamental_data_tools.py` | EDIT | #2/#3 new tool functions |
| `tradingagents/agents/utils/agent_utils.py` | EDIT | #2/#3/#4 export new tools |
| `tradingagents/agents/__init__.py` | NO CHANGE | Tools don't need agent-level export |
| `tradingagents/dataflows/ttm_analysis.py` | NEW | #2 TTM computation |
| `tradingagents/dataflows/peer_comparison.py` | NEW | #3 peer comparison logic |
| `tradingagents/dataflows/macro_regime.py` | NEW | #4 macro regime classifier |
| `tradingagents/dataflows/interface.py` | EDIT | #2/#3 register new tools in TOOLS_CATEGORIES |
| `tests/test_debate_rounds.py` | NEW | #1 tests |
| `tests/test_ttm_analysis.py` | NEW | #2 tests |
| `tests/test_peer_comparison.py` | NEW | #3 tests |
| `tests/test_macro_regime.py` | NEW | #4 tests |
| `tests/test_config_wiring.py` | NEW | Integration wiring tests |
---
## Execution Order
1. **Step 1** (Debate Rounds) — Independent, can start immediately
2. **Step 4A** (Macro Regime Module) — Independent, can start in parallel
3. **Step 2A** (TTM Module) — Independent, can start in parallel
4. **Step 3A** (Peer Comparison Module) — Independent, can start in parallel
5. **Step 2B2D** (TTM Integration) — Depends on 2A
6. **Step 3B3D** (Peer Integration) — Depends on 3A
7. **Step 4B4E** (Macro Integration) — Depends on 4A
8. **Step 5** (All Tests) — Depends on all above
Steps 1, 2A, 3A, 4A can all run in parallel.
---
## Risk Mitigation
- **yfinance quarterly data limit:** If yfinance returns <8 quarters, TTM module gracefully computes with available data and notes the gap. Alpha Vantage fallback provides full 20 quarters.
- **New state field (macro_regime_report):** Default empty string. All existing agents that don't produce it will leave it empty — no reducer conflicts.
- **Rate limits:** Macro regime and peer comparison both call yfinance which has no rate limit. Sector performance via Alpha Vantage is already rate-limited at 75/min.
- **Backward compatibility:** All changes are additive. `max_debate_rounds=1` still works. New tools are optional in prompts. `macro_regime_report` defaults to empty.