Encompass Version Analysis

Price Analysis between Encompass Versions 7.2.5 and 7.3.0.

Alyssa Anderson | August 23, 2024

This report compares on-peak and off-peak power prices across ten geographic areas and two distinct scenarios, using data from Encompass 7.3.0 and 7.2.5.

Main Takeaways

In analyzing the differences between Encompass 7.3.0 and 7.2.5, I observe significant price discrepancies across both monthly and hourly data. The areas ERCOT-NORTH and PJM-DOM exhibit the most volatility, with price differences ranging from $0.20 to $30.00. Most of the price discrepancies begin after the year 2030 and appear to occur at random, although with more analysis daily or monthly underlying patterns could emerge.

In the hourly price comparison, results from version 7.3.0 generally trend higher than those from version 7.2.5. Additionally, the daily spreads and spread deltas reveal substantial variability. Unfortunately, further in-depth analysis will be required to understand the reasons behind these discrepancies and pinpoint the source of the differences between the Encompass versions.

Monthly Price Analysis

Show the code
options(repos = c(CRAN = "https://cran.rstudio.com"))


# Setting up libraries
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(snakecase)
library(lubridate)
library(esquisse)
library(writexl)
library(scales)

# import data on monthly prices

area_peak <- read_excel("C:/Users/alanderson/Documents/Area_Fundamental_Prices.xlsx")

# filtering by area and scenario

Scenario1_Minus_Ercot <- area_peak %>%
  filter(scenario == "1a. NERC Market", area != "ERCOT-North")

Scenario2_Minus_Ercot <- area_peak %>%
  filter(scenario == "1a. NERC Market w CO2 Limit", area != "ERCOT-North")

Just_Ercot <- area_peak %>%
  filter(area == "ERCOT-North")

Scenario1_Minus_Ercot_PJM <- Scenario1_Minus_Ercot %>%
  filter(area != "PJM-DOM")

Comparison of Monthly Energy Prices: Encompass 7.2.5 and 7.3.0

  • ERCOT-NORTH was analyzed separately due to larger fluctuations in prices which skewed the axes when compared to other areas.

  • Below is a side-by-side comparison of the monthly on-peak and off-peak power prices in all areas apart from ERCOT-NORTH in the 1a. NERC Market scenario.

  • The graphs initially do not show much variability, however, at a closer look we’ll begin to see differences between the Encompass versions.

    (The red areas are where version 7.3.0 prices differ from 7.2.5)

