Dynamic vs Fixed Tariffs
How the engine handles flat and dynamic electricity tariffs, and why the tariff type can dramatically affect battery value and payback period.
Tariff types
The tariff object in a scan request supports two modes:
| Type | Field | Description |
|---|---|---|
"flat" | flatRateCentsPerKwh | A single price per kWh, constant across all hours |
"dynamic" | dynamicRateType | Hourly wholesale prices from EPEX Day-Ahead |
The tariff type fundamentally changes how the engine values self-consumption, feed-in, and battery operation.
Flat tariff modelling
With a flat tariff, every kWh has the same value regardless of when it is consumed or exported:
import_cost[h] = grid_import[h] × flat_rate
export_value[h] = grid_export[h] × feed_in_rate
The flat feed-in rate defaults to EUR 0.10/kWh (configurable via feedInEurPerKwh). With a flat tariff, the only economic benefit of solar is the spread between the import rate and the feed-in rate. Batteries provide limited additional value because there is no price variation to exploit.
With the current Dutch feed-in tariff phase-out, the default feed-in rate may be lower than historical values. You can set a custom rate via feedInEurPerKwh in the tariff object.
Dynamic tariff modelling
With dynamic tariffs, the engine uses historical hourly wholesale prices from EPEX Day-Ahead for the Netherlands:
import_cost[h] = grid_import[h] × spot_price[h] × (1 + markup)
export_value[h] = grid_export[h] × spot_price[h]
Spot prices vary significantly: negative prices (you get paid to consume) can occur during windy/sunny periods, while evening peaks can reach EUR 0.50+/kWh.
The dynamic import tariff dataset uses 2025 EPEX Day-Ahead prices (all-in incl. energiebelasting, ODE, and 21 % BTW). The feed-in rate uses raw EPEX base prices (spot wholesale, excl. taxes), clamped to ≥ 0. Using the current calendar year instead of future projections ensures the simulation is based on real, verified market data rather than speculative forecasts.
Price distribution (typical year)
- Name
minimum- Type
- EUR/kWh
- Description
-0.05 to 0.00 (negative during oversupply)
- Name
median- Type
- EUR/kWh
- Description
0.08 – 0.12
- Name
p95- Type
- EUR/kWh
- Description
0.30 – 0.50
- Name
maximum- Type
- EUR/kWh
- Description
0.80+ (rare peak events)
Dynamic tariff request
{
"tariff": {
"type": "dynamic",
"dynamicRateType": "EPEX"
}
}
Battery arbitrage
Batteries become significantly more valuable with dynamic tariffs because they can exploit price spreads:
- Charge the battery during low-price hours (midday solar surplus, or negative-price hours)
- Discharge during high-price evening peaks
The engine optimizes this hourly dispatch automatically. Typical arbitrage revenue:
| Configuration | Annual arbitrage value |
|---|---|
| 5 kWh battery, dynamic tariff | EUR 200 – 350 / year |
| 10 kWh battery, dynamic tariff | EUR 350 – 500 / year |
| 5 kWh battery, flat tariff | EUR 50 – 100 / year |
Battery arbitrage alone rarely justifies the battery investment. The main value comes from increased self-consumption (avoiding grid import), with arbitrage as an additional benefit.
Feed-in compensation
How exported solar energy is valued differs by tariff type:
| Tariff type | Feed-in rate | Notes |
|---|---|---|
| Flat | User-configurable (default EUR 0.10/kWh) | Set via feedInEurPerKwh in the tariff object |
| Dynamic | Hourly EPEX base price (clamped ≥ 0) | Raw spot wholesale, excl. taxes — auto-calculated |
For flat tariffs, feedInEurPerKwh defaults to EUR 0.10/kWh if not provided.
For dynamic tariffs this field must NOT be sent — the engine uses 8 760 hourly
EPEX base (spot) prices from epex_base_wholesale.json instead.
With dynamic tariffs, the engine may recommend a battery specifically to avoid exporting during low-price hours and instead discharge during high-price hours.
Impact comparison
The tariff type affects multiple scan outputs:
| Metric | Flat tariff | Dynamic tariff |
|---|---|---|
| Annual savings | Predictable, moderate | Higher variance, often higher mean |
| Payback period | Longer (less savings) | Shorter (more savings from arbitrage) |
| Battery ROI | Low (no price spread) | Significant (price arbitrage) |
| Optimal battery size | Often 0 or minimal | Larger batteries economically justified |
| Self-sufficiency | Same | Same (physical, not economic) |
| CO₂ savings | Same | Same (based on kWh, not price) |