Supervisory Banking Statistics - SUP

Data - ECB

Last observation: Q1 2026 (N = 14814) · H2 2025 (N = 1248)

First observation: Q2 2015 (N = 3908) · H1 2018 (N = 436)

Last data update: 01 sept. 2026, 04:06

Last compile: 02 sept. 2026, 23:44

Structure

Info

  • Data Structure Definition (DSD). html

Performance Indicators

https://www.bankingsupervision.europa.eu/banking/statistics/html/index.en.html

Return on equity

Graph

significant institutions (SIs) and less significant institutions (LSIs):

Code
SUP |>
  filter(grepl("Return on equity", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE"),
         BS_SUFFIX == "PCT") |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Return on equity") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(7) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-100, 100, 2),
                     labels = percent_format(accuracy = 1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

Cost-to-income ratio

Code
SUP |>
  filter(grepl("Cost-to-income ratio", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE"),
         BS_SUFFIX == "PCT") |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Cost-to-income Ratio") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(7) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-10, 100, 10),
                     labels = percent_format(accuracy = .1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

Net interest income

FR, IT, DE

Code
SUP |>
  filter(grepl("Net interest income", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE"),
         BS_SUFFIX == "PCT") |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net Interest Income/Total operating income") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(7) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-10, 100, 10),
                     labels = percent_format(accuracy = .1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

FR, IT, DE, ES, NL, SI

Net interest margin

FR, IT, DE

Code
SUP |>
  filter(grepl("Net interest margin", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE")) |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net Interest Margin") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(6) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-10, 50, 0.1),
                     labels = percent_format(accuracy = .1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

FR, IT, DE, ES, NL, SI

Code
SUP |>
  filter(grepl("Net interest margin", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE", "ES", "NL", "SI"),
         SBS_DI_1 == "SII") |>
  quarter_to_date() |>
  arrange(desc(date)) |>
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net Interest Margin") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color)) + 
  add_flags(6) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-10, 50, 0.1),
                     labels = percent_format(accuracy = .1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

FR, IT, DE, ES, NL, BE, AT, PT

2015-

Code
SUP |>
  filter(grepl("Net interest margin", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE", "ES", "NL", "BE", "AT", "PT"),
         SBS_DI_1 == "SII") |>
  quarter_to_date() |>
  arrange(desc(date)) |>
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net Interest Margin") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color)) + 
  add_flags(8) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-10, 50, 0.1),
                     labels = percent_format(accuracy = .1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

2018-

Code
SUP |>
  filter(grepl("Net interest margin", TITLE),
         REF_AREA %in% c("U2", "FR", "IT", "DE", "ES", "NL", "BE", "AT", "PT"),
         SBS_DI_1 == "SII") |>
  quarter_to_date() |>
  filter(date >= as.Date("2018-01-01")) |>
  arrange(desc(date)) |>
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net Interest Margin") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color)) + 
  add_flags(8) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(-10, 50, 0.1),
                     labels = percent_format(accuracy = .1)) +
  theme(legend.position = c(0.25, 0.90),
        legend.title = element_blank())

Liquidity

Liquidity coverage ratios (LCR)

The LCR is the percentage resulting from dividing the bank’s stock of high-quality assets by the estimated total net cash outflows over a 30 calendar day stress scenario.

Code
SUP |>
  filter(CB_ITEM == "I3017",
         REF_AREA %in% c("U2", "FR", "IT", "DE"),
         !(SBS_DI_1 == "_Z")) |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  arrange(desc(date)) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Liquidity coverage ratio") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(6) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(0, 500, 50),
                     labels = percent_format(accuracy = 1),
                     limits = c(0, 3.5)) +
  theme(legend.position = c(0.2, 0.90),
        legend.title = element_blank())

Liquidity buffer

Code
SUP |>
  filter(CB_ITEM == "A6310",
         REF_AREA %in% c("U2", "FR", "IT", "DE")) |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  arrange(desc(date)) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Liquidity buffer") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(6) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = seq(0, 1000, 2)) +
  theme(legend.position = c(0.2, 0.90),
        legend.title = element_blank())

Net liquidity outflow

Code
SUP |>
  filter(CB_ITEM == "A6320",
         REF_AREA %in% c("U2", "FR", "IT", "DE")) |>
  quarter_to_date() %>%
  select_if(~ n_distinct(.) > 1) |>
  arrange(desc(date)) |>
  add_flag_color("Ref_area") |>
  mutate(OBS_VALUE = OBS_VALUE/100) |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net liquidity outflow") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = Sbs_di_1)) + 
  add_flags(6) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = seq(0, 1000, 2)) +
  theme(legend.position = c(0.2, 0.90),
        legend.title = element_blank())

Net liquidity outflow

Code
SUP |>
  filter(grepl("Net liquidity outflow", TITLE),
         REF_AREA %in% c("B01", "FR", "IT", "DE")) |>
  quarter_to_date() |>
  mutate(OBS_VALUE = OBS_VALUE/100,
         Ref_area = ifelse(REF_AREA == "B01", "Europe", Ref_area)) %>%
  select_if(~ n_distinct(.) > 1) |>
  add_flag_color("Ref_area") |>
  na.omit() |>
  ggplot() + theme_minimal() + xlab("") + ylab("Net liquidity outflow") +
  geom_line(aes(x = date, y = OBS_VALUE, color = color, linetype = paste0(SBS_DI_1, SBS_BREAKDOWN))) + 
  add_flags(6) + scale_color_identity() +
  scale_x_date(breaks = seq(1960, 2100, 1) |> paste0("-01-01") |> as.Date(),
               labels = date_format("%Y")) +
  scale_y_continuous(breaks = 0.01*seq(0, 500, 50),
                     labels = percent_format(accuracy = 1),
                     limits = c(0, 3.5)) +
  theme(legend.position = c(0.55, 0.50),
        legend.title = element_blank())

Net Liquidity outflow - EU

B01 - EU countries participating in the Single Supervisory Mechanism (SSM)

Capital adequacy

  • Common equity Tier 1 ratio

  • Tier 1 ratio

https://www.bankingsupervision.europa.eu/press/pr/date/2023/html/ssm.pr2301114cb4953fd6.en.html#::text=The%20aggregate%20capital%20ratios%20of,capital%20ratio%20stood%20at%2018.68%25.