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.
- ASSUME turns electricity market simulation into a repeated learning game, not a static clearing exercise.
- Its core trick is separating a unit’s physical identity from the strategy that decides how it bids.
- Deep reinforcement learning is part of the main loop, so agents can adapt under competition instead of only following rules.
- The framework matters because it can expose market design failures before those rules meet a real grid.
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.
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.
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.
| Tool | Primary focus | Agent behavior | Market design focus | Best use case | Where ASSUME differs |
|---|---|---|---|---|---|
| AMIRIS | Large-scale electricity market simulation | Mostly rule-based | Strong | Scenario analysis and market studies | ASSUME leans harder into adaptive learning and strategy switching |
| PyPSA | Power system optimization and network modeling | Not agent-based | Complementary | Dispatch, flows, and network constraints | ASSUME can plug into PyPSA rather than replace it |
| Power TAC | Competitive trading environment | Strategic brokers | Moderate | Retail and wholesale trading competitions | ASSUME is built for European market design and grid realism |
| EMLab-py | Long-term agent-based energy transition modeling | Policy and investment agents | Moderate | Investment cycles and scenario exploration | ASSUME 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.
- Modular unit and strategy abstractions keep the simulation extensible.
- Docker and database support make experiments easier to repeat and inspect.
- DRL lives in the core architecture, not in a sidecar notebook.
- The package structure is built for research workflows with real runtime complexity.
That is why ASSUME feels credible. It is a tool for studying a complicated system without flattening the parts that make the system interesting.