Statistics for Traders #11: Pearson r across the whole CAD CPI × CADJPY sample is +0.44 — but within the big-beat bucket alone it's −0.15, and the bucket labels carry the signal
Across all 194 non-contaminated CAD CPI m/m releases on CADJPY at 15 minutes, the Pearson correlation coefficient between surprise-z and the 15-minute move is +0.44— exactly the shape you’d expect from a clean 5-bucket monotonic walk. But drop into any one of the 5 buckets and ask “does knowing the exact z within this bucket help me predict the move?” and the answer for 4 of 5 buckets is: no, the bucket-median is the best per-print estimate you have.
This is a natural follow-up to Stats #10 (autocorrelation) — autocorrelation is just correlation between a series and a lagged version of itself. Today’s post takes the general Pearson coefficient and applies it to two different series (surprise-z and 15-minute move) drawn from the same event history, sliced two ways: the whole-sample view, and the within-bucket view.
Pearson r — 60-second refresher
Given paired observations (x₁, y₁), (x₂, y₂), …, (xₙ, yₙ), the Pearson r is:
r = Cov(x,y) / (σ_x * σ_y) = mean((x−x̄)(y−ȳ)) / (mean((x−x̄)²)^0.5 * mean((y−ȳ)²)^0.5)
r is bounded in [−1, +1]. r = +1 means the ys are a perfect increasing linear function of the xs. r = −1 means the ys are a perfect decreasing linear function of the xs. r = 0 means no linear relationship. Two subtleties: (a) r only detects LINEAR relationships — a perfect y = x² relationship on a symmetric x-range has r = 0 despite being perfectly deterministic; (b) r is scale-invariant, so multiplying either series by any constant doesn’t change r.
The whole-sample view
Pool all 194 non-contaminated CAD CPI m/m × CADJPY releases at 15m, compute r between surprise-z and move-pips:
| Metric | Value | Interpretation |
|---|---|---|
| Pearson r | +0.4394 | Solid positive linear relationship |
| Spearman ρ | +0.4599 | Rank-based; near-identical to Pearson |
| 95% CI on r | (+0.32, +0.55) | Fisher z-transform, n=194 gives tight bounds |
r = +0.44 is the correlation-language version of the same story today’s slot-1 post told with a bucket table: bigger surprises correlate with bigger up-moves, and the relationship is strong enough to survive 194 noisy real-world observations. The 95% CI (+0.32 to +0.55) is narrow because n=194 is a lot of data.
The within-bucket view
Now the interesting cut. Split the 194 observations into their 5 surprise buckets and compute r separately within each bucket:
| Bucket | n | z-range | Pearson r | 95% CI |
|---|---|---|---|---|
| big_miss | 13 | −2.98 to −1.61 | +0.261 | (−0.34, +0.71) |
| small_miss | 48 | −1.48 to −0.51 | −0.116 | (−0.39, +0.17) |
| in_line | 81 | −0.50 to +0.50 | +0.299 | (+0.09, +0.49) |
| small_beat | 33 | +0.50 to +1.47 | +0.082 | (−0.27, +0.41) |
| big_beat | 19 | +1.55 to +4.16 | −0.148 | (−0.56, +0.33) |
Four of the five 95% CIs straddle zero. The only exception is in_line, where r = +0.30 with 95% CI (+0.09, +0.49)— the lower bound just barely excludes zero. The tail buckets — where we’d most want a “bigger surprise means bigger move” refinement — are exactly the buckets where the within-bucket surprise magnitude adds no reliable information.
Why: the bucket boundary is where the discretization gets its power
The 5-bucket approach the tool uses works well BECAUSE the underlying relationship is nearly step-like at the bucket boundaries. When you look at surprise-z varying from −4 to +4 continuously, the response looks like the +0.44 correlation from the whole sample. But at any given point inside a bucket, the response is close to the bucket-median regardless of exactly where in the bucket you are.
There are three plausible reasons this happens:
- Traders discretize.When the print hits, the market’s first reaction is to categorize it (“this is a beat”) not to condition on the exact number. Once the category is set, the initial move is driven by the category, not the magnitude within the category.
- Extremes are ambiguous.A z=+4 print is far enough into the tail that the market might question the print itself (data issue? seasonal adjustment quirk?) rather than trade a proportionally-bigger move. The tail bins collapse this ambiguity into a single “big” category.
- The residual within-bucket variation IS just noise. The tail buckets have n=13 to n=33, and the standard error of a within-bucket correlation is roughly 1/sqrt(n) — around 0.20 for n=25. Even if the true within-bucket r were +0.20, an n=25 sample would produce r estimates ranging from about −0.20 to +0.60. The observed r values in the tail buckets are well-within that noise range.
How to read a Pearson r 95% CI
The 95% CIs in the table come from Fisher’s 1915 z-transformation: transform r → z = 0.5·ln((1+r)/(1−r)), then z is approximately normal with standard error 1/sqrt(n−3), then transform the CI endpoints back. For big_beat with n=19 and r=−0.148:
z = 0.5 · ln((1 + (−0.148)) / (1 − (−0.148))) = 0.5 · ln(0.852 / 1.148) = 0.5 · ln(0.7422) = −0.149 SE = 1 / sqrt(19 − 3) = 1 / sqrt(16) = 0.25 z_lo = −0.149 − 1.96 · 0.25 = −0.639 z_hi = −0.149 + 1.96 · 0.25 = +0.341 r_lo = (exp(2·(−0.639)) − 1) / (exp(2·(−0.639)) + 1) = −0.564 r_hi = (exp(2·(+0.341)) − 1) / (exp(2·(+0.341)) + 1) = +0.329 → 95% CI on the true big_beat r: (−0.564, +0.329)
Half-width roughly ±0.45in r-space for n=19. That’s the reason the exact observed r=−0.148 tells you almost nothing — anything from strongly negative to moderately positive is within the noise band. Compare to the in_line bucket at n=81, where the CI half-width shrinks to about ±0.20, tight enough to exclude zero.
Pearson vs Spearman
Pearson r assumes the relationship between x and y is linear. Spearman ρ is the same formula applied to the RANKS of x and y — it’s robust to monotonic non-linearities and to outliers on either axis. When the relationship is truly linear and free of outliers, Pearson and Spearman are close. When they disagree substantially, the interesting question is which pair — a real non-linearity, or an outlier pulling Pearson around?
For today’s data, four of five buckets have Pearson and Spearman within 0.02 of each other. The big_miss bucket disagrees more: Pearson +0.26 vs Spearman +0.50, on n=13. Small n plus a couple of z-outliers is the usual culprit. Reading rule of thumb: when they diverge on small samples, trust Spearman.
Correlation ≠ causation — a small worked example
The whole-sample r of +0.44 does NOT prove that a CAD CPI beat CAUSES CADJPY to go up. It’s consistent with that, but it’s also consistent with both being driven by a common underlying factor. Concrete candidate: pre-existing CAD momentum. If CAD Employment three days earlier printed strong, the market may already be tilted CAD-hawkish, which biases both:
- the CPI z upward (because the consensus is stale relative to the freshest hawkish data), AND
- the CADJPY 15m move upward (via existing CAD momentum unrelated to the CPI print).
Under that scenario, r would still be +0.44 but the CPI print itself is doing less of the causal work. Untangling this would need an experiment we can’t run (you can’t randomize macro releases). The within-bucket-zero finding is more robust to this concern: whatever the underlying causal structure, once you know the bucket, the exact z inside it adds nothing.
Practical takeaway
When you read the tool’s bucket-median column, use it as your point estimate — don’t try to grind extra edge by looking at the exact surprise-z of the current print and interpolating within the bucket. The within-bucket correlations for the tail buckets don’t support that; the bucket boundary is doing the work. The one place a within-bucket gradient exists is the in_line bucket (r=+0.30 with a tight CI), which makes sense — in_line is a wide bucket by design (the “neither miss nor beat” middle) and the sub-z gradient inside it does carry a little information.
Cross-refs: Stats #1 introduced the z-score itself, Stats #3 explained why n=19 gives such wide CIs, and Stats #10 used a correlation-with-lagged-self special case to detect volatility clustering.
Open the tool → Free forever. No signup. No email required.