From 5a0e2ac37c8079ff54c612f610f83c43e2a5f8c6 Mon Sep 17 00:00:00 2001 From: Matt Spinola Date: Sat, 1 Aug 2026 11:55:08 -0400 Subject: [PATCH] docs: correct the reason crude's back-adjusted series goes negative Found by a test failing against real data while building crowdmon's notional module. The number was right, the explanation was wrong, and the real one is a better argument for the same conclusion. I wrote that crude's back-adjusted series "reaches -27.52, which is not a price", attributing it to additive back-adjustment accumulating roll gaps below zero over decades. Measured: both series bottom in April 2020. What actually happens is that the single enormous roll gap out of the May 2020 contract, which settled at -37.63, is propagated backwards through every earlier bar. The sharpest row in the store is 2020-04-21: crude traded at +11.57, an ordinary positive price, while the back-adjusted bar for that day reads -27.52. Crude was genuinely below zero on exactly ONE day; the back-adjusted series is below zero on 64. A second claim in the same paragraph was also wrong. I asserted the unadjusted series can never be negative; it can, because 2020-04-20 happened and unadj records it faithfully. That matters for implementations: a negative price is not by itself evidence of the wrong series, so normalisation code must not clip or reject one. On that day a long position genuinely had negative notional, and anything assuming sign(notional) == sign(position) is wrong on real data. The primary evidence is unaffected: the +294% / +257% / +194% errors are measured directly, and the CL offset is 0.0000 today against 105.47 on 2004-12-13. Docs only; 257 tests still pass. Co-Authored-By: Claude Opus 5 --- docs/design/crowdmon_step2_normalisation.md | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/design/crowdmon_step2_normalisation.md b/docs/design/crowdmon_step2_normalisation.md index ec14034..1f4355c 100644 --- a/docs/design/crowdmon_step2_normalisation.md +++ b/docs/design/crowdmon_step2_normalisation.md @@ -133,8 +133,26 @@ has a property that makes it dangerous: **The error is exactly zero at the present date and grows monotonically backwards**, because back-adjustment anchors on the most recent contract. So a notional computed from the back-adjusted series passes every spot check anyone would actually run, and silently -corrupts the entire history a backtest is evaluated over. Crude's back-adjusted series even -reaches **-27.52**, which is not a price. +corrupts the entire history a backtest is evaluated over. + +> **Corrected 2026-08-01**, by a test failing against real data. An earlier version of this +> paragraph said crude's back-adjusted series "reaches -27.52, which is not a price", +> attributing it to additive back-adjustment accumulating roll gaps below zero over +> decades. The number is right, the explanation was wrong, and the real one is a better +> argument. +> +> Both series bottom in **April 2020**. What happens is that the single enormous roll gap +> out of the May 2020 contract, which settled at **-37.63**, is propagated backwards +> through every earlier bar. The sharpest row in the store is **2020-04-21**: crude traded +> at **+11.57**, a perfectly ordinary positive price, while the back-adjusted bar for the +> same day reads **-27.52**. Crude was genuinely below zero on **exactly one day**; the +> back-adjusted series is below zero on **64**. +> +> A second claim in the same vein was also wrong: the unadjusted series *can* be negative, +> because 2020-04-20 really happened. So a negative price is not by itself evidence of the +> wrong series, and normalisation code must not clip or reject one. On that day a LONG +> position genuinely had negative notional. What identifies the artifact is that it reports +> a negative price on days the market was positive. Meanwhile volatility must come from the **back-adjusted** series, because that is the one with correct returns; unadjusted returns carry fake roll gaps.