Module 9 · Lesson 12 of 12 · Futures · About 5 minutes

Seasonality in Futures: Patterns, Causes and Limits

On this page
  1. What you will learn
  2. Why would a market have seasons?
  3. How is a seasonal chart built?
  4. Seasonality diagram
  5. What are the limits?
  6. What this does not tell you about seasonality
  7. Method in Practice
  8. Check yourself
  9. Reflect on your own process
  10. Sources

Before you read: Calendar Spreads and the Forward Curve in Futures

What you will learn

  • What seasonality describes and why some commodities have seasonal supply and demand.
  • How a seasonal chart averages past years, and what averaging hides.
  • Why seasonal tendencies often appear in the forward curve already.

Why would a market have seasons?

Why might natural gas behave differently in January than in May?

Seasonality groups observations by recurring calendar position. A structural explanation is a separate hypothesis: for example, planting/harvest can change grain supply and storage needs in particular crops and regions. Old-crop/new-crop contracts can represent different supply contexts. Calendar alignment alone does not prove that mechanism, a repeated price return or a tradable advantage. Different hemispheres, weather, inventories, policy and already-priced expectations can change the relationship. Crop-calendar data, such as the USDA’s Usual Planting and Harvesting Dates for U.S. Field Crops, supplies context, not return probabilities for the invented dataset below.

How is a seasonal chart built?

What does a line labeled “15-year average” actually show?

Declare series, selection, alignment, normalization and missing-data policy before averaging. Here is a fully supplied fictional example, not a 15-year study.

Predeclared design: one dummy product. For every study year use its same relative Month+2 expiry, selected before Month M begins and retained at all three checkpoints; no within-window contract switch. Checkpoints are the 1st, 6th and 11th exchange-business-day observations of Month M, labeled D0/D5/D10. We choose business-day offsets, not identical month/day dates or an interchangeable calendar-day clock. These quote paths measure a fixed-expiry price index, not returns on a margin deposit or a fully funded rolling portfolio.

Train on complete years A/B/C. Exclude year X from the whole three-point training curve under a predeclared complete-window rule because D5 is missing; disclose that missingness can itself be selective. Freeze this policy before opening holdout H. All prices below are invented quote units, not named futures or observations.

Year / use D0 price D5 price D10 price Contract policy
A/train 50 55 60 Same Month+2 expiry within year
B/train 100 90 80 Same rule
C/train 200 220 260 Same rule
X/excluded 80 MISSING 96 Same rule; not zero-imputed
H/held out 80 84 76 Same rule; not used to build training curve

Normalize each year to 100 at D0: I(y,d)=100×P(y,d)/P(y,D0). Valid positive starting prices are assumed; ratio normalization is inappropriate for zero/negative or arbitrarily shifted back-adjusted bases without another declared method.

Year D0 index D5 index D10 index End change from own start
A 100 110 120 +20%
B 100 90 80 −20%
C 100 110 130 +30%
X/excluded 100 missing 120 +20%, not included
H/holdout 100 105 95 −5%
Equal-year TRAINING mean 100 (110+90+110)/3=103.3333 (120+80+130)/3=110 +10%

Example arithmetic: A at D5=100×55/50=110; C at D10=100×260/200=130. Training end range is 80–130; one of three complete training years falls 20% despite the average rising 10%. Two of three rise in these supplied rows; that is a description of these toy rows, not a forward probability. Raw-level averaging gives total starting prices 350 and ending 400, hence (400/350−1)×100=14.2857%, a different weighting/statistic from the equal-year normalized 10%.

Missingness counterexample: including X only at D10 changes that endpoint mean to (120+80+130+120)/4=112.5 while D5 still uses three years. That unbalanced line has changing composition. Our chosen complete-window rule instead uses n=3 throughout, but does not make missingness harmless; show exclusions and investigate their reasons in actual research. Missing is not zero and interpolation is an assumption, not an observed price.

Holdout comparison: policy frozen, H ends 95, or −5%, versus the training end mean 110. The average did not predict this next invented year. Do not tune the window/expiry rule on H and continue calling it a pristine holdout.

If a longer window requires a roll: state the roll date/expiry-selection rule and how levels or returns are joined. An instantaneous old 100/new 103 quote switch produces a raw splice jump of 3% even if neither contract changes. A declared ratio-spliced price index can instead keep index 100 at the switch and, if the same new contract next rises 103→104, update to 100×104/103=100.970874. That is a price-relative index, not a cash payment on rolling or an account return. Our main table needs no adjustment because each year uses one fixed expiry. Different back/ratio-adjustment choices change the statistic; do not mix them silently. See Futures Expiration, Rollover and Continuous Charts and Calendar Spreads and the Forward Curve in Futures.

Seasonality diagram

