Energy Arbitrage Competition
Algorithmic electric grid optimization
Energy storage arbitrage is a core problem in modern electricity markets: a battery operator can profit by purchasing power when prices are low and selling it back when prices are high, but must act under uncertainty as real-time prices deviate from day-ahead forecasts due to weather, demand shocks, and transmission congestion.
The Energy Arbitrage competition challenges miners to optimize battery dispatch decisions across a simulated electrical grid. Miners submit algorithmic policies that decide when to charge and discharge batteries at each time step to maximize profit, while respecting physical constraints including battery state-of-charge limits, network power flow limits, and transaction/degradation costs.
Evaluation Overview
Each evaluation runs the miner's policy across 100 challenge instances. Instances cycle through 5 scenarios of increasing difficulty:
Baseline
20
30
10
96
1 Day
Congested
40
60
20
96
1 Day
Multiday
80
120
40
192
2 Days
Dense
100
200
60
192
2 Days
Capstone
150
300
100
192
2 Days
Each time step represents 15 minutes. Scenarios increase in network size, congestion, price volatility, and battery heterogeneity.
Each rounds's evaluation set is seeded to ensure determinism.
This seed changes from round to round.
Step by Step
At each time step, the miner's policy function receives:
The current state: battery state-of-charge levels, real-time nodal electricity prices, exogenous grid injections, feasible action bounds per battery, and accumulated profit.
The challenge view: network topology (nodes, lines, PTDF matrix, flow limits), battery parameters (capacity, power limits, efficiency), exogenous injection schedule for all time steps, and day-ahead prices.
The policy returns a list of actions (MW), one per battery. Negative values charge; positive values discharge.
Actions must stay within the provided bounds.
Real-time prices are generated stochastically at each step from a hidden seed -- miners cannot predict future RT prices.
Day-ahead prices are known in advance for the full horizon.
Constraints
Battery SOC: Must remain between 10% and 90% of capacity. Starts at 50%.
Charge/discharge efficiency: 95% each direction.
Network flow limits: Actions must not cause line flows to exceed limits (DC power flow model). Violations cause the step to fail.
Action bounds: Pre-computed at each step based on current SOC and battery power limits.
Timeouts:
Per-step timeout = 30 seconds.
Total evaluation timeout = 1200 seconds.
Profit Calculation
At each time step, per battery:
Scoring
Each instance is scored by comparing the miner's total profit against a baseline (the better of two built-in heuristic policies -- greedy and conservative):
quality = (miner_profit - baseline_profit) / (baseline_profit + 1e-6)quality_int = round(clamp(quality, -10, +10) * 1,000,000)The miner's final score is the average quality across all 100 instances.
To surpass the current winner, a miner must earn a raw score > 1% higher than the current top raw score.
If there is no current winner, the miner must beat the baseline raw score by at least 1%.
The
score_to_beatis displayed in the Apex CLI dashboard under competition information.
Miner Submissions
Miners submit a single .py file implementing:
def policy(challenge: PolicyView, state: State) -> list[float]:
Maximum submission size: 50,000 characters.
Default round length: 1 day.
Submission Fee: $1.00 USD.
1%
raw_scorethreshold to beat current top scorer.Miners code is revealed 1 day after evaluation.
Logs are opened after the current round is completed.
The submission rate limit is 4 submissions per hotkey within 24 hours, across all competitions.
An example of baseline solver implementations can be found in the energy_arbitrage/python folder.
The information about enabled packages is in requirements.txt. Only numpy is available beyond the standard library.
Last updated
