Market Performance Standards

Uncapped Performance Charges

The data below shows performance charges before the cap has been applied (known as uncapped charges). The actual amount of charges payable for underperformance against the Market Performance Standards will have a cap applied. The maximum amount charged in a month will be the capped amount. If uncapped charges fall below the capped amount, the entire uncapped charge will be payable. More information can be found in Section 3.4 and 3.5 of CSD 0002: Market Performance Framework.

tryCatch(
  expr = {
  mps_data_clean_temp %>%
    dplyr::filter(
      Period <= data.period
      ) %>%
    dplyr::select(
      Trading.Party.ID, Period, Standard, Charges, Group
      ) %>%
    ggplot2::ggplot(
      ggplot2::aes(x = Period, y = Charges, fill = Group)
      ) + 
    ggplot2::geom_bar(stat = "identity") + 
    ggplot2::theme(
      legend.title = ggplot2::element_blank(),
      text = ggplot2::element_text(size = 15)
      ) +
    ggplot2::scale_y_continuous(
      labels = scales::dollar_format(prefix = "£"),
      breaks = scales::pretty_breaks(4)
      ) +
    ggplot2::theme_bw() +
    ggplot2::scale_fill_manual(values = c("#425563", "#05C3DE", "#005F83", "#00A499", "#FFAA4D", "#F9E547", "#8866BC")) +
    ggplot2::labs(
      title = "Performance Charges",
      subtitle = "Breakdown by month and standard grouping",
      caption = "Source: MOSL"
      ) +
    ggplot2::ylab("") + ggplot2::xlab("")
  }, error = function(e){}
)
MPS_grouping <- dplyr::tibble(
  "Customer Access" = c("MPS 1", "MPS 2", "MPS 3", "MPS 4", "MPS 5",""), 
  "Disconnection/ Reconnection" = c("MPS 6", rep("", 5)),
  "Meter Read Submission" = c("MPS 7", "MPS 8", "MPS 9", "MPS 10", "MPS 11", ""),
  "Cyclic Meter Reads" = c("MPS 12", "MPS 13", "MPS 14", "MPS 15", "MPS 18", "MPS 19"),
  "Transfer Reads" = c("MPS 16", "MPS 17", rep("", 4))
  )

MPS_grouping %>% 
  kableExtra::kable(
    format = "latex", 
    caption = "Details of MPS Groupings",
    linesep = "",
    format.args = list(big.mark = ","),
    booktabs = TRUE,
    align = "c"
    ) %>%
  kableExtra::kable_styling(
    font_size = 10,
    latex_options = c(
      "repeat_header",
      "HOLD_position",
      "striped",
      position = "center", 
      full_width = FALSE
      )
    ) %>%
  kableExtra::row_spec(0, bold = TRUE) %>%
  kableExtra::column_spec(1:ncol(MPS_grouping), width = "2.4cm")
# Creating table of charges by MPS ---------------- 

tryCatch(
  expr = {
  mps_data_clean_temp %>%
    dplyr::filter(
      Period >= data.period %m-% months(11)
      ) %>%
    dplyr::select(Period, Standard, Charges) %>%
    dplyr::mutate(
      Period = format(Period, "%Y-%m")
      ) %>% 
    tidyr::spread(Standard, Charges) %>%
    dplyr::mutate(
      Total = rowSums(dplyr::select(., -Period), na.rm = TRUE)
      ) %>%
    dplyr::mutate_if(~ any(is.na(.)), ~ ifelse(is.na(.), 0, .)) %>%
    dplyr::mutate_if(is.numeric, scales::dollar_format(prefix = "£")) %>%
    kableExtra::kable(
      format = "latex", 
      caption = "Breakdown of Charges by Standard", 
      linesep = "",
      format.args = list(big.mark = ","),
      booktabs = TRUE,
      align = "c"
      ) %>%
    kableExtra::kable_styling(
      font_size = 10,
      latex_options = c(
        "repeat_header",
        "HOLD_position",
        "striped",
        position = "center", 
        full_width = FALSE,
        "scale_down"
        )
      ) %>%
    kableExtra::row_spec(0, bold = TRUE)
  }, error = function(e){}
)

Performance Overview

As of r format(data.period, "%B-%Y"), MOSL were monitoring r SHORT.NAME's performance against r nrow(perf_status_mps_temp) standards. The performance of Trading Parties against these standards is measured according to:

