What Is TradingAgents?
TradingAgents is a free, open-source Python framework from Tauric Research that analyzes a stock the way a trading firm would, with a team of language-model agents instead of one prompt. Four analysts study the market, sentiment, news and fundamentals; a bull and a bear argue over their reports; a trader turns the result into a plan; three risk analysts argue over that plan; and a portfolio manager makes the call. You give it a ticker and a date, and it returns a rating and a folder of reports.
The project began as a research paper, "TradingAgents: Multi-Agents LLM Financial Trading Framework" by Yijia Xiao, Edward Sun, Di Luo and Wei Wang, first posted to arXiv on 28 December 2024, the same day the repository was created. It is built on LangGraph, licensed under Apache 2.0, and had 115,371 GitHub stars and more than 22,000 forks when we wrote this. The current release is version 0.7.0, from 16 October 2026.
One sentence in the README matters more than the rest, so it is worth reading before anything else:
TradingAgents framework is designed for research purposes. Trading performance may vary based on many factors, including the chosen backbone language models, model temperature, trading periods, the quality of data, and other non-deterministic factors. It is not intended as financial, investment, or trading advice.
The code agrees with it. Version 0.7.0 contains no broker integration and no code that places orders: a run ends with a rating and its reasoning, and what you do with them is up to you. That makes it a tool for studying how multi-agent LLM systems reason about markets, not a bot that trades for you, and this page treats it that way.
Twelve Agents, Modeled on a Trading Firm
Every role in TradingAgents is a separate agent with its own prompt, and most of them have their own data. The analysts run at the same time, and the debate starts once all four reports are in.
| Role | What it does | Model tier |
|---|---|---|
| Market Analyst | Prices and up to 8 technical indicators (moving averages, MACD, RSI, Bollinger Bands, ATR, VWMA), checked against a verified price snapshot | Quick |
| Sentiment Analyst | Yahoo Finance headlines, StockTwits messages and Reddit posts, scored as one sentiment band | Quick |
| News Analyst | Company news, global macro headlines, FRED economic data and Polymarket prediction markets | Quick |
| Fundamentals Analyst | Balance sheet, cash flow, income statement, company overview and insider transactions | Quick |
| Bull and Bear Researchers | Argue for and against the trade from the four reports | Quick |
| Research Manager | Judges the debate and writes the investment plan | Deep |
| Trader | Turns the plan into a buy, hold or sell proposal | Quick |
| Aggressive, Conservative and Neutral Analysts | Argue over the trader's proposal from three risk appetites | Quick |
| Portfolio Manager | Makes the final decision on a five-step scale | Deep |
The two tiers are the main cost control. You choose a quick model and a deep model, and each can run on its own provider, so the managers could run on Claude while everything else runs on a cheaper OpenAI model. The defaults are OpenAI's GPT-6 Luna for the quick tier and GPT-6 Sol for the deep one.
The final answer is one of five ratings: Buy, Overweight, Hold, Underweight or Sell. When the portfolio manager's output contains no readable rating, the code records REVIEW instead of quietly treating it as a Hold, because a decision nobody can read is not a decision to hold.
Fifteen Model Calls Is the Floor for One Decision
Nothing in the README says how many times a run calls a language model, and that number is what you pay for. So we counted it from the code: the graph's routing in conditional_logic.py, the analyst loop in analysts/turn.py, the default settings in default_config.py, and the project's own end-to-end test, which runs the whole graph offline with a scripted model. We read version 0.7.0 (commit e8f5503) and did not pay for a live run, so this is a count of calls, not a bill.
With the default settings and all four analysts, one decision makes at least 15 model calls:
| Step | Calls at minimum | Tier |
|---|---|---|
| Market, news and fundamentals analysts | 2 each: one round of tool calls, then the report | Quick |
| Sentiment analyst | 1, because its data is fetched before the model is called | Quick |
| Bull and bear researchers | 2 × debate rounds (default 1) | Quick |
| Research manager | 1 | Deep |
| Trader | 1 | Quick |
| Three risk analysts | 3 × risk rounds (default 1) | Quick |
| Portfolio manager | 1 | Deep |
| Total | 15 | 13 quick, 2 deep |
The project's test agrees. It deliberately breaks the provider on the 12th call and describes that point as "past the analysts, before the decision", which is exactly where the count puts it: 7 analyst calls, then the bull, the bear, the research manager and the trader, so the 12th call is the first risk analyst.
Three things push a real run above 15:
- Tool rounds. The market analyst is told to fetch prices first, then compute indicators, then check the verified snapshot, so a model that follows the instructions needs several rounds before it writes. Each analyst may take up to 20 rounds of tool calls, plus one final call without tools when it runs out.
- Debate settings. The README's own Python example sets two rounds for the bull and bear, which adds 2 calls. Two rounds of both debates make it 20.
- Past decisions. Each run settles earlier decisions whose holding period has passed and writes a one-paragraph reflection on each, one more quick call per decision.
Two conclusions follow. The quick model carries 13 of the 15 calls, so it decides most of the cost, and the deep model is called only twice. And backtests multiply: the README's example grid, two tickers every 7 days from 1 June to 1 August with only the market and news analysts, is 18 decisions and at least 216 model calls before the reflections.
Debates Are a Setting You Choose
The debates are what make TradingAgents different from asking one model for an opinion, and they are fully configurable. The bull and bear take turns until each has spoken max_debate_rounds times, then the research manager writes a plan from the transcript. The aggressive, conservative and neutral analysts do the same for max_risk_discuss_rounds rounds before the portfolio manager decides. Both default to 1.
from tradingagents.graph.trading_graph import TradingAgentsGraph
from tradingagents.default_config import DEFAULT_CONFIG
config = DEFAULT_CONFIG.copy()
config["max_debate_rounds"] = 2 # bull and bear speak twice each
config["max_risk_discuss_rounds"] = 1 # each risk analyst speaks once
ta = TradingAgentsGraph(config=config)
state, decision = ta.propagate("NVDA", "2026-09-01")
print(decision) # Buy, Overweight, Hold, Underweight or SellMore rounds give the agents more chances to answer each other, at a cost of 2 calls per extra debate round and 3 per extra risk round. The same settings are available as environment variables for the CLI: TRADINGAGENTS_MAX_DEBATE_ROUNDS and TRADINGAGENTS_MAX_RISK_ROUNDS.
You can also pass in what you already hold. Without a portfolio, the agents write guidance for a reader who applies it to their own position; with one, the trader, the risk analysts and the portfolio manager work against your actual cash and positions. The CLI takes it as a JSON file (tradingagents --portfolio my_book.json) and refuses to start when the file does not validate, so checking it in a JSON formatter first saves a failed start.
Point-in-Time Data, and the One Feed That Is Not
A backtest is only honest if each run sees what was public on its date. Most of TradingAgents' recent releases are about exactly that, and the README is specific about how each source behaves.
Fundamentals are read as filed. US company statements come from SEC EDGAR, which records the date every figure was filed, so a run dated in the past reads the statements as they stood that day. The README's example is Apple's total assets for fiscal 2008, filed as $39.6 billion and restated to $36.2 billion in 2010. We checked it against EDGAR's public API: the figure for the period ending 27 September 2008 appears as $39.572 billion in the 10-K filed on 27 October 2009, and as $36.171 billion in the amended 10-K filed on 25 January 2010. A run dated between those two filings reads the first number.
Other sources hold back what they cannot date. Yahoo Finance dates a statement by the period it covers rather than by when it was published, so a run dated in the past is told those statements are withheld. Insider trades are dated by when they happened, not when they were filed, so they are withheld for past dates too. News articles published after the analysis date are filtered out, and the project keeps regression tests for the ways that filter has leaked in the past.
Social sentiment is the exception. The sentiment analyst trims StockTwits and Reddit posts to the seven days before the analysis date, so nothing from after it leaks in. The problem is the other direction. Its code says these feeds "serve recent items and are not archived, so a historical run's sentiment inputs are not point-in-time." A run dated months back finds little or nothing in its window, and the feed tells the model the window was never observed rather than reporting that nobody posted. That is presumably why the README's backtest example selects only the market and news analysts, and it is the setting to copy: leave the sentiment analyst out of anything you backtest.
Memory and Backtests Score Decisions Against the Market
TradingAgents keeps a memory log of its own decisions at ~/.tradingagents/memory/trading_memory.md. While the analysts of a later run work, it settles every logged decision whose holding period has passed: it fetches the realized return, and the alpha against the market's benchmark (SPY for US tickers, regional indexes such as the Nikkei 225 or Nifty 50 elsewhere), then writes a short reflection. The portfolio manager reads recent decisions on the same ticker, plus recent lessons from others, before it decides.
The holding period is 5 trading days, counted from the first close after the analysis date. Version 0.7.0 moved it from the close of the analysis date itself, because a run reads news published after that day's close and could not have traded on the earlier price.
To judge whether the system decides well rather than reading one run, run_backtest sweeps a grid of tickers and dates into a memory log of its own and scores each settled decision on realized alpha, grouped by rating:
tradingagents backtest NVDA,AAPL --start 2026-06-01 --end 2026-08-01 --every 7An interrupted sweep resumes with the same run_id, skipping the cells that already ran. Each run also writes its full state to full_states_log_<date>.json under the ticker's results folder, with the date, the final rating and the model settings. Collect a few of those into one JSON array and a JSON to CSV converter turns them into a spreadsheet with one row per run.
The paper reports that TradingAgents improved cumulative returns, Sharpe ratio and maximum drawdown over baseline strategies. The README is careful in the other direction: backtest results "are not guaranteed to match any published figure", and the framework is "a research scaffold for studying multi-agent analysis, not a strategy with a fixed, replicable return."
Two Runs of the Same Ticker Will Not Match
The README says it directly: two runs of the same ticker and date can differ, and that is expected, not a bug. Language-model sampling varies even at a fixed temperature, reasoning models vary most because their reasoning is itself sampled, and the live news and social feeds change from day to day.
Some things no longer vary. The company behind a ticker is resolved before any agent runs, and the market analyst grounds every exact price and indicator claim in a verified snapshot. The README says these two changes address earlier reports of runs analyzing the wrong company or inventing price levels.
To see the variation yourself, run the same ticker and date twice and save both reports. Each saved report is a folder of Markdown files, one per agent (market.md, bull.md, trader.md, decision.md and so on), plus complete_report.html as one page. Comparing the two decision.md files in a text diff tool shows exactly where the reasoning changed, and a Markdown converter renders any single file as formatted HTML when you just want to read it.
For tighter repeatability, set temperature to 0 and choose models that honor it. The current default models are reasoning-first and largely ignore temperature, so the README suggests naming a non-reasoning model for both tiers when reproducibility matters more than depth.
Installing TradingAgents and Running Your First Analysis
TradingAgents needs Python 3.11 or newer and an API key for at least one model provider:
git clone https://github.com/TauricResearch/TradingAgents.git
cd TradingAgents
pip install .
cp .env.example .env # add your API keys
tradingagents # interactive CLIThe CLI asks for the ticker, date, provider, models and research depth, and remembers your answers for next time. For scripts and scheduled jobs it runs without questions from flags:
tradingagents --ticker NVDA --date 2026-09-23 --analysts market,news,fundamentals --save --no-showDocker works too (docker compose run --rm tradingagents), with an Ollama profile for local models.
The provider list is long: OpenAI, Google, Anthropic, xAI, DeepSeek, Qwen, GLM, MiniMax, OpenRouter, Mistral, Kimi, Groq, NVIDIA, Azure OpenAI, AWS Bedrock, Ollama, and any OpenAI-compatible server such as vLLM or LM Studio. Since version 0.7.0 it can also run on a ChatGPT Plus or Pro plan instead of an API key, after a one-time tradingagents login chatgpt; those runs count toward the plan's usage limits.
Any market Yahoo Finance covers works, using the exchange suffix: 0700.HK for Hong Kong, 7203.T for Tokyo, RELIANCE.NS for India, 600519.SS for Shanghai, and crypto pairs like BTC-USD. SEC EDGAR covers companies that file with the SEC, including foreign companies listed in the US; other listings fall back to the next data vendor.
Two defaults are worth knowing. Checkpoint resume is off unless you pass --checkpoint, which lets a crashed run continue from its last completed step. And the interactive CLI checks for a newer release at most once a day in the background; it sends nothing about your runs, and TRADINGAGENTS_NO_UPDATE_CHECK=1 turns it off.
Who Should Use TradingAgents, and Who Should Not
TradingAgents is a good fit if you want to study how LLM agents reason about markets: researchers and students working on multi-agent systems, developers who want a well-tested LangGraph project to learn from, and quantitative tinkerers who want to see whether structured debate changes a model's calls. Its strengths are the ones that matter for research. The roles are explicit, the debates are configurable, the data is point-in-time where it can be, and it has a real backtest harness that scores decisions against a benchmark.
It is the wrong tool if you are looking for something to trade your money. It places no orders, the README says it is not financial advice, two runs can disagree, and every decision costs at least 15 model calls. Treat its ratings as a research output to study, and keep the sentiment analyst out of anything you backtest.



