Causal Forecasting

Causal forecast, drivers and benchmarking

A causal SARIMAX per fuel takes the DAG-selected drivers as regressors and is scored against the baseline on identical rolling-origin backtests, ten training-window and horizon combinations per fuel.

Best causal run per fuel, against the benchmark

Blue is actual demand, green is the baseline forecast (drivers held at their last value) with its 95% interval. Scenario percentages are each branch's largest deviation from the baseline inside its horizon.

Gasoline0.783 MASE
Beats the benchmark (SARIMAX, MASE 0.848) by +7.6%
Next 12 weeks: average 8,733 kb/d↓ 2.7% vs last actual
Peak vs baseline →Oil Shock: -0.4%Refinery Down: +0.1%Slowdown: +0.9%
Gasoline0.686 MASE
Beats the benchmark (SARIMAX, MASE 0.717) by +4.3%
Next 24 weeks: average 8,602 kb/d↓ 4.3% vs last actual
Peak vs baseline →Oil Shock: -0.4%Refinery Down: +1.1%Slowdown: +0.9%
All runs, drivers and scenarios →
Distillate (diesel)0.829 MASE
Beats the benchmark (SARIMAX, MASE 0.844) by +1.9%
Next 12 weeks: average 3,969 kb/d↑ 1.1% vs last actual
Peak vs baseline →Oil Shock: +0.2%Refinery Down: -3.4%Slowdown: -3.2%
Distillate (diesel)0.833 MASE
Beats the benchmark (SARIMAX, MASE 0.836) by +0.3%
Next 24 weeks: average 3,938 kb/d↑ 2.9% vs last actual
Peak vs baseline →Oil Shock: +0.2%Refinery Down: -2.7%Slowdown: -3.2%
All runs, drivers and scenarios →
Jet fuel0.774 MASE
Beats the benchmark (ETS, MASE 0.792) by +2.3%
Next 12 weeks: average 1,708 kb/d↑ 3.3% vs last actual
Peak vs baseline →Oil Shock: +0.3%Refinery Down: -2.3%Slowdown: -2.7%
Jet fuel0.725 MASE
Beats the benchmark (SARIMAX, MASE 0.827) by +12.3%
Next 24 weeks: average 1,736 kb/d↑ 1.9% vs last actual
Peak vs baseline →Oil Shock: +0.3%Refinery Down: -4.0%Slowdown: -2.7%
All runs, drivers and scenarios →

All runs, drivers and scenarios per fuel

Same ten windows and horizons as the benchmark. MASE is scored with drivers held at their last value, so it is directly comparable with the benchmark; the known-drivers score is the upper bound.

Causal SARIMAX, trained from 2005, 12-week horizon: test MASE 0.783 with drivers held (known: 0.720).
Beats the benchmark (SARIMAX, MASE 0.848) by +7.6%. Beats seasonal-naive by 22%.
p=1 d=1 q=1 K=6 trend=n log=True · drivers: p_gas_l8, vmt_l0, ev_demand_l0, ev_supply_l0

All runs, 12 weeks

WindowHorizonMASE (held)MASE (known)MASE (blend)MAPE (held)Benchmark MASEvs benchmark
200012w0.7850.7760.7783.07%0.836 (SARIMAX)+6.1%
200512w0.7830.7200.7803.10%0.848 (SARIMAX)+7.6%best
201012w0.7870.7450.7753.11%0.818 (SARIMAX)+3.7%
201512w0.8540.8420.8393.33%0.839 (SARIMAX)-1.8%
202012w0.8500.8560.8633.37%1.067 (ETS)+20.3%

Best run: 2005, 12 weeks

Drag to zoom, double-click to reset, click legend entries to hide series. Solid test line: future drivers held at their last value (honest). Dashed: actual future drivers fed in (upper bound).

Bars split each week's forecast change against the last actual week into seasonality, each driver family and the underlying level/trend; the line is the net change.

Driver coefficients

