nexa-marketdata

Unified Python client for European power market data. Nord Pool, EPEX SPOT, ENTSO-E, and EEX.

Unified API client for European power market data sources. One interface for Nord Pool, EPEX SPOT, ENTSO-E Transparency Platform, and EEX.

Python 3.11+ MIT License 0.1.0 Alpha

pip install nexa-marketdata

GitHub | PyPI


Why this exists

The European power market data landscape is fragmented. Every exchange has its own API, its own data format, its own quirks. The community alternatives (entsoe-py, kipe/nordpool) are volunteer-maintained and frequently break when APIs change.

nexa-marketdata provides a single, well-tested client that handles:

  • Multiple exchanges through a consistent interface
  • 15-minute MTU data natively (EU transition: 30 Sept 2025)
  • Rate limiting so you do not get banned from ENTSO-E at 03:00
  • Timezone normalisation across bidding zones
  • Caching to avoid redundant API calls
  • Proper error handling with meaningful exceptions, not silent failures

Quick start

Set your credentials as environment variables:

export NORDPOOL_USERNAME="your-username"
export NORDPOOL_PASSWORD="your-password"
export ENTSOE_API_KEY="your-key-here"
from nexa_marketdata import NexaClient
from nexa_marketdata.types import BiddingZone
import datetime

client = NexaClient()

# Fetch day-ahead prices for NO2 (South Norway)
prices = client.day_ahead_prices(
    zone=BiddingZone.NO2,
    start=datetime.date(2025, 10, 1),
    end=datetime.date(2025, 10, 7),
)

print(prices.head())
#             start                end  price_eur_mwh bidding_zone
# 0  2025-10-01 00:00+00:00  2025-10-01 00:15+00:00         42.31          NO2
# 1  2025-10-01 00:15+00:00  2025-10-01 00:30+00:00         41.88          NO2
# ...

Implementation status

Component Status
Nord Pool — day-ahead prices Yes
Core types and exceptions Yes
Unified NexaClient In progress
ENTSO-E client Planned
EPEX SPOT client Planned
EEX client Planned
Response caching Planned
Rate limiting Planned
Timezone normalisation Planned

Key features

DataFrame output

All data is returned as pandas DataFrames. Prices and volumes use Decimal, not float.

from nexa_marketdata import NexaClient
from nexa_marketdata.types import BiddingZone
import datetime

client = NexaClient()

prices = client.day_ahead_prices(
    zone=BiddingZone.NO1,
    start=datetime.date(2025, 10, 1),
    end=datetime.date(2025, 10, 2),
)

# Standard pandas operations work directly
hourly = prices.resample("h", on="start").mean(numeric_only=True)
print(f"Peak hour: {hourly['price_eur_mwh'].idxmax()}")

Type-safe bidding zones

Bidding zones are modelled as an enum, not raw strings. The library normalises zone identifiers across exchanges.

from nexa_marketdata.types import BiddingZone

# Nordic zones
BiddingZone.NO1  # South Norway
BiddingZone.NO2  # South-West Norway
BiddingZone.SE3  # Central Sweden
BiddingZone.FI   # Finland

# Central European zones
BiddingZone.DE_LU  # Germany-Luxembourg
BiddingZone.FR     # France

MTU-aware resolution

The library handles the 30 September 2025 transition from hourly to 15-minute MTUs. Historical data is returned in the resolution it was published; post-transition data is 15-minute by default.


Configuration

Credentials are read from environment variables. You can also use a .env file:

NORDPOOL_USERNAME=your-username
NORDPOOL_PASSWORD=your-password
ENTSOE_API_KEY=your-key-here

Premium: Hosted Data Proxy

Coming Soon

For teams that need higher reliability, historical backfill, and no rate limit headaches:

  • Cached proxy with sub-second response times
  • Historical data backfill API (2015 onwards)
  • 99.9% uptime SLA
  • Priority support

Pricing starts at EUR 49/month per seat. Learn more.