Signal catalog

Generated 2026-08-11 04:05 UTC from the live server. Regenerate with flight/ops/gen_signal_catalog.py after any catalog change; --check fails if this file and the engine disagree.

53 signals · 16 contradictions · 35 producers · 57 aliases

Read the description, not the name. A name is shorthand; the description is what the predicate actually tests — including what it does NOT test.

Contradictions

A contradiction fires when every required signal fires and no excluded one does. Its name is printed verbatim as the report headline, so the name is published prose, not an internal label.

arb_shut_but_eu_drawing

crude_build_products_at_lows

diesel_clean_long

eu_comfortable_us_tight

flow_freight_divergence

forced_storage_build

freight_locked_arb

fundamental_rally

gasoline_overhang

global_stocks_tight

opec_revision_vs_price

refiner_margin_trap

regime_curve_destruction

rotterdam_squeeze

supply_shock_signature

us_comfortable_eu_tight

Signals

crude supply

signalfires whenmetricwhat it tests
crude_building> 1.0crude_stock_wowCrude stocks (excl. SPR) built more than 1.0 million barrels week-on-week
crude_oversupplied> 80crude_seasonal_pctlCrude stocks > 80th seasonal percentile
crude_undersupplied< 20crude_seasonal_pctlCrude stocks < 20th seasonal percentile
cushing_building_fast> 5.0cushing_7d_pctCushing built >5% in 7 days
cushing_full> 2.0cushing_zCushing inventory z-score above 2 (a statistical high vs its own history — NOT a claim about tank capacity; the name is shorthand)
cushing_tight< -2.0cushing_zCushing inventory z-score below -2
production_at_seasonal_high>= 99production_seasonal_pctlProduction at or above the 99th percentile of the same-week distribution (a seasonal high, NOT an all-time record)

european

signalfires whenmetricwhat it tests
eu_electricity_price_extreme> 2.0de_electricity_price_zGerman electricity price z-score above 2 (demand destruction / energy crisis signal)
eu_gas_stocks_comfortable> 80eu_gas_seasonal_pctlEU27 gas stocks above 80th seasonal percentile
eu_gas_stocks_tight< 20eu_gas_seasonal_pctlEU27 gas stocks below 20th seasonal percentile
eu_oil_exports_rising> 10eu_oil_exports_3m_pctEU27 oil exports up >10% over 3 months (refinery product re-export)
eu_oil_imports_declining< -10eu_oil_imports_3m_pctEU27 oil imports dropped >10% over 3 months
eu_oil_imports_surging> 10eu_oil_imports_3m_pctEU27 oil imports surged >10% over 3 months
eu_oil_stocks_comfortable> 80eu_oil_seasonal_pctlEU27 oil stocks above 80th seasonal percentile
eu_oil_stocks_tight< 20eu_oil_seasonal_pctlEU27 oil stocks below 20th seasonal percentile
eu_renewables_accelerating> 2.0eu_renewables_yoy_changeEU27 renewable share up >2pp year-on-year (long-term oil demand displacement)
nl_stocks_tight< 20nl_oil_seasonal_pctlNetherlands (Rotterdam/ARA hub) oil stocks below 20th seasonal percentile

market structure

signalfires whenmetricwhat it tests
bubble_detected> 0.0bubble_gsadf_excessPeak BSADF of an ONGOING explosive episode (within 21 days) exceeds its 95% critical value, and the move is upward. The test detects explosive roots in either direction — downward episodes are excluded here because they are crashes, not bubbles. Absent when the last episode is stale, which is the usual state. Populate via bubble_test()
crude_price_extreme> 95wti_price_pctlWTI price above 95th historical percentile (flat price extreme)
freight_collapsed< -2.0bwet_zBWET freight z-score below -2
freight_extreme> 3.0bwet_zBWET freight z-score above 3
punishing_carry< -15.0roll_yield_pct12-month roll yield (M12/M1 − 1, negative in backwardation) worse than -15% — the curve pays the market NOT to store
spread_inverted< 0brent_wti_spreadBrent below WTI
spread_wide> 2.0brent_wti_zscoreBrent-WTI spread z-score above 2
steep_backwardation< -10.0m1_m1212-month curve (M12−M1, negative = backwardation) below -$10: prompt $10+ over the 12-month — steep backwardation
steep_contango> 5.0m1_m1212-month curve (M12−M1) above +$5: contango
vix_oil_supply_shock> 0.5vix_corrVIX-WTI correlation above 0.5 — a correlation CONSISTENT WITH a supply shock, which does not by itself identify one (the name is shorthand)

opec compliance