Show the code
# Plot: Scenario 1, On-peak, minus Ercot
plot_Scenario6 <-  ggplot(Scenario1_Minus_Ercot, aes(x = Date)) +
  geom_line(aes(y = on_peak_price_m_wh_7_3, color = "On-peak Price 7.3")) + 
  geom_line(aes(y = on_peak_price_m_wh_7_2, color = "On-peak Price 7.2")) + 
  scale_color_hue(direction = 1) +
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "1a. NERC Market: Encompass 7.2 and 7.3 On-peak Power Prices",
    subtitle = "(Does Not Include Ercot-North)",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("On-peak Price 7.2" = "lightsteelblue", "On-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(area))
print(plot_Scenario6)

Show the code
# Plot: Scenario 1, Off-peak, minus Ercot
plot_Scenario8 <-  ggplot(Scenario1_Minus_Ercot, aes(x = Date)) +
  geom_line(aes(y = off_peak_price_m_wh_7_3, color = "Off-peak Price 7.3")) + 
  geom_line(aes(y = off_peak_price_m_wh_7_2, color = "Off-peak Price 7.2")) + 
  scale_color_hue(direction = 1) +
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "1a. NERC Market: Encompass 7.2 and 7.3 Off-peak Power Prices",
    subtitle = "(Does Not Include Ercot-North)",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("Off-peak Price 7.2" = "lightsteelblue", "Off-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(area))
print(plot_Scenario8)

  • We see similar outputs for the scenario with carbon dioxide limitations: 1a. NERC Market w CO2 Limit.
Show the code
# Scenario 2, On-peak, minus Ercot
plot_Scenario5 <-  ggplot(Scenario2_Minus_Ercot, aes(x = Date)) +
  geom_line(aes(y = on_peak_price_m_wh_7_3, color = "On-peak Price 7.3")) + 
  geom_line(aes(y = on_peak_price_m_wh_7_2, color = "On-peak Price 7.2")) + 
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "1a. NERC Market w CO2 Limit: Encompass 7.2 and 7.3 On-peak Power Prices",
    subtitle = "(Does Not Include Ercot-North)",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("On-peak Price 7.2" = "lightsteelblue", "On-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(area))
print(plot_Scenario5)

Show the code
# Scenario 2, Off-peak, minus Ercot
plot_Scenario7 <-  ggplot(Scenario2_Minus_Ercot, aes(x = Date)) +
  geom_line(aes(y = off_peak_price_m_wh_7_3, color = "Off-peak Price 7.3")) + 
  geom_line(aes(y = off_peak_price_m_wh_7_2, color = "Off-peak Price 7.2")) + 
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "1a. NERC Market w CO2 Limit: Encompass 7.2 and 7.3 Off-peak Power Prices",
    subtitle = "(Does Not Include Ercot-North)",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("Off-peak Price 7.2" = "lightsteelblue", "Off-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(area))
print(plot_Scenario7)

ERCOT-NORTH Price Comparison

  • Below is an in depth look at the ERCOT-NORTH area as it displayed the greatest price variability.

  • The graphs show that ERCOT-NORTH has more significant differences between the Encompass 7.2.5 and 7.3.0 monthly prices.

Show the code
# Plot: Just Ercot, both Scenarios, On-peak
plot_Scenario5 <-  ggplot(Just_Ercot, aes(x = Date)) +
  geom_line(aes(y = on_peak_price_m_wh_7_3, color = "On-peak Price 7.3")) + 
  geom_line(aes(y = on_peak_price_m_wh_7_2, color = "On-peak Price 7.2")) + 
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "Ercot-North: Encompass 7.2 and 7.3 On-peak Power Prices",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("On-peak Price 7.2" = "lightslategray", "On-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(scenario))
print(plot_Scenario5)

Show the code
# Plot: Just Ercot, both Scenarios, Off-peak
plot_Scenario5 <-  ggplot(Just_Ercot, aes(x = Date)) +
  geom_line(aes(y = off_peak_price_m_wh_7_3, color = "Off-peak Price 7.3")) + 
  geom_line(aes(y = off_peak_price_m_wh_7_2, color = "Off-peak Price 7.2")) + 
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "Ercot-North: Encompass 7.2 and 7.3 Off-peak Power Prices",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("Off-peak Price 7.2" = "lightslategray", "Off-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(scenario))
print(plot_Scenario5)

PJM-DOM

  • PJM-DOM also showed higher volatility, so below the graphs examine this area in more detail.
  • PJM-DOM has a large outlier in the base case in year 2044, which may need to be investigated.
Show the code
# filtering for PJM-DOM
Just_PJM_DOM <- area_peak %>%
  filter(area == "PJM-DOM")
  
# setting date

Just_PJM_DOM$Date <- as.Date(Just_PJM_DOM$Date)

# PJM-DOM both scenarios, on-peak
plot_Scenario5 <-  ggplot(Just_PJM_DOM, aes(x = Date)) +
  geom_line(aes(y = on_peak_price_m_wh_7_3, color = "On-peak Price 7.3")) + 
  geom_line(aes(y = on_peak_price_m_wh_7_2, color = "On-peak Price 7.2")) + 
  scale_color_hue(direction = 1) +
  labs(
    x = NULL,
    y = "Nominal $/MWh",
    title = "PJM-DOM: Encompass 7.2 and 7.3 On-peak Power Prices",
    color = "Area"
  ) +
  theme_minimal() +
  scale_color_manual(values = c("On-peak Price 7.2" = "lightslategray", "On-peak Price 7.3" = "darkred")) +
  facet_wrap(vars(scenario))
print(plot_Scenario5)

Monthly Deltas

Difference Between Monthly Power Prices: Encompass 7.3.0 - Encompass 7.2.5

  • On-peak and Off-Peak Deltas for Scenario: 1a. NERC Market

  • PJM-DOM is still the most volatile, with the deltas trending below zero, indicating that the prices in 7.2.5 are greater than in the 7.3.0 version.

  • ERCOT-NORTH and PJM-DOM have separated graphs below.

Show the code
# All areas Scenario 1 on-peak deltas
graph20 <- ggplot(Scenario1_Minus_Ercot) +
  aes(x = Date, y = on_peak_price_delta) +
  geom_line() +
  scale_color_hue(direction = 1)+
  labs(
    y = "On-peak Price Delta",
    x= NULL,
    title = "1a. NERC Market: On-peak Price Difference by Area",
    subtitle = "Delta = Difference Between Encompass Versions 7.3.0 and 7.2.5"
  ) +
  theme_minimal() +
  facet_wrap(vars(area))
print(graph20)

Show the code
# all areas scenario 1, on-peak, minus PJM-DOM

minuspjm <- ggplot(Scenario1_Minus_Ercot_PJM) +
  aes(x = Date, y = on_peak_price_delta) +
  geom_line(colour = "#112446") +
  labs(
    y = "On-peak Price Delta",
    x= NULL,
    title = "1a. NERC Market: On-peak Price Difference (Minus PJM-DOM & ERCOT)",
    subtitle = "Delta = Difference Between Encompass Versions 7.3.0 and 7.2.5"
  ) +
  theme_minimal() +
  facet_wrap(vars(area))
print(minuspjm)

Show the code
# all off peak 
minuspjm1 <- ggplot(Scenario1_Minus_Ercot_PJM) +
  aes(x = Date, y = off_peak_price_delta) +
  geom_line(colour = "#112446") +
  labs(
    y = "Off-peak Price Delta",
    x= NULL,
    title = "1a. NERC Market: Off-peak Price Difference (Minus PJM-DOM & ERCOT)",
    subtitle = "Delta = Difference Between Encompass Versions 7.3.0 and 7.2.5"
  ) +
  theme_minimal() +
  facet_wrap(vars(area))
print(minuspjm1)

ERCOT-NORTH Deltas

  • The monthly prices show considerable difference in the ERCOT-NORTH area between the Encompass versions.
Show the code
#Ercot onpeak Deltas

ercot1 <- ggplot(Just_Ercot) +
  aes(x = Date, y = on_peak_price_delta, colour = scenario) +
  geom_line() +
  scale_color_hue(direction = 1) +
  labs(
    y = "On-peak Price Delta",
    x= NULL,
    title = "ERCOT-NORTH: On-peak Price Difference by Scenario",
    subtitle = "Delta = Difference between Encompass Versions 7.3.0 and 7.2.5",
    color = "Scenario"
  ) +
  theme_minimal() +
  facet_wrap(vars(scenario))
print(ercot1)

Show the code
#Ercot offpeak Deltas

ercot2 <- ggplot(Just_Ercot) +
  aes(x = Date, y = off_peak_price_delta, colour = scenario) +
  geom_line() +
  scale_color_hue(direction = 1) +
  labs(
    y = "Off-peak Price Delta",
    x = NULL,
    title = "ERCOT-NORTH: Off-peak Price Difference by Scenario",
    subtitle = "Delta = Difference Between Encompass Versions 7.3.0 and 7.2.5",
    color = "Scenario"
  ) +
  theme_minimal() +
  facet_wrap(vars(scenario))
print(ercot2)

PJM-DOM Deltas

Show the code
# on-peak deltas PJM-DOM

pjm1 <- ggplot(Just_PJM_DOM) +
  aes(x = Date, y = on_peak_price_delta, colour = scenario) +
  geom_line() +
  scale_color_hue(direction = 1) +
  labs(
    y = "On-peak Price Delta",
    x= NULL,
    title = "PJM-DOM: On-peak Price Difference by Scenario",
    subtitle = "Delta = Difference between Encompass Versions 7.3.0 and 7.2.5",
    color = "Scenario"
  ) +
  theme_minimal() +
  facet_wrap(vars(scenario))
print(pjm1)

Show the code
# off-peak deltas PJM-DOM

pjm2 <- ggplot(Just_PJM_DOM) +
  aes(x = Date, y = off_peak_price_delta, colour = scenario) +
  geom_line() +
  scale_color_hue(direction = 1) +
  labs(
    y = "Off-peak Price Delta",
    x = NULL,
    title = "PJM-DOM: Off-peak Price Difference by Scenario",
    subtitle = "Delta = Difference Between Encompass Versions 7.3.0 and 7.2.5",
    color = "Scenario"
  ) +
  theme_minimal() +
  facet_wrap(vars(scenario))
print(pjm2)

Hourly Price Analysis

Show the code
# import data

hourly_prices_7.2 <- read_excel("C:/Users/alanderson/Documents/7.3_Area Interval Report - MISO-IN-KY 2045.xlsx", sheet = "Base Case 7.2")

hourly_prices_7.3 <- read_excel("C:/Users/alanderson/Documents/7.3_Area Interval Report - MISO-IN-KY 2045.xlsx", sheet = "Area Interval 7.3")

# merge

merged_hourly <- merge(hourly_prices_7.2, hourly_prices_7.3, by = c("Scenario", "RunID", "BA", "Area", "Year", "Month", "Day", "Interval"), suffixes= c("_7.2", "_7.3"))

# rename Energy Column

hourly1 <- merged_hourly %>%
  rename(energy_price_7.3 = "Energy Price ($/MWh)_7.3")
hourly1 <- hourly1 %>%
  rename(energy_price_7.2 = "Energy Price ($/MWh)_7.2")

# create deltas

hourly1 <- hourly1 %>%
  mutate(
    energy_price_deltas = round(energy_price_7.3 - energy_price_7.2, digits = 4),
  )

# create a date column

hourly1$datetime <- make_datetime(year= hourly1$Year,
                                  month = hourly1$Month,
                                  day = hourly1$Day,
                                  hour = hourly1$Interval
                                    )

# creating daily min and max prices 

daily_spread_7.2 <- hourly1 %>%
  mutate(date = as.Date(datetime))%>%
  group_by(date) %>%
  summarise(daily_min = min(energy_price_7.2, na.rm =TRUE),
            daily_max = max(energy_price_7.2, na.rm = TRUE))


daily_spread_7.2 <- daily_spread_7.2 %>%
  mutate(
    daily_spread = round(daily_max - daily_min, digits = 4),
  )

daily_spread_7.3 <- hourly1 %>%
  mutate(date = as.Date(datetime))%>%
  group_by(date) %>%
  summarise(daily_min = min(energy_price_7.3, na.rm =TRUE),
            daily_max = max(energy_price_7.3, na.rm = TRUE))

daily_spread_7.3 <- daily_spread_7.3 %>%
  mutate(
    daily_spread = round(daily_max - daily_min, digits = 4),
  )

# merge by date

merged_daily_spread <- merge(daily_spread_7.2, daily_spread_7.3, by = c("date"), suffixes= c("_7.2", "_7.3"))

# find daily spread deltas

merged_daily_spread <- merged_daily_spread %>%
  mutate(
    daily_spread_deltas = round(daily_spread_7.3 - daily_spread_7.2, digits = 4),
  )

Comparison of Hourly Energy Prices: Encompass 7.2.5 and 7.3.0

  • The graph below shows the hourly energy prices from both Encompass versions in the MISO-IN-KY area for the year 2045 in scenario 1a. NERC Market. The prices seem to align closely with minor fluctuations, however, when see greater differences when looking at the deltas.
Show the code
# comparison of hourly price in 7.2 and 7.3

hourly_plot2 <- ggplot(hourly1, aes(x = datetime)) +
  geom_line(aes(y = energy_price_7.3, color = "Energy Price 7.3")) + 
  geom_line(aes(y = energy_price_7.2, color = "Energy Price 7.2")) + 
   labs(
    y = "Energy Price $/MWh",
    x = NULL,
    title = "MISO-IN-KY: 2045 Hourly Energy Price Comparisons",
    colour = NULL,
    subtitle = "Deltas = Difference Between Encompass Versions 7.3.0 and 7.2.5"
  ) +
  scale_color_manual(values = c("Energy Price 7.2" = "lightslategray", "Energy Price 7.3" = "darkred")) +
  theme_minimal()
print(hourly_plot2)

Difference Between Hourly Energy Prices: Encompass 7.3.0 - Encompass 7.2.5

  • Price Volatility: There is notable volatility between the two Encompass hourly price outputs, which was not visible when comparing the energy prices in the previous graph.

  • Most of the deltas tend to be greater than zero, indicating that 7.3.0 hourly prices are trending higher than 7.2.5 hourly prices.

Show the code
hourly_plot <- ggplot(hourly1) +
  aes(x = datetime, y = energy_price_deltas) +
  geom_line(colour = "#409FBC") +
  labs(
    y = "Energy Price Deltas",
    x = NULL,
    title = "MISO-IN-KY: 2045 Hourly Energy Price Deltas",
    subtitle = "Deltas = Difference Between Encompass Versions 7.3.0 and 7.2.5"
  ) +
  theme_minimal()
print(hourly_plot)

Comparison of Daily Spreads: Encompass 7.2.5 and 7.3.0

  • The first graph overlays the daily spreads of maximum and minimum energy prices for Encompass versions 7.2.5 and 7.3.0, allowing for direct comparison of each versions price volatility.

  • The second graph takes the difference between the two spreads. There are considerable deviations from zero, showing that the daily spreads are not equal between the Encompass versions.

Show the code
# comparison of daily spreads

daily_plot2 <- ggplot(merged_daily_spread, aes(x = date)) +
  geom_line(aes(y = daily_spread_7.3, color = "Daily Spread 7.3")) + 
  geom_line(aes(y = daily_spread_7.2, color = "Daily Spread 7.2")) + 
   labs(
    y = "Daily Spread",
    x = NULL,
    title = "MISO-IN-KY: 2045 Daily Spread Energy Price Comparisons",
    colour = NULL,
    subtitle = "Daily Spread = Difference between MAX and MIN Energy Prices per Day"
  ) +
  scale_color_manual(values = c("Daily Spread 7.2" = "lightslategray", "Daily Spread 7.3" = "darkred")) +
  theme_minimal()
print(daily_plot2)

Show the code
# daily spread deltas
daily_plot <- ggplot(merged_daily_spread) +
  aes(x = date, y = daily_spread_deltas) +
  geom_line(colour = "#4682B4") +
  labs(
    y = "Daily Spread Deltas",
    x = NULL,
    title = "MISO-IN-KY: 2045 Daily Energy Price Spread",
    subtitle = "Spread = Difference between the MIN and MAX Daily Energy Prices; Deltas = Difference Between Encompass Versions 7.3.0 and 7.2.5"
  )+
  theme_minimal()
 print(daily_plot)

Conclusion

From this rudimentary analysis, the energy price outputs from Encompass version 7.3.0 and 7.2.5 are not equal, and more research is needed to determine the root cause of the discrepancies.

Appendix

Data Sources:

Monthly Data: ACES-SP24 Base Case Monthly Power Prices (7.2.5); Area Monthly 7.3

Hourly Data: Select Hourly Shapes from ACES SP24 Base Case (7.2.5); Area Interval Report 7.3

Areas:

  • CAISO-SP15

  • ERCOT-North

  • MISO-IN-KY

  • MISO-ND-MN

  • PJM-AD

  • PJM-DOM

  • SERC-NC-SC

  • SERC-SOCO

  • SPP-SPS

  • WECC-ECO

Scenarios:

  • 1a. NERC Market

  • 1a. NERC Market w CO2 Limit


MISO-IN-KY Monthly Price Graphs

Show the code
# filtering for MISO-IN-KY
Scenario1_MISO_IN <- area_peak %>%
  filter(scenario== "1a. NERC Market", area == "MISO-IN-KY")

Scenario2_MISO_IN <- area_peak %>%
  filter(scenario== "1a. NERC Market w CO2 Limit", area == "MISO-IN-KY")

# setting date
Scenario1_MISO_IN$Date <- as.Date(Scenario1_MISO_IN$Date)
Scenario2_MISO_IN$Date <- as.Date(Scenario2_MISO_IN$Date)


# Plot: MISO Scenario 1 offpeak
plot_Scenario1 <- ggplot(Scenario1_MISO_IN, aes(x = Date)) + 
  geom_line(aes(y = off_peak_price_m_wh_7_3, color = "Off-peak Price 7.3")) + 
  geom_line(aes(y = off_peak_price_m_wh_7_2, color = "Off-peak Price 7.2")) + 
  labs( 
    y = "Nominal $/MWh", 
    x = NULL, 
    color = "Encompass Version", 
    title = paste("1a. NERC Market, MISO-IN-KY: Encompass 7.2 and 7.3 Off-peak Power Prices")) + 
  theme_minimal() + 
  scale_color_manual(values = c("Off-peak Price 7.2" = "darkgreen", "Off-peak Price 7.3" = "red")) + 
  scale_x_date(date_labels = "%m/%Y", 
               date_breaks = "8 months") + 
  scale_y_continuous(labels = scales::label_dollar()) + 
  theme(axis.text.x = element_text(size = 6, angle = 90, vjust = 0.5, hjust = 0.5))+
  facet_grid(~ scenario)
print(plot_Scenario1)

Show the code
# Plot: MISO Scenario 1 onpeak
plot_Scenario1 <- ggplot(Scenario1_MISO_IN, aes(x = Date)) + 
  geom_line(aes(y = on_peak_price_m_wh_7_3, color = "On-peak Price 7.3")) + 
  geom_line(aes(y = on_peak_price_m_wh_7_2, color = "On-peak Price 7.2")) + 
  labs( 
    y = "Nominal $/MWh", 
    x = NULL, 
    color = "Encompass Version", 
    title = paste("1a. NERC Market, MISO-IN-KY: Encompass 7.2 and 7.3 On-peak Power Prices")) + 
  theme_minimal() + 
  scale_color_manual(values = c("On-peak Price 7.2" = "darkgreen", "On-peak Price 7.3" = "red")) + 
  scale_x_date(date_labels = "%m/%Y", 
               date_breaks = "8 months") + 
  scale_y_continuous(labels = scales::label_dollar()) + 
  theme(axis.text.x = element_text(size = 6, angle = 90, vjust = 0.5, hjust = 0.5))+
  facet_grid(~ scenario)
print(plot_Scenario1)