DriverFitted coefficientWhat it means
X - Prices: retail gasoline price (8-week lag)elasticity -0.028 (not significant)A 10% rise in retail gasoline price (8-week lag) moves demand -0.3%.
X - Activity: vehicle miles travelled (mobility) (same week)elasticity +0.449 (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +4.5%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-4.9% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -4.9% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-0.0% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -0.0% vs a normal week.

What each model component contributes

ComponentFitted valuesWhat it explains
AR - autoregressivep=1 (coef +0.31)Momentum: this week's forecast leans on the previous 1 week of demand with these weights.
I - integrated / trendd=1The model forecasts week-over-week changes, so the latest level is the baseline.
MA - moving averageq=1 (coef -0.90)Shock smoothing: forecast errors from the last 1 week adjust this week's forecast.
S - seasonality (via X)K=6 Fourier pairs, 5.0% peak-to-troughRepeating yearly cycle - the calendar's contribution to demand.
X - Prices: retail gasoline price (8-week lag)elasticity -0.028 (not significant)A 10% rise in retail gasoline price (8-week lag) moves demand -0.3%.
X - Activity: vehicle miles travelled (mobility) (same week)elasticity +0.449 (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +4.5%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-4.9% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -4.9% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-0.0% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -0.0% vs a normal week.

Causal effects from the DAG (DoWhy)

EstimandAdjust for (backdoor)CoefficientEffect of the scenario shockRefutations (should be near 0 / unchanged)Sensitivity
WTI +25% -> gasoline demand (8-week lag)crude_prod, crude_stk, macro-0.0162 (p=0.003)-0.36%placebo +0.000 · subset -0.017 · +cause -0.016[-0.154, -0.018] · 5 valid sets: [-0.016, -0.016]
IPI -5% -> gasoline demand (4-week lag)ev_demand-0.1721 (p=0.668)+0.89%placebo +0.000 · subset -0.169 · +cause -0.173[-1.133, -0.225] · 3 valid sets: [-0.172, -0.172]
utilization -10 pts -> gasoline output(none needed)+0.0034 (p=0.000)-3.37%placebo -0.000 · subset +0.003 · +cause +0.003[+0.003, +0.004] · 10 valid sets: [+0.003, +0.003]

Coefficients are elasticities on year-on-year log changes (utilization in points), COVID window excluded. Placebo should be near 0; subset and random-cause should stay close to the estimate; the sweep shows the estimate's range under small unobserved confounders.

Same fitted model, four driver paths. Only the drivers change along each scenario's DAG chain.

BranchWhat changesPeak effect vs baselineWeek 12: forecast → effect
Oil ShockWTI +25% -> gasoline demand (8-week lag): DoWhy effect -0.36% (adjusted for crude_prod, crude_stk, macro), phased in over 8 weeks-32 (-0.36%) in week 118,421 → -30 (-0.36%)
Refinery Downutilization -10 pts -> supply-event flag on for 2 weeks, crack -3.4 $/bbl, p_gas -2.9%, p_dsl -3.6%, p_jet -5.6%+7 (+0.08%) in week 98,451 → +0 (+0.00%)
SlowdownIPI -5% -> gasoline demand (4-week lag): DoWhy effect +0.89% (adjusted for ev_demand), phased in over 4 weeks+78 (+0.89%) in week 118,526 → +75 (+0.89%)

Other runs

2000 · MASE 0.785 (drivers known 0.776)

p=3 d=1 q=2 K=6 trend=n log=False

2010 · MASE 0.787 (drivers known 0.745)

p=2 d=1 q=2 K=4 trend=n log=True

2015 · MASE 0.854 (drivers known 0.842)

p=3 d=1 q=2 K=6 trend=n log=False

2020 · MASE 0.850 (drivers known 0.856)

p=2 d=1 q=2 K=1 trend=t log=False

Causal SARIMAX, trained from 2000, 24-week horizon: test MASE 0.686 with drivers held (known: 0.701).
Beats the benchmark (SARIMAX, MASE 0.717) by +4.3%. Beats seasonal-naive by 31%.
p=3 d=1 q=2 K=6 trend=n log=False · drivers: p_gas_l8, vmt_l0, ev_demand_l0, ev_supply_l0

All runs, 24 weeks

WindowHorizonMASE (held)MASE (known)MASE (blend)MAPE (held)Benchmark MASEvs benchmark
200024w0.6860.7010.6922.79%0.717 (SARIMAX)+4.3%best
200524w0.7590.7100.7283.08%0.722 (SARIMAX)-5.1%
201024w0.7430.6980.7223.01%0.743 (SARIMAX)-0.1%
201524w0.7840.7050.7413.17%0.794 (SARIMAX)+1.2%
202024w0.7650.7490.8183.10%0.789 (SARIMAX)+3.0%

Best run: 2000, 24 weeks

Drag to zoom, double-click to reset, click legend entries to hide series. Solid test line: future drivers held at their last value (honest). Dashed: actual future drivers fed in (upper bound).

Bars split each week's forecast change against the last actual week into seasonality, each driver family and the underlying level/trend; the line is the net change.

Driver coefficients

DriverFitted coefficientWhat it means
X - Prices: retail gasoline price (8-week lag)+401.4 kbd per log-unit (significant)A 10% rise in retail gasoline price (8-week lag) moves demand +38 kbd.
X - Activity: vehicle miles travelled (mobility) (same week)+1539.7 kbd per log-unit (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +147 kbd.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)+8 kbd in flagged weeks (not significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs +8 kbd vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)+98 kbd in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs +98 kbd vs a normal week.

What each model component contributes

ComponentFitted valuesWhat it explains
AR - autoregressivep=3 (coef +0.98, -0.10, +0.01)Momentum: this week's forecast leans on the previous 3 weeks of demand with these weights.
I - integrated / trendd=1The model forecasts week-over-week changes, so the latest level is the baseline.
MA - moving averageq=2 (coef -1.60, +0.61)Shock smoothing: forecast errors from the last 2 weeks adjust this week's forecast.
S - seasonality (via X)K=6 Fourier pairs, 563 kbd peak-to-troughRepeating yearly cycle - the calendar's contribution to demand.
X - Prices: retail gasoline price (8-week lag)+401.4 kbd per log-unit (significant)A 10% rise in retail gasoline price (8-week lag) moves demand +38 kbd.
X - Activity: vehicle miles travelled (mobility) (same week)+1539.7 kbd per log-unit (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +147 kbd.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)+8 kbd in flagged weeks (not significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs +8 kbd vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)+98 kbd in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs +98 kbd vs a normal week.

Causal effects from the DAG (DoWhy)

EstimandAdjust for (backdoor)CoefficientEffect of the scenario shockRefutations (should be near 0 / unchanged)Sensitivity
WTI +25% -> gasoline demand (8-week lag)crude_prod, crude_stk, macro-0.0162 (p=0.003)-0.36%placebo +0.000 · subset -0.017 · +cause -0.016[-0.154, -0.018] · 5 valid sets: [-0.016, -0.016]
IPI -5% -> gasoline demand (4-week lag)ev_demand-0.1721 (p=0.668)+0.89%placebo +0.000 · subset -0.169 · +cause -0.173[-1.133, -0.225] · 3 valid sets: [-0.172, -0.172]
utilization -10 pts -> gasoline output(none needed)+0.0034 (p=0.000)-3.37%placebo -0.000 · subset +0.003 · +cause +0.003[+0.003, +0.004] · 10 valid sets: [+0.003, +0.003]

Coefficients are elasticities on year-on-year log changes (utilization in points), COVID window excluded. Placebo should be near 0; subset and random-cause should stay close to the estimate; the sweep shows the estimate's range under small unobserved confounders.

Same fitted model, four driver paths. Only the drivers change along each scenario's DAG chain.

BranchWhat changesPeak effect vs baselineWeek 24: forecast → effect
Oil ShockWTI +25% -> gasoline demand (8-week lag): DoWhy effect -0.36% (adjusted for crude_prod, crude_stk, macro), phased in over 8 weeks-32 (-0.36%) in week 118,286 → -30 (-0.36%)
Refinery Downutilization -10 pts -> supply-event flag on for 2 weeks, crack -3.4 $/bbl, p_gas -2.9%, p_dsl -3.6%, p_jet -5.6%+98 (+1.10%) in week 18,316 → +0 (+0.00%)
SlowdownIPI -5% -> gasoline demand (4-week lag): DoWhy effect +0.89% (adjusted for ev_demand), phased in over 4 weeks+78 (+0.89%) in week 118,390 → +74 (+0.89%)

Other runs

2005 · MASE 0.759 (drivers known 0.710)

p=2 d=1 q=2 K=4 trend=c log=True

2010 · MASE 0.743 (drivers known 0.698)

p=2 d=1 q=2 K=4 trend=c log=True

2015 · MASE 0.784 (drivers known 0.705)

p=3 d=1 q=3 K=4 trend=c log=True

2020 · MASE 0.765 (drivers known 0.749)

p=3 d=1 q=3 K=2 trend=c log=True

Causal SARIMAX, trained from 2020, 12-week horizon: test MASE 0.829 with drivers held (known: 0.841).
Beats the benchmark (SARIMAX, MASE 0.844) by +1.9%. Beats seasonal-naive by 17%.
p=2 d=1 q=3 K=3 trend=c log=True · drivers: hdd_anom_l0, ev_demand_l0, ev_supply_l0, pmi_l13

All runs, 12 weeks

WindowHorizonMASE (held)MASE (known)MASE (blend)MAPE (held)Benchmark MASEvs benchmark
200012w0.8720.8840.8716.97%0.863 (SARIMAX)-1.1%
200512w0.9310.9380.9287.44%0.840 (SARIMAX)-10.8%
201012w0.9330.9470.9227.45%0.882 (SARIMAX)-5.8%
201512w0.8970.9080.8847.16%0.867 (SARIMAX)-3.5%
202012w0.8290.8410.8436.59%0.844 (SARIMAX)+1.9%best

Best run: 2020, 12 weeks

Drag to zoom, double-click to reset, click legend entries to hide series. Solid test line: future drivers held at their last value (honest). Dashed: actual future drivers fed in (upper bound).

Bars split each week's forecast change against the last actual week into seasonality, each driver family and the underlying level/trend; the line is the net change.

Driver coefficients

DriverFitted coefficientWhat it means
X - Weather: heating-degree-day anomaly (same week)+0.0413% per unit (not significant)Each unit of heating-degree-day anomaly (same week) moves demand +0.041%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-8.3% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -8.3% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-3.4% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -3.4% vs a normal week.
X - Activity: manufacturing PMI (leading) (13-week lag)elasticity +0.256 (significant)A 10% rise in manufacturing PMI (leading) (13-week lag) moves demand +2.6%.

What each model component contributes

ComponentFitted valuesWhat it explains
AR - autoregressivep=2 (coef -0.09, -0.73)Momentum: this week's forecast leans on the previous 2 weeks of demand with these weights.
I - integrated / trendd=1, intercept -4.45e-07The model forecasts week-over-week changes, so the latest level is the baseline. A fitted baseline trend is added on top.
MA - moving averageq=3 (coef -0.81, +0.56, -0.74)Shock smoothing: forecast errors from the last 3 weeks adjust this week's forecast.
S - seasonality (via X)K=3 Fourier pairs, 11.1% peak-to-troughRepeating yearly cycle - the calendar's contribution to demand.
X - Weather: heating-degree-day anomaly (same week)+0.0413% per unit (not significant)Each unit of heating-degree-day anomaly (same week) moves demand +0.041%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-8.3% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -8.3% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-3.4% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -3.4% vs a normal week.
X - Activity: manufacturing PMI (leading) (13-week lag)elasticity +0.256 (significant)A 10% rise in manufacturing PMI (leading) (13-week lag) moves demand +2.6%.

Causal effects from the DAG (DoWhy)

EstimandAdjust for (backdoor)CoefficientEffect of the scenario shockRefutations (should be near 0 / unchanged)Sensitivity
WTI +25% -> distillate demand (8-week lag)crude_prod, crude_stk, macro+0.0106 (p=0.560)+0.24%placebo +0.002 · subset +0.012 · +cause +0.011[-0.103, +0.006] · 5 valid sets: [+0.011, +0.011]
IPI -5% -> distillate demand (4-week lag)(none needed)+0.6295 (p=0.012)-3.18%placebo +0.011 · subset +0.632 · +cause +0.628[-0.853, +0.220] · 24 valid sets: [+0.629, +0.629]
utilization -10 pts -> distillate output(none needed)+0.0098 (p=0.000)-9.31%placebo +0.000 · subset +0.010 · +cause +0.010[+0.009, +0.010] · 10 valid sets: [+0.010, +0.010]

Coefficients are elasticities on year-on-year log changes (utilization in points), COVID window excluded. Placebo should be near 0; subset and random-cause should stay close to the estimate; the sweep shows the estimate's range under small unobserved confounders.

Same fitted model, four driver paths. Only the drivers change along each scenario's DAG chain.

BranchWhat changesPeak effect vs baselineWeek 12: forecast → effect
Oil ShockWTI +25% -> distillate demand (8-week lag): DoWhy effect +0.24% (adjusted for crude_prod, crude_stk, macro), phased in over 8 weeks+10 (+0.24%) in week 94,007 → +10 (+0.24%)
Refinery Downutilization -10 pts -> supply-event flag on for 2 weeks, crack -3.4 $/bbl, p_gas -2.9%, p_dsl -3.6%, p_jet -5.6%-132 (-3.42%) in week 23,998 → +0 (+0.00%)
SlowdownIPI -5% -> distillate demand (4-week lag): DoWhy effect -3.18% (adjusted for (none needed)), phased in over 4 weeks-130 (-3.18%) in week 93,871 → -127 (-3.18%)

Other runs

2000 · MASE 0.872 (drivers known 0.884)

p=2 d=1 q=3 K=3 trend=c log=True

2005 · MASE 0.931 (drivers known 0.938)

p=2 d=1 q=3 K=4 trend=n log=False

2010 · MASE 0.933 (drivers known 0.947)

p=2 d=1 q=3 K=3 trend=n log=False

2015 · MASE 0.897 (drivers known 0.908)

p=2 d=1 q=3 K=4 trend=n log=False

Causal SARIMAX, trained from 2020, 24-week horizon: test MASE 0.833 with drivers held (known: 0.843).
Beats the benchmark (SARIMAX, MASE 0.836) by +0.3%. Beats seasonal-naive by 17%.
p=0 d=1 q=1 K=3 trend=n log=True · drivers: hdd_anom_l0, ev_demand_l0, ev_supply_l0, pmi_l13

All runs, 24 weeks

WindowHorizonMASE (held)MASE (known)MASE (blend)MAPE (held)Benchmark MASEvs benchmark
200024w0.8470.8550.8496.85%0.819 (SARIMAX)-3.4%
200524w0.8830.8900.8837.17%0.836 (SARIMAX)-5.6%
201024w0.8960.9070.8937.27%0.857 (SARIMAX)-4.6%
201524w0.8710.8810.8637.06%0.891 (ETS)+2.3%
202024w0.8330.8430.8396.73%0.836 (SARIMAX)+0.3%best

Best run: 2020, 24 weeks

Drag to zoom, double-click to reset, click legend entries to hide series. Solid test line: future drivers held at their last value (honest). Dashed: actual future drivers fed in (upper bound).

Bars split each week's forecast change against the last actual week into seasonality, each driver family and the underlying level/trend; the line is the net change.

Driver coefficients

DriverFitted coefficientWhat it means
X - Weather: heating-degree-day anomaly (same week)+0.0451% per unit (not significant)Each unit of heating-degree-day anomaly (same week) moves demand +0.045%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-8.3% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -8.3% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-2.7% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -2.7% vs a normal week.
X - Activity: manufacturing PMI (leading) (13-week lag)elasticity +0.260 (significant)A 10% rise in manufacturing PMI (leading) (13-week lag) moves demand +2.6%.

What each model component contributes

ComponentFitted valuesWhat it explains
AR - autoregressivep=0Not used: no direct carry-over from recent weeks.
I - integrated / trendd=1The model forecasts week-over-week changes, so the latest level is the baseline.
MA - moving averageq=1 (coef -1.00)Shock smoothing: forecast errors from the last 1 week adjust this week's forecast.
S - seasonality (via X)K=3 Fourier pairs, 11.0% peak-to-troughRepeating yearly cycle - the calendar's contribution to demand.
X - Weather: heating-degree-day anomaly (same week)+0.0451% per unit (not significant)Each unit of heating-degree-day anomaly (same week) moves demand +0.045%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-8.3% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -8.3% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-2.7% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -2.7% vs a normal week.
X - Activity: manufacturing PMI (leading) (13-week lag)elasticity +0.260 (significant)A 10% rise in manufacturing PMI (leading) (13-week lag) moves demand +2.6%.

Causal effects from the DAG (DoWhy)

EstimandAdjust for (backdoor)CoefficientEffect of the scenario shockRefutations (should be near 0 / unchanged)Sensitivity
WTI +25% -> distillate demand (8-week lag)crude_prod, crude_stk, macro+0.0106 (p=0.560)+0.24%placebo +0.002 · subset +0.012 · +cause +0.011[-0.103, +0.006] · 5 valid sets: [+0.011, +0.011]
IPI -5% -> distillate demand (4-week lag)(none needed)+0.6295 (p=0.012)-3.18%placebo +0.011 · subset +0.632 · +cause +0.628[-0.853, +0.220] · 24 valid sets: [+0.629, +0.629]
utilization -10 pts -> distillate output(none needed)+0.0098 (p=0.000)-9.31%placebo +0.000 · subset +0.010 · +cause +0.010[+0.009, +0.010] · 10 valid sets: [+0.010, +0.010]

Coefficients are elasticities on year-on-year log changes (utilization in points), COVID window excluded. Placebo should be near 0; subset and random-cause should stay close to the estimate; the sweep shows the estimate's range under small unobserved confounders.

Same fitted model, four driver paths. Only the drivers change along each scenario's DAG chain.

BranchWhat changesPeak effect vs baselineWeek 24: forecast → effect
Oil ShockWTI +25% -> distillate demand (8-week lag): DoWhy effect +0.24% (adjusted for crude_prod, crude_stk, macro), phased in over 8 weeks+10 (+0.24%) in week 84,076 → +10 (+0.24%)
Refinery Downutilization -10 pts -> supply-event flag on for 2 weeks, crack -3.4 $/bbl, p_gas -2.9%, p_dsl -3.6%, p_jet -5.6%-104 (-2.73%) in week 24,067 → +0 (+0.00%)
SlowdownIPI -5% -> distillate demand (4-week lag): DoWhy effect -3.18% (adjusted for (none needed)), phased in over 4 weeks-130 (-3.18%) in week 93,937 → -129 (-3.18%)

Other runs

2000 · MASE 0.847 (drivers known 0.855)

p=2 d=1 q=2 K=3 trend=c log=True

2005 · MASE 0.883 (drivers known 0.890)

p=2 d=1 q=2 K=3 trend=n log=False

2010 · MASE 0.896 (drivers known 0.907)

p=1 d=1 q=1 K=3 trend=c log=False

2015 · MASE 0.871 (drivers known 0.881)

p=2 d=1 q=3 K=3 trend=n log=False

Causal SARIMAX, trained from 2010, 12-week horizon: test MASE 0.774 with drivers held (known: 0.747).
Beats the benchmark (ETS, MASE 0.792) by +2.3%. Beats seasonal-naive by 23%.
p=2 d=1 q=2 K=3 trend=n log=True · drivers: vmt_l0, emp_l4, ev_demand_l0, ev_supply_l0

All runs, 12 weeks

WindowHorizonMASE (held)MASE (known)MASE (blend)MAPE (held)Benchmark MASEvs benchmark
200012w0.8050.7760.7907.01%0.783 (SARIMAX)-2.8%
200512w0.7930.7600.7766.91%0.773 (SARIMAX)-2.6%
201012w0.7740.7470.7936.76%0.792 (ETS)+2.3%best
201512w0.8000.7530.8227.00%0.845 (ETS)+5.4%
202012w0.8250.7580.8727.25%0.825 (ETS)-0.0%

Best run: 2010, 12 weeks

Drag to zoom, double-click to reset, click legend entries to hide series. Solid test line: future drivers held at their last value (honest). Dashed: actual future drivers fed in (upper bound).

Bars split each week's forecast change against the last actual week into seasonality, each driver family and the underlying level/trend; the line is the net change.

Driver coefficients

DriverFitted coefficientWhat it means
X - Activity: vehicle miles travelled (mobility) (same week)elasticity +0.536 (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +5.4%.
X - Activity: employment level (macro) (4-week lag)elasticity +3.864 (significant)A 10% rise in employment level (macro) (4-week lag) moves demand +38.6%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-23.1% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -23.1% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-2.3% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -2.3% vs a normal week.

What each model component contributes

ComponentFitted valuesWhat it explains
AR - autoregressivep=2 (coef +0.15, -0.01)Momentum: this week's forecast leans on the previous 2 weeks of demand with these weights.
I - integrated / trendd=1The model forecasts week-over-week changes, so the latest level is the baseline.
MA - moving averageq=2 (coef -1.19, +0.26)Shock smoothing: forecast errors from the last 2 weeks adjust this week's forecast.
S - seasonality (via X)K=3 Fourier pairs, 8.5% peak-to-troughRepeating yearly cycle - the calendar's contribution to demand.
X - Activity: vehicle miles travelled (mobility) (same week)elasticity +0.536 (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +5.4%.
X - Activity: employment level (macro) (4-week lag)elasticity +3.864 (significant)A 10% rise in employment level (macro) (4-week lag) moves demand +38.6%.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-23.1% in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -23.1% vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-2.3% in flagged weeks (not significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -2.3% vs a normal week.

Causal effects from the DAG (DoWhy)

EstimandAdjust for (backdoor)CoefficientEffect of the scenario shockRefutations (should be near 0 / unchanged)Sensitivity
WTI +25% -> jet demand (8-week lag)crude_prod, crude_stk, macro+0.0141 (p=0.109)+0.32%placebo -0.004 · subset +0.013 · +cause +0.014[-0.114, +0.012] · 5 valid sets: [+0.014, +0.014]
IPI -5% -> jet demand (4-week lag)ev_demand+0.5371 (p=1.000)-2.72%placebo +0.028 · subset +0.551 · +cause +0.539[-0.958, +0.350] · 3 valid sets: [+0.537, +0.537]
utilization -10 pts -> jet output(none needed)+0.0156 (p=0.000)-14.47%placebo +0.000 · subset +0.016 · +cause +0.016[+0.015, +0.017] · 10 valid sets: [+0.016, +0.016]

Coefficients are elasticities on year-on-year log changes (utilization in points), COVID window excluded. Placebo should be near 0; subset and random-cause should stay close to the estimate; the sweep shows the estimate's range under small unobserved confounders.

Same fitted model, four driver paths. Only the drivers change along each scenario's DAG chain.

BranchWhat changesPeak effect vs baselineWeek 12: forecast → effect
Oil ShockWTI +25% -> jet demand (8-week lag): DoWhy effect +0.32% (adjusted for crude_prod, crude_stk, macro), phased in over 8 weeks+6 (+0.32%) in week 101,671 → +5 (+0.32%)
Refinery Downutilization -10 pts -> supply-event flag on for 2 weeks, crack -3.4 $/bbl, p_gas -2.9%, p_dsl -3.6%, p_jet -5.6%-41 (-2.29%) in week 11,666 → +0 (+0.00%)
SlowdownIPI -5% -> jet demand (4-week lag): DoWhy effect -2.72% (adjusted for ev_demand), phased in over 4 weeks-48 (-2.72%) in week 111,620 → -45 (-2.72%)

Other runs

2000 · MASE 0.805 (drivers known 0.776)

p=0 d=1 q=3 K=6 trend=n log=True

2005 · MASE 0.793 (drivers known 0.760)

p=0 d=1 q=1 K=5 trend=n log=True

2015 · MASE 0.800 (drivers known 0.753)

p=0 d=1 q=2 K=2 trend=n log=True

2020 · MASE 0.825 (drivers known 0.758)

p=0 d=1 q=2 K=2 trend=n log=True

Causal SARIMAX, trained from 2015, 24-week horizon: test MASE 0.725 with drivers held (known: 0.728).
Beats the benchmark (SARIMAX, MASE 0.827) by +12.3%. Beats seasonal-naive by 27%.
p=0 d=1 q=2 K=4 trend=n log=False · drivers: vmt_l0, emp_l4, ev_demand_l0, ev_supply_l0

All runs, 24 weeks

WindowHorizonMASE (held)MASE (known)MASE (blend)MAPE (held)Benchmark MASEvs benchmark
200024w0.7420.7380.7486.54%0.779 (ETS)+4.8%
200524w0.7370.7390.7446.49%0.764 (ETS)+3.6%
201024w0.7340.7570.7496.49%0.768 (ETS)+4.5%
201524w0.7250.7280.7636.39%0.827 (SARIMAX)+12.3%best
202024w0.7690.7380.8326.80%0.944 (SARIMAX)+18.5%

Best run: 2015, 24 weeks

Drag to zoom, double-click to reset, click legend entries to hide series. Solid test line: future drivers held at their last value (honest). Dashed: actual future drivers fed in (upper bound).

Bars split each week's forecast change against the last actual week into seasonality, each driver family and the underlying level/trend; the line is the net change.

Driver coefficients

DriverFitted coefficientWhat it means
X - Activity: vehicle miles travelled (mobility) (same week)+259.0 kbd per log-unit (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +25 kbd.
X - Activity: employment level (macro) (4-week lag)+1585.1 kbd per log-unit (significant)A 10% rise in employment level (macro) (4-week lag) moves demand +151 kbd.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-357 kbd in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -357 kbd vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-73 kbd in flagged weeks (significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -73 kbd vs a normal week.

What each model component contributes

ComponentFitted valuesWhat it explains
AR - autoregressivep=0Not used: no direct carry-over from recent weeks.
I - integrated / trendd=1The model forecasts week-over-week changes, so the latest level is the baseline.
MA - moving averageq=2 (coef -1.07, +0.22)Shock smoothing: forecast errors from the last 2 weeks adjust this week's forecast.
S - seasonality (via X)K=4 Fourier pairs, 141 kbd peak-to-troughRepeating yearly cycle - the calendar's contribution to demand.
X - Activity: vehicle miles travelled (mobility) (same week)+259.0 kbd per log-unit (significant)A 10% rise in vehicle miles travelled (mobility) (same week) moves demand +25 kbd.
X - Activity: employment level (macro) (4-week lag)+1585.1 kbd per log-unit (significant)A 10% rise in employment level (macro) (4-week lag) moves demand +151 kbd.
X - Events: demand-shock weeks (9/11, GFC, COVID) (same week)-357 kbd in flagged weeks (significant)Demand in demand-shock weeks (9/11, GFC, COVID) runs -357 kbd vs a normal week.
X - Events: supply-disruption weeks (hurricanes, freezes, outages) (same week)-73 kbd in flagged weeks (significant)Demand in supply-disruption weeks (hurricanes, freezes, outages) runs -73 kbd vs a normal week.

Causal effects from the DAG (DoWhy)

EstimandAdjust for (backdoor)CoefficientEffect of the scenario shockRefutations (should be near 0 / unchanged)Sensitivity
WTI +25% -> jet demand (8-week lag)crude_prod, crude_stk, macro+0.0141 (p=0.109)+0.32%placebo -0.004 · subset +0.013 · +cause +0.014[-0.114, +0.012] · 5 valid sets: [+0.014, +0.014]
IPI -5% -> jet demand (4-week lag)ev_demand+0.5371 (p=1.000)-2.72%placebo +0.028 · subset +0.551 · +cause +0.539[-0.958, +0.350] · 3 valid sets: [+0.537, +0.537]
utilization -10 pts -> jet output(none needed)+0.0156 (p=0.000)-14.47%placebo +0.000 · subset +0.016 · +cause +0.016[+0.015, +0.017] · 10 valid sets: [+0.016, +0.016]

Coefficients are elasticities on year-on-year log changes (utilization in points), COVID window excluded. Placebo should be near 0; subset and random-cause should stay close to the estimate; the sweep shows the estimate's range under small unobserved confounders.

Same fitted model, four driver paths. Only the drivers change along each scenario's DAG chain.

BranchWhat changesPeak effect vs baselineWeek 24: forecast → effect
Oil ShockWTI +25% -> jet demand (8-week lag): DoWhy effect +0.32% (adjusted for crude_prod, crude_stk, macro), phased in over 8 weeks+6 (+0.32%) in week 141,650 → +5 (+0.32%)
Refinery Downutilization -10 pts -> supply-event flag on for 2 weeks, crack -3.4 $/bbl, p_gas -2.9%, p_dsl -3.6%, p_jet -5.6%-73 (-3.98%) in week 11,644 → +0 (+0.00%)
SlowdownIPI -5% -> jet demand (4-week lag): DoWhy effect -2.72% (adjusted for ev_demand), phased in over 4 weeks-48 (-2.72%) in week 161,600 → -45 (-2.72%)

Other runs

2000 · MASE 0.742 (drivers known 0.738)

p=3 d=1 q=2 K=4 trend=n log=False

2005 · MASE 0.737 (drivers known 0.739)

p=3 d=1 q=2 K=5 trend=c log=False

2010 · MASE 0.734 (drivers known 0.757)

p=0 d=1 q=3 K=6 trend=n log=False

2020 · MASE 0.769 (drivers known 0.738)

p=1 d=1 q=3 K=1 trend=c log=False

Edge equations used by the scenarios

Slopes on year-on-year changes along each DAG edge, COVID window excluded.

EdgeSlopeUnitsStatus
wti->p_gas0.5499elasticity (log/log)ok
wti->p_dsl0.6109elasticity (log/log)ok
wti->p_jet1.022elasticity (log/log)ok
ipi->emp0.2436elasticity (log/log)ok
ipi->vmt0.1035elasticity (log/log)ok
util->crack0.3396$/bbl per utilization pointok
crack->p_gas0.0088log-price per $/bblok
crack->p_dsl0.0108log-price per $/bblok
crack->p_jet0.0169log-price per $/bblok

Stage 03Causal forecast, drivers and benchmarking

What goes into this stage, what happens, and what comes out.

What goes in

  • The weekly panel and the DAG shortlist of drivers
  • Baseline forecasts for the same windows

What happens

  • Tune orders and driver lags with Optuna, with differencing constrained to at least one
  • Project future driver values with seasonal naive plus drift, since real forecasts do not know them
  • Blend the causal and univariate forecasts and score both against the benchmark
  • Decompose each forecast into seasonality, trend and driver contributions

What comes out

  • Weekly forecasts with intervals per fuel
  • A driver decomposition that says why the number moved
  • A benchmark table: score and windows won per fuel
SARIMAX + driversOptunaSeasonal naive + driftDecompositionBenchmark tableSee all four stages on the home page →