Forward Price Projection

Forecast10-year price path under an export-restriction shock, with accuracy attribution

L2

How to read this output

The forecast result has 5 stat chips, a baseline-vs-scenario price chart, optional ±1σ confidence band, and a calibration-accuracy panel.

Direction↑/↓/flat at the peak of the scenario relative to baseline (price ratio > 1.05 / < 0.95 / between)

e.g. ↑ Up → scenario peak rose at least 5% above the no-shock counterfactual at that year

Peak vs baselinemax_t [ P_scenario(t) / P_baseline(t) ] in the post-shock horizon. The cleanest single number for "how big was the shock impact".

e.g. 1.68× means scenario price was at most 68% above the no-shock baseline at the peak year

Peak yearthe year where peak-vs-baseline was reached

e.g. Restriction starts 2025; peak year 2026 means price peaks one year into the restriction

Normalisesthe first year after the restriction ends from which scenario stays within ±10% of baseline for the rest of the horizon. "Never" means the model does not return to baseline within the simulated window.

e.g. 2030 (+3yr post-end) → 3 years after restriction end, prices return to within ±10% of where they would have been without the shock

Restrictionthe do(·) value and active years for the export-restriction shock

e.g. 30% · 2025–2027 → export_restriction pinned to 0.30 from 2025 through 2027 inclusive

CI band (gray fan)1σ confidence band from 24 parameter perturbations (±10% on α_P, η_D, τ_K). Wide band = forecast sensitive to calibration uncertainty.

e.g. If the band crosses the baseline line, the shock direction is not robust to parameter uncertainty

in_sample_DA / oos_DAhistorical directional accuracy of this commodity's calibration. 1.0 = perfect sign-of-change calls, 0.5 = chance.

e.g. graphite: in_sample 1.0, oos 0.467 → fits its own period perfectly but the regime shift makes cross-period transfer hard

Key takeaway: A high Peak vs baseline + late or 'Never' normalisation = severe scar from the shock. Use the CI band to gauge whether the headline direction is solid or marginal.

L2

What this page computes (thin L2 — supply-shock interventions only)

Formal: P(Y | do(export_restriction = m for years [t_a, t_b])) — restrict export supply, integrate ODE forward

Demand-side equation (price elasticity η_D enters here)

D_t  =  D_0 · g^t · (P_t / P_ref)^η_D
          · (1 − policy.substitution) · (1 − policy.efficiency)
          · (1 + demand_surge_t) · demand_destruction_mult_t

Supply-side equation (α_P, τ_K, capacity utilisation)

u_t   =  clamp( u_0 + β_u · log(P_t / P_ref),  u_min,  u_max )
Q_t   =  K_t · u_t
Q_eff,t = Q_t · (1 − shock.export_restriction_t)
          · policy_supply_mult_t · capacity_supply_mult_t

dK/dt =  (K_target(P_t) − K_t) / τ_K          [capacity adjusts at rate 1/τ_K]
dP/dt =  α_P · (shortage_t − λ_cover · inventory_gap_t) + σ_P · dW_t

Calibrated parameters {α_P, η_D, τ_K, g} per episode

Per-mineral values are fitted by differential evolution to maximise
DA + Spearman ρ vs. CEPII BACI bilateral unit values
(see src/minerals/predictability.py lines 71–89).

Caveat: This page is a convenience L2 interface for supply-shock interventions. For the canonical do-calculus surface — intervening on any structural parameter (η_D, τ_K, substitution_elasticity, fringe_capacity_share, …) via explicit graph surgery — use the L2 — Intervention page.

Source: src/minerals/model.py — step(); calibration in src/minerals/predictability.py

No forecast yet

Pick a commodity, year, and severity on the left, then click Run forecast.