Skip to content

Morwane/power-structuring-analytics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Power Structuring Analytics

A quant toolkit for structured power trading: the spark spread and its tolling optionality (gas-plant economics as a strip of spread options), renewable capture rates and PPA valuation, plus forward-curve shaping and scenario analysis. Python, look-ahead-free, unit-tested.

Power analytics

Why this project

A structured-power desk doesn't trade a flat price — it trades shape and optionality: a flexible gas plant is a strip of options on the spark spread; a wind/solar PPA is worth its capture rate, not the headline forward; and risk is run on a gas × power scenario grid. This repo implements those four desk primitives end-to-end.

Module Desk question it answers
src/spark.py What is the spark spread, and what is a flexible plant's optionality worth (tolling, Kirk's spread-option formula)?
src/capture.py What does a wind/solar asset actually capture vs baseload, and what is a PPA worth?
src/curve.py Peak/off-peak shaping of a monthly forward; the gas × power scenario grid.
src/data.py LSEG loader or a documented, reproducible illustrative dataset.

The four primitives

1. Spark spread & tolling optionality

The spark spread is the margin of a gas plant: power − heat_rate·gas − var_cost ($/MWh). A plant runs only when this is positive, so its value is a strip of daily call options on the spark spread — a tolling agreement. Each is a two-asset spread option, priced with Kirk's approximation (the desk-standard closed form). Add a carbon term (carbon·emission_factor) for the EU clean spark spread.

Tolling strip option value

2. Renewable capture rate & PPA

Renewables earn the price only when generating. Solar produces midday — exactly when solar floods the grid and depresses prices (the duck curve) — so it captures below baseload. The capture rate is the number that makes or breaks a PPA price:

solar: capture rate 93.8%  (capture $26.2 vs baseload $27.9)   ← penalised
wind : capture rate 104.9% (capture $29.3 vs baseload $27.9)   ← closer to 100%

Renewable capture rate

A fixed-price PPA is then marked as capture_price − strike per MWh produced, with the breakeven strike = capture price (the fair fixed price).

3. Forward-curve shaping

Power is quoted in monthly peak/off-peak blocks but settles hourly. shape_profile derives the average hourly shape so a monthly forward can be shaped to an hourly curve; peak_offpeak_means gives the peak/off-peak ratio.

4. Scenario grid

The standard 2-D risk view a structured desk runs — spark spread across joint gas-price and power-price shocks:

           gas-50%  gas-25%  gas+0%  gas+25%  gas+50%
power+0%      12.9      6.9     1.0     -5.0    -11.0
power+20%     18.5     12.5     6.5      0.5     -5.4

Spark-spread scenario grid

Data

The repo runs out-of-the-box on a documented, fully reproducible illustrative dataset (src/data.synthetic_hourly) that reproduces the structural features the analytics exploit (seasonal + diurnal power shape, the midday solar depression, an anti-correlated wind profile, mean-reverting gas). It is not market data.

To run on real data, scripts/pull_power_data.py fetches Henry Hub gas + a U.S. ISO power hub from LSEG (entitlement-dependent; edit the RICs to your hub). Real market data is gitignored and never committed.

pip install -r requirements.txt
python scripts/run_analysis.py            # illustrative (no entitlement needed)
python scripts/run_analysis.py --lseg     # real LSEG data (after pull_power_data.py)
pytest -q

Limitations

  • The illustrative dataset is for demonstration; capture rates and spark levels reflect the synthetic structure, not a real ISO. Re-run with LSEG data for live numbers.
  • Kirk's approximation is the desk-standard spread-option proxy; for deep out-of-the-money or high-correlation regimes a Monte-Carlo or Bjerksund–Stensland spread option is more accurate.
  • Forward vols are estimated from daily average prices; a real desk uses quoted option implieds.
  • Research/education only — not trading advice.

Repository structure

power-structuring-analytics/
├── README.md · LICENSE · requirements.txt
├── src/
│   ├── data.py      # LSEG loader + reproducible illustrative generator
│   ├── spark.py     # spark spread, implied heat rate, Kirk tolling option
│   ├── capture.py   # renewable capture rate + PPA valuation
│   └── curve.py     # peak/off-peak shaping + scenario grid
├── scripts/
│   ├── pull_power_data.py   # LSEG fetch (audit-first; data/ gitignored)
│   └── run_analysis.py      # end-to-end report + figure
├── tests/test_analytics.py
└── docs/assets/

Built with Python (pandas, numpy, scipy, matplotlib). Methods: spread-option pricing (Kirk), generation-weighted capture analysis, load shaping.

About

Quant toolkit for structured power trading: spark spread & tolling optionality (Kirk), renewable capture rate, PPA valuation, forward-curve shaping and scenario analysis.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages