Skip to content

Market Lite

Public API for the storage-arbitrage market envs. Both focus on price-physics coupling rather than a full ISO market stack. For physics, see Physics → Markets. For the exact bid-based SCED solver, see API → Market SCED. For the GenCos competitive market, see API → Market MARL.

CostBasedMarketEnv

from powerzoojax.envs import (
    CostBasedMarketEnv,
    CostMarketState,
    CostMarketParams,
    make_cost_market_params,
)

Generator dispatch comes from dc_opf using true marginal costs. Reward is storage revenue sum(LMP * P * dt). The core CMDP vector is costs = (cost_thermal_overload,), with static name ("thermal_overload",). info["cost_sum"] is the aggregate diagnostic.

powerzoojax.envs.market.cost_based_market.CostBasedMarketEnv

Bases: Environment

Cost-based LMP arbitrage environment for battery storage.

The agent controls batteries (via attached bundles) on the grid. Generator dispatch comes from grid/dc_opf.dc_opf (ADMM). Nodal LMP follows dc_opf._compute_lmp_alm — not clearing._compute_lmp_kkt_ed.

Action: concatenated bundle actions (see each ResourceBundle). Observation: [lmp_norm, time_sin, time_cos, demand_norm, ]. Reward: sum_i LMP_{bus_i} × P_i × Δt (revenue-based). Cost: thermal overload (CMDP channel).

reset(key, params)

step(key, state, action, params)

Step the market environment.

  1. Run resource bundles (feasible P, SOC update).
  2. Apply net injections as load modification.
  3. Run DC-OPF → dispatch, flows, LMP.
  4. Reward = sum_i LMP[bus_i] × P_i × Δt.

observation_space(params)

action_space(params)

powerzoojax.envs.market.cost_based_market.CostMarketState

Bases: MarketState

State for CostBasedMarketEnv.

powerzoojax.envs.market.cost_based_market.CostMarketParams

Bases: MarketParams

Parameters for CostBasedMarketEnv.

powerzoojax.envs.market.cost_based_market.make_cost_market_params(case, load_profiles=None, resources=(), lmp_scale=100.0, max_steps=48, delta_t_hours=0.5, steps_per_day=48, cost_thermal_weight=1.0)

Create CostMarketParams from a CaseData.

Parameters:

Name Type Description Default
case CaseData

CaseData instance (must have PTDF, cost coefficients, etc.).

required
load_profiles Array

(T, n_loads) load demand array [MW]. If None, flat mid-range profile is generated.

None
resources tuple

Tuple of ResourceBundle instances (e.g. BatteryBundle). If empty, a default single-device battery at external bus id 1 is created via make_battery_bundle (same defaults as the legacy flat battery fields).

()
lmp_scale float

LMP normalisation factor for observations.

100.0
max_steps int

Episode length.

48
delta_t_hours float

Time step duration [hours].

0.5
steps_per_day int

Steps per day (for time encoding).

48
cost_thermal_weight float

Weight for thermal overload cost.

1.0

Returns:

Type Description
CostMarketParams

CostMarketParams.

BidBasedMarketEnv

from powerzoojax.envs import (
    BidBasedMarketEnv,
    BidMarketState,
    BidMarketParams,
    make_bid_market_params,
)

Approximate (heuristic) piecewise ED clearing on offer curves. Recovered LMPs are KKT-style approximations on true marginal cost (not exact dual prices). For paper-quality LMPs use the exact PD-IPM solver in Market SCED.

powerzoojax.envs.market.bid_based_market.BidBasedMarketEnv

Bases: Environment

Competitive electricity market with piecewise-linear offer curves.

Battery agent participates in a market where generators submit offers. Clearing uses piecewise_ed (approximate piecewise ED, not exact SCED). LMP is MC-based KKT recovery at dispatch point; not a strict offer-price dual.

Action: concatenated bundle actions. Observation: [lmp_norm, sin, cos, demand_norm, mean_offer_norm, ]. Reward: sum_i LMP × P_i × Δt (revenue-based). Cost: thermal overload (CMDP channel).

reset(key, params)

step(key, state, action, params)

Step the bid-based market environment.

observation_space(params)

action_space(params)

powerzoojax.envs.market.bid_based_market.BidMarketState

Bases: MarketState

State for BidBasedMarketEnv.

Extends MarketState with offer-based fields.

powerzoojax.envs.market.bid_based_market.BidMarketParams

Bases: MarketParams

Parameters for BidBasedMarketEnv.

