1 Background

1.1 What is BBSW?

The Bank Bill Swap Rate (BBSW) is Australia’s key short-term interest rate benchmark. It represents the mid-rate for Australian dollar-denominated bank bills (BABs/NCDs) traded in the interbank market.

BBSW is used to:

  • Price floating-rate bonds, loans, and securitised products
  • Value interest rate swaps and other derivatives
  • Benchmark bank funding costs and monetary policy transmission

ASX calculates BBSW daily using a volume-weighted average price (VWAP) methodology based on market transactions observed between 08:30–10:00 AEST. Since January 2017, ASX has been the sole administrator (replacing AFMA).

1.2 Interpretation Guide

  • Rates are expressed as annualised percentage yields (e.g., 4.30 = 4.30% p.a.)
  • Higher rates indicate tighter liquidity or higher credit/term premia
  • The spread between tenors (e.g., 6M minus 1M) reflects the term premium
  • BBSW typically moves in response to:
    • RBA cash rate decisions and forward guidance
    • Bank funding conditions and credit risk sentiment
    • Seasonal liquidity patterns (e.g., quarter-end, year-end)
  • An inverted curve (short rates > long rates) can signal expectations of future rate cuts

1.3 Data Source

Item Detail
Source Reserve Bank of Australia — Statistical Table F1
Title Interest Rates and Yields – Money Market – Daily
URL https://www.rba.gov.au/statistics/tables/#interest-rates
Direct download https://www.rba.gov.au/statistics/tables/xls/f01d.xlsx
Tenors available 1-month, 3-month, 6-month (EOD BABs/NCDs)
R package readrba by Matt Cowgill — CRAN

Note: The 2-month, 4-month, and 5-month tenors are not published by the RBA. These are only available via ASX paid subscription or Bloomberg terminal (tickers BBSW1MBBSW6M Index).

2 Data Extraction

library(readrba)
library(dplyr)
library(tidyr)
library(ggplot2)
library(knitr)
f1 <- read_rba(table_no = "f1")
start_date <- as.Date("2025-01-01")
end_date   <- Sys.Date()

bbsw <- f1 %>%
  filter(
    series %in% c(
      "EOD 1-month BABs/NCDs",
      "EOD 3-month BABs/NCDs",
      "EOD 6-month BABs/NCDs"
    ),
    date >= start_date,
    date <= end_date
  )

bbsw_wide <- bbsw %>%
  select(date, series, value) %>%
  pivot_wider(names_from = series, values_from = value) %>%
  arrange(date) %>%
  rename(
    `1M_BBSW` = `EOD 1-month BABs/NCDs`,
    `3M_BBSW` = `EOD 3-month BABs/NCDs`,
    `6M_BBSW` = `EOD 6-month BABs/NCDs`
  )

Period: 01 January 2025 to 07 April 2026 — 315 trading days

3 Summary Statistics

summary_stats <- bbsw_wide %>%
  summarise(
    across(
      c(`1M_BBSW`, `3M_BBSW`, `6M_BBSW`),
      list(
        Min  = ~ min(., na.rm = TRUE),
        Max  = ~ max(., na.rm = TRUE),
        Mean = ~ round(mean(., na.rm = TRUE), 4),
        Last = ~ last(na.omit(.))
      ),
      .names = "{.fn}_{.col}"
    )
  )

stats_df <- data.frame(
  Statistic = c("Min", "Max", "Mean", "Latest"),
  `1M` = as.numeric(summary_stats[1, c(1, 4, 7, 10)]),
  `3M` = as.numeric(summary_stats[1, c(2, 5, 8, 11)]),
  `6M` = as.numeric(summary_stats[1, c(3, 6, 9, 12)])
)
names(stats_df) <- c("Statistic", "1-Month", "3-Month", "6-Month")

kable(stats_df, align = "lrrr", caption = "BBSW Summary Statistics (% p.a.)")
BBSW Summary Statistics (% p.a.)
Statistic 1-Month 3-Month 6-Month
Min 3.3803 4.3375 3.7953
Max 4.0809 3.4400 4.4075
Mean 3.8551 4.3204 3.6075
Latest 4.8108 4.0357 4.8108

4 Data Preview

4.1 First 10 Trading Days

kable(head(bbsw_wide, 10), caption = "Earliest 10 observations")
Earliest 10 observations
date 1M_BBSW 3M_BBSW 6M_BBSW
2025-01-02 4.3325 4.4075 4.5097
2025-01-03 4.3225 4.3877 4.4782
2025-01-06 4.3375 4.4075 4.5103
2025-01-07 4.3158 4.3777 4.4772
2025-01-08 4.2698 4.3281 4.4356
2025-01-09 4.3114 4.3369 4.4434
2025-01-10 4.3315 4.3628 4.4393
2025-01-13 4.3368 4.3597 4.4585
2025-01-14 4.3150 4.3411 4.4453
2025-01-15 4.3099 4.3484 4.4400

4.2 Last 10 Trading Days

