15 KiB
Implementation Plan: Medium-Term Positioning Upgrade
Lead Architect Overview
Four objectives to upgrade TradingAgents for medium-term (1–3 month) positioning:
- Agentic Debate — Increase debate rounds to 2–3
- Fundamental Data — Extend look-back to 8 quarters with TTM trend computation
- Relative Performance — Sector & peer comparison tools
- 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
- Change
-
File:
tradingagents/graph/trading_graph.py(line 146)- Pass config values to
ConditionalLogic: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.
- Pass config values to
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_limitof 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.pycompute_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
@toolfunctionget_ttm_analysis(ticker, curr_date) -> str - Internally calls existing vendor-routed
get_income_statement,get_balance_sheet,get_cashflowwithfreq="quarterly" - Passes raw data to
compute_ttm_metrics()andformat_ttm_report()
- Add new
-
File:
tradingagents/agents/utils/agent_utils.py- Export
get_ttm_analysistool
- Export
2C: Update Fundamentals Analyst Prompt (Economist Agent)
-
File:
tradingagents/agents/analysts/fundamentals_analyst.py- Add
get_ttm_analysisto 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_analysisto obtain a Trailing Twelve Months (TTM) trend report including revenue growth, margin trajectories, and key ratio trends. Then supplement withget_fundamentalsfor the latest snapshot. Write a comprehensive report covering multi-quarter trends, not just the most recent filing."
- Add
-
File:
tradingagents/graph/trading_graph.py—_create_tool_nodes()- Add
get_ttm_analysisto the"fundamentals"ToolNode
- Add
2D: Data Layer — Ensure 8 Quarters Available
-
yfinance:
ticker.quarterly_income_stmtreturns 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_stmtwhich returns available quarters (typically 4-5). Also callticker.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.
- Approach: Call
-
File:
tradingagents/default_config.py- Add to
tool_vendors:"get_ttm_analysis": "alpha_vantage,yfinance"to prefer Alpha Vantage for richer quarterly history
- Add to
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.pyget_sector_peers(ticker) -> list[str]- Use yfinance
Ticker.info["sector"]to identify sector - Return top 5-8 peers from same sector (use existing
_SECTOR_TICKERSmapping fromalpha_vantage_scanner.py, or yfinance Sector.top_companies)
- Use yfinance
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
- Download price history for ticker + peers via
3B: New Tools — get_peer_comparison and get_sector_relative (API Integrator)
-
File:
tradingagents/agents/utils/fundamental_data_tools.pyget_peer_comparison(ticker, curr_date) -> str— @tool- Calls
get_sector_peers()andcompute_relative_performance() - Returns ranked peer table with ticker highlighted
- Calls
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_comparisonandget_sector_relativeto 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."
- Add
-
File:
tradingagents/graph/trading_graph.py—_create_tool_nodes()- Add both tools to
"fundamentals"ToolNode
- Add both tools to
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_CATEGORIESunder"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.pyclassify_macro_regime(curr_date: str = None) -> dict- Returns:
{"regime": "risk-on"|"risk-off"|"transition", "confidence": float, "signals": dict, "summary": str}
- Returns:
- Signal sources (all via yfinance — free, no API key needed):
- VIX level:
yf.Ticker("^VIX")→ <16 risk-on, 16-25 transition, >25 risk-off - VIX trend: 5-day vs 20-day SMA — rising = risk-off signal
- Credit spread proxy:
yf.Ticker("HYG")vsyf.Ticker("LQD")— HYG/LQD ratio declining = risk-off - Yield curve proxy:
yf.Ticker("TLT")(20yr) vsyf.Ticker("SHY")(1-3yr) — TLT outperforming = risk-off (flight to safety) - Market breadth: S&P 500 (
^GSPC) above/below 200-SMA - Sector rotation signal: Defensive sectors (XLU, XLP, XLV) outperforming cyclicals (XLY, XLK, XLI) = risk-off
- VIX level:
- 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 newmacro_tools.py)get_macro_regime(curr_date) -> str— @tool- Calls
classify_macro_regime()andformat_macro_report()
-
File:
tradingagents/agents/utils/agent_utils.py- Export
get_macro_regime
- Export
4C: Add Macro Regime to Agent State
- File:
tradingagents/agents/utils/agent_states.py- Add to
AgentState:macro_regime_report: Annotated[str, "Macro regime classification (risk-on/risk-off/transition)"]
- Add to
4D: Wire Into Market Analyst (API Integrator)
-
File:
tradingagents/agents/analysts/market_analyst.py- Add
get_macro_regimeto tools list - Update prompt to include: "Before analyzing individual stock technicals, call
get_macro_regimeto determine the current market environment (risk-on, risk-off, or transition). Interpret all subsequent technical signals through this macro lens." - Return
macro_regime_reportin output dict
- Add
-
File:
tradingagents/graph/trading_graph.py—_create_tool_nodes()- Add
get_macro_regimeto"market"ToolNode
- Add
4E: Feed Macro Regime Into Downstream Agents
-
File:
tradingagents/agents/managers/research_manager.py- Add
macro_regime_reportto thecurr_situationstring that gets passed to the judge - Update prompt to reference macro regime in decision-making
- Add
-
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_reportto logged state
- Add
Step 5: Integration Tests (Tester Agent)
Assigned to: Tester Agent
5A: Test Debate Rounds — tests/test_debate_rounds.py
- Test
ConditionalLogicwithmax_debate_rounds=2:- Verify bull/bear alternate correctly for 4 turns
- Verify routing to "Research Manager" after count >= 4
- Test
ConditionalLogicwithmax_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
TradingAgentsGraphconfig toConditionalLogic
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_analysistool 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 toConditionalLogic - 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
- Step 1 (Debate Rounds) — Independent, can start immediately
- Step 4A (Macro Regime Module) — Independent, can start in parallel
- Step 2A (TTM Module) — Independent, can start in parallel
- Step 3A (Peer Comparison Module) — Independent, can start in parallel
- Step 2B–2D (TTM Integration) — Depends on 2A
- Step 3B–3D (Peer Integration) — Depends on 3A
- Step 4B–4E (Macro Integration) — Depends on 4A
- 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=1still works. New tools are optional in prompts.macro_regime_reportdefaults to empty.