Skip to content

How to Query Floating / Index-Priced Volumes

The floating views — fct_volume_pwr_floating_15m, fct_volume_pwr_floating_15m_deal, and the EWE wrapper equivalents — expose volumes for power deals settled against a published index (instrument_sub_type = 'PWR Index') rather than at a fixed agreed price.

When to use which view

Need View
Fixed-price deals (VWAP) fct_volume_pwr_15m
Floating / index deals (index price) fct_volume_pwr_floating_15m
Both, joined together Both, joined on (delivery_date_utc, begin_utc, business_case, grid)

The floating views have the same gap-fill, partition-pruning, and date-filter rules as the fixed views.

Column shape difference

Floating views replace the VWAP columns with a single index price:

Fixed Floating
buy_vwap_price_eur_per_mwh
sell_vwap_price_eur_per_mwh
power_index_price_eur_per_mwh

And they add:

  • internal_business_unit
  • external_business_unit
  • power_index_name

The grain is correspondingly wider: business_case + grid + internal_BU + external_BU + power_index_name + begin_utc (+ deal_id on the _deal variant).

Basic query

select
    delivery_date_utc,
    begin_utc,
    business_case,
    grid,
    power_index_name,
    sum(volume_buy_mw)                  as volume_buy_mw,
    sum(volume_sell_mw)                 as volume_sell_mw,
    avg(power_index_price_eur_per_mwh)  as avg_index_price
from fct_volume_pwr_floating_15m
where delivery_date_utc = current_date
group by 1, 2, 3, 4, 5
order by 1, 2, 3, 4, 5

Index price interpretation

power_index_price_eur_per_mwh is the index print for the period — for example, the EPEX PWR EPEX_DE_INTRADAY 15min index for 2026-04-15 14:30 UTC. One row's price is not weighted by anything from this view; it's the published price for the period from core_endur_index_pricing_15m_daily.

A given (business_case, grid, period) cell can have multiple rows if multiple (internal_BU, external_BU, power_index_name) combinations contribute. The price is per-index, so different rows can have different prices in the same cell.

Filtering to a single index

select
    delivery_date_utc, begin_utc, business_case, grid,
    sum(volume_buy_mw)                  as volume_buy_mw,
    sum(volume_sell_mw)                 as volume_sell_mw,
    avg(power_index_price_eur_per_mwh)  as index_price
from fct_volume_pwr_floating_15m
where power_index_name = 'PWR EPEX_DE_INTRADAY 15min'
  and delivery_date_utc between '2026-04-01' and '2026-04-30'
group by 1, 2, 3, 4

Spread analysis vs fixed-price VWAP

Join fixed and floating views on the same (delivery_date_utc, begin_utc, business_case, grid) cell. The fixed-price VWAP and the index price are both in EUR/MWh.

select
    fp.delivery_date_utc,
    fp.begin_utc,
    fp.business_case,
    fp.grid,
    fp.volume_buy_mw,
    fp.buy_vwap_price_eur_per_mwh,
    fl.power_index_name,
    fl.power_index_price_eur_per_mwh,
    fp.buy_vwap_price_eur_per_mwh - fl.power_index_price_eur_per_mwh as buy_vwap_vs_index
from fct_volume_pwr_15m fp
left join fct_volume_pwr_floating_15m fl
    on fp.delivery_date_utc = fl.delivery_date_utc
   and fp.begin_utc         = fl.begin_utc
   and fp.business_case     = fl.business_case
   and fp.grid              = fl.grid
where fp.delivery_date_utc between '2026-04-01' and '2026-04-07'
  and fp.volume_buy_mw > 0
order by 1, 2

When more than one index applies to a (business_case, grid) cell, the LEFT JOIN fans out; pick a single index or aggregate per power_index_name.

Deal-grain drill-down

select
    delivery_date_utc, begin_utc,
    deal_id, business_case, grid,
    internal_business_unit, external_business_unit,
    power_index_name,
    volume_buy_mw, volume_sell_mw,
    power_index_price_eur_per_mwh
from fct_volume_pwr_floating_15m_deal
where delivery_date_utc = current_date
  and volume_buy_mw + volume_sell_mw > 0
order by deal_id, begin_utc

The volume_buy_mw + volume_sell_mw > 0 predicate is a quick way to suppress gap rows when you only want active intervals.

Pitfalls

Don't filter on instrument_sub_type

It's already applied upstream — every row in the floating views satisfies instrument_sub_type = 'PWR Index'. Adding the predicate is redundant; a different value just yields zero rows.

Index price is not zero-filled when volume is zero

Wait, yes it is — gap rows return 0 for power_index_price_eur_per_mwh, same as the volume columns. If you need to distinguish "no trade in this slot" from "no published index price", count rows with volume_buy_mw + volume_sell_mw > 0 instead of inspecting the price.

Don't average the index price across periods naively

AVG(power_index_price_eur_per_mwh) over a day includes gap-row zeros, dragging the average down. Either filter to volume > 0 first or volume-weight the average yourself.