> For the complete documentation index, see [llms.txt](https://docs.gridstatus.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gridstatus.io/data-guides/market-guides/independent-electricity-system-operator-ieso.md).

# Independent Electricity System Operator (IESO)

<figure><img src="/files/AsWKKGnXpkjDmN1psSp8" alt=""><figcaption></figcaption></figure>

The Independent Electricity System Operator (IESO) is the market operator for Ontario. IESO today is a crown corporation that fills the roles of ISO/RTO, LSE, and planning and procurement authority.  While IESO was formed around the same time as deregulation led to ISOs and RTOs in the US, their market structure heavily relied on out of market payments and systemwide pricing until May 1st, 2025 when nodal pricing and a full two settlement system went into effect.

IESO’s structure is unique in North American power markets, acting as if its neighbor, NYISO, also contained the New York Power Authority (NYPA), the New York State Energy Research and Development Authority (NYSERDA), and were a state-owned corporation. Despite this, many market products largely resemble their US counterparts, so whether you've worked in NYISO, MISO, or PJM, the contours of IESO market should be familiar. However, this doesn't mean the market is without its quirks, so let's dig in.

{% hint style="info" %}
For a full list of our current IESO datasets, you can [filter our Data Catalog ](https://www.gridstatus.io/datasets?source=ieso)by the IESO market.\
\
For more detail on Market Renewal and IESO's history, check out our blog, [Market Renewal in Ontario: Navigating IESO's Shift to a Nodal System](https://blog.gridstatus.io/market-renewal-in-ontario/).
{% endhint %}

### Fuel Mix

A great way to quickly understand the ground state in a particular market is via the installed generation, and one way to get a sense of that is through [fuel mix data](https://www.gridstatus.io/datasets/ieso_fuel_mix), which is [charted](https://www.gridstatus.io/charts/fuel-mix?iso=ieso\&date=2025-04-21to2025-04-26) on the [IESO Live Page](https://www.gridstatus.io/live/ieso).

<figure><img src="/files/dd96PUfmyMrydby6XuZR" alt=""><figcaption></figcaption></figure>

IESO is a fairly unique region in terms of fuel mix, with \~75% of demand served by nuclear and hydro assets, while wind and gas make up most of the remainder. This fuel mix data is also unique, in that it is derived from [generator-level generation data](https://www.gridstatus.io/datasets/ieso_generator_report_hourly), which is provided by IESO in near real-time.

<figure><img src="/files/6OZaAllqe7tUDmliRqVB" alt=""><figcaption></figcaption></figure>

Most North American markets don't offer this kind of real-time insight, and it's a great tool for contextualizing specific outcomes in the market as they occur. This became even more useful with the addition of the nodal market, as participants could see the intraday impact of specific assets based on their location.

You can make charts or dashboards of generator sets in the Grid Status platform, but if you want to query a specific generator using the API, you can write a code snippet like this:

```python
from gridstatusio import GridStatusClient
import os

GS_KEY = os.environ["GS_API_KEY"]
client = GridStatusClient(GS_KEY)

df_gen = client.get_dataset(
    dataset = 'ieso_generator_report_hourly',
    start = '2025-02-19',
    end = '2025-02-28',
    filter_column = 'generator_name',
    filter_value = 'BELLE RIVER',
    timezone = 'US/Eastern',
    )
```

And if you wanted to plot the data:

```python
import matplotlib.pyplot as plt

# Apply dark background and increase font sizes
plt.style.use('dark_background')
plt.rcParams.update({
    'font.size': 16,
    'axes.labelsize': 18,
    'axes.titlesize': 20,
    'xtick.labelsize': 14,
    'ytick.labelsize': 14,
    'figure.figsize': (14, 6)
})

fuel_type = df_gen['fuel_type'].values[0]

# Create the plot
fig, ax = plt.subplots()

ax.plot(df_gen['interval_start_local'], df_gen['output_mw'], color='cyan', linewidth=2)

# Add labels and title
ax.set_title(f'Belle River ({fuel_type}) Output')
ax.set_xlabel(None)
ax.set_ylabel('MW')

# Improve x-axis readability
fig.autofmt_xdate()

# Add gridlines
ax.grid(True, which='both', linestyle='--', linewidth=0.5, alpha=0.7)

plt.tight_layout()
plt.show()
```

Which returns this chart.

<figure><img src="/files/CXSbC4Sluu1E40iHOeJC" alt=""><figcaption></figcaption></figure>

Ontario Power Generation (OPG) owns the bulk of the generating capacity in the province, and, like IESO, was split out from Ontario Hydro. On the transmission side, another sibling, Hydro One, maintains much of the physical network.&#x20;

### Prices

Previously, IESO had a single systemwide price, the Hourly Ontario Energy Price (HOEP), with some variation at the interchanges. Post-Market Renewal, the system has largely moved over to Locational Marginal Prices (LMPs). However, Ontarian quirks remain. To get a complete view of prices, the day-ahead and real-time each have [4 datasets](https://www.gridstatus.io/datasets?filter=lmp\&source=ieso): LMPs for nodes, interties, virtual zonal, and Ontario-wide. These are detailed in our [LMP guide](https://docs.gridstatus.io/data-guides#independent-electricity-system-operator-ieso). If you want complete pricing, we've prepared [real-time](https://www.gridstatus.io/datasets/ieso_lmp_real_time_5_min_all) and day-ahead datasets that combine the individual datasets for each set of prices.

With the introduction of a nodal market we've expanded our nodal map to cover Ontario.

<figure><img src="/files/wQCdaQidBzDBl2gHnPJI" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
While coordinates are not available by default in the API or Snowflake, [reach out](https://www.gridstatus.io/contact) if you're interested in access.
{% endhint %}

### Load

There are a [number of datasets](https://www.gridstatus.io/datasets?filter=load\&source=ieso) in IESO that have information on demand, including [five-minute load ](https://www.gridstatus.io/datasets/ieso_load)data from their *Realtime Constrained Totals* report.

IESO also publishes forecasts, in both [zonal](https://www.gridstatus.io/datasets/ieso_zonal_load_forecast_hourly) and [Ontario-wide](https://www.gridstatus.io/datasets/ieso_load_forecast_hourly) varieties. If we plot some of the series from forecast and actual demand together a big discrepancy between **market** and **Ontario** demand arises.

<figure><img src="/files/9A6FFoXEiYkSokuWVKuC" alt=""><figcaption></figcaption></figure>

The Ontario value is internal demand, while market total adds includes several elements omitted from Ontario alone. Exports tends to be a significant factor, as IESO is a net exporter in most intervals. The complete calculation for Ontario demand is:

*Total Energy + Total Generation Without Offers -Total Exports +Total Off Market +/- Over/Under*\
*Generation*

### The Adequacy Report

IESO publishes an [adequacy report](https://www.gridstatus.io/datasets/ieso_adequacy_report_forecast#dataset-columns) which contains:

> **information on Ontario's electricity requirements for today through 34 days out**&#x20;

Outages, capacity offered and forecast by type, interchange, demand, and more, this dataset may have the most columns of any in our catalog. It powers our IESO outages card.

<figure><img src="/files/tnQ9nHIgZ50qoptibve0" alt=""><figcaption></figcaption></figure>

And can be used to examine the difference between interchange offers and schedules

<figure><img src="/files/QNlz9neNAAqenxecCgOn" alt=""><figcaption></figcaption></figure>

This report is published multiple times a day - twice per hour for the current day, 13 times for the next day, and twice per day for future days. This means that the near-term data in particular can undergo meaningful shifts throughout the day.&#x20;

We can pull the data using python:

```python
from gridstatusio import GridStatusClient
import os

GS_KEY = os.environ["GS_API_KEY"]
client = GridStatusClient(GS_KEY)

df = client.get_dataset(
    dataset = 'ieso_adequacy_report_forecast',
    start = '2025-04-20',
    end = '2025-04-26',
    timezone = 'US/Eastern',
    )
df.columns

```

and then plot the forecasts of peak demand across that period of time:

```python
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

pivot = df.pivot_table(
    index='interval_start_local',
    columns='publish_time_local',
    values='ontario_peak_demand'
)

times = pivot.columns.sort_values()
cmap = plt.get_cmap('plasma')
colors = [cmap(i/(len(times)-1)) for i in range(len(times))]

plt.style.use('default')
plt.rcParams.update({
    'font.size': 14,
    'text.color': 'black',
    'axes.labelcolor': 'black',
    'xtick.color': 'black',
    'ytick.color': 'black',
    'figure.facecolor': 'white',
    'axes.facecolor':   'white',
})

# 5. Plot all lines without a legend
fig, ax = plt.subplots(figsize=(12, 6))
for t, col in zip(times, colors):
    ax.plot(pivot.index, pivot[t], color=col, linewidth=2)

# 6. Remove chart border
for spine in ax.spines.values():
    spine.set_visible(False)

ax.set_ylim(10000, 20000)
ax.grid(axis='y', linestyle='--', linewidth=0.5)
ymin, ymax = ax.get_ylim()
ax.axhline(y=ymin, color='black', linewidth=1)

ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: f'{int(x/1000)}k'))
y_pos = ymax - 0.02 * (ymax - ymin)

oldest, newest = times[0], times[-1]
bbox_props = dict(boxstyle='round,pad=0.3', facecolor='lightgrey', edgecolor='none')
ax.text(
    pivot.index[0], y_pos,
    f'Oldest: {oldest.strftime("%Y-%m-%d %H:%M")}',
    va='top', ha='left',
    color=colors[0],
    fontsize=12,
    fontweight='bold',
    bbox=bbox_props
)
ax.text(
    pivot.index[-1], y_pos,
    f'Newest: {newest.strftime("%Y-%m-%d %H:%M")}',
    va='top', ha='right',
    color=colors[-1],
    fontsize=12,
    fontweight='bold',
    bbox=bbox_props
)

ax.set_title('Ontario Peak Demand by Publish Time', pad=16, color='black')
ax.set_xlabel(None)
ax.set_ylabel('MW')

plt.tight_layout()
plt.show()

```

And here's the plot.

<figure><img src="/files/QYnJuhMNm4mZr4eQyHuc" alt=""><figcaption></figcaption></figure>

To make this even easier, we recently lauched the beta verison of a new Forecast Analysis app.&#x20;

This new tool allows you to view forecast vintages and actuals in a graph, table, or both. Currently, we support IESO's Onatrio Load forecast, Wind and Solar, and total outages.&#x20;

<figure><img src="/files/UCchwAUZraj37p1POxgv" alt=""><figcaption></figcaption></figure>

Give the beta a test [here](https://www.gridstatus.io/forecast-analysis) and pass along any impressions and feedback!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.gridstatus.io/data-guides/market-guides/independent-electricity-system-operator-ieso.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
