29 KiB
Financial Tools & Indicators — Comprehensive Analysis
Scope: All technical-indicator, fundamental, and risk implementations in
tradingagents/dataflows/andtradingagents/portfolio/risk_metrics.py.Perspective: Dual review — Quantitative Economist × Senior Software Developer.
Table of Contents
1. Implementation Accuracy
1.1 Technical Indicators (stockstats via yfinance)
| Indicator | Key | Library | Mathematically Correct? | Notes |
|---|---|---|---|---|
| 50-day SMA | close_50_sma |
stockstats | ✅ Yes | Standard arithmetic rolling mean of closing prices over 50 periods. |
| 200-day SMA | close_200_sma |
stockstats | ✅ Yes | Same as above over 200 periods. |
| 10-day EMA | close_10_ema |
stockstats | ✅ Yes | Recursive EMA: EMA_t = α·P_t + (1-α)·EMA_{t-1}, α = 2/(n+1). stockstats implements the standard Wilder/exponential formula. |
| MACD | macd |
stockstats | ✅ Yes | Difference of 12-period and 26-period EMAs. |
| MACD Signal | macds |
stockstats | ✅ Yes | 9-period EMA of the MACD line. |
| MACD Histogram | macdh |
stockstats | ✅ Yes | MACD line minus Signal line. |
| RSI (14) | rsi |
stockstats | ✅ Yes | Wilder's RSI: 100 - 100/(1 + avg_gain/avg_loss). Uses EMA smoothing of gains/losses (Wilder's method, which is the industry standard). |
| Bollinger Middle | boll |
stockstats | ✅ Yes | 20-period SMA of close. |
| Bollinger Upper | boll_ub |
stockstats | ✅ Yes | Middle + 2 × rolling standard deviation. |
| Bollinger Lower | boll_lb |
stockstats | ✅ Yes | Middle − 2 × rolling standard deviation. |
| ATR (14) | atr |
stockstats | ✅ Yes | Wilder's smoothed average of True Range: `max(H-L, |
| VWMA | vwma |
stockstats | ✅ Yes | Volume-weighted moving average: Σ(P_i × V_i) / Σ(V_i). Only available via the yfinance/stockstats vendor (not Alpha Vantage or Finnhub). |
| MFI | mfi |
stockstats | ✅ Yes | Money Flow Index: volume-weighted RSI variant. yfinance-only. |
Verdict: All technical indicators delegate to the stockstats library, which
implements the canonical formulas (Wilder RSI, standard EMA, Bollinger 2σ, etc.).
No custom re-implementations exist for these indicators — the code is a thin data-fetching
and formatting layer around stockstats.
1.2 Alpha Vantage Indicators
The Alpha Vantage vendor (alpha_vantage_indicator.py) calls the Alpha Vantage REST API
endpoints directly (e.g., SMA, EMA, MACD, RSI, BBANDS, ATR). These endpoints
return pre-computed indicator values. The app does no local calculation — it fetches
CSV data, parses it, and filters by date range.
| Aspect | Assessment |
|---|---|
| API call mapping | ✅ Correct — each indicator maps to the right AV function. |
| CSV parsing | ✅ Correct — column name mapping (COL_NAME_MAP) accurately targets the right CSV column for each indicator. |
| Date filtering | ✅ Correct — filters results to the [before, curr_date] window. |
| VWMA handling | ⚠️ Known limitation — returns an informative message since Alpha Vantage has no VWMA endpoint. Documented in code (line 157–160). |
1.3 Finnhub Indicators
The Finnhub vendor (finnhub_indicators.py) calls the /indicator endpoint with
Unix-timestamp date ranges. It handles multi-value indicators (MACD: 3 values per row;
BBANDS: 3 values per row) and single-value indicators correctly.
| Aspect | Assessment |
|---|---|
| Timestamp conversion | ✅ Correct — adds 86 400s to end date to ensure inclusive. |
| Multi-value formatting | ✅ Correct — MACD returns macd + signal + histogram; BBANDS returns upper + middle + lower. |
| Error handling | ✅ Raises FinnhubError on empty/no_data responses. |
| Output format | ✅ Mirrors Alpha Vantage output style for downstream agent consistency. |
1.4 Portfolio Risk Metrics (risk_metrics.py)
All computed in pure Python (stdlib math only — no pandas/numpy dependency).
| Metric | Formula | Correct? | Notes |
|---|---|---|---|
| Sharpe Ratio | (μ / σ) × √252 |
✅ Yes | Annualised, risk-free rate = 0. Uses sample std (ddof=1). |
| Sortino Ratio | (μ / σ_down) × √252 |
✅ Yes | Denominator uses only negative returns. Correct minimum of 2 downside observations. |
| 95% VaR | -percentile(returns, 5) |
✅ Yes | Historical simulation — 5th percentile with linear interpolation. Expressed as positive loss fraction. |
| Max Drawdown | peak-to-trough | ✅ Yes | Walks NAV series tracking running peak. Returns most negative (worst) drawdown. |
| Beta | Cov(r_p, r_b) / Var(r_b) |
✅ Yes | Correctly uses sample covariance (n−1 denominator). |
| Sector Concentration | holdings_value / total_value × 100 |
✅ Yes | From the most-recent snapshot's holdings_snapshot. |
1.5 Macro Regime Classifier (macro_regime.py)
Uses 6 market signals to classify: risk-on / transition / risk-off.
| Signal | Data Source | Method | Correct? |
|---|---|---|---|
| VIX level | ^VIX via yfinance |
< 16 → risk-on, > 25 → risk-off |
✅ Standard thresholds from CBOE VIX interpretation guides. |
| VIX trend | ^VIX 5-SMA vs 20-SMA |
Rising VIX (SMA5 > SMA20) → risk-off | ✅ Standard crossover approach. |
| Credit spread | HYG/LQD ratio | 1-month change of HY-bond / IG-bond ratio | ✅ Well-established proxy for credit spread changes. |
| Yield curve | TLT/SHY ratio | TLT outperformance → flight to safety | ✅ TLT (20yr) vs SHY (1-3yr) is a standard duration proxy. |
| Market breadth | ^GSPC vs 200-SMA |
SPX above/below 200-SMA | ✅ Classic breadth indicator used by institutional investors. |
| Sector rotation | Defensive vs Cyclical ETFs | 1-month return spread (XLU/XLP/XLV vs XLY/XLK/XLI) | ✅ Correct sector classification; standard rotation analysis. |
Custom calculations: The _sma() and _pct_change_n() helpers are simple 5-line
implementations. They are mathematically correct and use pandas rolling().mean().
No need to replace with a library — the overhead would outweigh the benefit.
1.6 TTM Analysis (ttm_analysis.py)
Computes trailing twelve months metrics by summing the last 4 quarterly income-statement flow items and using the latest balance-sheet stock items. Handles transposed CSV layouts (Alpha Vantage vs yfinance) via auto-detection.
| Metric | Correct? | Notes |
|---|---|---|
| TTM Revenue | ✅ | Sum of last 4 quarterly revenues. |
| Margin calculations | ✅ | Gross/operating/net margins = profit / revenue × 100. |
| ROE | ✅ | TTM net income / latest equity × 100. |
| Debt/Equity | ✅ | Latest total debt / latest equity. |
| Revenue QoQ | ✅ | `(latest - previous) / |
| Revenue YoY | ✅ | Compares latest quarter to 4 quarters prior (quarterly[-5]). |
| Margin trend | ✅ | Classifies last 3 values as expanding/contracting/stable. |
1.7 Peer Comparison (peer_comparison.py)
| Aspect | Assessment |
|---|---|
| Return calculation | ✅ (current - base) / base × 100 for 1W/1M/3M/6M/YTD horizons using trading-day counts (5, 21, 63, 126). |
| Alpha calculation | ✅ Stock return minus ETF return per period. |
| Sector mapping | ✅ 11 GICS sectors mapped to SPDR ETFs. Yahoo Finance sector names normalised correctly. |
| Batch download | ✅ Single yf.download() call for all symbols (efficient). |
2. Library Assessment
2.1 Current Library Stack
| Library | Version | Role | Industry Standard? |
|---|---|---|---|
| stockstats | ≥ 0.6.5 | Technical indicator computation (SMA, EMA, MACD, RSI, BBANDS, ATR, VWMA, MFI) | ⚠️ Moderate — well-known in Python quant community but not as widely used as TA-Lib or pandas-ta. ~1.3K GitHub stars. |
| yfinance | ≥ 0.2.63 | Market data fetching (OHLCV, fundamentals, news) | ✅ De facto standard for free Yahoo Finance access. ~14K GitHub stars. |
| pandas | ≥ 2.3.0 | Data manipulation, CSV parsing, rolling calculations | ✅ Industry standard. Used by virtually all quantitative Python workflows. |
| requests | ≥ 2.32.4 | HTTP API calls to Alpha Vantage and Finnhub | ✅ Industry standard for HTTP in Python. |
2.2 Alternative Libraries Considered
| Alternative | What It Provides | Pros | Cons |
|---|---|---|---|
TA-Lib (via ta-lib Python wrapper) |
200+ indicators, C-based performance | ✅ Gold standard in quant finance ✅ Extremely fast (C implementation) ✅ Widest indicator coverage |
❌ Requires C library system install (complex CI/CD) ❌ No pip-only install ❌ Platform-specific build issues |
| pandas-ta | 130+ indicators, pure Python/pandas | ✅ Pure Python — pip install only ✅ Active maintenance ✅ Direct pandas DataFrame integration |
⚠️ Slightly slower than TA-Lib ⚠️ Larger dependency footprint |
| tulipy | Technical indicators, C-based | ✅ Fast (C implementation) ✅ Simple API |
❌ Requires C build ❌ Less maintained than TA-Lib |
2.3 Recommendation: Keep stockstats
Current choice is appropriate for this application. Here's why:
-
Indicators are consumed by LLMs, not HFT engines: The indicators are formatted as text strings for LLM agents. The performance difference between stockstats and TA-Lib is irrelevant at this scale (single-ticker, daily data, <15 years of history).
-
Pure Python install: stockstats requires only pip — no C library builds. This simplifies CI/CD, Docker images, and contributor onboarding significantly.
-
Sufficient coverage: All indicators used by the trading agents (SMA, EMA, MACD, RSI, Bollinger Bands, ATR, VWMA, MFI) are covered by stockstats.
-
Mathematical correctness: stockstats implements the canonical formulas (verified above). The results will match TA-Lib and pandas-ta to within floating-point precision.
-
Migration cost: Switching to pandas-ta or TA-Lib would require changes to
stockstats_utils.py,y_finance.py, and all tests — with no user-visible benefit.
When to reconsider: If the project adds high-frequency backtesting (thousands of tickers × minute data), TA-Lib's C performance would become relevant.
3. The Alpha Vantage Debate
3.1 Available Indicators via Alpha Vantage API
All indicators used by TradingAgents are available as pre-computed endpoints from the Alpha Vantage Technical Indicators API:
| Indicator | AV Endpoint | Available? |
|---|---|---|
| SMA | function=SMA |
✅ |
| EMA | function=EMA |
✅ |
| MACD | function=MACD |
✅ (returns MACD, Signal, Histogram) |
| RSI | function=RSI |
✅ |
| Bollinger Bands | function=BBANDS |
✅ (returns upper, middle, lower) |
| ATR | function=ATR |
✅ |
| VWMA | — | ❌ Not available |
| MFI | function=MFI |
✅ (but not currently mapped in our AV adapter) |
3.2 Comparative Analysis
| Dimension | Local Calculation (stockstats + yfinance) | Alpha Vantage API (pre-computed) |
|---|---|---|
| Cost | Free (yfinance) | 75 calls/min premium; 25/day free tier. Each indicator = 1 API call. A full analysis (12 indicators × 1 ticker) consumes 12 calls. |
| Latency | ~1–2s for initial data fetch + <100ms for indicator computation | ~0.5–1s per API call × 12 indicators = 6–12s total |
| Rate Limits | No API rate limits from yfinance (though Yahoo may throttle aggressive use) | Strict rate limits. Premium tier: 75 calls/min. Free tier: 25 calls/day. |
| Indicator Coverage | Full: any indicator stockstats supports (200+ including VWMA, MFI) | Limited to Alpha Vantage's supported functions. No VWMA. |
| Data Freshness | Real-time — downloads latest OHLCV data then computes | Real-time — Alpha Vantage computes on their latest data |
| Reproducibility | Full control — same input data + code = exact same result. Can version-control parameters. | Black box — AV may change smoothing methods, seed values, or data adjustments without notice. |
| Customisation | Full — change period, smoothing, add custom indicators | Limited to AV's parameter set per endpoint |
| Offline/Testing | Cacheable — OHLCV data can be cached locally for offline dev and testing | Requires live API calls (no offline mode without caching raw responses) |
| Accuracy | Depends on stockstats implementation (verified correct above) | Presumably correct — Alpha Vantage is a major data vendor |
| Multi-ticker Efficiency | One yf.download call for many tickers, then compute all indicators locally | Separate API call per ticker × per indicator |
3.3 Verdict: Local Calculation (Primary) with API as Fallback
The current architecture — yfinance + stockstats as primary, Alpha Vantage as fallback vendor — is the correct design for these reasons:
-
Cost efficiency: A single analysis run needs 12+ indicators. At the free AV tier (25 calls/day), this exhausts the quota on 2 tickers. Local computation is unlimited.
-
Latency: A single yfinance download + local stockstats computation is 5–10× faster than 12 sequential Alpha Vantage API calls with rate limiting.
-
Coverage: VWMA and MFI are not available from Alpha Vantage. Local computation is the only option for these indicators.
-
Testability: Local computation can be unit-tested with synthetic data and cached OHLCV files. API-based indicators require live network access or complex mocking.
-
Fallback value: Alpha Vantage's pre-computed indicators serve as an independent verification and as a fallback when yfinance is unavailable (e.g., Yahoo Finance outages or API changes). The vendor routing system in
interface.pyalready supports this.
The Alpha Vantage vendor is not a wasted implementation — it provides resilience and cross-validation capability. However, it should remain the secondary vendor.
4. Data Flow & API Mapping
4.1 Technical Indicators Tool
Agent-Facing Tool: get_indicators(symbol, indicator, curr_date, look_back_days)
in tradingagents/agents/utils/technical_indicators_tools.py
yfinance Vendor (Primary)
Agent → get_indicators() tool
→ route_to_vendor("get_indicators", ...)
→ get_stock_stats_indicators_window() [y_finance.py]
→ _get_stock_stats_bulk() [y_finance.py]
→ yf.download(symbol, 15yr range) [External: Yahoo Finance API]
→ _clean_dataframe() [stockstats_utils.py]
→ stockstats.wrap(data) [Library: stockstats]
→ df[indicator] # triggers calculation
→ format as date: value string
→ return formatted indicator report to agent
| Attribute | Detail |
|---|---|
| Data Source | Yahoo Finance via yfinance library |
| Calculation | stockstats library — wraps OHLCV DataFrame, indicator access triggers lazy computation |
| Caching | CSV file cache in data_cache_dir (15-year OHLCV per symbol) |
| External API | Yahoo Finance (via yfinance download()) — 1 call per symbol |
Alpha Vantage Vendor (Fallback)
Agent → get_indicators() tool
→ route_to_vendor("get_indicators", ...)
→ get_indicator() [alpha_vantage_indicator.py]
→ _fetch_indicator_data()
→ _make_api_request("SMA"|"EMA"|...) [External: Alpha Vantage API]
→ _parse_indicator_data() # CSV parsing + date filtering
→ return formatted indicator report to agent
| Attribute | Detail |
|---|---|
| Data Source | Alpha Vantage REST API |
| Calculation | Pre-computed by Alpha Vantage — no local calculation |
| Caching | None (live API call per request) |
| External API | Alpha Vantage https://www.alphavantage.co/query — 1 call per indicator |
Finnhub Vendor
Agent → (not routed by default — only if vendor="finnhub" configured)
→ get_indicator_finnhub() [finnhub_indicators.py]
→ _make_api_request("indicator", ...) [External: Finnhub API]
→ parse JSON response (parallel lists: timestamps + values)
→ return formatted indicator report
| Attribute | Detail |
|---|---|
| Data Source | Finnhub REST API /indicator endpoint |
| Calculation | Pre-computed by Finnhub — no local calculation |
| Caching | None |
| External API | Finnhub https://finnhub.io/api/v1/indicator — 1 call per indicator |
Supported Indicators by Vendor:
| Indicator | yfinance (stockstats) | Alpha Vantage | Finnhub |
|---|---|---|---|
| SMA (50, 200) | ✅ | ✅ | ✅ |
| EMA (10) | ✅ | ✅ | ✅ |
| MACD / Signal / Histogram | ✅ | ✅ | ✅ |
| RSI | ✅ | ✅ | ✅ |
| Bollinger Bands (upper/middle/lower) | ✅ | ✅ | ✅ |
| ATR | ✅ | ✅ | ✅ |
| VWMA | ✅ | ❌ | ❌ |
| MFI | ✅ | ❌ (endpoint exists but unmapped) | ❌ |
4.2 Fundamental Data Tools
Agent-Facing Tools: get_fundamentals, get_balance_sheet, get_cashflow,
get_income_statement in tradingagents/agents/utils/fundamental_data_tools.py
yfinance Vendor (Primary)
Agent → get_fundamentals() tool
→ route_to_vendor("get_fundamentals", ...)
→ get_fundamentals() [y_finance.py]
→ yf.Ticker(ticker).info [External: Yahoo Finance API]
→ extract 27 key-value fields
→ return formatted fundamentals report
Agent → get_balance_sheet() / get_cashflow() / get_income_statement()
→ route_to_vendor(...)
→ yf.Ticker(ticker).quarterly_balance_sheet / quarterly_cashflow / quarterly_income_stmt
[External: Yahoo Finance API]
→ DataFrame.to_csv()
→ return CSV string with header
| Attribute | Detail |
|---|---|
| Data Source | Yahoo Finance via yfinance library |
| Calculation | No calculation — raw financial statement data |
| External APIs | Yahoo Finance (1 API call per statement) |
Alpha Vantage Vendor (Fallback)
Agent → get_balance_sheet() / get_cashflow() / get_income_statement()
→ route_to_vendor(...)
→ _make_api_request("BALANCE_SHEET" | "CASH_FLOW" | "INCOME_STATEMENT")
[External: Alpha Vantage API]
→ CSV parsing
→ return CSV string
| Attribute | Detail |
|---|---|
| Data Source | Alpha Vantage REST API |
| Calculation | No calculation — pre-computed by Alpha Vantage |
| External APIs | Alpha Vantage (1 call per statement) |
4.3 TTM Analysis Tool
Agent-Facing Tool: get_ttm_analysis(ticker, curr_date)
in tradingagents/agents/utils/fundamental_data_tools.py
Agent → get_ttm_analysis() tool
→ route_to_vendor("get_income_statement", ticker, "quarterly") [1 vendor call]
→ route_to_vendor("get_balance_sheet", ticker, "quarterly") [1 vendor call]
→ route_to_vendor("get_cashflow", ticker, "quarterly") [1 vendor call]
→ compute_ttm_metrics(income_csv, balance_csv, cashflow_csv) [ttm_analysis.py]
→ _parse_financial_csv() × 3 # auto-detect AV vs yfinance layout
→ sum last 4 quarters (flow items)
→ latest value (stock items)
→ compute margins, ROE, D/E
→ compute QoQ/YoY revenue growth
→ classify margin trends
→ format_ttm_report(metrics, ticker)
→ return Markdown report
| Attribute | Detail |
|---|---|
| Data Source | 3 quarterly financial statements via configured vendor |
| Calculation | Local: TTM summation, margin ratios, growth rates, trend classification |
| Internal Requests | 3 route_to_vendor() calls for financial statements |
| External APIs | Yahoo Finance (3 calls) or Alpha Vantage (3 calls), depending on vendor config |
4.4 Peer Comparison Tool
Agent-Facing Tool: get_peer_comparison(ticker, curr_date)
in tradingagents/agents/utils/fundamental_data_tools.py
Agent → get_peer_comparison() tool
→ get_peer_comparison_report(ticker) [peer_comparison.py]
→ get_sector_peers(ticker)
→ yf.Ticker(ticker).info [External: Yahoo Finance]
→ map sector → _SECTOR_TICKERS list
→ compute_relative_performance(ticker, sector_key, peers)
→ yf.download([ticker, ...peers, ETF]) [External: Yahoo Finance — 1 batch call]
→ _safe_pct() for 1W/1M/3M/6M horizons
→ _ytd_pct() for YTD
→ rank by 3-month return
→ compute alpha vs sector ETF
→ return Markdown peer ranking table
| Attribute | Detail |
|---|---|
| Data Source | Yahoo Finance for OHLCV prices (6-month history) |
| Calculation | Local: percentage returns, ranking, alpha computation |
| Internal Requests | 1 ticker info lookup + 1 batch price download |
| External APIs | Yahoo Finance (2 calls: .info + download()) |
4.5 Sector Relative Tool
Agent-Facing Tool: get_sector_relative(ticker, curr_date)
Agent → get_sector_relative() tool
→ get_sector_relative_report(ticker) [peer_comparison.py]
→ get_sector_peers(ticker)
→ yf.Ticker(ticker).info [External: Yahoo Finance]
→ yf.download([ticker, sector_ETF]) [External: Yahoo Finance — 1 call]
→ _safe_pct() for 1W/1M/3M/6M
→ compute alpha per period
→ return Markdown comparison table
| Attribute | Detail |
|---|---|
| Data Source | Yahoo Finance for ticker + sector ETF prices |
| Calculation | Local: return percentages, alpha = stock return − ETF return |
| External APIs | Yahoo Finance (2 calls: .info + download()) |
4.6 Macro Regime Tool
Agent-Facing Tool: get_macro_regime(curr_date)
in tradingagents/agents/utils/fundamental_data_tools.py
Agent → get_macro_regime() tool
→ classify_macro_regime() [macro_regime.py]
→ _fetch_macro_data()
→ yf.download(["^VIX"], period="3mo") [External: Yahoo Finance]
→ yf.download(["^GSPC"], period="14mo") [External: Yahoo Finance]
→ yf.download(["HYG", "LQD"], period="3mo") [External: Yahoo Finance]
→ yf.download(["TLT", "SHY"], period="3mo") [External: Yahoo Finance]
→ yf.download([def_ETFs + cyc_ETFs], period="3mo") [External: Yahoo Finance]
→ _evaluate_signals()
→ _signal_vix_level() # threshold check
→ _signal_vix_trend() # SMA5 vs SMA20 crossover
→ _signal_credit_spread() # HYG/LQD 1-month change
→ _signal_yield_curve() # TLT vs SHY performance spread
→ _signal_market_breadth() # SPX vs 200-SMA
→ _signal_sector_rotation() # defensive vs cyclical ETF spread
→ _determine_regime_and_confidence()
→ format_macro_report(regime_data)
→ return Markdown regime report
| Attribute | Detail |
|---|---|
| Data Source | Yahoo Finance for VIX, S&P 500, bond ETFs, sector ETFs |
| Calculation | Local: 6 signal evaluators with custom thresholds. Simple helper functions _sma(), _pct_change_n(). |
| Internal Requests | 5 batch yf.download() calls |
| External APIs | Yahoo Finance only (5 calls, batched by symbol group) |
4.7 Core Stock Data Tool
Agent-Facing Tool: get_stock_data(symbol, start_date, end_date)
in tradingagents/agents/utils/core_stock_tools.py
yfinance Vendor (Primary)
Agent → get_stock_data() tool
→ route_to_vendor("get_stock_data", ...)
→ get_YFin_data_online() [y_finance.py]
→ yf.Ticker(symbol).history(...) [External: Yahoo Finance]
→ round numerics, format CSV
→ return CSV string
Alpha Vantage Vendor (Fallback)
Agent → get_stock_data() tool
→ route_to_vendor("get_stock_data", ...)
→ get_stock() [alpha_vantage_stock.py]
→ _make_api_request("TIME_SERIES_DAILY_ADJUSTED")
[External: Alpha Vantage]
→ return CSV string
| Attribute | Detail |
|---|---|
| Data Source | Yahoo Finance (primary) or Alpha Vantage (fallback) |
| Calculation | None — raw OHLCV data |
| External APIs | Yahoo Finance or Alpha Vantage (1 call) |
4.8 News Data Tools
Agent-Facing Tools: get_news, get_global_news, get_insider_transactions
in tradingagents/agents/utils/news_data_tools.py
| Tool | Primary Vendor | Fallback | External API Sequence |
|---|---|---|---|
get_news(ticker, ...) |
yfinance | Alpha Vantage | 1. yf.Ticker(ticker).news → Yahoo Finance |
get_global_news(...) |
yfinance | Alpha Vantage | 1. yf.Search("market").news → Yahoo Finance |
get_insider_transactions(ticker) |
Finnhub | Alpha Vantage, yfinance | 1. Finnhub /stock/insider-transactions API |
4.9 Scanner Data Tools
Agent-Facing Tools: get_market_movers, get_market_indices, get_sector_performance,
get_industry_performance, get_topic_news
in tradingagents/agents/utils/scanner_tools.py
| Tool | Primary Vendor | External API Sequence |
|---|---|---|
get_market_movers(category) |
yfinance | 1. yf.Screener() → Yahoo Finance |
get_market_indices() |
yfinance | 1. yf.download(["^GSPC","^DJI",...]) → Yahoo Finance |
get_sector_performance() |
yfinance | 1. yf.Sector(key) → Yahoo Finance (per sector) |
get_industry_performance(sector) |
yfinance | 1. yf.Industry(key) → Yahoo Finance (per industry) |
get_topic_news(topic) |
yfinance | 1. yf.Search(topic).news → Yahoo Finance |
4.10 Calendar Tools (Finnhub Only)
Agent-Facing Tools: get_earnings_calendar, get_economic_calendar
| Tool | Vendor | External API |
|---|---|---|
get_earnings_calendar(from, to) |
Finnhub (only) | Finnhub /calendar/earnings |
get_economic_calendar(from, to) |
Finnhub (only) | Finnhub /calendar/economic (FOMC, CPI, NFP, GDP, PPI) |
4.11 Portfolio Risk Metrics
Agent-Facing Tool: compute_portfolio_risk_metrics()
in tradingagents/agents/utils/portfolio_tools.py
Agent → compute_portfolio_risk_metrics() tool
→ compute_risk_metrics(snapshots, benchmark_returns) [risk_metrics.py]
→ _daily_returns(nav_series) # NAV → daily % changes
→ Sharpe: μ/σ × √252
→ Sortino: μ/σ_down × √252
→ VaR: -percentile(returns, 5)
→ Max drawdown: peak-to-trough walk
→ Beta: Cov(r_p, r_b) / Var(r_b)
→ Sector concentration from holdings
→ return JSON metrics dict
| Attribute | Detail |
|---|---|
| Data Source | Portfolio snapshots from Supabase database |
| Calculation | 100% local — pure Python math module, no external dependencies |
| External APIs | None — operates entirely on stored portfolio data |
4.12 Vendor Routing Architecture
All data tool calls flow through route_to_vendor() in tradingagents/dataflows/interface.py:
@tool function (agents/utils/*_tools.py)
→ route_to_vendor(method_name, *args, **kwargs)
→ get_category_for_method(method_name) # lookup in TOOLS_CATEGORIES
→ get_vendor(category, method_name) # check config: tool_vendors → data_vendors
→ try primary vendor implementation
→ if FALLBACK_ALLOWED and primary fails:
try remaining vendors in order
→ if all fail: raise RuntimeError
Fallback-Allowed Methods (cross-vendor fallback is safe for these):
get_stock_data— OHLCV data is fungibleget_market_indices— index quotes are fungibleget_sector_performance— ETF-based, same approachget_market_movers— approximation acceptable for screeningget_industry_performance— ETF-based proxy
Fail-Fast Methods (no fallback — data contracts differ between vendors):
get_indicators,get_fundamentals,get_balance_sheet,get_cashflow,get_income_statement,get_news,get_global_news,get_insider_transactions,get_topic_news,get_earnings_calendar,get_economic_calendar
Summary
| Area | Verdict |
|---|---|
| Implementation accuracy | ✅ All indicators and metrics are mathematically correct. No custom re-implementations of standard indicators — stockstats handles the math. |
| Library choice | ✅ stockstats is appropriate for this use case (LLM-consumed daily indicators). TA-Lib would add build complexity with no user-visible benefit. |
| Alpha Vantage role | ✅ Correctly positioned as fallback vendor. Local computation is faster, cheaper, and covers more indicators. |
| Data flow architecture | ✅ Clean vendor routing with configurable primary/fallback. Each tool has a clear data source → calculation → formatting pipeline. |