# How AI Agents Turn Financial Evidence into a Recommendation

> Following TradingAgents from data access to its final recommendation shows how reports, debate, and lessons from later outcomes shape a decision—and where an application must supply validation and execution.

Published: 2026-10-07 · Lumisonde (https://lumisonde.com/reports/tradingagents-decision-path/)
Citations JSON (per-claim receipts): https://lumisonde.com/reports/tradingagents-decision-path/citations.json
Continues: https://lumisonde.com/reports/decision-ready-market-view/

## The brief

**Question:** How can several AI agents turn financial evidence into a usable recommendation—and what still needs to be checked?

**Stake:** A developer needs to know which information supports a financial judgment, what the returned result means, and what an application must handle before acting on it.

**Answer:** TradingAgents connects analyst reports, opposing arguments, a research plan, a Trader proposal, risk discussion, and a final Portfolio Manager recommendation. [3] The caller receives a recommendation and intermediate artifacts, while the traced graph ends without submitting an order. [1, 2, 3] A developer should inspect what each stage actually receives, preserve qualifications about dates and missing data, and control the history of earlier lessons when comparing designs. Static inspection explains this mechanism; it does not establish that coordination beats a simpler reviewer or that the recommendation is profitable.

In *What a market view must contain before a financial agent builds a position*, we asked what a market judgment must specify before it can inform position sizing. This installment moves from those design requirements into an actual implementation: how does a financial agent framework turn evidence into a recommendation, and what information reaches each decision stage?

A financial agent needs to connect an information set to a decision. A price series, a company filing, and a news story do not become investment reasoning simply by appearing in the same prompt. Someone must interpret them, challenge that interpretation, and preserve the details that make the resulting judgment meaningful.

An agentic financial framework implements those responsibilities as a workflow. [TradingAgents](https://github.com/TauricResearch/TradingAgents) offers a concrete example: its graph connects analyst reports, opposing arguments, a research plan, a Trader proposal, risk discussion, and a final Portfolio Manager decision. [3] The useful governing idea is to design that chain as a sequence of information transformations. Giving a stage a financial job title describes its assignment; tracing its inputs and consumer reveals what it actually contributes.

Use that path to follow three questions: what evidence can enter the analysis, what survives the handoffs, and how earlier outcomes affect a later recommendation. By the end, you should be able to locate those operations in the code and decide which parts you would reuse, test, or supply in your own application.

The following account examines a fixed implementation, with evidence available through October 5, 2026; its immutable revision is listed in References. No repository code, tests, model calls, backtests, or trades were executed for this account. We will begin with the output a caller receives, connect the caller to the graph, then follow what the decision is allowed to know and what survives into its final judgment. That same path reveals how to test whether coordination improves a decision rather than merely lengthening its explanation.

## What does a decision contain?

The public Python operation is `TradingAgentsGraph.propagate(company_name, trade_date, asset_type="stock", portfolio=None)`, which returns final state and a signal: Buy, Overweight, Hold, Underweight, Sell, or `REVIEW` when no rating is readable. [1] Overweight and Underweight are intermediate favorable and unfavorable views, respectively; the Trader later maps them to Buy and Sell proposals. [20] The final state gives the caller more than a label: it retains analyst reports, research and risk debate histories, the investment plan, the Trader proposal, and `final_trade_decision`. [1]

This return contract tells an application how to inspect a recommendation. It does not tell an account how to execute one. On the traced path, the Portfolio Manager produces state updates, its graph edge goes to `END`, and the graph records the decision before returning it. [1, 2, 3] The README describes approved proposals being sent to a simulated exchange, but that description is not an execution step in this callable path. [11, 1, 2, 3] A downstream application would need a separately defined order contract: quantity, venue, account authorization, capital and exposure checks, and fill behavior. In particular, a Sell view for a caller with no position does not by itself authorize a short sale.

The caller's book changes the meaning of the judgment. `PortfolioContext` accepts cash, a currency label, and positions with signed quantity and optional average price; an empty supplied book renders no position in the analyzed instrument, while `portfolio=None` reaches decision prompts as unknown holdings and cash. [1, 5, 6] Imagine two hypothetical callers reading the same favorable thesis: one holds nothing, while the other is already heavily concentrated in the company. The first may consider opening exposure; the second may decide against adding. Context lets the model discuss that distinction. The inspected portfolio object renders the caller's facts rather than calculating or enforcing allocation feasibility. [5]

## Connect the caller to the graph

The integration path starts with configuration. `DEFAULT_CONFIG` is built when its module is imported, incorporates `TRADINGAGENTS_*` environment overrides, and can be rebuilt with `build_default_config()` to reread them. [7] Its model settings distinguish quick and deep tiers, with optional provider and endpoint overrides for each; the client factory resolves those overrides and does not pass the base provider's endpoint to a tier using a different provider. [7, 8] In the graph, analysts, researchers, Trader, and risk debaters use the quick tier, while the two managers use the deep tier. [3]

Choose the information branches independently of the model tiers. The programmatic analyst keys are `market`, `social`, `news`, and `fundamentals`; `social` selects sentiment, and an unknown key or empty selection raises an error. [9] Category data-provider settings live in `data_vendors`, with method-specific overrides in `tool_vendors`; the checked-in defaults use Yahoo for prices, indicators, and news, and SEC EDGAR followed by Yahoo for statement fundamentals. [7] These choices alter which operations can supply evidence, not just the wording of a prompt.

Here is a schematic integration, not an executed prediction; the call, return, review guard, and optional report-export interfaces follow the pinned implementation. [1, 24]

```python
# Schematic only: constructing and running this graph has side effects.
from copy import deepcopy
from tradingagents.default_config import DEFAULT_CONFIG
from tradingagents.graph.trading_graph import TradingAgentsGraph
from tradingagents.agents.rating import is_review

config = deepcopy(DEFAULT_CONFIG)
# Before use, select authorized provider/model IDs, vendors, and storage paths.
graph = TradingAgentsGraph(
    selected_analysts=("market", "news"), config=config
)
state, rating = graph.propagate("NVDA", "2026-09-01", portfolio=None)
thesis = state["final_trade_decision"]
if is_review(rating):
    pass  # Application-owned placeholder: caller must supply the inspection handoff.
# REVIEW is not an order or a Hold judgment; this snippet implements no handoff.
# Optional: graph.save_reports(state, "NVDA", html=False)
```

The example's analyst subset illustrates selection, not an evidence-validated optimal configuration. Deep-copying the defaults is a convenient way to modify nested settings without sharing those edits with the original dictionary.

Actual initialization creates cache/results directories, constructs provider clients and persistent memory, checks that the tool-round bound fits the recursion limit, and compiles the workflow; `propagate` also rejects noncanonical or future analysis dates. [1] The pinned README specifies Python 3.11 or later and the selected provider's API credentials. [11] Thus the snippet is a route into the implementation, not proof that a caller's credentials, SDKs, data access, or model selection will work.

After a completed call, inspect the reports and intermediate plans alongside the final thesis. The graph writes selected final artifacts to a state JSON log and separately records the recommendation in memory; calling `save_reports` additionally writes available section reports and `complete_report.md`, with HTML enabled unless disabled. [1, 10] Saving makes the handoffs available for inspection. It does not verify the claims carried through them.

## Decide what the tools may reveal

Choosing branches and vendors defines where evidence can come from. Before judging a company on a particular date, the application must also decide what those sources may reveal as of that date. On graph tool calls, instrument and run date are injected from state rather than chosen by the model; wrappers cap requested dates and windows before routed retrieval, and an unreadable window start returns an error before the vendor call. [12, 13] The model can choose a useful indicator or lookback while the application retains authority over the instrument and latest allowed date.

Provider routing supplies another boundary. A method override takes precedence over its category, an explicit comma-separated chain restricts fallback to selected supported vendors, and the router returns the first successful response. [14] A withholding notice returned as normal text can therefore stop the chain without supplying financial facts. [13, 14] The boundary is also not universal: the verified market-snapshot tool calls its Yahoo snapshot builder directly, outside this vendor router. [12]

A date cutoff needs a disclosure rule. The SEC adapter selects company facts filed on or before the requested date and keeps the latest eligible filing for each period, so a later amendment cannot replace a value before the amendment's filing day. [15] For historical requests, the shared statement guard instead withholds data from sources that label accounting periods without supplying filing dates. [13] Consider a fictional December quarter filed in March: a February decision cannot use those figures simply because December is already over. Filing time, not accounting-period time, governs that admission.

Missing coverage has its own meaning. The sentiment node constructs a seven-day window from run state, fetches routed news, StockTwits, and Reddit before invoking the model, and does not bind a model-directed retrieval loop. [17] Shared coverage rules distinguish a feed that cannot reach an old window from a window in which no items were observed. [13] Filtering recent posts cannot recover an absent archive. A coverage warning is evidence about the information set, not bearish sentiment about the company.

Price history illustrates a different limit: the Yahoo loader for open, high, low, close, and volume (OHLCV) obtains a current adjusted history and removes rows after the requested date. [16] That operation bounds row dates; it does not reconstruct the exact response or version of adjusted price history available on the historical day. Likewise, the SEC adapter's selection rule uses a filing calendar date rather than an intraday availability timestamp. [15] For an honest historical comparison, a developer therefore needs to preserve source responses and specify decision time in addition to respecting these guards.

## Follow the evidence, not the job titles

Once the information branches are selected, the graph runs them as parallel analyst subgraphs with private message histories, returning only each designated report. [3] The first-stage join waits for the analyst subgraphs and the Memory Log branch before starting the Bull Researcher. [3] We will follow the Memory Log branch in the feedback section. Tool-enabled analysts alternate model turns and tool execution, eventually receiving a final-report instruction when their configured tool-round bound is reached. [3] The prefetched sentiment path above performs a different job: it interprets a prepared bundle instead of letting the model choose its retrieval.

The next stages change interpretation rather than gather more evidence. Bull and Bear receive the analyst reports, debate history, and latest opponent argument, then append competing cases; the Research Manager receives the debate history and renders its recommendation, rationale, and strategic actions as `investment_plan`. [18, 19] Research discussion stops at `2 * max_debate_rounds`, and the Aggressive → Conservative → Neutral risk rotation stops at `3 * max_risk_discuss_rounds`. [22] Turn counts determine when synthesis happens; they do not establish that participants have agreed on the facts.

The Trader reveals why prompt access matters more than a neat role diagram. It receives the research plan and caller portfolio, and, when available, the original `market_report`; its prompt maps Overweight and Underweight into Buy and Sell proposals and asks for absolute entry/stop prices or omission. [20] This direct technical-report path is intended to retain price structure that a research summary may lose. [20] The exact source fragment makes the conditional access visible: [20]

```python
        market_report = (state["market_report"] or "").strip()
        portfolio_context = get_portfolio_context_from_state(state)

        if market_report:
            grounding = (
                "Ground concrete price levels (entry, stop-loss, position sizing) in the technical "
                "market report's price structure -- current price, support/resistance, ATR, and "
                "volatility -- and use the research plan for direction and strategy. "
            )
            report_section = f"Technical Market Report:\n{market_report}\n\n"
        else:
            grounding = ""
            report_section = ""
```

Later, `report_section` is inserted into the Trader's user message. [20] If the market analyst was not selected or supplied no report, the branch inserts neither that report nor its grounding instruction. A hypothetical summary such as “momentum is improving” cannot supply an exact price level that it omitted. Direct access removes that particular information bottleneck; it does not prove that the model uses the detail correctly.

The risk perspectives regain direct access to all four analyst-report fields, alongside the Trader proposal, caller portfolio, and risk discussion. [21] The final Portfolio Manager instead directly receives the research plan, Trader proposal, risk history, portfolio, and nonempty prior context—not the original analyst-report fields. [2] Original evidence can reach that final prompt through the intervening text, but remaining somewhere in state does not make a fact a direct input to the decision-maker. For example, losing “only two posts were available” while retaining “bullish sentiment” would change the basis of a judgment. This is an illustrative failure to look for, not an observed TradingAgents trace.

Schemas help those handoffs remain usable. `ResearchPlan` separates recommendation, rationale, and actions; `TraderProposal` adds optional entry/stop prices and text sizing; renderers turn parsed objects back into Markdown for downstream consumption. [4] Optional numeric normalization drops a price value if it is a percentage or a string that does not describe a single number. [4] The inspected decision fields do not encode evidence locators, allocation checks, or an executable quantity. [4] A well-formed price is still a claim requiring grounding.

Structured invocation can fall back to an ordinary model call; the final manager takes a typed rating directly when available and otherwise parses its prose. [2, 23] The deterministic parser looks for explicit rating labels and sends unreadable or unresolved ambiguous output to `REVIEW`, rather than inventing Hold. [24] This preserves a crucial distinction for callers: a neutral judgment and a result whose direction cannot be read require different handling. The fallback is a recovery route, not a guarantee of completion—the ordinary model call can fail too.

## Let outcomes become context—carefully

A recommendation can also affect future recommendations. At completion, the graph records the final decision and rating as a pending Markdown-memory entry; recording invokes no model, depends on a configured persistent path, and suppresses duplicate ticker/date entries. [1, 25] A subsequent graph run automatically attempts to settle pending decisions across tickers in its parallel Memory Log branch, then loads prior context; callers can also explicitly request settlement when they stop analyzing an instrument. [1]

Settlement obtains Yahoo closes, uses the first instrument session on or after the analysis date and the session `holding_days` bars later, requires the full instrument window and benchmark coverage, and calculates instrument return minus benchmark return. [26] The default holding window is five sessions. [7, 26] That is a fixed-window asset outcome, not the P&L of a position filled at the Trader's proposed entry or stopped at its proposed loss level.

The quick-model Reflector receives the final thesis, raw return, benchmark-relative return, benchmark name, and holding window, and generates a short prose lesson that is persisted with the outcome; price or reflection failure leaves the entry pending. [25, 26, 27] Its instruction acknowledges that the outcome window may be shorter than the thesis horizon. [27] This is adaptation through future prompt context, not model-weight training or independent verification of why the asset moved.

Retrieval excludes pending entries and, for historical runs, keeps only entries whose stored resolution date is no later than the analysis date; current-date runs disable that cutoff. [1, 25] It selects up to five same-ticker records and three cross-ticker lessons in reverse insertion order, and the Portfolio Manager inserts the resulting `past_context` when nonempty. [2, 25] Thus a developer must treat the starting log and its insertion history as decision inputs.

One subtle boundary changes historical interpretation. The stored resolution date is the exit price bar's date, while the reflection is generated when settlement runs. [26] Filtering on the former excludes outcomes that had not yet happened, but does not establish that the lesson existed then or that its model knew only then-available facts. A historical replay needs to audit lesson-generation time and model knowledge as well as outcome time.

## When is coordination worth its complexity?

The information chain and its lesson history are now the objects of comparison. Because earlier lessons enter later decisions, their exposure is an input to control when comparing coordinated and simpler workflows.

The architecture offers plausible benefits: separate opposing cases can expose neglected risks, and direct report access can protect task-critical detail from summary loss. It also adds opportunities for shared errors, persuasive repetition, and information loss. Roles within the quick tier share a model, and structured fallback can introduce an additional call. [3, 23] Neither node count nor disagreement is a measure of independent reasoning.

The current evaluator answers a narrower question. `run_backtest` traverses ticker/date cells using one graph and a sweep-specific memory log, supplies the same portfolio context to every cell, and does not carry positions or cash forward. [28] Its scorer treats positive benchmark-relative return as a directional hit for Buy/Overweight and negative return as a hit for Underweight/Sell; Hold has no directional hit rate and `REVIEW` is unscored. [28] Mean return for a Sell group remains the asset's excess return, not short-sale profit. Because the graph shares the lesson log, position-independent cells need not be history-independent. Preserve or control that history before comparing workflows.

Existing experiments inform the comparison without settling it. The original TradingAgents paper describes a January 1–March 29, 2024 trading simulation with heterogeneous financial inputs and comparison baselines (Buy-and-Hold, MACD, KDJ+RSI, ZMR, and SMA). [29] Those alternatives differ in information and computation as well as coordination, so the comparison does not isolate the benefit of the present graph's debates or handoffs. Its older simulated trading endpoint is also different from this implementation's recommendation scoring.

A FinRobot-platform study supplies a more direct single/group comparison: it analyzes 2023 10-Ks for 30 Dow companies using `GPT-4-1106-vision-preview` across single-, dual-, and triple-agent configurations. [30] GPT-4's 1–5 report scores favor single over triple agents for fundamentals (4.70 versus 3.97) and sentiment (3.93 versus 3.77), but favor triple over single for risk (3.83 versus 3.57). [30] That is evidence of task-dependent results, not an independently verified factual-error rate: GPT-4 judged model-generated reports, agents could choose retrieval, and task-specific tools differed. [30] It motivates choosing coordination for a particular operation rather than assuming that more roles help every financial task.

Historical knowledge and sensitivity to supplied evidence raise further diagnostic questions. *Profit Mirage* evaluates older TradingAgents and four other frameworks with GPT-4o in NASDAQ-100 periods Q2–Q3 2021 and Q3–Q4 2024, reports performance degradation, and separately perturbs news, prices, and factors at selected events. [31] Its temporal split and input changes motivate checks for historical-knowledge effects and sensitivity to supplied evidence. Similar aggregate index returns do not make two regimes identical, however, and an unchanged categorical action after one perturbation does not uniquely establish memorization. These findings cannot be transferred into a leakage verdict on the pinned implementation.

For this revision, I would compare the full graph with two simpler workflows. Give one tool-using analyst/reviewer the same permitted sources to compare whole workflows; separately give one reviewer the identical analyst bundle to isolate downstream interpretation. Hold model strength, portfolio, date policy, and lesson exposure constant. Report both evidence-matched and inference-budget-matched comparisons, recording actual calls, tokens, and latency rather than diagram nodes. Repeat samples across instruments, dates, and regimes, with uncertainty intervals. These are proposed tests, not measured improvements.

Check several endpoints separately: benchmark-relative directional outcome over a declared horizon; factual and numeric correctness; survival of important qualifiers; completion, unavailable-data, and unreadable-output rates; and response to genuinely decisive contradictory inputs. Count pending and failed cases alongside scored ones. The current summary itself warns of one model sample per cell and unarchived text feeds. [28] If the intended application is portfolio trading, a further experiment needs carried capital, quantities, fills, costs, and enforced constraints. A recommendation score cannot supply those missing operations.

Coordination is worth retaining when these comparisons show that a particular handoff or challenge improves the required decision quality at an acceptable cost. Until then, the system is an inspectable design hypothesis, and a simpler reviewer remains a meaningful alternative.

## Conclusion

Agentic AI implements a financial framework by connecting controlled information access to explicit interpretive responsibilities and a usable decision contract. TradingAgents makes that connection concrete: reports become arguments, arguments become plans, selected original detail bypasses a summary, and outcome-derived lessons become later context.

For a developer, the central design question is what each consumer actually sees—and what the caller may safely do with the result. Preserve the facts and qualifications needed for the next operation, distinguish unreadable output from neutral judgment, and test coordination against a simpler workflow with comparable evidence, computation, and memory. A rated thesis is a useful product of this chain. Verified investment reasoning and authorized execution require additional evidence and mechanisms.

## Limitations

This is revision-pinned static implementation analysis, not a runtime demonstration. Code and tests read do not establish provider availability, successful model invocation, passing tests, or faithful reasoning. The recommendation-only conclusion applies to the public Python path traced here; it is not a repository-wide claim about every derivative or broker adapter.

Date guards, filing-date selection, and outcome cutoffs are meaningful boundaries, but they do not establish complete intraday knowability, archived provider vintages, historically clean model priors, or contemporaneously generated reflections. No frequency or magnitude of contamination or qualifier loss is measured here.

The current-revision causal benefit of coordination remains unestablished by the evidence discussed. Original-paper experiments, adjacent studies, recommendation scoring, and proposed controlled tests answer different questions. Neither their project names nor persuasive agent prose turns them into a verified net-portfolio performance claim. This article is an implementation explanation, not investment advice or a live-trading procedure.

## References

[1] TradingAgentsGraph: initialization, public call, recording, and report export — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/graph/trading_graph.py
[2] Portfolio Manager: actual final prompt and rating authority — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/managers/portfolio_manager.py
[3] Graph setup: private analyst subgraphs, join, and downstream edges — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/graph/setup.py
[4] Decision schemas and Markdown renderers — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/schemas.py
[5] PortfolioContext and position rendering — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/portfolio.py
[6] Shared context: missing reports and unknown portfolio — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/context.py
[7] Default configuration and environment overrides — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/default_config.py
[8] Tier-specific provider client factory — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/llm_clients/factory.py
[9] Analyst selection and execution specifications — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/graph/analyst_execution.py
[10] Report-tree writer — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/reporting.py
[11] Pinned README: prerequisites and organizational description — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/README.md
[12] State-injected analyst tools — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/tools.py
[13] Date windows, historical withholding, and coverage notices — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/dataflows/date_window.py
[14] Configured vendor routing and fallback — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/dataflows/router.py
[15] SEC EDGAR fact selection — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/dataflows/vendors/sec_edgar.py
[16] Yahoo adjusted OHLCV loading and date filtering — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/dataflows/vendors/yahoo/ohlcv.py
[17] Sentiment analyst prefetch and invocation — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/analysts/sentiment_analyst.py
[18] Opposing research prompts: Bull and Bear — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/researchers/bull_researcher.py
[19] Research Manager: debate-to-plan handoff — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/managers/research_manager.py
[20] Trader: technical-report bypass and proposal prompt — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/trader/trader.py
[21] Risk prompts: Aggressive, Conservative, and Neutral — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/risk_mgmt/aggressive_debator.py
[22] Research and risk turn-count routing — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/graph/conditional_logic.py
[23] Structured-output binding and free-text fallback — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/structured.py
[24] Rating extraction and REVIEW sentinel — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/agents/rating.py
[25] Persistent memory log, outcome update, and as-of retrieval — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/memory/log.py
[26] Price-window settlement and benchmark-relative outcome, with Yahoo close-retrieval helper — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/memory/settlement.py
[27] Outcome reflection prompt and quick-model call — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/memory/reflection.py
[28] Current recommendation evaluator — https://raw.githubusercontent.com/TauricResearch/TradingAgents/1394a3f72aa4393e1a98f51b382434c4b4c2d972/tradingagents/backtest.py
[29] TradingAgents: Multi-Agents LLM Financial Trading Framework, v7 — simulation setup and baselines, Sections 5–6 — http://arxiv.org/abs/2412.20138v7
[30] Enhancing Investment Analysis: Optimizing AI-Agent Collaboration in Financial Research, v1 — methods and report-quality comparison, Section 4 and Table 2 — http://arxiv.org/abs/2411.04788v1
[31] Profit Mirage: Revisiting Information Leakage in LLM-based Financial Agents, v1 — temporal and counterfactual evaluations, Sections 2.1–2.2 — https://arxiv.org/html/2510.07920v1

---
Every [N] marker above is verifiable: fetch the citations JSON, match the marker id, and check the extraction (summary and key facts) plus placements against the source URL. Verification guide: https://lumisonde.com/for-agents/