tryCatch(
  expr = {
  agg_perf <- mps_aggregate_perf %>%
    dplyr::filter(Trading.Party.ID == TRADING.PARTY) %>%
    dplyr::select(Period, Agg_Perf_roll) %>%
    dplyr::rename(GroupPerf = Agg_Perf_roll) %>%
    dplyr::mutate(Group = "Aggregate Performance")

  mps_data_clean_temp %>%
    dplyr::group_by(Period, Group) %>%
    dplyr::summarise(
      GroupPerf = sum(OnTimeTasks) / sum(TaskVolume)
      ) %>%
    dplyr::ungroup() %>%
    dplyr::group_by(Group) %>%
    dplyr::mutate(
      GroupPerf = zoo::rollapply(GroupPerf, 6, mean, align = "right", fill = NA)
      ) %>%
    dplyr::ungroup() %>%
    base::rbind(., agg_perf) %>%
    droplevels() %>%
    tidyr::drop_na() %>%
    ggplot2::ggplot() + 
    ggplot2::geom_line(
      ggplot2::aes(
        x = Period, 
        y = GroupPerf, 
        colour = Group,
        linetype = Group
        )
      ) +
    ggplot2::geom_point(
      ggplot2::aes(
        x = Period, 
        y = GroupPerf,
        colour = Group,
        fill = Group,
        shape = Group
        )
      ) +
    ggplot2::theme(
      legend.title = ggplot2::element_blank(),
      text = ggplot2::element_text(size = 15)
      ) +
    ggplot2::scale_y_continuous(
      labels = scales::percent_format(accuracy = 1),
      breaks = scales::pretty_breaks(4)
      ) +
    ggplot2::theme_bw() + 
    ggplot2::scale_colour_manual(
      values = c("#425563", "#05C3DE", "#005F83", "#00A499", "#FFAA4D", "#F9E547", "#8866BC")
      ) +
    ggplot2::scale_fill_manual(
      values = c("#425563", "#05C3DE", "#005F83", "#00A499", "#FFAA4D", "#F9E547", "#8866BC")
      ) +
    ggplot2::labs(
      title = paste0("MPS On-Time Task Completion: ", SHORT.NAME),
      subtitle = "Breakdown by month and standard",
      caption = "Source: MOSL\nNote: Aggregate performance corresponds to the 6-month average of aggregate MPS performance"
      ) +
    ggplot2::ylab("") + ggplot2::xlab("")
  }, 
  error = function(e){}
)
tryCatch(
  expr = {
  mps_data_clean_temp %>% 
    dplyr::filter(
      Period >= max(mps_data_clean_temp$Period) %m-% months(11)
      ) %>%
    dplyr::mutate(
      Performance = scales::percent(Performance, accuracy = 1),
      Period = format(Period, "%Y-%m")
      ) %>%
    dplyr::select(
      Period, Standard, Performance
      ) %>%
    tidyr::spread(key = Standard, value = Performance) %>%
    kableExtra::kable(
      format = "latex", 
      caption = "MPS Performance by Month",
      linesep = "",
      format.args = list(big.mark = ","),
      booktabs = TRUE,
      align = "c"
      ) %>%
    kableExtra::kable_styling(
      font_size = 10,
      latex_options = c(
        "repeat_header",
        "HOLD_position",
        "striped",
        position = "center", 
        full_width = FALSE,
        "scale_down"
        )
      ) %>%
    kableExtra::row_spec(0, bold = TRUE)
  }, error = function(e){}
)

r SHORT.NAME's 6-month aggregate MPS performance is r scales::percent(mps_aggregate_perf_temp$Agg_Perf_roll, accuracy = 1), which currently ranks as:

tryCatch(
  expr = {
  mps_aggregate_perf %>%
    dplyr::filter(Period == data.period) %>%
    ggplot2::ggplot() +
    ggplot2::geom_bar(
      ggplot2::aes(
        x = reorder(ShortName, -rank_league), 
        y = Agg_Perf_roll,
        fill = dplyr::if_else(Trading.Party.ID == TRADING.PARTY, "highlight", "normal")
        ), 
      stat = "identity",
      show.legend = FALSE
      ) +
    ggplot2::scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
    ggplot2::scale_fill_manual(values = c("#425563", "azure3")) +
    ggplot2::coord_flip() +
    ggplot2::theme_bw() +
    ggplot2::theme(text = ggplot2::element_text(size = 15)) +
    ggplot2::labs(
      title = "Peer Comparison Tables: Market Performance Standards",
      subtitle = "Six-month rolling aggregate performance",
      caption = "Source: MOSL", x = "", y = ""
      ) +
    ggplot2::facet_wrap(~LeagueGroup, scales = "free", ncol = 2)
  }, 
  error = function(e){}
)

