The one-sentence version
Large Language Model (LLM) Agents are excellent at "storytelling": give them a piece of data, and they can fluently explain, "Because news sentiment improved, stock prices rose." The problem is that financial data is riddled with correlations caused by common causes. A causal story that sounds plausible might simply be two variables being driven simultaneously by a third factor. This type of "financial hallucination" is more insidious than fabricating facts: the data is real, the correlation is real, but the causal explanation is wrong. This article equips Agents with three causal tools: drawing causal graphs, controlling for confounding variables, and performing placebo and negative control tests, and explains what each can and cannot rule out.
Disclaimer
This article is for technical educational purposes only and does not constitute investment advice. The code used in this article uses simulated data.
Layer 1: The Intuition
1.1 A Very Persuasive Error
An Agent analyzes three years of data and reaches the following conclusion:
"The news sentiment index is significantly positively correlated with the next day's returns (t = 13). Improving sentiment drives investors to buy, thereby pushing up stock prices. It is recommended to construct a sentiment factor."
It sounds airtight. However, the actual situation might be: overall market risk appetite is simultaneously driving both news sentiment (journalists become more optimistic) and stock prices; sentiment itself has no effect on stock prices. Once the driving mechanism of risk appetite changes, this "factor" will fail.
1.2 Two Types of Hallucinations
| Type | Example | Detection Difficulty |
|---|---|---|
| Factual Hallucination | Fabricating a non-existent earnings figure | Relatively easy: cross-check data sources |
| Causal Hallucination | Data and correlation are real, but the causal explanation is wrong | Hard: requires causal reasoning |
Large models learn the "because... therefore..." narrative style from vast amounts of financial text, and financial media itself is full of hindsight attribution. An Agent's causal hallucination is largely inherited.
1.3 Three Lines of Defense
Layer 2: Three Tools
2.1 Causal Graph (DAG)
Require the Agent to first draw the possible causal relationships between relevant variables before providing a conclusion:
Once drawn, paths other than "Sentiment → Returns" become obvious. Pearl's causal inference theory provides rules for determining "which variables need to be controlled" (the Backdoor Criterion).
2.2 Controlling for Confounding Variables
Include confounding variables (or their proxies) in a regression to see if the original effect remains:
- Effect decreases significantly or disappears → The original correlation was primarily from the confounder;
- Effect remains largely unchanged → At least this confounder has been ruled out (but others may exist).
2.3 Placebo Tests and Negative Controls
| Method | Procedure | What it rules out |
|---|---|---|
| Placebo (Permutation) Test | Shuffle the time order of the factor and repeat many times to obtain the distribution "when no relationship exists" | Rules out "pure coincidence" |
| Negative Control | Find a variable that cannot be a cause (e.g., data released after returns) and see if it is also "correlated" with returns | If it is also correlated, it indicates the correlation comes from a common cause or data issues |
| Temporal Negative Control | Test the relationship between the factor and past returns; a factor cannot influence the past | Rules out reverse causality and look-ahead bias |
Key distinction: A permutation test can only prove "it is not a coincidence"; it cannot prove "it is causal." A correlation caused by a confounder will still appear "significant" under a permutation test.
Layer 3: Code Demonstration
3.1 Simulation: Returns are driven only by risk appetite; sentiment has no effect
import numpy as np, pandas as pd, statsmodels.api as sm
rng = np.random.default_rng(21)
T = 1000
# Confounder: Market risk appetite (unobservable, but can be proxied)
risk_on = rng.normal(size=T)
sentiment = 0.8 * risk_on + rng.normal(scale=0.6, size=T) # "News sentiment factor" discovered by Agent
ret = 0.5 * risk_on + rng.normal(scale=1.0, size=T) # Returns are actually driven only by risk appetite
df = pd.DataFrame({[["sentiment"]]: sentiment, "ret": ret,
"risk_proxy": risk_on + rng.normal(scale=0.3, size=T)})
naive = sm.OLS(df["ret"], sm.add_constant(df"sentiment")).fit()
print("Naive regression: sentiment coefficient", round(naive.params["sentiment"], 3), " t =", round(naive.tvalues["sentiment"], 1))
ctrl = sm.OLS(df["ret"], sm.add_constant(df[["sentiment", "risk_proxy"]])).fit()
print("After controlling for confounders: sentiment coefficient", round(ctrl.params["sentiment"], 3), " t =", round(ctrl.tvalues["sentiment"], 1))
null = []
for _ in range(500):
s = rng.permutation(df["sentiment"].values)
null.append(np.corrcoef(s, df["ret"])[0, 1])
obs = df["sentiment"].corr(df["ret"])
print("Observed correlation", round(obs, 3), " Placebo 95th percentile", round(np.quantile(np.abs(null), 0.95), 3))
future_only = 0.8 * risk_on + rng.normal(scale=0.6, size=T) # Shares the same source as sentiment but cannot be a cause in time
print("Correlation between negative control and returns", round(np.corrcoef(future_only, ret)[0, 1], 3))
Output:
Naive regression: sentiment coefficient 0.45 t = 13.0
After controlling for confounders: sentiment coefficient 0.099 t = 1.8
Observed correlation 0.381 Placebo 95th percentile 0.06
Correlation of negative control variable with returns 0.384
3.2 Interpretation
| Test | Result | Conclusion |
|---|---|---|
| Naive Regression | t = 13, highly "significant" | This is how the Agent's original conclusion was formed |
| Control Confounders | Coefficient drops from 0.45 to 0.10, t = 1.8, no longer significant | Most of the effect comes from risk appetite |
| Permutation Test | Observed correlation of 0.38 far exceeds the placebo distribution | Only shows "it is not a coincidence," cannot prove causality |
| Negative Control | A variable that cannot be a cause also has a correlation of 0.38 | Strongly suggests the correlation comes from a common cause |
The coefficient after control did not drop to zero (0.10) because the proxy variable risk_proxy carries measurement error and failed to fully absorb the confounding. This is the norm in reality: controlling for confounders can only be done "as best as possible."
3.3 Turning it into Agent Workflow Standards
Add the following requirements to the system prompts and tools for research Agents:
- Conclusions must include a causal graph: List at least three possible confounding variables;
- Mandatory tests: Control for major confounders (market, industry, market cap, risk appetite proxies), permutation tests, and at least one negative control;
- Conclusion grading:
| Level | Condition | Phrasing |
|---|---|---|
| Correlation | Passed permutation test only | "X is correlated with Y, cause unknown" |
| Robust Correlation | Remains significant after controlling for major confounders; negative control is not significant | "After controlling for known factors, X remains correlated with Y" |
| Causal Evidence | Has natural experiments, exogenous shocks, or intervenable evidence | "There is evidence that X affects Y" |
- Prohibited phrasing: Do not use "leads to," "drives," or "because" when only correlation evidence is available;
- Adversarial Agent: Use another Agent specifically to propose alternative explanations.
3.4 Limitations
- Unobserved confounders can never be completely ruled out;
- Financial markets are reflexive: once a factor is widely used, it changes the market itself;
- The strongest causal evidence comes from intervention (see "Interventional Training"), and in financial markets, true randomized experiments are almost impossible. What can be utilized are "natural experiments": policy changes, index rebalancing, changes in trading rules, etc.
Summary
| Layer | Key points |
|---|---|
| Problem | Financial Hallucination: Data is true, correlation is true, causal explanation is wrong |
| Tools | Causal graphs, controlling confounders, permutation tests, negative controls |
| Key distinction | Permutation tests rule out coincidence, not confounders; negative controls can expose common causes |
| Standards | Conclusions with causal graphs, mandatory testing, conclusion grading, prohibited causal phrasing, Adversarial Agent |