A professional reader of any analytical publication asks four questions: How are the signals defined? Can I inspect the methodology? Can I reproduce the numbers? How well do they calibrate over time? This page answers all four — and every answer below is live-derivable from the platform, not marketing copy about it.
The design principle: the prose in an EnergyScope report sits on top of a structured analytical layer with explicit signal definitions, pre-registered scoring rules, a public revision trail, and (from July 2026) a Brier-scored calibration ledger. The report doesn't ask to be trusted — it shows its working and scores its own past calls, every edition. The essay version of this argument: Reliable Reports Are a Systems Problem — why the writer goes last.
Every signal is a named boolean predicate over a flat metrics dict — a key, an operator, and a threshold. Nothing is discretionary at firing time. The full catalog is machine-introspectable: derived_signals(schema=True) returns exactly what is rendered below (53 signals, 57 accepted input aliases, 16 contradictions).
| Signal | Fires when | Meaning |
|---|---|---|
| Refined products & cracks | ||
| crack_extreme | crack_321_z > 3.0 | 3-2-1 crack z-score above 3 (z window: 2020–) |
| gasoline_crack_extreme | crack_gasoline_z > 3.0 | Gasoline crack z-score above 3 |
| diesel_crack_extreme | crack_diesel_z > 3.0 | Diesel crack z-score above 3 |
| gasoline_oversupplied / _undersupplied | gasoline_seasonal_pctl > 90 / < 20 | Gasoline stocks vs 5-year same-week percentile |
| distillate_oversupplied / _undersupplied | distillate_seasonal_pctl > 90 / < 20 | Distillate stocks vs seasonal percentile |
| refinery_strong / refinery_weak | refinery_util > 92 / < 85 | US refinery utilization extremes. Unconditional levels, not seasonally adjusted — so these fire with the turnaround calendar (weak in spring/autumn, strong in mid-summer) as well as with genuine market states. The refining family is the one group still on raw levels rather than seasonal percentiles. |
| maintenance_detected | maintenance_trough_z < −2.0 | Structural turnaround trough in refinery runs — expected to co-fire with refinery_weak through the spring and autumn maintenance seasons |
| Crude supply | ||
| crude_oversupplied / _undersupplied | crude_seasonal_pctl > 80 / < 20 | US crude stocks (ex-SPR) vs seasonal percentile |
| cushing_full / cushing_tight | cushing_z > 2.0 / < −2.0 | Cushing (WTI delivery point) inventory z-score |
| cushing_building_fast | cushing_7d_pct > 5.0 | Cushing built more than 5% in 7 days |
| production_at_seasonal_high | production_seasonal_pctl ≥ 99 | US crude production at or above the 99th percentile of the same-week distribution — a seasonal high, NOT an all-time record (renamed 2026-08-11: it fired at 13,804 kb/d while the all-time weekly high was 13,862). A state descriptor on a secularly rising series, so it stays true for long stretches; not an event |
| Market structure | ||
| steep_backwardation / steep_contango | m1_m12 < −10 / > 5 | 12-month curve, M12−M1 ($/bbl; negative = backwardation — the key name is legacy). Below −$10 the prompt sits $10+ over the 12-month; above +$5 is contango. |
| punishing_carry | roll_yield_pct < −15 | 12-month roll yield (M12/M1 − 1, negative in backwardation) worse than −15% — the curve pays the market not to store. |
| freight_extreme / freight_collapsed | bwet_z > 3.0 / < −2.0 | Crude tanker freight z-score extremes. BWET is the Breakwave Tanker Shipping ETF (NYSE Arca, 2023 inception) — a freight-futures wrapper settling against Baltic assessments, not a Baltic index; ~3 years of history, so these thresholds sit on a short sample. |
| spread_wide / spread_inverted | brent_wti_zscore > 2.0 / spread < 0 | Brent–WTI spread stretched, or Brent below WTI |
| crude_price_extreme | wti_price_pctl > 95 | WTI flat price above its 95th historical percentile |
| bubble_detected | bubble_gsadf_excess > 0 | GSADF test statistic exceeds its critical value (explosive behavior) |
| Positioning & macro | ||
| wti_specs_extended / wti_specs_short / wti_positioning_median | wti_mm_pctl > 90 / < 10 / 30–70 | WTI managed-money positioning percentile (CFTC). Read as risk context — crowding and squeeze vulnerability — not as a directional call; why. |
| brent_specs_extended / brent_specs_short / brent_positioning_median | brent_mm_pctl > 90 / < 10 / 30–70 | Brent managed-money positioning percentile (ICE Futures Europe COT, not CFTC) |
| vix_oil_supply_shock | vix_corr > 0.5 | VIX–WTI correlation positive — a co-movement pattern consistent with a supply shock, which does not by itself identify one; the name is shorthand |
| Cross-Atlantic (EU/US composition) | ||
| eu_oil_stocks_tight / _comfortable | eu_oil_seasonal_pctl < 20 / > 80 | EU27 oil stocks vs seasonal percentile |
| eu_gas_stocks_tight / _comfortable | eu_gas_seasonal_pctl < 20 / > 80 | EU27 gas stocks vs seasonal percentile |
| nl_stocks_tight | nl_oil_seasonal_pctl < 20 | Netherlands national oil stocks vs seasonal percentile — a national aggregate on the EU reporting cycle, used as a proxy for the ARA region. It is not the weekly Insights Global independent tank survey that "ARA stocks" usually means on a European desk. |
| eu_oil_imports_declining / _surging | eu_oil_imports_3m_pct < −10 / > 10 | EU27 oil import flow shift over 3 months |
| eu_oil_exports_rising | eu_oil_exports_3m_pct > 10 | EU27 product re-export flows rising |
| eu_electricity_price_extreme | de_electricity_price_z > 2.0 | German power price extreme — demand-destruction / energy-crisis signal |
| eu_renewables_accelerating | eu_renewables_yoy_change > 2.0 | EU27 renewable share up >2pp YoY — long-term displacement |
| Agency layer (OPEC MOMR · IEA OMR) | ||
| opec_demand_upgraded / _downgraded | opec_world_demand_revision > 0.1 / < −0.1 | OPEC month-over-month world demand revision (mb/d) |
| opec_production_gap | opec_call_production_gap > 2.0 | Call on crude minus reported production > 2 mb/d — an implied stock draw on OPEC's own balance, not a measured shortfall. Read the aggregates before trading it: the MOMR's call is on DoC crude (the wider Declaration of Cooperation group), so pairing it with an OPEC-only production figure would overstate the gap by construction. |
| opec_call_rising | opec_call_qoq_change > 0 | Call on DoC crude up quarter-over-quarter — sequential, not seasonally adjusted, so it fires through the normal Q1→Q3 demand build most years |
| opec_compliance_gap_extreme | opec_compliance_gap_max_kbd > 200 | Largest direct-communication vs secondary-source production divergence across members > 200 kb/d — a reporting divergence. Quota behaviour is one possible cause; condensate boundary definitions and months where a member does not submit are others, and the threshold is chronically satisfied by a couple of members |
| opec_iea_spread_widening / _inverted | opec_iea_demand_spread_2026 > 1.5 / < −0.5 | OPEC vs IEA demand-forecast divergence (mb/d) |
| Weather | ||
| weather_cold_extreme / weather_mild_winter | hdd_anomaly_z > 2.0 / < −2.0 | US heating degree days vs 10-year average |
| weather_hot_extreme | cdd_anomaly_z > 2.0 | US cooling degree days extreme — gasoline + power-gen demand |
m1_m12 carries deferred minus prompt (M12−M1), so negative means backwardation; roll_yield_pct (M12/M1 − 1) is likewise negative in backwardation, which is the opposite sign of the long-investor "roll yield" convention. Read with the other convention in mind these definitions look inverted, which is why they are spelled out — the signals were firing correctly; the labels weren't saying so.Single signals describe; contradictions — named combinations that a desk reads as one thesis-level statement, whether the legs pull against each other (refiner_margin_trap, freight_locked_arb) or reinforce (global_stocks_tight) — are what a desk actually argues about, so they are the report headlines. Each has a required signal set, optional exclusions, a score (average of component scores), and a fixed narrative. Fourteen of the sixteen require two or more signals; two (diesel_clean_long, flow_freight_divergence) are a single required signal with an exclusion. (us_comfortable_eu_tight was rebuilt 2026-08-11: it previously paired one requirement with an exclusion, which together with global_stocks_tight exhaustively partitioned a boolean — a guaranteed headline whenever the EU leg fired. Its US leg is now an assertion, crude_oversupplied.) A sample:
| Contradiction | Requires | The reading |
|---|---|---|
| regime_curve_destruction | steep_backwardation + punishing_carry | Backwardation steep, roll yield punishing — storage economics destroyed. Inventory holders liquidate into the squeeze, deepening it. Its two legs are near-algebraic restatements of each other (they cross at roughly $67 flat), so it counts as one observation about the curve, not two independent ones. |
| fundamental_rally | spread_wide + wti_positioning_median | Prices/spread at extremes but spec positioning at median — the rally is fundamental, not crowded. (The stretched leg is the Brent–WTI location spread, not flat price; and median positioning is also consistent with short-covering already done.) |
| freight_locked_arb | spread_wide + freight_extreme | Spread wide while freight sits at an extreme — watch freight alongside the spread, because a wide spread with expensive shipping may not be an executable arb. Whether it is actually shut depends on the spread in $/bbl against the freight rate; this conjunction compares z-scores, not economics. |
| supply_shock_signature | vix_oil_supply_shock + freight_extreme | VIX–WTI correlation positive while tanker freight is at an extreme — the pattern associated with supply-side shocks rather than demand panic. A PATTERN MATCH, not an identification: neither leg observes a supply disruption, and the freight leg is an ETF measuring cost, not availability. |
| diesel_clean_long | diesel_crack_extreme − distillate_oversupplied | Diesel crack extreme without inventory overhang — the cleanest long signal in the complex. |
| global_stocks_tight | crude_undersupplied + eu_oil_stocks_tight | US crude AND EU oil stocks both in the bottom fifth of their seasonal ranges — tightness on both sides of the Atlantic at once, so a wider arb cannot relieve one from the other. Not tested here: freight, whether cargoes actually move, or flat price. |
| opec_revision_vs_price | opec_demand_downgraded + crude_price_extreme | OPEC cut demand while price sits at extremes — bearish divergence; the biggest demand-side bull turned cautious. |
How the contradiction layer is scored — and why it mostly isn't. Most contradictions combine conditions that are individually uncommon (2σ z-thresholds, or 20th/80th/90th-percentile cuts), so the joint base rate keeps the sample in single digits however long the history runs. The two single-signal-plus-exclusion forms are scoreable to the same extent as their required signal, and inherit its sample. So the signal layer is scored against its own firings; the contradiction layer is largely argued. Each one is named, its component signals are published, and its reading is fixed in advance — so it can be disagreed with precisely, which is the honest alternative to a statistic that will never exist.
Full catalog — all 53 predicates, the 57-alias input map, and all 16 contradiction definitions — at /signals (generated from the running server) or via derived_signals(schema=True) on any connected client.
Yes — the rules the reports operate under are written down, versioned, and enforced by the tooling rather than by good intentions.
signal_backtest)Every claimed edge is an event study over the signal's own historical firings, under always-on honesty guards:
cushing_tight currently returns exactly that warning). Until the engine computes point-in-time statistics natively, backtest evidence certifies the point-in-time variant of a rule, not the full-sample one. This affects 14 of the 53 signals — the 13 z-based predicates plus vix_oil_supply_shock, whose rolling correlation behaves the same way. The percentile- and level-threshold signals are unaffected.cushing_z, bwet_z, vix_corr and wti_price_pctl currently ship without a stated window, and a per-signal window field is being added to the schema so the claim becomes mechanically true rather than a matter of diligence. Where a window is stated, it is authoritative.Every quantitative claim in a report traces to a named tool call against versioned data.
report(preset=...) emits the flat metrics dict the narrative was derived from; save_report_run stores it with the HTML, and compare_runs diffs any two runs server-side. The engine's "what changed" is checkable against the report's "what changed".report(watchlist=..., preset="monthly_risk"), derived_signals(metrics=...), and signal_backtest(signal=...) against the live server and compare.The honest answer today: being measured — first resolution August 2026. The machinery is running and the ledger is open, but one unresolved entry is not a track record. This section is a promissory note with a date on it; it becomes evidence a year from now, and the reader is entitled to hold it to that.
The calibration ledger OPENED 24 JUL 2026 scores every edition's scenario probabilities. Priors are frozen at publication and never restated; each scenario set resolves against the realized Brent front-month at the stated horizon and receives a multi-category Brier score. Uniform guessing scores 0.667 on a 3-way set — that is a floor, not a skill bar: the honest comparison is the climatological base rate (how often that outcome occurs anyway), and resolved entries will be reported against both, because beating a forecaster who refuses to look at history proves nothing. Replayed or hindsight entries are marked as such and never Brier-scored. Entry 1 — the July 2026 update's 50/30/20 scenario prior — RESOLVES 24 AUG 2026
Every edition ends by scoring the previous one, under one non-negotiable condition: scoring is pre-registered, never retrospective. Trigger-based calls score mechanically against thresholds frozen at publication; prose claims are editorially scored and flagged as such; and every new call ships with its scoring rule attached, so the next edition cannot choose how to grade this one. In the panel's first outing, the mechanical calls held — and none of the three editorially-scored prose claims survived the backtest as stated. That result was printed.
The demo reports below were produced under exactly these rules — revision trails, appendices, and performance panels included.
Demo Reports Analyst Workflows