signalfires whenmetricwhat it tests
opec_call_rising> 0opec_call_qoq_changeCall on DoC crude rising quarter-over-quarter. NOTE: the call series extends past the last realized quarter, so this reads the shape of OPEC's own FORECAST, not an observed change — a legitimate thing to watch, but not a realized q/q move
opec_compliance_gap_extreme> 200opec_compliance_gap_max_kbdMax /Table 5-8 direct - Table 5-7 secondary/ across OPEC members > 200 tb/d (compliance-gaming signal, Iraq typical offender)
opec_demand_downgraded< -0.1opec_world_demand_revisionOPEC MoM revision to world oil demand < -0.1 mb/d (more bearish than last month)
opec_demand_upgraded> 0.1opec_world_demand_revisionOPEC MoM revision to world oil demand > +0.1 mb/d (more bullish than last month)
opec_iea_spread_inverted< -0.5opec_iea_demand_spread_2026IEA 2026 world demand forecast exceeds OPEC by > 0.5 mb/d (unusual - IEA bullish, OPEC cautious)
opec_iea_spread_widening> 1.5opec_iea_demand_spread_2026OPEC 2026 world demand forecast exceeds IEA by > 1.5 mb/d (diverging outlooks, classic OPEC-bullish setup)
opec_production_gap> 2.0opec_call_production_gapCall on DoC crude minus OPEC crude production > 2 mb/d, on the most recent quarter BOTH series cover (structural undersupply on OPEC own figures). Period-aligned since 2026-08-11: it previously differenced last-vs-last, which took a forecast quarter against a print six quarters earlier

positioning

signalfires whenmetricwhat it tests
brent_positioning_medianbetween 30 and 70brent_mm_pctlBrent managed money between 30th and 70th percentile (no crowded trade)
brent_specs_extended> 90brent_mm_pctlBrent managed money positioning > 90th percentile
brent_specs_short< 10brent_mm_pctlBrent managed money positioning < 10th percentile
wti_positioning_medianbetween 30 and 70wti_mm_pctlWTI managed money between 30th and 70th percentile (no crowded trade)
wti_specs_extended> 90wti_mm_pctlWTI managed money positioning > 90th percentile
wti_specs_short< 10wti_mm_pctlWTI managed money positioning < 10th percentile

refined products

signalfires whenmetricwhat it tests
crack_extreme> 3.0crack_321_z3-2-1 crack z-score above 3
diesel_crack_extreme> 3.0crack_diesel_zDiesel crack z-score above 3
distillate_oversupplied> 90distillate_seasonal_pctlDistillate stocks > 90th seasonal percentile
distillate_undersupplied< 20distillate_seasonal_pctlDistillate stocks < 20th seasonal percentile
gasoline_crack_extreme> 3.0crack_gasoline_zGasoline crack z-score above 3
gasoline_oversupplied> 90gasoline_seasonal_pctlGasoline stocks > 90th seasonal percentile
gasoline_undersupplied< 20gasoline_seasonal_pctlGasoline stocks < 20th seasonal percentile
maintenance_detected< -2.0maintenance_trough_zRefinery runs z-score below -2 — a utilization trough. Turnarounds are the usual cause but an unplanned outage or weak demand looks identical here; the signal does not distinguish them (refining desk signal — populate via maintenance_signal())
refinery_strong> 92refinery_utilRefinery utilization above 92%
refinery_weak< 85refinery_utilRefinery utilization below 85%

weather

signalfires whenmetricwhat it tests
weather_cold_extreme> 2.0hdd_anomaly_zUS heating degree days z-score above 2 vs 10-year average (cold snap, bullish heating oil/distillate demand)
weather_hot_extreme> 2.0cdd_anomaly_zUS cooling degree days z-score above 2 vs 10-year average (heat wave, bullish gasoline + AC power gen)
weather_mild_winter< -2.0hdd_anomaly_zUS heating degree days z-score below -2 (mild winter, bearish distillate/heating oil)

Canonical metric contract

Where a metric is computed by more than one surface, this is the definition all of them must use — published so a number can be reproduced from the published formula.

brent_wti_spread

brent_wti_zscore

crack_321_z

roll_yield_pct

wti_mm_pctl

Producers

Which series each metric comes from, and over what window.

