ASSUME: The Electricity Market Simulator That Lets Agents Learn to Trade

A Python framework for testing market design, bidding strategy, and grid behavior with agent-based models, deep reinforcement learning, and coupled market clearing.

8 min read View on GitHub More from assume-framework

A wide market scene where generators, batteries, and demand assets appear as trading participants around a central clearing board, while small strategy nodes exchange signals overhead. It explains that ASSUME models both the market rules and the adaptive agents inside the market.
ASSUME treats the grid like a living market, where participants can adapt instead of simply following fixed rules.
Key Takeaways

Most energy models optimize. ASSUME asks a harder question: what happens when the participants in the market learn, adapt, and start exploiting the rules you gave them? That shift makes it less like a solver and more like a laboratory for strategic behavior.

That matters in modern power systems because the old equilibrium story is getting brittle. High renewable penetration, redispatch, block products, and network constraints create conditions where behavior changes the outcome as much as physics does.

Why this is not just another power system model

ASSUME is built to study emergent behavior. It combines agent-based modeling, market clearing, forecasting, and deep reinforcement learning so researchers can probe what happens when generators, storage, and demand-side units react to one another instead of sitting still inside a fixed optimization problem.

The project is especially useful when you care about market design, not just dispatch. If a rule invites gaming, or a bidding format pushes agents into weird corners, ASSUME is designed to surface that behavior.

A unique feature of the ASSUME toolbox is its integration of Deep Reinforcement Learning methods into the behavioral strategies of market agents.

ASSUME Developers, Project Maintainers · ASSUME GitHub Repository

Inside the market: units, strategies, and orders

The architecture is clean on purpose. A BaseUnit represents the physical asset. A BaseStrategy decides how that asset bids. Order and MarketConfig define the market language that ties the system together.

The same asset can keep its physics while swapping strategies, which is why ASSUME is useful for testing behavior instead of hard-coding it.

A close-up of a single battery split into layers, with a physical asset at the bottom, a strategy layer in the middle, and forecast and market signals above it. It shows that ASSUME separates the asset from the bidding logic so strategy can change without changing the unit itself.
A battery in ASSUME is not just a battery. It is a physical unit plus a strategy layer plus a learning loop.

That separation is the architectural trick. A battery can keep its physics while swapping a naive bidding rule for a trained policy. The market sees the same unit class, but the strategy underneath can evolve.

The real engine is the feedback loop

ASSUME is interesting because it is not a one-shot market model. It is a repeated loop: observe, forecast, bid, clear, settle, learn, repeat. That loop is what turns the simulator into a learning environment.

The framework’s forecaster prepares the information state. The strategy turns that state into orders. Market clearing produces outcomes, and those outcomes flow back into the agent’s next decision. If the agent is using DRL, the loop becomes a training environment as well as a market.

Unit observes state
  -> Forecaster updates expectations
  -> Strategy selects bid logic
  -> Orders are created
  -> Market clears orders
  -> Settlement and dispatch results return
  -> Learning module updates policy
  -> Next round begins with a new state

That sounds simple, but it is the point. Once the loop closes, the market is no longer a static map of supply and demand. It becomes a space where strategy itself changes the future.

World.py is the conductor

At runtime, World ties the system together. It wires the container, the clock, the agents, and the simulation lifecycle. In practice, that means the framework can manage many roles without forcing every entity into a monolithic class.

The role-based setup matters because it keeps the code flexible. A unit can carry multiple responsibilities through roles, while the orchestration layer stays focused on coordination instead of business logic.

Why DRL matters here

Deep reinforcement learning is not a decorative add-on. In ASSUME, it sits inside the strategy layer, which means learning happens where bidding decisions actually live. That is a much stronger use case than bolting a model onto a simulator after the fact.

The project’s DRL work, including MATD3-style approaches and training buffers, is aimed at strategic interaction. Agents do not just learn the world. They learn against other agents inside the world.

class BaseUnit:
    def calculate_bids(self, market_state):
        return self.strategy.calculate_bids(market_state, unit=self)

class BaseStrategy:
    def calculate_bids(self, market_state, unit):
        raise NotImplementedError

# Rule-based and DRL strategies can be swapped
# without changing the physical unit model.
ToolPrimary focusAgent behaviorMarket design focusBest use caseWhere ASSUME differs
AMIRISLarge-scale electricity market simulationMostly rule-basedStrongScenario analysis and market studiesASSUME leans harder into adaptive learning and strategy switching
PyPSAPower system optimization and network modelingNot agent-basedComplementaryDispatch, flows, and network constraintsASSUME can plug into PyPSA rather than replace it
Power TACCompetitive trading environmentStrategic brokersModerateRetail and wholesale trading competitionsASSUME is built for European market design and grid realism
EMLab-pyLong-term agent-based energy transition modelingPolicy and investment agentsModerateInvestment cycles and scenario explorationASSUME is more operational and bidding-focused

The comparison is the clue to the niche. ASSUME is not trying to beat optimization tools at their own game. It sits where market design, adaptive behavior, and grid realism overlap.

What makes it production-serious

The repo does not read like a prototype. It has modular packages for units, strategies, markets, and reinforcement learning, plus Docker-based infrastructure for visualization and storage. That gives it a research-engineering feel rather than a demo feel.

The stack also signals intent. Python, PyTorch, pandas, SQLAlchemy, Docker, Grafana, TimescaleDB, and PyPSA are all there to support repeatable experiments, not just one-off notebooks.

That is why ASSUME feels credible. It is a tool for studying a complicated system without flattening the parts that make the system interesting.

Sources and further reading