Skip to content

Market

An EnergyMarket represents an electricity market where your portfolio can buy and/or sell energy. This is how you model revenue from selling excess generation or purchasing power when it's cheaper than running your own assets.

Basic usage

from odys.energy_system_models.markets import EnergyMarket

market = EnergyMarket(
    name="day_ahead",
    max_trading_volume_per_step=150.0,
)

By default, the market allows both buying and selling up to the specified volume per timestep.

Fields

Field Type Required Default Description
name str Yes - Unique identifier for the market
max_trading_volume_per_step float Yes - Maximum volume that can be traded per timestep (MW)
trade_direction TradeDirection No "both" Allowed trade directions: "buy", "sell", or "both"
stage_fixed bool No False If True, trading decisions are fixed across all scenarios

Trade direction

You can restrict which way the market trades:

from odys.energy_system_models.markets import EnergyMarket, TradeDirection

# Can only sell into this market
sell_only = EnergyMarket(
    name="feed_in",
    max_trading_volume_per_step=100.0,
    trade_direction=TradeDirection.SELL,
)

# Can only buy from this market
buy_only = EnergyMarket(
    name="backup_supply",
    max_trading_volume_per_step=50.0,
    trade_direction=TradeDirection.BUY,
)

Stage-fixed decisions

When stage_fixed=True, the optimizer must commit to the same trading volumes across all stochastic scenarios. This models markets where you need to lock in your position before uncertainty is resolved -- like a day-ahead market where bids are placed before you know the actual wind/solar output.

day_ahead = EnergyMarket(
    name="day_ahead",
    max_trading_volume_per_step=150.0,
    stage_fixed=True,  # same volumes in all scenarios
)

intraday = EnergyMarket(
    name="intraday",
    max_trading_volume_per_step=50.0,
    stage_fixed=False,  # can adjust per scenario (default)
)

This is particularly useful in stochastic optimization setups.

Market prices

Prices are provided through the Scenario (or StochasticScenario), not on the market object itself:

from odys.energy_system_models.scenarios import Scenario

scenario = Scenario(
    market_prices={
        "day_ahead": [50, 55, 45, 60, 70, 65, 50],
    },
    load_profiles={"load": [100, 120, 80, 90, 110, 100, 95]},
)

The key must match the market's name.

Multiple markets

You can pass multiple markets to the EnergySystem:

from odys.energy_system import EnergySystem

energy_system = EnergySystem(
    portfolio=portfolio,
    markets=(
        EnergyMarket(name="sdac", max_trading_volume_per_step=150),
        EnergyMarket(name="sidc1", max_trading_volume_per_step=100),
        EnergyMarket(name="sidc2", max_trading_volume_per_step=50),
    ),
    scenarios=scenario,
    timestep=timedelta(minutes=30),
    number_of_steps=7,
    power_unit="MW",
)

Results

After optimization, access market results through result.markets:

result = energy_system.optimize()

result.markets.sell_volume  # energy sold per market per timestep
result.markets.buy_volume   # energy bought per market per timestep

Each of these is a pandas.DataFrame.