Merge pull request #43 from aguzererler/copilot/update-portfolio-management-flow
docs: align portfolio flow with implementation, add token estimates and CLI reference
This commit is contained in:
commit
01b892041b
56
README.md
56
README.md
|
|
@ -159,6 +159,62 @@ An interface will appear showing results as they load, letting you track the age
|
|||
<img src="assets/cli/cli_transaction.png" width="100%" style="display: inline-block; margin: 0 2%;">
|
||||
</p>
|
||||
|
||||
### CLI Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `analyze` | Interactive per-ticker multi-agent analysis (select analysts, LLM, date) |
|
||||
| `scan` | Run the 3-phase macro scanner (geopolitical → sector → synthesis) |
|
||||
| `pipeline` | Full pipeline: macro scan JSON → filter by conviction → per-ticker deep dive |
|
||||
| `portfolio` | Run the Portfolio Manager workflow (requires portfolio ID + scan JSON) |
|
||||
| `check-portfolio` | Review current holdings only — no new candidates |
|
||||
| `auto` | End-to-end: scan → pipeline → portfolio manager (one command) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Per-ticker analysis (interactive prompts for ticker, date, LLM, analysts)
|
||||
python -m cli.main analyze
|
||||
|
||||
# Run macro scanner for a specific date
|
||||
python -m cli.main scan --date 2026-03-21
|
||||
|
||||
# Run the full pipeline (scan → filter → per-ticker analysis)
|
||||
python -m cli.main pipeline
|
||||
|
||||
# Run portfolio manager with a specific portfolio and scan results
|
||||
python -m cli.main portfolio
|
||||
|
||||
# Review current holdings without new candidates
|
||||
python -m cli.main check-portfolio --portfolio-id main_portfolio --date 2026-03-21
|
||||
|
||||
# Full autonomous mode: scan → pipeline → portfolio
|
||||
python -m cli.main auto --portfolio-id main_portfolio --date 2026-03-21
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Install dev dependencies
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# Run all unit tests (integration and e2e excluded by default)
|
||||
python -m pytest tests/ -v
|
||||
|
||||
# Run only portfolio tests
|
||||
python -m pytest tests/portfolio/ -v
|
||||
|
||||
# Run a specific test file
|
||||
python -m pytest tests/portfolio/test_models.py -v
|
||||
|
||||
# Run tests with coverage (requires pytest-cov)
|
||||
python -m pytest tests/ --cov=tradingagents --cov-report=term-missing
|
||||
```
|
||||
|
||||
> **Note:** Integration tests that require network access or database connections
|
||||
> auto-skip when the relevant environment variables (`SUPABASE_CONNECTION_STRING`,
|
||||
> `FINNHUB_API_KEY`, etc.) are not set.
|
||||
|
||||
## TradingAgents Package
|
||||
|
||||
### Implementation Details
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Current Milestone
|
||||
|
||||
Portfolio Manager Phases 2-5 complete. All 93 tests passing (4 integration skipped).
|
||||
Portfolio Manager feature fully implemented (Phases 1–10). All 588 tests passing (14 skipped).
|
||||
|
||||
# Recent Progress
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ Portfolio Manager Phases 2-5 complete. All 93 tests passing (4 integration skipp
|
|||
- Business logic: avg cost basis, cash accounting, trade recording, snapshots
|
||||
- **PR #22 merged**: Unified report paths, structured observability logging, memory system update
|
||||
- **feat/daily-digest-notebooklm** (shipped): Daily digest consolidation + NotebookLM source sync
|
||||
- **Portfolio Manager Phases 2-5** (current branch):
|
||||
- **Portfolio Manager Phases 2-5** (implemented):
|
||||
- `tradingagents/portfolio/risk_evaluator.py` — pure-Python risk metrics (log returns, Sharpe, Sortino, VaR, max drawdown, beta, sector concentration, constraint checking)
|
||||
- `tradingagents/portfolio/candidate_prioritizer.py` — conviction × thesis × diversification × held_penalty scoring
|
||||
- `tradingagents/portfolio/trade_executor.py` — executes BUY/SELL (SELLs first), constraint pre-flight, EOD snapshot
|
||||
|
|
@ -22,11 +22,13 @@ Portfolio Manager Phases 2-5 complete. All 93 tests passing (4 integration skipp
|
|||
- `tradingagents/graph/portfolio_setup.py` — PortfolioGraphSetup (sequential 6-node workflow)
|
||||
- `tradingagents/graph/portfolio_graph.py` — PortfolioGraph (mirrors ScannerGraph pattern)
|
||||
- 48 new tests (28 risk_evaluator + 10 candidate_prioritizer + 10 trade_executor)
|
||||
- **Portfolio CLI integration**: `portfolio`, `check-portfolio`, `auto` commands in `cli/main.py`
|
||||
- **Documentation updated**: Flow diagram in `docs/portfolio/00_overview.md` aligned with actual 6-node sequential implementation; token estimation per model added; CLI & test commands added to README.md
|
||||
|
||||
# In Progress
|
||||
|
||||
- Portfolio Manager Phase 6: CLI integration / end-to-end wiring (next)
|
||||
- Refinement of macro scan synthesis prompts (ongoing)
|
||||
- End-to-end integration testing with live LLM + Supabase
|
||||
|
||||
# Active Blockers
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Portfolio Manager Agent — Design Overview
|
||||
|
||||
<!-- Last verified: 2026-03-20 -->
|
||||
<!-- Last verified: 2026-03-21 -->
|
||||
|
||||
## Feature Description
|
||||
|
||||
|
|
@ -98,116 +98,191 @@ SQLAlchemy) and no `supabase-py` REST client is used.
|
|||
|
||||
---
|
||||
|
||||
## 5-Phase Workflow
|
||||
## Implemented Workflow (6-Node Sequential Graph)
|
||||
|
||||
The portfolio manager runs as a **sequential LangGraph workflow** inside
|
||||
`PortfolioGraph`. The scanner and price fetching happen **before** the graph
|
||||
is invoked (handled by the CLI or calling code). The graph itself processes
|
||||
6 nodes in strict sequence:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PHASE 1 (parallel) │
|
||||
┌──────────────────────────────────┐
|
||||
│ PRE-GRAPH (CLI / caller) │
|
||||
│ │
|
||||
│ • ScannerGraph.scan(date) │
|
||||
│ → scan_summary JSON │
|
||||
│ • yfinance price fetch │
|
||||
│ → prices dict {ticker: float} │
|
||||
└──────────────┬───────────────────┘
|
||||
│
|
||||
┌──────────────▼───────────────────┐
|
||||
│ PortfolioGraph.run( │
|
||||
│ portfolio_id, date, │
|
||||
│ prices, scan_summary) │
|
||||
└──────────────┬───────────────────┘
|
||||
│
|
||||
┌────────────────────────────────────▼───────────────────────────────────────┐
|
||||
│ NODE 1: load_portfolio (Python, no LLM) │
|
||||
│ │
|
||||
│ 1a. ScannerGraph.scan(date) 1b. Load Holdings + Fetch Prices │
|
||||
│ → macro_scan_summary.json → List[Holding] with │
|
||||
│ watchlist of top candidates current_price, current_value │
|
||||
└───────────────────────────────────┬───────────────────────────────────────┘
|
||||
│ • Queries Supabase for portfolio + holdings via PortfolioRepository │
|
||||
│ • Enriches holdings with current prices and computes weights │
|
||||
│ → portfolio_data (JSON string with portfolio + holdings dicts) │
|
||||
└───────────────────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PHASE 2 (parallel) │
|
||||
│ NODE 2: compute_risk (Python, no LLM) │
|
||||
│ │
|
||||
│ 2a. New Candidate Analysis 2b. Holding Re-evaluation │
|
||||
│ MacroBridge.run_all_tickers() HoldingReviewerAgent (quick_think)│
|
||||
│ Full bull/bear pipeline per 7-day price + 3-day news │
|
||||
│ HIGH/MEDIUM conviction → JSON: signal/confidence/reason │
|
||||
│ candidates that are NOT urgency per holding │
|
||||
│ already held │
|
||||
└───────────────────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PHASE 3 (Python, no LLM) │
|
||||
│ │
|
||||
│ Risk Metrics Computation │
|
||||
│ • Computes portfolio risk metrics from enriched holdings │
|
||||
│ • Sharpe ratio (annualised, rf = 0) │
|
||||
│ • Sortino ratio (downside deviation) │
|
||||
│ • Portfolio beta (vs SPY) │
|
||||
│ • Portfolio beta (vs SPY benchmark) │
|
||||
│ • 95 % VaR (historical simulation, 30-day window) │
|
||||
│ • Max drawdown (peak-to-trough, 90-day window) │
|
||||
│ • Sector concentration (weight per GICS sector) │
|
||||
│ • Correlation matrix (all holdings) │
|
||||
│ • What-if scenarios (buy X, sell Y → new weights) │
|
||||
└───────────────────────────────────┬───────────────────────────────────────┘
|
||||
│ → risk_metrics (JSON string) │
|
||||
└───────────────────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PHASE 4 Portfolio Manager Agent (deep_think + memory) │
|
||||
│ NODE 3: review_holdings (LLM — mid_think) │
|
||||
│ │
|
||||
│ Reads: macro context, holdings, candidate signals, re-eval signals, │
|
||||
│ risk metrics, budget constraint, past decisions (memory) │
|
||||
│ │
|
||||
│ Outputs structured JSON: │
|
||||
│ { │
|
||||
│ "sells": [{"ticker": "X", "shares": 10, "reason": "..."}], │
|
||||
│ "buys": [{"ticker": "Y", "shares": 5, "reason": "..."}], │
|
||||
│ "holds": ["Z"], │
|
||||
│ "target_cash_pct": 0.08, │
|
||||
│ "rationale": "...", │
|
||||
│ "risk_summary": "..." │
|
||||
│ } │
|
||||
└───────────────────────────────────┬───────────────────────────────────────┘
|
||||
│ HoldingReviewerAgent (create_holding_reviewer) │
|
||||
│ • Tools: get_stock_data, get_news │
|
||||
│ • Uses run_tool_loop() for inline tool execution │
|
||||
│ • Reviews each open position → HOLD or SELL recommendation │
|
||||
│ → holding_reviews (JSON string — ticker → review mapping) │
|
||||
└───────────────────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PHASE 5 Trade Execution (Mock) │
|
||||
│ NODE 4: prioritize_candidates (Python, no LLM) │
|
||||
│ │
|
||||
│ • Validate decisions against constraints (position size, sector, cash) │
|
||||
│ • Record each trade in Supabase (trades table) │
|
||||
│ • Update holdings (avg cost basis, shares) │
|
||||
│ • Deduct / credit cash balance │
|
||||
│ • Take immutable portfolio snapshot │
|
||||
│ • Save PM decision + risk report to filesystem │
|
||||
│ • Scores scan_summary.stocks_to_investigate using: │
|
||||
│ conviction × thesis × diversification × held_penalty │
|
||||
│ • Ranks candidates by composite score │
|
||||
│ → prioritized_candidates (JSON string — sorted list) │
|
||||
└───────────────────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ NODE 5: pm_decision (LLM — deep_think) │
|
||||
│ │
|
||||
│ PM Decision Agent (create_pm_decision_agent) │
|
||||
│ • Pure reasoning — no tools │
|
||||
│ • Reads: portfolio_data, risk_metrics, holding_reviews, │
|
||||
│ prioritized_candidates, analysis_date │
|
||||
│ • Outputs structured JSON: │
|
||||
│ { │
|
||||
│ "sells": [{"ticker": "X", "shares": 10, "rationale": "..."}], │
|
||||
│ "buys": [{"ticker": "Y", "shares": 5, "rationale": "..."}], │
|
||||
│ "holds": [{"ticker": "Z", "rationale": "..."}], │
|
||||
│ "cash_reserve_pct": 0.10, │
|
||||
│ "portfolio_thesis": "...", │
|
||||
│ "risk_summary": "..." │
|
||||
│ } │
|
||||
└───────────────────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ NODE 6: execute_trades (Python, no LLM) │
|
||||
│ │
|
||||
│ TradeExecutor │
|
||||
│ • SELLs first (frees cash), then BUYs │
|
||||
│ • Constraint pre-flight (position size, sector, cash) │
|
||||
│ • Records trades in Supabase, updates holdings & cash │
|
||||
│ • Takes immutable EOD portfolio snapshot │
|
||||
│ → execution_result (JSON string with executed/failed trades) │
|
||||
└────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### State Definition
|
||||
|
||||
The graph state is defined in `tradingagents/portfolio/portfolio_states.py`
|
||||
as `PortfolioManagerState(MessagesState)`:
|
||||
|
||||
| Field | Type | Written By |
|
||||
|-------|------|------------|
|
||||
| `portfolio_id` | `str` | Caller (initial state) |
|
||||
| `analysis_date` | `str` | Caller (initial state) |
|
||||
| `prices` | `dict` | Caller (initial state) |
|
||||
| `scan_summary` | `dict` | Caller (initial state) |
|
||||
| `portfolio_data` | `Annotated[str, _last_value]` | Node 1 |
|
||||
| `risk_metrics` | `Annotated[str, _last_value]` | Node 2 |
|
||||
| `holding_reviews` | `Annotated[str, _last_value]` | Node 3 |
|
||||
| `prioritized_candidates` | `Annotated[str, _last_value]` | Node 4 |
|
||||
| `pm_decision` | `Annotated[str, _last_value]` | Node 5 |
|
||||
| `execution_result` | `Annotated[str, _last_value]` | Node 6 |
|
||||
| `sender` | `Annotated[str, _last_value]` | All nodes |
|
||||
|
||||
### Comparison: Original Design vs Implementation
|
||||
|
||||
| Aspect | Original Design (docs) | Current Implementation |
|
||||
|--------|----------------------|------------------------|
|
||||
| Phases 1a/1b | Parallel (scanner + load holdings) | Sequential — scanner runs in pre-graph step |
|
||||
| Phases 2a/2b | Parallel (MacroBridge + HoldingReviewer) | Sequential — review_holdings then prioritize |
|
||||
| Candidate analysis | MacroBridge per-ticker full pipeline | Pure Python scoring (no per-ticker LLM analysis) |
|
||||
| Holding reviewer tier | `quick_think` | `mid_think` |
|
||||
| Phase 3 risk metrics | Includes correlation matrix, what-if | Sharpe, Sortino, VaR, beta, drawdown, sector |
|
||||
| Graph topology | Mixed parallel + sequential | Fully sequential (6 nodes) |
|
||||
|
||||
---
|
||||
|
||||
## Agent Specifications
|
||||
## Agent Specifications (as implemented)
|
||||
|
||||
### Portfolio Manager Agent (PMA)
|
||||
### Portfolio Manager Decision Agent (`pm_decision_agent.py`)
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| LLM tier | `deep_think` |
|
||||
| Memory | Enabled — reads previous PM decision files from filesystem |
|
||||
| LLM tier | `deep_think` (default: `gpt-5.2`) |
|
||||
| Pattern | `create_pm_decision_agent(llm)` → closure |
|
||||
| Memory | Via context injection (portfolio_data, prior decisions) |
|
||||
| Output format | Structured JSON (validated before trade execution) |
|
||||
| Invocation | Once per run, after Phases 1–3 |
|
||||
| Tools | None — pure reasoning agent |
|
||||
| Invocation | Node 5 in the sequential graph, once per run |
|
||||
|
||||
**Prompt inputs:**
|
||||
- Macro scan summary (top candidates + context)
|
||||
- Current holdings list (ticker, shares, avg cost, current price, weight, sector)
|
||||
- Candidate analysis signals (BUY/SELL/HOLD per ticker from Phase 2a)
|
||||
- Holding review signals (signal, confidence, reason, urgency per holding from Phase 2b)
|
||||
- Risk metrics report (Phase 3 output)
|
||||
- Budget constraint (available cash)
|
||||
- Portfolio constraints (see below)
|
||||
- Previous decision (last PM decision file for memory continuity)
|
||||
**Prompt inputs (injected via state):**
|
||||
- `portfolio_data` — Current holdings + portfolio state (JSON from Node 1)
|
||||
- `risk_metrics` — Sharpe, Sortino, VaR, beta, drawdown, sector data (JSON from Node 2)
|
||||
- `holding_reviews` — Per-ticker HOLD/SELL recommendations (JSON from Node 3)
|
||||
- `prioritized_candidates` — Ranked candidate list with scores (JSON from Node 4)
|
||||
- `analysis_date` — Date string for context
|
||||
|
||||
### Holding Reviewer Agent
|
||||
**Output schema:**
|
||||
```json
|
||||
{
|
||||
"sells": [{"ticker": "X", "shares": 10.0, "rationale": "..."}],
|
||||
"buys": [{"ticker": "Y", "shares": 5.0, "price_target": 200.0,
|
||||
"sector": "Technology", "rationale": "...", "thesis": "..."}],
|
||||
"holds": [{"ticker": "Z", "rationale": "..."}],
|
||||
"cash_reserve_pct": 0.10,
|
||||
"portfolio_thesis": "...",
|
||||
"risk_summary": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Holding Reviewer Agent (`holding_reviewer.py`)
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| LLM tier | `quick_think` |
|
||||
| LLM tier | `mid_think` (default: falls back to `gpt-5-mini`) |
|
||||
| Pattern | `create_holding_reviewer(llm)` → closure |
|
||||
| Memory | Disabled |
|
||||
| Output format | Structured JSON |
|
||||
| Tools | `get_stock_data` (7-day window), `get_news` (3-day window), RSI, MACD |
|
||||
| Invocation | Once per existing holding (parallelisable) |
|
||||
| Tools | `get_stock_data`, `get_news` |
|
||||
| Tool execution | `run_tool_loop()` inline (up to 5 rounds) |
|
||||
| Invocation | Node 3 in the sequential graph, once per run |
|
||||
|
||||
**Output schema per holding:**
|
||||
```json
|
||||
{
|
||||
"ticker": "AAPL",
|
||||
"signal": "HOLD",
|
||||
"confidence": 0.72,
|
||||
"reason": "Price action neutral; no material news. RSI 52, MACD flat.",
|
||||
"urgency": "LOW"
|
||||
"AAPL": {
|
||||
"ticker": "AAPL",
|
||||
"recommendation": "HOLD",
|
||||
"confidence": "high",
|
||||
"rationale": "Strong momentum, no negative news.",
|
||||
"key_risks": ["Sector concentration", "Valuation stretch"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -241,29 +316,116 @@ These rules trigger specific actions and are part of the PM Agent's system promp
|
|||
|
||||
---
|
||||
|
||||
## 10-Phase Implementation Roadmap
|
||||
## Implementation Roadmap (Status)
|
||||
|
||||
| Phase | Deliverable | Effort |
|
||||
|-------|-------------|--------|
|
||||
| 1 | Data foundation (this PR) — models, DB, filesystem, repository | ~2–3 days |
|
||||
| 2 | Holding Reviewer Agent | ~1 day |
|
||||
| 3 | Risk metrics engine (Phase 3 of workflow) | ~1–2 days |
|
||||
| 4 | Portfolio Manager Agent (LLM, structured output) | ~2 days |
|
||||
| 5 | Trade execution engine (Phase 5 of workflow) | ~1 day |
|
||||
| 6 | Full orchestration graph (LangGraph) tying all phases | ~2 days |
|
||||
| 7 | CLI command `pm run` | ~0.5 days |
|
||||
| 8 | End-to-end integration tests | ~1 day |
|
||||
| 9 | Performance tuning + concurrency (Phase 2 parallelism) | ~1 day |
|
||||
| 10 | Documentation, memory system update, PR review | ~0.5 days |
|
||||
| Phase | Deliverable | Status | Source |
|
||||
|-------|-------------|--------|--------|
|
||||
| 1 | Data foundation — models, DB, filesystem, repository | ✅ Done (PR #32) | `tradingagents/portfolio/models.py`, `repository.py`, etc. |
|
||||
| 2 | Holding Reviewer Agent | ✅ Done | `tradingagents/agents/portfolio/holding_reviewer.py` |
|
||||
| 3 | Risk metrics engine | ✅ Done | `tradingagents/portfolio/risk_evaluator.py`, `risk_metrics.py` |
|
||||
| 4 | Portfolio Manager Decision Agent (LLM, structured output) | ✅ Done | `tradingagents/agents/portfolio/pm_decision_agent.py` |
|
||||
| 5 | Trade execution engine | ✅ Done | `tradingagents/portfolio/trade_executor.py` |
|
||||
| 6 | Full orchestration graph (LangGraph) | ✅ Done | `tradingagents/graph/portfolio_graph.py`, `portfolio_setup.py` |
|
||||
| 7 | CLI commands (`portfolio`, `check-portfolio`, `auto`) | ✅ Done | `cli/main.py` |
|
||||
| 8 | Candidate prioritizer | ✅ Done | `tradingagents/portfolio/candidate_prioritizer.py` |
|
||||
| 9 | Portfolio state for LangGraph | ✅ Done | `tradingagents/portfolio/portfolio_states.py` |
|
||||
| 10 | Tests (models, report_store, risk, trade, candidates) | ✅ Done | `tests/portfolio/` (588 tests total, 14 skipped) |
|
||||
|
||||
**Total estimate: ~15–22 days**
|
||||
---
|
||||
|
||||
## Token Estimation per Model
|
||||
|
||||
Estimated token usage per model tier across all three workflows. Numbers
|
||||
assume default models (`quick_think` = gpt-5-mini, `deep_think` = gpt-5.2,
|
||||
`mid_think` falls back to gpt-5-mini when not configured).
|
||||
|
||||
### Trading Workflow (`TradingAgentsGraph.propagate`)
|
||||
|
||||
| Agent | LLM Tier | Tools | LLM Calls | Est. Input Tokens | Est. Output Tokens |
|
||||
|-------|----------|-------|-----------|-------------------|-------------------|
|
||||
| Market Analyst | quick_think | get_stock_data, get_indicators, get_macro_regime | 3–5 | ~3,000–5,000 | ~1,500–3,000 |
|
||||
| Social Media Analyst | quick_think | get_news | 1–2 | ~2,000–3,000 | ~1,000–2,000 |
|
||||
| News Analyst | quick_think | get_news, get_global_news | 2–3 | ~2,000–4,000 | ~1,000–2,500 |
|
||||
| Fundamentals Analyst | quick_think | get_ttm_analysis, get_fundamentals, etc. | 4–6 | ~4,000–8,000 | ~2,000–4,000 |
|
||||
| Bull Researcher | mid_think | — | 1–2 per round | ~4,000–8,000 | ~1,500–3,000 |
|
||||
| Bear Researcher | mid_think | — | 1–2 per round | ~4,000–8,000 | ~1,500–3,000 |
|
||||
| Research Manager (Judge) | deep_think | — | 1 | ~6,000–12,000 | ~2,000–4,000 |
|
||||
| Trader | mid_think | — | 1 | ~3,000–5,000 | ~1,000–2,000 |
|
||||
| Aggressive Risk Analyst | quick_think | — | 1–2 per round | ~3,000–6,000 | ~1,000–2,000 |
|
||||
| Neutral Risk Analyst | quick_think | — | 1–2 per round | ~3,000–6,000 | ~1,000–2,000 |
|
||||
| Conservative Risk Analyst | quick_think | — | 1–2 per round | ~3,000–6,000 | ~1,000–2,000 |
|
||||
| Risk Judge | deep_think | — | 1 | ~6,000–12,000 | ~2,000–4,000 |
|
||||
|
||||
**Trading workflow totals** (with `max_debate_rounds=2`):
|
||||
- **LLM calls**: ~19–27
|
||||
- **Tool calls**: ~15–25
|
||||
- **quick_think tokens**: ~35,000–55,000 input, ~12,000–20,000 output
|
||||
- **deep_think tokens**: ~12,000–24,000 input, ~4,000–8,000 output
|
||||
|
||||
### Scanner Workflow (`ScannerGraph.scan`)
|
||||
|
||||
| Agent | LLM Tier | Tools | LLM Calls | Est. Input Tokens | Est. Output Tokens |
|
||||
|-------|----------|-------|-----------|-------------------|-------------------|
|
||||
| Geopolitical Scanner | quick_think | get_topic_news | 2–3 | ~2,000–4,000 | ~1,000–2,500 |
|
||||
| Market Movers Scanner | quick_think | get_market_movers, get_market_indices | 2–3 | ~2,000–4,000 | ~1,000–2,500 |
|
||||
| Sector Scanner | quick_think | get_sector_performance | 1–2 | ~1,500–3,000 | ~800–2,000 |
|
||||
| Industry Deep Dive | mid_think | get_industry_performance, get_topic_news | 5–7 | ~6,000–10,000 | ~3,000–5,000 |
|
||||
| Macro Synthesis | deep_think | — | 1 | ~8,000–15,000 | ~3,000–5,000 |
|
||||
|
||||
**Scanner workflow totals**:
|
||||
- **LLM calls**: ~9–13
|
||||
- **Tool calls**: ~11–16
|
||||
- **quick_think tokens**: ~5,500–11,000 input, ~2,800–7,000 output
|
||||
- **deep_think tokens**: ~8,000–15,000 input, ~3,000–5,000 output
|
||||
|
||||
### Portfolio Workflow (`PortfolioGraph.run`)
|
||||
|
||||
| Node | LLM Tier | Tools | LLM Calls | Est. Input Tokens | Est. Output Tokens |
|
||||
|------|----------|-------|-----------|-------------------|-------------------|
|
||||
| load_portfolio | — | — | 0 | 0 | 0 |
|
||||
| compute_risk | — | — | 0 | 0 | 0 |
|
||||
| review_holdings | mid_think | get_stock_data, get_news | 1 call reviews all holdings (up to 5 tool rounds) | ~3,000–6,000 | ~1,500–3,000 |
|
||||
| prioritize_candidates | — | — | 0 | 0 | 0 |
|
||||
| pm_decision | deep_think | — | 1 | ~6,000–12,000 | ~2,000–4,000 |
|
||||
| execute_trades | — | — | 0 | 0 | 0 |
|
||||
|
||||
**Portfolio workflow totals** (assuming 5 holdings):
|
||||
- **LLM calls**: 2 (review + decision)
|
||||
- **Tool calls**: ~10 (2 per holding)
|
||||
- **mid_think tokens**: ~3,000–6,000 input, ~1,500–3,000 output
|
||||
- **deep_think tokens**: ~6,000–12,000 input, ~2,000–4,000 output
|
||||
|
||||
### Full Auto Mode (`scan → pipeline → portfolio`)
|
||||
|
||||
| Workflow | quick_think | deep_think |
|
||||
|----------|-------------|------------|
|
||||
| Scanner | ~5K–11K in / ~3K–7K out | ~8K–15K in / ~3K–5K out |
|
||||
| Trading (× 3 tickers — aggregate) | ~105K–165K in / ~36K–60K out | ~36K–72K in / ~12K–24K out |
|
||||
| Portfolio | — | ~6K–12K in / ~2K–4K out |
|
||||
| **Totals** | **~110K–176K in / ~39K–67K out** | **~50K–99K in / ~17K–33K out** |
|
||||
|
||||
> **Note:** `mid_think` defaults to `quick_think_llm` when not configured,
|
||||
> so mid_think token counts are included under quick_think totals above.
|
||||
> Actual token usage varies with portfolio size, number of candidates, and
|
||||
> debate rounds.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- `tradingagents/pipeline/macro_bridge.py` — existing scan → per-ticker bridge
|
||||
- `tradingagents/report_paths.py` — filesystem path conventions
|
||||
- `tradingagents/default_config.py` — config pattern to follow
|
||||
- `tradingagents/agents/scanners/` — scanner agent examples
|
||||
- `tradingagents/graph/scanner_setup.py` — parallel graph node patterns
|
||||
- `tradingagents/graph/portfolio_graph.py` — PortfolioGraph orchestrator
|
||||
- `tradingagents/graph/portfolio_setup.py` — 6-node sequential workflow setup
|
||||
- `tradingagents/portfolio/portfolio_states.py` — PortfolioManagerState definition
|
||||
- `tradingagents/agents/portfolio/holding_reviewer.py` — Holding reviewer LLM agent
|
||||
- `tradingagents/agents/portfolio/pm_decision_agent.py` — PM decision LLM agent
|
||||
- `tradingagents/portfolio/risk_evaluator.py` — Pure-Python risk metrics
|
||||
- `tradingagents/portfolio/candidate_prioritizer.py` — Candidate scoring/ranking
|
||||
- `tradingagents/portfolio/trade_executor.py` — Trade execution with constraint checks
|
||||
- `tradingagents/portfolio/models.py` — Portfolio, Holding, Trade, PortfolioSnapshot
|
||||
- `tradingagents/portfolio/repository.py` — Unified data-access façade
|
||||
- `tradingagents/portfolio/report_store.py` — Filesystem document storage
|
||||
- `tradingagents/pipeline/macro_bridge.py` — Existing scan → per-ticker bridge
|
||||
- `tradingagents/report_paths.py` — Filesystem path conventions
|
||||
- `tradingagents/default_config.py` — Config pattern and LLM tier defaults
|
||||
- `tradingagents/graph/scanner_graph.py` — Scanner pipeline (runs before portfolio)
|
||||
- `cli/main.py` — CLI commands: `portfolio`, `check-portfolio`, `auto`
|
||||
|
|
|
|||
Loading…
Reference in New Issue