Last lesson left you with a slogan — a backtest measures association, not effect — and a promise that there is real machinery behind it. This is the machinery. Two pieces of grammar, both stolen from epidemiology and computer science, that let you say exactly what a causal claim is and exactly which assumptions would make your data answer it.
The first is the potential-outcomes framework (Rubin): a way to define a causal effect for a single trade, a single stock, a single order, without ever mentioning a regression. The second is the causal DAG (Pearl): a picture that makes your assumptions about what-causes-what auditable, and that tells you — mechanically — which variables you must control for and which you must leave alone. The punchline of the whole lesson is a single contrast most quants get backwards: a confounder you are obligated to control, and a collider you are forbidden to. Control the wrong one and you don’t reduce bias — you manufacture it.
Potential outcomes: two worlds, one of them always missing
Before you read — take a guess
For one stock, you define the return it WOULD earn if you trade it, Y(1), and the return it WOULD earn if you do not, Y(0). After the month is over and you traded it, what do you actually get to observe?
Analogy. Picture a wardrobe with two doors. Behind the left door is the version of your morning where you took the umbrella; behind the right, the version where you left it. Both versions are perfectly well-defined — there is a fact about whether you’d have got soaked — but you only ever walk through one door. The other world is real but unwitnessed. Every trade is that wardrobe: there is a genuine return-if-traded and a genuine return-if-not, and the market only ever lets you see through the door you opened.
Definition. For each unit (a stock-month, a trade, an order), the potential outcomes are — the outcome if the unit is treated — and — the outcome if it is not. The individual treatment effect is
“Treatment” is just whatever intervention you care about: holding the high-signal basket, routing the order aggressively, applying the overlay. The effect is the difference for the same unit, in the same period, all else identical — which is exactly why it is so hard to get.
The fundamental problem of causal inference. For any single unit you observe at most one of and — whichever corresponds to the treatment that actually happened. The other is a counterfactual: real, well-defined, and permanently unobserved. So is, for every individual unit, uncomputable from data alone. Causal inference is the science of filling in that missing column with assumptions you can defend.
Worked example. Five stock-months. You traded (treated, ) three of them and skipped (control, ) two. The column you observe is whichever potential outcome matches the treatment; the other is the unobservable ”?”.
| Unit | Treated? | Y(1) — if traded | Y(0) — if not | Observed Y | Effect Y(1)−Y(0) |
|---|---|---|---|---|---|
| A | Yes | +2.0% | ? | +2.0% | ? |
| B | Yes | +1.0% | ? | +1.0% | ? |
| C | Yes | +3.0% | ? | +3.0% | ? |
| D | No | ? | +0.5% | +0.5% | ? |
| E | No | ? | −0.5% | −0.5% | ? |
Every “Effect” cell is a ”?” because every row is missing one of its two potential outcomes. There is no arithmetic that recovers here — the data simply does not contain it. The entire rest of the field exists to estimate averages of that missing quantity, which, unlike the individual effect, you can get at under the right assumptions.
The counterfactual is missing data, not a modelling choice
A frequent beginner error is to treat a stock’s “return if not traded” as something you can read off the same stock’s history, or proxy with a similar stock. You cannot — not for that unit in that period. The counterfactual is genuinely absent, and pretending otherwise (e.g. “its return last month was the counterfactual”) silently smuggles in the assumption that nothing else changed, which is the very thing you have to prove. Treat the missing column as missing, and be explicit about how you intend to fill it.
When to use it
Reach for potential-outcomes notation the moment a debate gets fuzzy about what effect we’re even estimating. Forcing yourself to write “the unit is a stock-month, treatment is holding the top decile, is its forward return held, is its forward return not held” disambiguates more arguments than any regression output. If you cannot name the unit and the two worlds, you are not yet asking a causal question.
State the fundamental problem precisely.
Pick the right option for each blank, then check.
For any single unit we observe at most of its two potential outcomes, so the individual treatment effect is never computable from data alone — the other outcome is a missing counterfactual.
From individual effects to averages: ATE, ATT, and the bias you inherit
Before you read — take a guess
You cannot get any individual effect. So you compute the naive difference: average observed return of the trades you took minus the average of the ones you skipped. In general, what is this difference equal to?
Analogy. You can’t know whether a specific patient would have recovered without the drug — but average over thousands and the missing halves start to cancel, if the treated and untreated groups were otherwise alike. The danger is when they aren’t: if doctors gave the drug only to the healthiest patients, the treated group would look great even if the drug were a sugar pill. The gap between “drug works” and “healthy people got the drug” is selection bias, and it is the exact reason your traded names beating your skipped names proves nothing on its own.
Definitions. Two averages do the heavy lifting:
- ATE — Average Treatment Effect, over the whole population:
- ATT — Average Treatment effect on the Treated, over only the units that actually got treated:
ATE answers “what if we treated everybody?”; ATT answers “what did treatment do to the units we actually treated?” They differ whenever the treated units respond differently from a random unit — which, in a strategy you chose, is the normal case.
Why the naive difference is ATT plus bias. The thing you can actually compute is the difference in observed means:
Decompose it by adding and subtracting the treated group’s untreated potential outcome:
The second bracket asks: in the untreated world, would the units you chose to treat have done differently from the ones you skipped? If yes — if your chosen trades were special even absent the treatment — the naive difference is contaminated.
Worked example. Take the five units above. Suppose the truth (which an oracle, not you, can see) is:
| Unit | Treated? | Y(1) | Y(0) | True effect |
|---|---|---|---|---|
| A | Yes | +2.0% | +1.5% | +0.5% |
| B | Yes | +1.0% | +0.6% | +0.4% |
| C | Yes | +3.0% | +2.4% | +0.6% |
| D | No | +0.4% | +0.0% | +0.4% |
| E | No | −0.1% | −0.5% | +0.4% |
The true ATE is the average of the effect column: . The true ATT (treated units A, B, C) is .
Now the naive difference you’d actually compute from observed returns: treated mean ; control mean . Naive difference .
That wildly overstates the true ATT of . The gap is the selection bias: the units you chose to trade (A, B, C) had high baseline returns , while the skipped units had a baseline of . The baseline gap is . And indeed — exactly the naive number. You “earned” ; only of it was the treatment. The other was you cherry-picking names that were going to outperform anyway.
ATT is not ATE, and the naive diff is usually neither
Two traps in one. First, do not quote a number estimated on your traded book as if it applied to the whole universe — that is ATT masquerading as ATE, and it breaks the instant you scale the strategy to names that respond differently. Second, never report the raw traded-minus-skipped spread as “the effect.” Under self-selection it is ATT plus a selection-bias term that can dwarf the effect itself, as the worked example’s vs shows. The only thing that zeroes the bias term for free is assignment you did not control — randomisation, or a natural experiment.
When to use it
Decide up front whether your decision needs ATE or ATT. Sizing an existing book? You want ATT — the effect on the kind of names you actually hold. Deciding whether to launch a strategy across the whole universe, or extrapolate to names you’ve never traded? You need ATE, and you must worry that your treated sample isn’t representative. And always, always write the bias term down explicitly before trusting a difference-in-means — if you can’t argue the baseline gap is zero, the difference is not an effect.
Sort each quantity by whether it is something you can compute directly from observed data, or something that needs a causal assumption to identify.
Place each item in the right group.
- The ATT — average effect on the units you actually traded
- The raw difference between the traded and skipped averages
- Average observed return of the trades you took
- The individual treatment effect for stock A this month
- The ATE across the whole universe
- Average observed return of the trades you skipped
Ignorability and the do-operator: when conditioning equals intervening
Before you read — take a guess
What does Pearl's do(X) operator represent, and how does it differ from ordinary conditioning on X?
Analogy. Conditioning on “the patient took the drug” is asking who, among the people who chose the drug, recovered? — and the people who chose it might differ in a hundred ways. The do-operator is reaching into the world and making a randomly chosen patient take it, regardless of who they are. One observes a self-selected slice; the other performs surgery on the causal machine. In markets: conditioning on “the signal was high” pools all the reasons it was high; is you forcing it high by trading, snapping the strings that normally raise it.
Definition. The interventional quantity you actually want is — the average outcome in a world where is set to by fiat, deleting the arrows that ordinarily point into . The observational quantity your data hands you is . Ignorability (a.k.a. unconfoundedness, conditional independence, “no unmeasured confounders”) is the assumption that makes them coincide, possibly after controlling for a set of covariates :
Read it as: once you hold fixed, the treatment is as good as randomly assigned — the units’ potential outcomes carry no further information about whether they got treated. Under ignorability, — the conditional, averaged over the confounders, is the causal effect.
Random assignment is the clean version. If treatment is assigned by a coin flip, then is independent of everything — including both potential outcomes — with no needed: . The selection-bias term from the previous section, , is then exactly zero, because the groups are interchangeable by construction. That is why randomised experiments identify the ATE for free, and why finding a market analogue of a coin flip (a natural experiment) is the holy grail of later lessons.
Worked example. Recall the naive difference was against a true ATT of — a bias of . Now suppose instead you had assigned treatment by literally flipping a coin per name. Then the treated and skipped groups have, in expectation, the same baseline : the -vs- gap disappears because high-baseline names are no longer over-represented among the treated. The selection-bias bracket collapses to , and the naive difference now estimates the effect itself, (the ATE). Same units, same potential outcomes — only the assignment mechanism changed, and that alone is what turned a worthless into an honest estimate.
Ignorability is an assumption, not a result — and it is untestable
You cannot check unconfoundedness from the data, because it is a statement about the unobserved counterfactual outcomes. No p-value confirms “no unmeasured confounders.” Worse, conditioning on more variables does not monotonically help — controlling for the wrong variable (a collider, next section) can create the very dependence ignorability requires you not to have. So “I controlled for a lot of stuff” is not evidence for ignorability; it can be evidence against it. You earn ignorability by argument and design, never by throwing covariates at a regression.
When to use it
Whenever someone hands you an observational “edge” and asks if it’s real, the operational question is: is there a set of observed variables such that, holding fixed, the signal is as-good-as-randomly assigned? If yes, you can adjust for and read off the effect. If no — if a confounder is unmeasured, or you’d have to condition on something you shouldn’t — observational adjustment cannot save you, and you need an actual intervention or a natural experiment. The do-operator is the question; ignorability is the licence to answer it with conditioning.
If ignorability is untestable, how is causal inference from observational data not just hand-waving?
Answer. The honesty comes from making the assumption explicit and falsifiable in its consequences, not from testing it directly. You state the DAG you believe, derive what would have to be true if it held (placebo outcomes that should show no effect, pre-treatment trends that should be parallel, dose-response that should be monotone), and test those implications. You also run sensitivity analysis: how strong would an unmeasured confounder have to be to overturn the result? If a tiny hidden confounder flips the sign, the finding is fragile; if it would take an implausibly huge one, it’s robust. Causal inference is disciplined argument about an untestable assumption, surrounded by testable consequences — not a magic test that certifies “this is causal.”
Causal DAGs: drawing your assumptions so they can be audited
Before you read — take a guess
In a causal directed acyclic graph (DAG), what do the nodes and arrows mean, and what does 'acyclic' rule out?
Analogy. A DAG is a plumbing diagram for causation. Nodes are junctions (variables); arrows are pipes that carry influence one way (direct causes); “acyclic” means no pipe loops back to feed its own source. Crucially, a plumber doesn’t discover the layout by watching water — they draw what they believe is connected and then check whether the observed flows are consistent. Your DAG is the same: it is a declaration of belief about what causes what, drawn before you stare at correlations, and its whole value is that it makes those beliefs explicit enough to be wrong.
Definitions. A causal DAG is a graph of variables (nodes) and directed edges (arrows), where an arrow from to means ” is a direct cause of ,” and acyclic means you can never follow arrows from a node back to itself (no causal loops). Some vocabulary you will lean on:
- A path is any sequence of connected edges between two nodes, ignoring arrow direction.
- A directed (causal) path follows arrows head-to-tail, e.g. — this is genuine causal flow.
- A back-door path between treatment and outcome is any path that starts with an arrow into (i.e. ). Back-door paths carry non-causal association — they are how confounding sneaks in.
The central skill is reading a DAG for which paths transmit association and which are blocked. A path is blocked if it passes through a controlled-for confounder, or through an uncontrolled collider; it is open otherwise. The effect of on is identified when every back-door path is blocked while every genuine causal path stays open — and the next section shows that “block” and “open” depend entirely on whether the middle node is a confounder or a collider.
Worked example — encoding an assumption. Suppose you believe a momentum signal affects forward return both directly and through “attracting follow-on flow” , and that the broad market regime drives both the signal and the return. You’d draw:
This DAG asserts a lot: there are two causal routes from to ( directly and ), and one back-door path carrying spurious association. The diagram tells you immediately that to estimate the causal effect of you must block the back door (control ) but must not control — controlling would close off part of the very effect you’re trying to measure. None of that came from the data; it came from your willingness to commit your assumptions to a picture.
The DAG is your assumption, not a discovery — garbage in, garbage out
A DAG does not validate itself. If you draw the wrong arrows — omit a confounder, point an edge the wrong way, miss a feedback channel — every identification conclusion you derive from it is confidently wrong. The graph is a device for being explicit, and its honesty is entirely on you. Two analysts with different DAGs will reach different “rigorous” conclusions from the same data, and the data cannot adjudicate between them. That is not a flaw in DAGs; it is the unavoidable truth that causal claims always rest on assumptions — DAGs just stop you from hiding them.
When to use it
Draw the DAG before you fit anything, at the proposal stage, and circulate it — a DAG is the single best artefact for making a research debate concrete, because disagreements become “you have an arrow I don’t” instead of vague unease. Then use it operationally: list every back-door path from treatment to outcome, and for each, identify the minimal set of variables to control to block it (the “back-door criterion”). If no observable set blocks all back doors without opening a collider, the effect is not identified by adjustment, and you need a different design.
Define the dangerous kind of path.
Pick the right option for each blank, then check.
A path from treatment X to outcome Y is one that begins with an arrow pointing into X; it carries non-causal association and must be blocked to identify the effect.
Confounder vs collider: the one contrast quants get backwards
Before you read — take a guess
A confounder sits as X ← Z → Y (common cause); a collider sits as X → Z ← Y (common effect). What is the correct conditioning rule for each?
Analogy. A confounder is a puppeteer holding strings to both the signal and the return — you must cut its strings (control it) or it animates a fake relationship between them. A collider is the opposite: it’s a shared victim, a downstream node that both the signal and the return push on. Imagine two unrelated alarms, “low battery” and “intruder,” that both can trip your security light. The alarms are independent — until you condition on “the light is on.” Now, given the light is on, learning the battery was fine makes an intruder more likely: you’ve created a spurious negative dependence by conditioning on their common effect. Controlling a collider is detective-fiction logic — “if it wasn’t the butler, it must have been the maid” — and it has no place in your regression unless you want phantom correlations.
Definitions. With treatment , outcome , and a third variable :
- is a confounder when : a common cause. It opens a back-door path that is open by default. Controlling for closes it, removing the spurious association — you must control a confounder.
- is a collider when : a common effect. The path is blocked by default (no association flows through a collider). Controlling for (or any descendant of it) opens the path, injecting spurious association that was never there — you must not control a collider. This is collider bias (a.k.a. selection bias, Berkson’s paradox).
The symmetry is the whole point: same human instinct (“when in doubt, add the control variable”), diametrically opposite consequences. Confounders are sins of omission (forgetting to control), colliders are sins of commission (controlling something you shouldn’t).
Worked finance example — index inclusion as a collider. Suppose a stock’s chance of being added to a major index is driven by both its size () and its momentum (): big stocks get in, and so do strong recent performers. Draw it: . Among all stocks, size and momentum may be independent. But run your study only on index members — i.e. condition on — and watch a phantom appear. Concretely: a stock can earn its way into the index by being huge even with mediocre momentum, or by having blazing momentum despite middling size. So within the index, the small-ish members are disproportionately the high-momentum ones (that’s how they got in), and the low-momentum members are disproportionately the giants. You’ve manufactured a negative size-momentum correlation among members that does not exist in the wild. Any “edge” you find by combining size and momentum on an index-only sample is partly this artefact — born entirely from conditioning on the collider “Included.” The fix is not to control for inclusion; it’s to study the unconditioned universe (or model the selection explicitly).
Toggle the third node Z between confounder (X ← Z → Y, a common cause) and collider (X → Z ← Y, a common effect), then tick 'Control for Z'. Watch the rule flip: controlling CLOSES the confounder's back-door path (good — it isolates the real X → Y effect) but OPENS a brand-new spurious path through the collider (bad — it manufactures bias). The genuine X → Y arrow stays put throughout; only the spurious path responds to your conditioning choice. The takeaway the diagram dramatises: 'control for everything' is a trap.
'Control for everything' is the most expensive mistake in applied causal work
The kitchen-sink regression — throw in every available covariate and trust the coefficient — feels rigorous and is often catastrophic. Each control is either a confounder (helps), a collider (hurts, creates bias), or a mediator on the causal path (hurts, removes real effect). Adding controls blindly is as likely to inject bias as to remove it. The classic finance traps: conditioning on index membership, on survivors (a collider on “still trading”), on having passed a liquidity screen, or on post-treatment outcomes — every one of these is a common effect you opened by selecting on it. Before any variable enters the model, ask of the DAG: is this a common cause, a common effect, or on the path? Only the first earns a place.
When to use it
Use the confounder/collider test as a gate on every candidate control variable and every sample filter — because a sample filter is just conditioning by another name. For each one, locate it on your DAG: if it’s a common cause of treatment and outcome, control it; if it’s a common effect (or a descendant of one, or the basis of your sample selection), leave it out and worry that your existing selection already opened it. The most dangerous colliders are the ones you condition on without noticing — survivorship, success filters, “names with enough data” — so audit how your sample was built, not just which variables your model names.
Pick a term, then click its definition.
Recap
You now own the two pieces of grammar the rest of the course speaks in. Potential outcomes define a causal effect for a single unit as — two worlds, one of which is always missing — which is why individual effects are uncomputable and the field chases averages: the ATE over everyone, the ATT over the treated, and never the raw difference-in-means, which is ATT plus a selection-bias term that cherry-picking can blow up (recall observed for a true effect). The bias vanishes under ignorability — treatment as-good-as-random given — which is exactly the licence to swap the interventional for the observational , and which randomisation grants for free. Causal DAGs make those assumptions auditable: arrows are claims of direct causation, back-door paths are how confounding leaks in, and identification means blocking every back door while leaving the causal paths open. And the contrast that separates the careful from the burned: control a confounder (a common cause, open by default) and never a collider (a common effect, blocked by default — until you select on it and conjure the bias yourself). “Control for everything” is not caution; it is a coin flip between fixing bias and inventing it.
Big picture
Potential outcomes & causal DAGs
- Potential outcomes & DAGs
- Potential outcomes (Rubin)
- Y(1) and Y(0): two worlds
- Effect = Y(1) − Y(0)
- Fundamental problem: one is always missing
- Averages, not individuals
- ATE — over everyone
- ATT — over the treated
- Naive diff = ATT + selection bias
- Identification
- do(X): intervene, cut arrows into X
- Ignorability: as-good-as-random given Z
- Randomisation zeroes the bias term
- Causal DAGs
- Nodes = variables, arrows = direct causes
- Back-door paths carry spurious association
- Block back doors, keep causal paths open
- Confounder vs collider
- Confounder X ← Z → Y: control it
- Collider X → Z ← Y: do NOT control it
- Index inclusion = collider trap
- Potential outcomes (Rubin)
Mixed check: counterfactuals, bias, and bad controls
The true ATT of a strategy is 0.6%, but the units you chose to trade had an average untreated return of 1.2% while the names you skipped averaged 0.1% untreated. What naive traded-minus-skipped difference will you observe?
Check your answer to continue.