Pipeline for energy price forecasting and battery trading optimization in competitive electricity markets.
It integrates advanced machine learning (LSTM), robust statistical models, and an operational battery trading strategy to deliver safe, accurate, and profitable decisions.
-
forecasting: Hybrid forecasting system combining LSTM and fallback statistical models with flat forecast detection. -
battery_strategy: Battery trading strategy based on price peak/trough detection, percentile threshold trading, and safe end-of-day resets. -
helper_function: Battery physical constraints simulation and validation utilities. -
energy_forecast: Orchestrates the full pipeline: forecasting - strategy execution - validation - visualization - submission export. -
energy_train: LSTM training script that handles data scaling, batching, and model persistence.
Ensure you have Python 3.x installed and the following libraries:
numpypandasscipymatplotlib(optional, for visualization)tensorfloworpytorch(depending on the LSTM implementation)
Install dependencies using:
pip install numpy pandas scipy matplotlib tensorflowRun the training script to build and save the LSTM model using historical price data:
python3 energy_train.pyKey points:
- Utilizes a 96-step (24 hour) lookback window with 15-minute intervals.
- Applies data scaling and batching for efficient training.
- Saves trained LSTM model and scalers for use in forecasting.
Execute the complete forecasting and battery trading simulation pipeline with:
python3 energy_forecast.pyimagesputs will be stored in the images/ directory and include:
- Price forecasts from LSTM and fallback statistic model (based on existing records)
- Buy/sell signal triggers
- Executed trades and battery SoC trajectories
- Diagnostic plots and detailed daily summaries
- Kaggle submission CSV file ready for competition
- Battery capacity configurable between 0 and 10 MWh.
- Initial state of charge (SoC) resets daily to 5 MWh.
- Trades have minimum size of 0.1 MWh.
- Trading decisions triggered by price peak/trough detection with prominence filtering.
- Uses percentile thresholds (default buy below 20th, sell above 80th percentile).
- Trade sizes adapt dynamically based on current market volatility and price spreads.
- End-of-day logic safely discharges battery energy to ensure SoC reset and avoid penalties.
- Modify the LSTM architecture or input features in
energy_trainfor improved forecasting accuracy. - Adjust percentile thresholds or prominence criteria in
battery_strategyto refine trading aggressiveness. - Integrate additional diagnostics or logging to support backtesting or real-time deployment.
All diagnostic plots and strategy visualizations are generated in the out/best/ directory when you run energy_forecast.py. They help verify the quality of the forecast, the statistical properties of the prices, and the behavior of the trading strategy.
Raw price history at 15‑minute resolution. This plot shows the full evolution of market prices over time, including volatility bursts and extreme spikes. It gives a quick sense of the regime you are trading in and is the baseline for all further analysis.
Histogram of normalized prices. It highlights the typical price range and how heavy the tails are. This is useful for tuning percentile‑based thresholds (for example, where the 20th and 80th percentiles sit relative to the bulk of the distribution).
Original price series together with short‑term SMA (7 periods) and longer‑term EMA (30 periods). These smooth trends help you understand local momentum and mean‑reversion behavior, and they can be used to design alternative rule‑based strategies or as additional features for the LSTM.
Left: autocorrelation function (ACF) over a wide range of lags. Right: lag‑1 scatter plot. Together they show how strongly current prices depend on past values and whether the series exhibits serial correlation or non‑linear structure. Weak autocorrelation justifies using simpler models as fallbacks when the LSTM is uncertain.
Spectral view of price variability. Peaks at low frequencies correspond to slow intra‑week or multi‑day cycles, while a flat spectrum indicates noise‑like behavior. This helps validate the choice of the 96‑step (24‑hour) lookback window and seasonal period.
Additive decomposition of the scaled price into trend, seasonal, and residual components for a 96‑step daily period. It confirms that the dominant pattern is a smooth trend with relatively small intra‑day seasonal structure, and that residuals are centered and suitable for modeling with LSTM or simple AR‑style baselines.
Average seasonal component over a single 96‑step day. Each point corresponds to the average deviation from the trend at a given time of day. This is useful for understanding typical daily shape (for example evening peaks) and for validating that de‑seasonalization does not distort the signal.
Top: original vs de‑seasonalized scaled price. Bottom: de‑seasonalized and first‑differenced series. This transformation pipeline is what a classical statistical model would see: a near‑stationary series where residual structure is easier to model. It also clarifies how much of the variation comes from predictable daily cycles versus genuine shocks.
Three‑panel view of the simulated strategy for a multi‑day horizon.
Top: forecasted price and detected buy/sell points.
Middle: executed charge/discharge actions in MWh.
Bottom: resulting state of charge (SoC) trajectory of the 10 MWh battery.
This figure validates that trades respect physical constraints (capacity, min trade size, SoC bounds), that energy is cycled around detected peaks and troughs, and that end‑of‑day SoC resets are enforced while accumulating profit.
The scores show the profit gained from energy transactions, mainly from selling energy at high prices. Higher bars mean the model earned more profit on both the public and private datasets.