kable(tail(bbsw_wide, 10), caption = "Most recent 10 observations")
Most recent 10 observations
date 1M_BBSW 3M_BBSW 6M_BBSW
2026-03-20 4.0812 4.3075 4.7825
2026-03-23 3.9900 4.2530 4.7355
2026-03-24 4.0500 4.2837 4.7106
2026-03-25 4.0400 4.2810 4.7231
2026-03-26 4.0707 4.3093 4.7589
2026-03-27 4.0785 4.3233 4.7987
2026-03-30 4.0349 4.2952 4.7841
2026-03-31 4.0450 4.3000 4.7750
2026-04-01 4.0100 4.2683 4.7472
2026-04-02 4.0809 4.3204 4.8108

5 Visualisation

5.1 Time Series — All Tenors

bbsw_long <- bbsw_wide %>%
  pivot_longer(
    cols = c(`1M_BBSW`, `3M_BBSW`, `6M_BBSW`),
    names_to = "Tenor",
    values_to = "Rate"
  ) %>%
  mutate(Tenor = factor(Tenor,
    levels = c("1M_BBSW", "3M_BBSW", "6M_BBSW"),
    labels = c("1 Month", "3 Month", "6 Month")
  ))

ggplot(bbsw_long, aes(x = date, y = Rate, colour = Tenor)) +
  geom_line(linewidth = 0.7) +
  labs(
    title   = "Australian Bank Bill Swap Rates (BBSW)",
    subtitle = paste("Daily EOD rates |", format(min(bbsw_wide$date), "%d %b %Y"),
                     "–", format(max(bbsw_wide$date), "%d %b %Y")),
    x = NULL, y = "Rate (% p.a.)", colour = "Tenor",
    caption = "Source: RBA Statistical Table F1 via readrba"
  ) +
  theme_minimal(base_size = 13) +
  theme(legend.position = "top", plot.title = element_text(face = "bold"),
        panel.grid.minor = element_blank()) +
  scale_colour_manual(values = c("1 Month" = "#1b9e77", "3 Month" = "#d95f02", "6 Month" = "#7570b3"))

5.2 Term Spread (6M minus 1M)

A positive spread indicates a normal upward-sloping yield curve. A negative spread suggests the market is pricing in future rate cuts.

spread_df <- bbsw_wide %>%
  mutate(Spread_6M_1M = `6M_BBSW` - `1M_BBSW`) %>%
  filter(!is.na(Spread_6M_1M))

ggplot(spread_df, aes(x = date, y = Spread_6M_1M)) +
  geom_line(colour = "#d95f02", linewidth = 0.7) +
  geom_hline(yintercept = 0, linetype = "dashed", colour = "grey40") +
  labs(
    title    = "BBSW Term Spread (6M minus 1M)",
    subtitle = "Positive = normal curve | Negative = inverted",
    x = NULL, y = "Spread (percentage points)",
    caption = "Source: RBA Statistical Table F1 via readrba"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"), panel.grid.minor = element_blank())

5.3 Yield Curve Snapshot

Comparing today’s short-end curve against 3 months ago.

latest_date  <- max(bbsw_wide$date, na.rm = TRUE)
compare_date <- bbsw_wide %>%
  filter(date <= latest_date - 90) %>%
  pull(date) %>%
  max()

curve_data <- bbsw_wide %>%
  filter(date %in% c(latest_date, compare_date)) %>%
  pivot_longer(
    cols = c(`1M_BBSW`, `3M_BBSW`, `6M_BBSW`),
    names_to = "Tenor", values_to = "Rate"
  ) %>%
  mutate(
    Months = case_when(
      Tenor == "1M_BBSW" ~ 1,
      Tenor == "3M_BBSW" ~ 3,
      Tenor == "6M_BBSW" ~ 6
    ),
    Label = format(date, "%d %b %Y")
  )

ggplot(curve_data, aes(x = Months, y = Rate, colour = Label)) +
  geom_line(linewidth = 1) +
  geom_point(size = 3) +
  scale_x_continuous(breaks = c(1, 3, 6), labels = c("1M", "3M", "6M")) +
  labs(
    title    = "BBSW Yield Curve Snapshot",
    subtitle = paste("Comparing", format(compare_date, "%d %b %Y"),
                     "vs", format(latest_date, "%d %b %Y")),
    x = "Tenor", y = "Rate (% p.a.)", colour = NULL,
    caption = "Source: RBA Statistical Table F1 via readrba"
  ) +
  theme_minimal(base_size = 13) +
  theme(legend.position = "top", plot.title = element_text(face = "bold"),
        panel.grid.minor = element_blank()) +
  scale_colour_manual(values = c("#7570b3", "#d95f02"))

6 Export

library(writexl)
output_file <- "BBSW_2025_to_Today.xlsx"
write_xlsx(bbsw_wide, output_file)

Data exported to BBSW_2025_to_Today.xlsx — 315 rows.


Report generated on 07 April 2026 at 19:25 AEST using R 4.5.1 and readrba.