Left: a line chart of the normalized index (D0 = 100) at three business-day offsets in Month M, D0, D5 and D10. Training years A (100, 110, 120), B (100, 90, 80) and C (100, 110, 130) sit inside a shaded min/max envelope; the thick training mean runs 100, 103.3333, 110; the dashed held-out year H runs 100, 105, 95. Labels mark 100 (all) at D0, 110 (A/C) at D5 and the end values 130, 120, 110, 95 and 80. Right: a table of all normalized index inputs for A, B, C, the training mean, H held out and X excluded (100, missing, 120). Below it, a separate X inset: points 100 at D0 and 120 at D10 with no connecting line, and D5 marked missing below the axis.
Read the diagram step by step
  1. Authored fiction. Education only; no observed results or predictive guarantee.
  2. Frozen training / holdout design
  3. Dummy product; same relative Month+2 expiry kept within each year. Month M business-day offsets D0/D5/D10 are the 1st/6th/11th observations. Index I=100×P/P(D0), positive start assumed. Train on complete A/B/C only; freeze policy before opening H.
  4. POINTWISE min/max · NOT confidence
  5. Envelope uses only the THREE training years at each checkpoint. It is not a probability interval or a ten-year historical study. Lines connect supplied checkpoints; no other observations are supplied.
  6. Equal-year TRAINING mean (bold)
  7. H held out, NOT used in training
  8. Outlined envelope: pointwise training minimum/maximum, NOT a confidence band.
  9. X excluded from the WHOLE window
  10. Predeclared complete-window rule: X 100 / MISSING / 120. D5 is missing—not zero and not interpolated. Training n=3 stays the same at all checkpoints; missingness can still be selective.
  11. Separate X inset · NO connecting path
  12. D5 marker is outside the value plot: no observed index value is assigned.
  13. All points come from the displayed fixed-expiry fictional table. Training mean rises while B falls; held-out H also falls. No ten-year data, empirical probability or confidence interval is implied.

Illustrative diagram constructed for teaching. Not real market data.

All points come from the displayed fixed-expiry fictional table. Training mean rises while B falls; held-out H also falls. No ten-year data, empirical probability or confidence interval is implied.

What are the limits?

If everyone knows about a seasonal pattern, where does it show up?

Calendar grouping, a plausible physical driver and a forecasting claim are three different statements. Month+2 contract choice controls part of the example’s exposure; it does not prove identical carry, inventories or delivery context across years. A known seasonal supply pattern can already affect forward prices, so a calendar label is not free information about excess returns.

Tiny samples, outlier years, omitted observations and selecting months/roll rules after seeing the result can create persuasive averages without predictive content. Predeclare whether seasonal windows are calendar dates, business-day offsets or crop-year stages; preserve sample counts, dispersion, selection rules and holdouts. Do not multiply the number of nearly identical tested windows into independent evidence. This toy exercise does not validate a seasonal trade, historical hit rate or live result. See Trading Plans, Journaling and Honest Backtesting and Overfitting and Repainting: When Indicator Results Look Too Good for the already-developed testing/bias distinctions.

What this does not tell you about seasonality

  • What any market will do this year.
  • Whether a seasonal tendency is already priced in.
  • Real seasonal data. Sources include exchange and government reports.
  • Nothing here suggests any trade.

Method in Practice: tested across years, including a failed one

Fictional example. John, Harbor Index futures, the prices, times, costs and results are all invented for teaching. This shows how a written plan can be built and tested. It is not a recommendation, and nothing here says how often this idea works.

Try it on a real chart. Test this idea yourself on past sessions with bar replay. Keep your own count, including the days with no trade.

The idea. A seasonal pattern is a count of past years (this lesson). John tests "the second half of December rose in most years" with his own rule and costs, and looks hardest at the worst year.

Three outcomes (invented numbers: this shows how to count, not how the method performs)

  • Up years: 6 of 10

  • The failed year: year 6 fell 3.2 points, the stop filled past its price, and the loss used the whole cap

  • After costs, all 10 years: +$155 in total, on 1 contract

Show the count

(buy 1 contract at the close of the 11th trading day of December, sell at the close of the year's last trading day, stop 1.30 points below entry, planned loss $140)

Year12345678910
Net after costs+$95+$140−$40+$60+$115−$150+$85−$75+$30−$105

Total +$155. Year 6's stop at −1.30 filled at −1.45 in a fast drop: −$145 − $5 = −$150, more than the planned $140 and the whole cap. Journal: "The seasonal 'rule' made $155 in ten years, and one year took $150 of it. I'm not trading it."

Test it yourself

  • Write the dates, entry, exit and stop before counting the years.
  • Include every year, especially the bad ones.
  • Ask what the same dates would show in a market with no reason to be seasonal.

Where it breaks

  • Ten years is ten cases.
  • One bad year can erase several good ones.
  • The calendar can line up with other events that change from year to year.

Reflection question: For any seasonal belief you hold, how many years have you counted, and which was the worst?

Check yourself

  1. Compute C’s D10 index and the balanced training mean at D10. Hint: individual years.
  2. Why not replace X’s missing middle observation with 0? What if only its endpoint is added?
  3. Does old 100/new 103 at a roll imply a 3% earned return?
  4. What does holdout H’s 95 ending index establish?
  5. Name two physical mechanisms that could contribute to commodity seasonality without promising a price direction. Hint: harvests, weather.
  6. Why can a well-known seasonal condition already affect later-month futures prices, and why is recognizing the condition not automatically an excess return? Hint: the forward curve.

Reflect on your own process

For your own notes; there is no score and no right answer.

  1. Before you look at any seasonal chart, what does your written research plan say about window, contract choice and missing data?
  2. How do you record which years were excluded from an average, and why?
  3. Where in your journal would you keep a holdout year separate from the years you used to build a pattern?
  4. For any seasonal belief you hold, how many years have you counted, and which was the worst?

Sources

Last reviewed . Spotted a mistake? Report an error.