powerzoojax.envs.market.bid_based_market.make_bid_market_params(case, load_profiles=None, resources=(), lmp_scale=100.0, max_steps=48, delta_t_hours=0.5, steps_per_day=48, cost_thermal_weight=1.0, n_segments=5, markup_std=0.05)

Create BidMarketParams from a CaseData.

Parameters:

Name Type Description Default
case CaseData

CaseData instance.

required
load_profiles Array

(T, n_loads) load demand [MW]. If None, flat mid-range.

None
resources tuple

ResourceBundle tuple. If empty, default BatteryBundle at external bus id 1 (legacy defaults).

()
lmp_scale float

LMP normalisation factor.

100.0
max_steps int

Episode length.

48
delta_t_hours float

Time step duration [hours].

0.5
steps_per_day int

Steps per day.

48
cost_thermal_weight float

Weight for thermal overload cost.

1.0
n_segments int

Number of offer curve segments per generator.

5
markup_std float

Std dev of random markup (0 = truthful bidding).

0.05

Returns:

Type Description
BidMarketParams

BidMarketParams.

Alias exports

SimpleLMPArbitrageEnv, LMPMarketState, LMPMarketParams, and make_lmp_market_params are aliases of the cost-based equivalents. Either import path refers to the same implementation.

Shared market state

powerzoojax.envs.market.base.MarketState

Bases: EnvState

Market environment state.

Extends EnvState with last LMP, dispatch fields, and attached resource bundle states (SOC, etc.) in resource_states.

powerzoojax.envs.market.base.MarketParams

Bases: EnvParams

Market environment parameters.

Holds grid and market configuration. Battery / DER physics live in resources (e.g. BatteryBundle), not as flat fields on this struct. Array fields (PTDF, costs, etc.) are JAX leaves; scalar config fields are pytree_node=False (static under JIT).

Approximate clearing helpers (heuristic piecewise ED)

from powerzoojax.envs import make_cost_segments, piecewise_ed
from powerzoojax.envs.market.clearing import (
    prepare_piecewise_ed,
    PiecewiseEDSetup,
    PiecewiseEDResult,
)

powerzoojax.envs.market.clearing.make_cost_segments(case, n_segments=5)

Build piecewise-linear offer segments from quadratic cost data.

For each generator with MC(P) = mc_a·P² + mc_b·P + mc_c, the operating range [p_min, p_max] is divided into n_segments equal-width blocks. Price of each block = MC evaluated at block midpoint.

Parameters:

Name Type Description Default
case CaseData

CaseData with unit cost coefficients and power limits.

required
n_segments int

Number of segments per generator.

5

Returns:

Type Description
CostSegments

CostSegments with seg_widths (n_units, K) and seg_prices (n_units, K).

powerzoojax.envs.market.clearing.prepare_piecewise_ed(case, n_segments=5)

Prepare PiecewiseEDSetup from CaseData.

Called once at setup time. All heavy matrix operations use NumPy. The result is a frozen pytree passed to JIT-compiled functions.

Parameters:

Name Type Description Default
case CaseData

CaseData instance.

required
n_segments int

Number of offer-curve segments per generator.

5

Returns:

Type Description
PiecewiseEDSetup

PiecewiseEDSetup ready for piecewise_ed().

powerzoojax.envs.market.clearing.piecewise_ed(setup, node_load_mw, offer_prices=None, max_iter=50, tol=0.001)

Solve piecewise-linear economic dispatch with congestion management.

This is an approximate network-constrained economic dispatch, not an exact LP/QP SCED. Dispatch uses merit-order + iterative PTDF penalty (heuristic, not globally optimal). LMP is recovered via weighted least-squares KKT stationarity, not from LP dual variables. Convergence is not guaranteed for all cases; check result.converged before using the result in downstream analysis.

Merit-order dispatch: segments are sorted by price, filled cheapest-first. Congestion managed by iterative penalty on line violations (same approach as dc_opf.py).

Parameters:

Name Type Description Default
setup PiecewiseEDSetup

Precomputed PiecewiseEDSetup.

required
node_load_mw Array

(n_nodes,) nodal load [MW].

required
offer_prices Array

(n_units, n_segments) $/MWh. If None, uses base prices.

None
max_iter int

Maximum iterations for congestion management.

50
tol float

Convergence tolerance [MW].

0.001

Returns:

Type Description
PiecewiseEDResult

PiecewiseEDResult.

powerzoojax.envs.market.clearing.PiecewiseEDSetup

Precomputed data for piecewise-linear economic dispatch.

Created once at setup time (NumPy), used at runtime (JAX).

powerzoojax.envs.market.clearing.PiecewiseEDResult

Output of piecewise-linear economic dispatch.