Statistics for Traders #32: Sample co-skewness on today's slot-1 UK Core CPI × GBPCAD sample — the aggregate Harvey-Siddique β_SKD is only +0.09 (small), but the bucket-conditional skewness of move_pips is +1.14 in big_beat and +0.58 in big_miss — asymmetric fat tails IN THE DIRECTION OF THE SURPRISE that correlation and aggregate co-skew both miss
Higher-moment cumulants on today’s slot-1 UK Core CPI × GBPCAD 15m sample (n=198). Correlation ρ(X,Y) = +0.508 captures the LINEAR part (r² = 25.8% of Y variance). Aggregate Harvey-Siddique β_SKD = γ_{X²Y} = +0.090 — small. But bucket-conditional skewness of Y reveals asymmetric fat tails IN THE DIRECTION OF the surprise: big_beat skew = +1.14, big_miss = +0.58 — hidden by aggregate averaging.
All numbers computed in Python via numpy 2.4.6 + scipy 1.17.1 on the same full 198-release /api/v1/news-impact/releasesresponse used to build today’s slot-1 post. Cross-verified.

Definitions
For X = surprise_z and Y = move_pips, standardize: zx = (X - μ_x)/σ_x and zy = (Y - μ_y)/σ_y. The four independent 3rd-order joint moments are:
| Moment | Formula | Interpretation |
|---|---|---|
| γ_1(X) [= XXX] | E[zx³] | Marginal skew of X |
| γ_1(Y) [= YYY] | E[zy³] | Marginal skew of Y |
| γ_{X²Y} [= XXY] | E[zx² · zy] = β_SKD | Y's mean shift when X² large (directional Y ~ |X|) |
| γ_{XY²} [= XYY] | E[zx · zy²] | |Y| shift when X large (Y variance ~ X) |
Aggregate cumulants on the n=198 sample
| Quantity | Value | |value|/SE | Read |
|---|---|---|---|
| μ_x | +0.042 | — | surprise_z centered near zero (expected: consensus is unbiased) |
| μ_y | -2.24p | — | GBPCAD drifts slightly down through 15m post-release |
| σ_x | 1.093 | — | surprise_z scaled to standard-Normal |
| σ_y | 30.59p | — | typical 15m GBPCAD move std ≈ 30 pips |
| ρ(X,Y) | +0.5075 | — | moderate positive linear r; r² = 0.258 |
| γ_1(X) | +0.258 | 1.48 | surprise_z slightly right-skewed, fails α=0.05 |
| γ_1(Y) | -0.123 | 0.71 | move_pips slightly left-skewed, fails α=0.05 |
| γ_2(X) excess | +0.536 | — | surprise_z slightly heavy-tailed |
| γ_2(Y) excess | +1.318 | — | move_pips heavily-heavy-tailed |
| γ_{X²Y} = β_SKD | +0.090 | 0.52 | small — Y's mean barely shifts with X² beyond linear r |
| γ_{XY²} | +0.015 | 0.09 | essentially zero — |Y| doesn't shift with X |
SE under Gaussian null (Bowman-Shenton) for the marginal and aggregate co-skew moments: sqrt(6/n) = sqrt(6/198) = 0.174. Neither marginal skew nor either co-skew clears α = 0.05 on their own. The aggregate picture says: the joint (X, Y) distribution looks approximately elliptical, with a strong linear part and small higher-order asymmetry. The bucket-conditional analysis, below, tells a different story.
Bucket-conditional skewness of Y = move_pips
| Bucket | n | mean | sd | skew | |skew|/SE | Read |
|---|---|---|---|---|---|---|
| big_miss | 15 | -20.05p | 25.78 | +0.58 | 0.92 | right-tail heavy — 2 anomalous +up prints |
| small_miss | 53 | -21.72p | 30.16 | -0.73 | 2.17 | LEFT-tail heavy — big-down outliers, only sig bucket |
| in_line | 62 | +1.09p | 23.54 | -0.25 | 0.80 | mildly left-tail |
| small_beat | 53 | +10.02p | 24.31 | +0.56 | 1.66 | right-tail heavy in beat direction |
| big_beat | 15 | +27.35p | 31.36 | +1.14 | 1.80 | STRONGLY right-tail — 2015 +106p, 2014 +81p |
Bucket-conditional |skew|/SE is computed against sqrt(6/n_bucket) — a Gaussian-null test on the bucket-specific sample size. small_miss (n=53) is the only bucket that individually clears α=0.05 (|skew|/SE = 2.17, p ≈ 0.03). But the DIRECTIONAL pattern is consistent across the tail buckets: big_beat and small_beat both have positive skew (right-tail-heavy in the winning beat direction), and big_miss has small positive skew driven by the 2 counter-directional outliers 2013-08-13 (+22p) and 2014-12-16 (+38p).
Why aggregate co-skew misses the bucket asymmetry
β_SKD = γ_{X²Y} = +0.090is small because the bucket-tail asymmetries partially cancel when pooled. Big_miss’s +0.58 (right tail in the WRONG direction — counter-directional +up outliers on a down-bucket) and big_beat’s +1.14 (right tail in the RIGHT direction — bigger-than-expected +up outliers on an up-bucket) contribute to β_SKD with opposite signs relative to the bucket-mean direction. The sum across buckets ends up near zero.
This is the classic Simpson-style cancellation for higher-order cumulants: an aggregate co-skew of near-zero does not mean the joint distribution is symmetric. It means the asymmetries are conditionally on X and self-cancelling on aggregation. To catch the signal you have to condition on X — via buckets, quantiles, or equivalently a nonparametric regression Y ~ X and look at the residual conditional distribution.
Practical trader read
(a) Fat tails in the winning direction on tail buckets. big_beat (+1.14) and small_beat (+0.56) both have right-tail-heavy move_pips distributions on the up (winning) side. Meaning: the distribution of returns from a "bet with the big-beat direction" strategy is positively skewed — the median (+20p) understates the mean (+27p), and the top-decile prints (+80p / +106p) drag the mean further right.
(b) Sharpe ratio understates the attractiveness. Sharpe penalizes variance regardless of sign. On a positively-skewed strategy, the right-tail variance is desirable (it’s where the upside lives), but Sharpe treats it identically to left-tail variance. Sortino (Stats #9) is a better metric when the fat tail is asymmetric IN the winning direction — the Sortino / Sharpe divergence itself is a diagnostic for exactly this kind of asymmetric-cumulant profile.
(c) Higher-order cumulants complement the linear r, they don’t replace it. r = +0.508 does most of the work (25.8% of Y variance). γ_{X²Y}= +0.09 adds only a small refinement. But conditional-on-X moments (bucket-skew here, or bucket-Sharpe, or bucket-percentile) can change the practical trade decision meaningfully. That’s the argument for looking at the tool’s per-bucket columns rather than just the correlation number.
Verification note
All numbers computed in Python via numpy 2.4.6 + scipy 1.17.1 on 2026-09-01 on the same 198-release /api/v1/news-impact/releases?event=FF:GBP_CORE_CPI_YOY&instrument=GBPCAD&window=15m&population=non_contaminated&limit=500 response feeding today’s slot-1 post. Chart via one-off script reusing scripts/insights-charts/svg.ts + theme.ts primitives + sharp; not committed under scripts/. Direct follow-up to Stats #7 (marginal skewness, 2026-08-07) — 25-day spacing. Queue rotates to suppressor-variable partial-vs-semi-partial (queued since Stats #25), higher-order VAR-b prewhitening (queued since Stats #20), co-kurtosis (natural sibling of today’s post).