A continuous futures series joins successive expiring contracts into one history. You can use that history to research signals, but calculating trading P&L directly from its price changes can manufacture gains and losses at every roll. The series doesn't tell you which contract you owned.
Take a particularly unforgiving example: NYMEX WTI crude oil on April 20, 2020. The May contract settled at negative $37.63 per barrel. June settled at positive $20.43. Both prices were real. The $58.06 between them was real, too. But switching a chart from May to June didn't earn a long position that difference.
Let's take that splice apart. These are historical settlement prices; the hypothetical accounting examples below use them to expose the arithmetic, not to claim that an order could have filled there.
CLK20 and CLM20: the identifiers the chart dropped
| Field | May contract | June contract |
|---|---|---|
| Contract identifier | CLK20 | CLM20 |
| Delivery month | May 2020 | June 2020 |
| April 20 settlement, dollars per barrel | −37.63 | 20.43 |
| Contract size | 1,000 barrels | 1,000 barrels |
The month code matters more than the ticker prefix. K means May; M means June. These contracts had different delivery obligations and different prices. May was approaching expiration amid extraordinary storage pressure. June bought another month.
A vendor's continuous symbol hides this distinction behind something pleasantly compact. I like compact symbols until they're the only identifier left in the trade log. Then debugging starts to resemble archaeology, with worse coffee.
Nor is there one universal continuous history. A vendor might roll a fixed number of business days before expiration, on a volume crossover, or according to another schedule. Many histories had already moved out of May before April 20. Our example deliberately splices these two settlements to make the failure visible; it isn't a claim about any particular vendor's roll.
1,000 barrels: the multiplier underneath each price
The standard NYMEX WTI futures contract represents 1,000 barrels. A $1 move therefore changes the value of a one-contract long by $1,000. A $0.01 tick is $10.
For an unchanged position in one contract, the basic calculation is:
gross_pnl = contracts × 1,000 × (ending_price − starting_price)
This still works below zero. Percentage returns on the quoted futures price become much less useful: crossing zero can make them undefined or reverse their apparent meaning. Strategy returns should come from the account's equity and cash-flow convention. The quoted barrel price isn't the capital committed to the strategy.
$58.06: the discontinuity at the splice
Suppose a naïve engine sees May's settlement followed by June's settlement and applies that formula as though the instrument hadn't changed:
invented_pnl = 1 × 1,000 × (20.43 − (−37.63))
= $58,060
Nothing moved through time in this comparison. Those are two contracts' prices from the same session. The engine has mistaken a cross-contract price difference for a holding-period gain.
In an actual daily splice, yesterday's old-contract price and today's new-contract price also contain ordinary market movement. That makes the mistake harder to see. The recorded change combines the old contract's movement with the difference between contracts at the switch.
And subtracting $58,060 as a supposed cash “roll cost” doesn't repair the model either. Futures aren't purchased by paying their full quoted notional. Closing one contract and opening another produces position changes, realized or settled P&L, fees, execution effects and margin requirements. The gap between their price levels isn't automatically a cash debit.
+58.06: the back-adjustment written into history
One common continuous-series construction adds the roll gap to earlier prices. Under that convention, May's −37.63 becomes 20.43, meeting June without a jump. Earlier observations in the same historical segment also move up by 58.06.
| Construction | What happens at this splice | Research consequence |
|---|---|---|
| Unadjusted | The $58.06 gap remains | Indicators can interpret the contract switch as a market move |
| Additive back-adjustment | Add 58.06 to the older segment | Within-segment dollar changes survive; historical levels and percentage changes shift |
| Ratio back-adjustment | Multiply the older segment by 20.43 / −37.63, approximately −0.543 | The negative factor reverses the sign of within-segment price changes |
That last row is why I won't accept “ratio-adjusted” as a complete data specification. A method that behaves sensibly with strictly positive prices needs an explicit policy around zero and negative prices.
Additive adjustment has its own consequences. A signal that buys below an absolute $30 threshold can change when later rolls rewrite earlier levels. A fast-minus-slow moving-average signal may be invariant to a common additive shift, provided both windows receive the same shift. Windows crossing an adjustment boundary need separate examination.
Keep the adjustment method, roll schedule and data version with the research result. For signals sensitive to adjusted levels, reconstruct the history available at each decision date. A current download may contain adjustments from rolls that hadn't happened yet.
The two order rows missing from the continuous chart
Here is a deliberately simplified ledger. Assume one May contract was marked at −30.00 before the roll. Assume the May exit and June entry occur at the historical settlements above, then June is marked at 21.00. Those assumed fills are an accounting illustration.
| Ledger event | Calculation | Gross P&L |
|---|---|---|
| Close one May long at −37.63 | 1,000 × (−37.63 − (−30.00)) | −$7,630 |
| Open one June long at 20.43 | No price movement at entry | $0 |
| Mark June at 21.00 | 1,000 × (21.00 − 20.43) | +$570 |
| Total | Before execution costs and fees | −$7,060 |
The $58.06 gap appears nowhere as standalone earnings or expense. Daily variation margin determines when futures P&L reaches cash; it doesn't create a second copy of that P&L.
A real roll may execute through a calendar-spread order rather than two independent orders. The simulator should represent whichever mechanism it assumes, including its fills and charges, while preserving the individual contract positions underneath.
My acceptance check is simple: every dollar of futures trading P&L must reconcile to a named contract, a quantity, a multiplier and two prices belonging to that contract. I also want the roll decision timestamp and its inputs. A volume-based rule using today's completed session volume cannot quietly trade earlier that same session.
Plot the continuous line for context. Under it, plot the contracts actually held and mark each transition. If the equity curve jumps at a transition, those two order rows are the first place I look.
← All posts