metricserieswindow (days)handlerstatus
brent_mm_pctlCFTC.BRENT.MM_Net1560percentileready
brent_wti_spreadPET.RBRTE.D, PET.RWTC.D-spreadready
brent_wti_zscorePET.RBRTE.D, PET.RWTC.D1300spreadready
bubble_gsadf_excessPET.RWTC.D126bubble_testready
bwet_zSHIP.BWET.D1260statsready
cdd_anomaly_z--noneno_data
crack_321_zPET.RWTC.D, PET.EER_EPMRU_PF4_Y35NY_DPG.D, PET.EER_EPD2DXL0_PF4_Y35NY_DPG.D1260crack_spreadready
crack_diesel_zPET.RWTC.D, PET.EER_EPD2DXL0_PF4_Y35NY_DPG.D1260crack_spreadready
crack_gasoline_zPET.RWTC.D, PET.EER_EPMRU_PF4_Y35NY_DPG.D1260crack_spreadready
crude_seasonal_pctlPET.WCESTUS1.W-seasonalready
cushing_7d_pctPET.W_EPC0_SAX_YCUOK_MBBL.W7changesready
cushing_zPET.W_EPC0_SAX_YCUOK_MBBL.W260statsready
de_electricity_price_zEUROSTAT.nrg_pc_205.DE.EUR.S.MWH20-499.E7000.I_TAX.KWH3650statsready
distillate_seasonal_pctlPET.WDISTUS1.W-seasonalready
eu_gas_seasonal_pctlEUROSTAT.nrg_stk_gas.EU27_2020.A.G3000.STKCL_NAT.MIO_M3-seasonalready
eu_oil_exports_3m_pctEUROSTAT.nrg_te_oil.EU27_2020.A.TOTAL.O4000.THS_T1825changesready
eu_oil_imports_3m_pctEUROSTAT.nrg_ti_oil.EU27_2020.A.TOTAL.O4000.THS_T1825changesready
eu_oil_seasonal_pctlEUROSTAT.nrg_stk_oil.EU27_2020.A.O4000.STKCL_NAT.THS_T-seasonalready
eu_renewables_yoy_changeEUROSTAT.nrg_ind_ren.EU27_2020.A.REN.PC1825changesready
gasoline_seasonal_pctlPET.WGTSTUS1.W-seasonalready
hdd_anomaly_z--noneno_data
m1_m12ICE.BRENT.M12.D, ICE.BRENT.M1.D-spreadready
maintenance_trough_zPET.WPULEUS3.W260maintenance_signalready
nl_oil_seasonal_pctlEUROSTAT.nrg_stk_oil.NL.A.O4000.STKCL_NAT.THS_T-seasonalready
opec_call_production_gapOPEC.MOMR11_1.MEMO.CALL_ON_DOC_CRUDE.Q, OPEC.MOMR11_1.NON_DOC.DOC_CRUDE_OIL_PRODUCTION.Q-custom_opec_gapcomputed
opec_call_qoq_changeOPEC.MOMR11_1.MEMO.CALL_ON_DOC_CRUDE.Q-custom_last_minus_prevcomputed
opec_compliance_gap_max_kbdOPEC.MOMR5_7.*.M, OPEC.MOMR5_8.*.M-custom_compliance_gapcomputed
opec_iea_demand_spread_2026--nonevirtual
opec_world_demand_revisionOPEC.MOMR11_1_REV.DEMAND.TOTAL_WORLD_DEMAND.A-latestready
production_seasonal_pctlPET.WCRFPUS2.W-seasonalready
refinery_utilPET.WPULEUS3.W-latestready
roll_yield_pctICE.BRENT.M1.D, ICE.BRENT.M12.D-custom_roll_yieldcomputed
vix_corrMACRO.VIX.D, PET.RWTC.D60rolling_correlationready
wti_mm_pctlCFTC.WTI.MM_Net1560percentileready
wti_price_pctlPET.RWTC.D-percentileready

Metric labels

keylabel
brent_mm_pctlBrent managed money net positioning percentile
brent_wti_spreadBrent-WTI spread ($/bbl)
brent_wti_zscoreBrent-WTI spread z-score
bubble_gsadf_excessGSADF bubble-test excess above critical value
bwet_zBWET freight z-score
cdd_anomaly_zUS cooling degree days anomaly z-score (vs 10-yr avg)
crack_321_z3-2-1 crack z-score
crack_diesel_zdiesel crack z-score
crack_gasoline_zgasoline crack z-score
crude_seasonal_pctlcrude stocks seasonal percentile
cushing_7d_pctCushing 7-day percent change
cushing_zCushing inventory z-score
de_electricity_price_zGerman electricity price z-score
distillate_seasonal_pctldistillate stocks seasonal percentile
eu_gas_seasonal_pctlEU27 gas stocks seasonal percentile
eu_oil_exports_3m_pctEU27 oil exports 3-month percent change
eu_oil_imports_3m_pctEU27 oil imports 3-month percent change
eu_oil_seasonal_pctlEU27 oil stocks seasonal percentile
eu_renewables_yoy_changeEU27 renewable share year-on-year change (pp)
gasoline_seasonal_pctlgasoline stocks seasonal percentile
hdd_anomaly_zUS heating degree days anomaly z-score (vs 10-yr avg)
m1_m1212-month curve, M12−M1 ($/bbl; negative = backwardation — key name is legacy)
maintenance_trough_zrefinery runs z-score (maintenance trough indicator)
nl_oil_seasonal_pctlNetherlands oil stocks seasonal percentile
opec_call_production_gapOPEC call-vs-production gap (mb/d)
opec_call_qoq_changeOPEC call on DoC crude QoQ change (mb/d)
opec_compliance_gap_max_kbdmax OPEC direct-vs-secondary production gap (tb/d)
opec_iea_demand_spread_2025OPEC-IEA 2025 world demand spread (mb/d)
opec_iea_demand_spread_2026OPEC-IEA 2026 world demand spread (mb/d)
opec_world_demand_revisionOPEC world demand MoM revision (mb/d)
production_seasonal_pctlUS crude production seasonal percentile
refinery_utilUS refinery utilization (%)
roll_yield_pct12-month roll yield (%, M12 vs M1)
vix_corrVIX-WTI correlation
wti_mm_pctlWTI managed money net positioning percentile
wti_price_pctlWTI price historical percentile

Method and provenance: signals-background.md (published at /methodology/background). Measured behaviour — fire rates, collinearity, base rates: signals-catalog-review-2-2026-08-10.md.