The current status of r SHORT.NAME's performance against each standard and performance measure as of r format(data.period, "%B-%Y") is summarised in the table(s) below.

``` {r message = FALSE, echo = FALSE, error = FALSE, warning = FALSE, results = "asis"}

tryCatch( expr = { perf_status_mps_temp %>% dplyr::select(Standard, SecondaryCategory, TaskVolume, Performance, Status, Action) %>% dplyr::mutate( Status = tidyr::replace_na(Status, ""), TaskVolume = scales::comma(TaskVolume, accuracy = 1), Performance = scales::percent(Performance, accuracy = 1) ) %>% kableExtra::kable( format = "latex", caption = "Current Status of MPS", linesep = "", booktabs = TRUE, col.names = c("MPS", "Category", "Task\nVolume", "Performance", "Rectification\nStatus", "MOSL\nAction") ) %>% kableExtra::kable_styling( latex_options = c( "repeat_header", "HOLD_position", "striped", position = "center", full_width = FALSE, "scale_down" ) ) %>% kableExtra::row_spec(0, bold = TRUE) }, error = function(e){} )

See Appendix for an explanation of how MOSL evaluates Trading Party performance against the standards.

```r

tryCatch(
  expr = {
  perf_status_mps_temp %>%
    ggplot2::ggplot() +
    ggrepel::geom_label_repel(
      ggplot2::aes(
        x = rolling.sd,
        y = rolling.mean,
        label = Standard,
        fill = Group
        ), 
      alpha = 0.8,
      colour = "white"
      ) +
    ggplot2::scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
    ggplot2::scale_x_reverse(labels = scales::percent_format(accuracy = 1)) +
    ggplot2::theme_bw() +
    ggplot2::scale_fill_manual(
      values = c("#425563", "#05C3DE", "#005F83", "#00A499", "#FFAA4D", "#F9E547", "#8866BC")
      ) +
    ggplot2::theme(
      text = ggplot2::element_text(size = 15)
      ) +
    ggplot2::labs(
      title = paste0("MPS Performance and Consistency as of ", format(as.Date(data.period), '%B %Y')),
      subtitle = "Rolling 6-month mean and standard deviation of MPS performance",
      caption = "Source: MOSL"
      ) +
    ggplot2::ylab("Performance") + ggplot2::xlab("Consistency")
  }, error = function(e){}
)

Detailed Analysis

mps_list <- unique(as.character(perf_status_mps_temp$Standard))

res <- lapply(mps_list, function (MPS_CHUNK) {

  knitr::knit_child(
    "pfm_report_mps_template.Rmd", envir = environment(), quiet = TRUE
    )
  }
  )

cat(unlist(res), sep = "\n")

\newpage

Market Aggregates

metrics.list <- c("MarketMean", "MarketTaskVolume")

for (METRIC in metrics.list) {

  mps_summary %>% 
    dplyr::select(
      Period, Standard, METRIC
      ) %>% 
    dplyr::filter(
      Period >= data.period %m-% months(11)
      ) %>% 
    dplyr::mutate(Period = format(Period, "%Y-%m")) %>%
    tidyr::spread(Period, METRIC) %>%
    dplyr::mutate_if(
      is.numeric, 
      ifelse(
        METRIC != "MarketTaskVolume", 
        scales::percent_format(accuracy = 1), 
        scales::number_format(big.mark = ",", accuracy = 1)
        )
      ) %>%
    kableExtra::kable(
      format = "latex", 
      caption = paste0("Market ", base::gsub("Market", x = METRIC, replacement = " ")), 
      linesep = "",
      digits = 1,
      booktabs = TRUE,
      align = "c"
      ) %>%
    kableExtra::kable_styling(
      latex_options = c(
        "repeat_header",
        "HOLD_position",
        "striped",
        "scale_down"
        )
      ) %>%
    kableExtra::row_spec(0, bold = TRUE) %>%
    print()

  cat("\n")

}


austl001/MOSLR documentation built on Aug. 17, 2022, 12:07 a.m.