Setup and Load
Packages
library(dplyr)
library(knitr)
library(tidyverse)
library(lubridate)
library(kableExtra)
library(pander)
Directory Setup
# ============================================================================
# PATH SETUP
# ============================================================================
BASE_PATH <- "C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025"
DATA_PROC <- file.path(BASE_PATH, "01_data/processed")
# Output directories
OUTPUT_PATH <- file.path(BASE_PATH, "03_documentation/borrowing_t_stat")
TABLE_PATH <- file.path(OUTPUT_PATH, "tables")
FIG_PATH <- file.path(OUTPUT_PATH, "figures")
# Create directories if they don't exist
dir.create(TABLE_PATH, recursive = TRUE, showWarnings = FALSE)
dir.create(FIG_PATH, recursive = TRUE, showWarnings = FALSE)
cat("Output directories:\n")
## Output directories:
cat(" Tables:", TABLE_PATH, "\n")
## Tables: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables
cat(" Figures:", FIG_PATH, "\n")
## Figures: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/figures
Helper Functions
# ==============================================================================
# HELPER FUNCTIONS
# ==============================================================================
# Safe division to avoid Inf/NaN
safe_div <- function(num, denom) {
result <- num / denom
result[!is.finite(result)] <- NA_real_
return(result)
}
# Format numbers with commas
fmt_num <- function(x, digits = 2) {
formatC(x, format = "f", digits = digits, big.mark = ",")
}
# Calculate T-statistic for difference in means (Welch's t-test)
# Returns only t-statistic (for backward compatibility)
calc_tstat <- function(vals1, vals2) {
# Remove NAs
vals1 <- vals1[!is.na(vals1)]
vals2 <- vals2[!is.na(vals2)]
n1 <- length(vals1)
n2 <- length(vals2)
# Need at least 2 observations in each group
if (n1 < 2 | n2 < 2) return(NA_real_)
mean1 <- mean(vals1)
mean2 <- mean(vals2)
var1 <- var(vals1)
var2 <- var(vals2)
# Welch's t-statistic
se <- sqrt(var1/n1 + var2/n2)
if (se == 0 | !is.finite(se)) return(NA_real_)
t_stat <- (mean1 - mean2) / se
return(t_stat)
}
# ==============================================================================
# NEW: Calculate T-statistic with p-value and significance stars
# ==============================================================================
calc_tstat_with_stars <- function(vals1, vals2) {
# Remove NAs
vals1 <- vals1[!is.na(vals1)]
vals2 <- vals2[!is.na(vals2)]
n1 <- length(vals1)
n2 <- length(vals2)
# Need at least 2 observations in each group
if (n1 < 2 | n2 < 2) {
return(list(tstat = NA_real_, pval = NA_real_, stars = ""))
}
# Perform Welch's t-test
test_result <- tryCatch({
t.test(vals1, vals2, var.equal = FALSE)
}, error = function(e) {
return(NULL)
})
if (is.null(test_result)) {
return(list(tstat = NA_real_, pval = NA_real_, stars = ""))
}
t_stat <- test_result$statistic
p_val <- test_result$p.value
# Determine significance stars
stars <- ""
if (!is.na(p_val)) {
if (p_val < 0.01) {
stars <- "***"
} else if (p_val < 0.05) {
stars <- "**"
} else if (p_val < 0.10) {
stars <- "*"
}
}
return(list(tstat = as.numeric(t_stat), pval = p_val, stars = stars))
}
Period Definitions
# ==============================================================================
# PERIOD DEFINITIONS
# ==============================================================================
periods <- tribble(
~period_num, ~period_name, ~start_date, ~end_date, ~description,
0, "Pre-BTFP", "2023-03-01", "2023-03-10", "DW only available",
1, "Acute", "2023-03-13", "2023-05-01", "Peak crisis phase",
2, "Post-Acute", "2023-05-02", "2023-10-31", "Stabilization",
3, "Arbitrage", "2023-11-01", "2024-01-24", "BTFP rate < IORB",
4, "Wind-down", "2024-01-25", "2024-03-11", "BTFP closing announced"
) %>%
mutate(across(c(start_date, end_date), as.Date))
# Key dates
BTFP_LAUNCH <- as.Date("2023-03-12")
BTFP_CLOSE <- as.Date("2024-03-11")
DW_DATA_END <- as.Date("2023-12-31")
BASELINE_DATE <- "2022Q4"
# Display periods
periods %>%
kable(col.names = c("Period", "Name", "Start", "End", "Description"),
caption = "Analysis Period Definitions") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Analysis Period Definitions
|
Period
|
Name
|
Start
|
End
|
Description
|
|
0
|
Pre-BTFP
|
2023-03-01
|
2023-03-10
|
DW only available
|
|
1
|
Acute
|
2023-03-13
|
2023-05-01
|
Peak crisis phase
|
|
2
|
Post-Acute
|
2023-05-02
|
2023-10-31
|
Stabilization
|
|
3
|
Arbitrage
|
2023-11-01
|
2024-01-24
|
BTFP rate < IORB
|
|
4
|
Wind-down
|
2024-01-25
|
2024-03-11
|
BTFP closing announced
|
Load Data
# ==============================================================================
# LOAD DATA
# ==============================================================================
cat("=== LOADING DATA ===\n")
## === LOADING DATA ===
call_q <- read_csv(file.path(DATA_PROC, "final_call_gsib.csv"), show_col_types = FALSE) %>%
mutate(idrssd = as.character(idrssd))
btfp_loans_raw <- read_csv(file.path(DATA_PROC, "btfp_loan_bank_only.csv"), show_col_types = FALSE) %>%
mutate(rssd_id = as.character(rssd_id),
btfp_loan_date = mdy(btfp_loan_date))
dw_loans_raw <- read_csv(file.path(DATA_PROC, "dw_loan_bank_2023.csv"), show_col_types = FALSE) %>%
mutate(rssd_id = as.character(rssd_id),
dw_loan_date = ymd(dw_loan_date))
cat("Call Report:", nrow(call_q), "observations\n")
## Call Report: 75989 observations
cat("BTFP Loans:", nrow(btfp_loans_raw), "loans\n")
## BTFP Loans: 6734 loans
cat("DW Loans:", nrow(dw_loans_raw), "loans\n")
## DW Loans: 10008 loans
Define Exclusions
# ============================================================================
# DEFINE EXCLUDED BANKS AND GSIB IDENTIFICATION
# ============================================================================
# Identify GSIBs at baseline
gsib_banks <- call_q %>%
filter(period == '2022Q4', gsib == 1) %>%
pull(idrssd)
# Identify failed banks
failed_banks <- call_q %>%
filter(period == '2022Q4', failed_bank == 1) %>%
pull(idrssd)
# Exclude failed + GSIBs for main analysis
excluded_banks <- union(gsib_banks, failed_banks)
cat("=== EXCLUSIONS ===\n")
## === EXCLUSIONS ===
cat("G-SIBs:", length(gsib_banks), "\n")
## G-SIBs: 33
cat("Failed banks:", length(failed_banks), "\n")
## Failed banks: 8
cat("Total excluded:", length(excluded_banks), "\n")
## Total excluded: 41
Prepare Baseline Data
(2022Q4)
cat("\n=== PREPARING BASELINE DATA (2022Q4) ===\n")
##
## === PREPARING BASELINE DATA (2022Q4) ===
# Step 1: Filter to baseline quarter and exclude failed/GSIB banks
has_failed_bank <- "failed_bank" %in% names(call_q)
has_gsib <- "gsib" %in% names(call_q)
baseline_q <- call_q %>%
filter(period == '2022Q4')
cat("Baseline observations (after exclusions):", nrow(baseline_q), "\n")
## Baseline observations (after exclusions): 4737
# Step 3: Calculate medians for cutoffs (BEFORE adding derived variables)
medians <- baseline_q %>%
summarise(
median_uninsured = median(uninsured_deposit_to_total_asset, na.rm = TRUE),
median_mtm = median(mtm_loss_to_total_asset, na.rm = TRUE),
q75_uninsured = quantile(uninsured_deposit_to_total_asset, 0.75, na.rm = TRUE),
q75_mtm = quantile(mtm_loss_to_total_asset, 0.75, na.rm = TRUE)
)
cat("Median uninsured ratio:", round(medians$median_uninsured, 2), "%\n")
## Median uninsured ratio: 21.97 %
cat("Median MTM loss ratio:", round(medians$median_mtm, 2), "%\n")
## Median MTM loss ratio: 5.26 %
cat("Q75 uninsured ratio:", round(medians$q75_uninsured, 2), "%\n")
## Q75 uninsured ratio: 30.27 %
cat("Q75 MTM loss ratio:", round(medians$q75_mtm, 2), "%\n")
## Q75 MTM loss ratio: 6.95 %
# Step 4: Add ALL derived variables to baseline
baseline_q <- baseline_q %>%
mutate(
# Market value adjustment: (Book Asset / MV Asset) - 1
cet1_ratio = safe_div(cet1, total_asset) * 100,
mv_asset = mm_asset,
mv_adjustment = if_else(mv_asset == 0 | is.na(mv_asset), NA_real_,
(total_asset / mv_asset) - 1),
# IDCR: (MV_Asset - s*Uninsured - Insured) / Insured
idcr_s50 = safe_div(mv_asset - 0.5 * uninsured_deposit - insured_deposit, insured_deposit),
idcr_s100 = safe_div(mv_asset - 1.0 * uninsured_deposit - insured_deposit, insured_deposit),
# Capital Insolvency: (Equity - s*Uninsured*MVAdj) / Assets
cap_insolvency_s50 = safe_div((total_asset - total_liability) - 0.5 * uninsured_deposit * mv_adjustment, total_asset),
cap_insolvency_s100 = safe_div((total_asset - total_liability) - 1.0 * uninsured_deposit * mv_adjustment, total_asset),
# Adjusted Equity (book equity ratio - MTM loss ratio, both in %)
adjusted_equity = book_equity_to_total_asset - mtm_loss_to_total_asset,
adjusted_tier1 = tier1cap_to_total_asset - mtm_loss_to_total_asset,
adjusted_cet1 = cet1_ratio - mtm_loss_to_total_asset,
# MTM Insolvent dummy (adjusted equity < 0)
mtm_insolvent = as.integer(adjusted_equity < 0),
mtm_insolvent_tier1 = as.integer(adjusted_tier1 < 0),
mtm_insolvent_cet1 = as.integer(adjusted_cet1 < 0),
# Uninsured leverage (uninsured deposit / book equity)
uninsured_leverage = uninsured_deposit_to_total_asset,
liquidity_available = safe_div(cash + rerepo + fed_fund_sold, total_asset) * 100,
# Run risk dummies
# a. Solvent and Liquid (both uninsured and MTM below median)
run_risk_1 = as.integer(
uninsured_deposit_to_total_asset < medians$median_uninsured &
mtm_loss_to_total_asset < medians$median_mtm
),
# b. Solvent and Illiquid
run_risk_2 = as.integer(
uninsured_deposit_to_total_asset > medians$median_uninsured &
mtm_loss_to_total_asset < medians$median_mtm
),
# c. Insolvent and Liquid
run_risk_3 = as.integer(
uninsured_deposit_to_total_asset < medians$median_uninsured &
mtm_loss_to_total_asset > medians$median_mtm
),
# d. Insolvent and ILLiquid (both uninsured and MTM above median)
run_risk_4 = as.integer(
uninsured_deposit_to_total_asset > medians$median_uninsured &
mtm_loss_to_total_asset > medians$median_mtm
),
# IDCR insolvency dummies
idcr_insolvent_s50 = as.integer(idcr_s50 < 0),
idcr_insolvent_s100 = as.integer(idcr_s100 < 0),
# Capital insolvency dummies
cap_insolvent_s50 = as.integer(cap_insolvency_s50 < 0),
cap_insolvent_s100 = as.integer(cap_insolvency_s100 < 0)
) %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0
)
cat("\nDerived variables added successfully.\n")
##
## Derived variables added successfully.
cat("Final baseline observations:", nrow(baseline_q), "\n")
## Final baseline observations: 4292
Table Functions
# ==============================================================================
# TABLE FORMAT FUNCTIONS WITH T-STATISTICS AND SIGNIFICANCE STARS
# ==============================================================================
# Main function to create summary table with consistent format
# Format: Mean (Median) [T-stat]*** with N below each row
# T-stat compares each group to Non-Borrower group
# Significance: *** p<0.01, ** p<0.05, * p<0.10
create_summary_table_v2 <- function(data, group_var, group_levels = NULL, reference_group = "Non-Borrower") {
# Define variable specifications
var_specs <- tribble(
~var_name, ~var_label, ~is_dummy,
"book_equity_to_total_asset", "Book Equity Ratio", FALSE,
"loss_asset_htm_only", "MTM Loss (HTM)", FALSE,
"mtm_loss_omo_eligible_to_total_asset", "MTM Loss (BTFP Elg.)", FALSE,
"mtm_loss_to_total_asset", "MTM Loss (Total)", FALSE,
"adjusted_equity", "Adjusted Equity", FALSE,
"mtm_insolvent", "Adjusted Equity < 0", TRUE,
"adjusted_tier1", "Adj. Tier1 Equity", FALSE,
"mtm_insolvent_tier1", "Adj. Tier1 Equity < 0", TRUE,
"adjusted_cet1", " Adj. Common equity tier1",FALSE,
"mtm_insolvent_cet1", "Adj. Common equity tier1 < 0", TRUE,
"uninsured_leverage", "Uninsured Leverage", FALSE,
"mtm_insolvent", "MTM Insolvent", TRUE,
"run_risk_1", "Solvent and Liquid", TRUE,
"run_risk_2", "Solvent and Illiquid", TRUE,
"run_risk_3", "Insolvent and Liquid", TRUE,
"run_risk_4", "Insolvent and Illiquid", TRUE,
"idcr_insolvent_s50", "IDCR Insolvent (s=0.5)", TRUE,
"idcr_insolvent_s100", "IDCR Insolvent (s=1.0)", TRUE,
"cap_insolvent_s50", "Capital Insolvent (s=0.5)", TRUE,
"cap_insolvent_s100", "Capital Insolvent (s=1.0)", TRUE,
"liquidity_available", "Available Liquidity Ratio", FALSE,
"change_uninsured_fwd_q", "Change Uninsured Deposits (Fwd Q)", FALSE,
"change_insured_deposit_fwd_q", "Change Insured Deposits (Fwd Q)", FALSE,
"abnormal_insured_outflow_10pct", "Abnormal Insured Outflow (10%)", TRUE,
"abnormal_insured_outflow_5pct", "Abnormal Insured Outflow (5%)", TRUE,
"abnormal_uninsured_outflow_10pct", "Abnormal Uninsured Outflow (10%)", TRUE,
"abnormal_uninsured_outflow_5pct", "Abnormal Uninsured Outflow (5%)", TRUE
)
# Get unique groups
if (is.null(group_levels)) {
group_levels <- unique(data[[group_var]])
}
# Calculate N for each group
n_by_group <- data %>%
group_by(.data[[group_var]]) %>%
summarise(N = n(), .groups = "drop")
# Get reference group data for T-stat calculation
ref_data <- data %>% filter(.data[[group_var]] == reference_group)
# Initialize output list
output_rows <- list()
# Add N row first
n_row <- c(Variable = "N", Row_Type = "count")
for (g in group_levels) {
n_val <- n_by_group %>% filter(.data[[group_var]] == g) %>% pull(N)
n_row[g] <- as.character(if(length(n_val) == 0) 0 else n_val)
}
output_rows[[1]] <- n_row
row_idx <- 2
# Process each variable
for (i in seq_len(nrow(var_specs))) {
v <- var_specs$var_name[i]
label <- var_specs$var_label[i]
is_dummy <- var_specs$is_dummy[i]
# Stats row: Mean (Median)
stats_row <- c(Variable = label, Row_Type = "stats")
# T-stat row (below stats)
tstat_row <- c(Variable = "", Row_Type = "tstat")
# N row (below t-stat)
obs_row <- c(Variable = "", Row_Type = "n")
# Get reference group values for T-stat
ref_vals <- if (v %in% names(ref_data)) ref_data[[v]] else numeric(0)
ref_vals <- ref_vals[!is.na(ref_vals)]
for (g in group_levels) {
group_data <- data %>% filter(.data[[group_var]] == g)
# Check if variable exists
if (!v %in% names(group_data)) {
stats_row[g] <- "—"
tstat_row[g] <- ""
obs_row[g] <- "0"
next
}
vals <- group_data[[v]]
vals <- vals[!is.na(vals)]
if (length(vals) == 0) {
stats_row[g] <- "—"
tstat_row[g] <- ""
obs_row[g] <- "0"
} else {
mean_val <- mean(vals, na.rm = TRUE)
median_val <- median(vals, na.rm = TRUE)
n_val <- length(vals)
if (is_dummy) {
stats_row[g] <- sprintf("%.2f (%.2f)", mean_val * 100, median_val * 100)
n_val <- sum(vals) # Count of banks where dummy = 1
} else {
stats_row[g] <- sprintf("%.2f (%.2f)", mean_val, median_val)
n_val <- length(vals) # Total non-NA observations
}
# Calculate T-stat vs reference group (skip for reference group itself)
if (g == reference_group) {
tstat_row[g] <- ""
} else {
# Use the new function with stars
tstat_result <- calc_tstat_with_stars(vals, ref_vals)
if (!is.na(tstat_result$tstat) && is.finite(tstat_result$tstat)) {
tstat_row[g] <- sprintf("[%.2f]%s", tstat_result$tstat, tstat_result$stars)
} else {
tstat_row[g] <- ""
}
}
obs_row[g] <- as.character(n_val)
}
}
output_rows[[row_idx]] <- stats_row
output_rows[[row_idx + 1]] <- tstat_row
output_rows[[row_idx + 2]] <- obs_row
row_idx <- row_idx + 3
}
# Convert to data frame
result_df <- bind_rows(lapply(output_rows, function(x) as_tibble_row(x)))
return(result_df)
}
# ==============================================================================
# LATEX TABLE EXPORT FUNCTION (UPDATED FOR T-STATS WITH STARS)
# ==============================================================================
export_latex_table <- function(summary_df, filepath, caption, label, note = NULL) {
# Get column names (excluding Variable and Row_Type)
group_cols <- names(summary_df)[!names(summary_df) %in% c("Variable", "Row_Type")]
n_groups <- length(group_cols)
# Clean column names for display
clean_cols <- gsub("_", " ", group_cols)
clean_cols <- gsub("Non Borrower", "Non-Borrower", clean_cols)
# Build LaTeX
latex <- c(
"\\begin{table}[htbp]",
"\\centering",
"\\small",
sprintf("\\caption{%s}", caption),
sprintf("\\label{%s}", label),
"",
sprintf("\\begin{tabular}{l%s}", paste(rep("c", n_groups), collapse = "")),
"\\toprule",
paste0(" & ", paste(clean_cols, collapse = " & "), " \\\\"),
"\\midrule"
)
# Add rows
for (i in seq_len(nrow(summary_df))) {
row <- summary_df[i, ]
var_name <- as.character(row$Variable)
row_type <- as.character(row$Row_Type)
vals <- as.character(row[group_cols])
if (row_type == "count") {
# N row - bold
latex <- c(latex,
sprintf("N & %s \\\\", paste(vals, collapse = " & ")),
"\\midrule")
} else if (row_type == "stats" && var_name != "") {
# Variable name row with statistics
latex <- c(latex, sprintf("%s & %s \\\\", var_name, paste(vals, collapse = " & ")))
} else if (row_type == "tstat") {
# T-stat row (smaller font, in brackets) - stars are already included
tstat_vals <- paste0("\\scriptsize{", vals, "}")
latex <- c(latex, sprintf("& %s \\\\", paste(tstat_vals, collapse = " & ")))
} else if (row_type == "n") {
# N below stats (italics)
n_vals <- paste0("\\textit{", vals, "}")
latex <- c(latex, sprintf("& %s \\\\[0.3em]", paste(n_vals, collapse = " & ")))
}
}
latex <- c(latex,
"\\bottomrule",
"\\end{tabular}",
"")
# Add note if provided (updated to include significance legend)
if (!is.null(note)) {
latex <- c(latex,
"\\vspace{0.3em}",
"\\begin{minipage}{0.95\\textwidth}",
"\\footnotesize",
sprintf("\\textit{Notes:} %s T-statistics in brackets compare each borrower group to Non-Borrowers using Welch's t-test. Significance: *** p$<$0.01, ** p$<$0.05, * p$<$0.10.", note),
"\\end{minipage}")
}
latex <- c(latex, "\\end{table}")
# Write to file
writeLines(latex, filepath)
cat("LaTeX table saved:", filepath, "\n")
return(invisible(latex))
}
# ==============================================================================
# HTML TABLE EXPORT FUNCTION
# ==============================================================================
export_html_table <- function(summary_df, filepath, caption) {
# Get column names (excluding Row_Type)
display_cols <- names(summary_df)[names(summary_df) != "Row_Type"]
# Clean column names
clean_names <- gsub("_", " ", display_cols)
clean_names <- gsub("Non Borrower", "Non-Borrower", clean_names)
# Create display dataframe
display_df <- summary_df %>%
select(all_of(display_cols))
# Generate HTML table
html_table <- display_df %>%
kable(format = "html",
col.names = clean_names,
caption = caption,
escape = FALSE) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE,
font_size = 12) %>%
row_spec(1, bold = TRUE) # Bold N row
# Save to file
save_kable(html_table, filepath)
cat("HTML table saved:", filepath, "\n")
return(invisible(html_table))
}
# ==============================================================================
# COMBINED EXPORT FUNCTION
# ==============================================================================
export_table <- function(summary_df, table_name, caption, label, note = NULL) {
# LaTeX export
latex_path <- file.path(TABLE_PATH, paste0(table_name, ".tex"))
export_latex_table(summary_df, latex_path, caption, label, note)
# HTML export
html_path <- file.path(TABLE_PATH, paste0(table_name, ".html"))
export_html_table(summary_df, html_path, caption)
# CSV export (for reference)
csv_path <- file.path(TABLE_PATH, paste0(table_name, ".csv"))
write_csv(summary_df, csv_path)
cat("CSV table saved:", csv_path, "\n")
return(invisible(list(latex = latex_path, html = html_path, csv = csv_path)))
}
Table 1: March 10, 2023
- DW Borrowers vs Non-Borrowers
# ==============================================================================
# TABLE 1: March 10, 2023 Only - DW Borrowers vs Non-Borrowers
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 1: March 10, 2023 - DW Borrowers vs Non-Borrowers\n")
## TABLE 1: March 10, 2023 - DW Borrowers vs Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
dw_mar10 <- dw_loans_raw %>%
filter(dw_loan_date == as.Date("2023-03-10")) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat("DW borrowers on March 10:", length(dw_mar10), "\n")
## DW borrowers on March 10: 52
table1_data <- baseline_q %>%
mutate(
borrower_type = if_else(idrssd %in% dw_mar10, "DW Borrower", "Non-Borrower")
)
table1 <- create_summary_table_v2(table1_data, "borrower_type",
group_levels = c("DW Borrower", "Non-Borrower"))
# Display
table1 %>%
select(-Row_Type) %>%
kable(caption = "Table 1: Pre-Crisis Bank Characteristics - DW Borrowers vs Non-Borrowers (March 10, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 1: Pre-Crisis Bank Characteristics - DW Borrowers vs Non-Borrowers
(March 10, 2023)
|
Variable
|
DW Borrower
|
Non-Borrower
|
|
N
|
47
|
4245
|
|
Book Equity Ratio
|
8.20 (8.45)
|
10.24 (8.85)
|
|
|
[-4.93]***
|
|
|
|
47
|
4245
|
|
MTM Loss (HTM)
|
0.23 (0.00)
|
0.20 (0.00)
|
|
|
[0.28]
|
|
|
|
47
|
4235
|
|
MTM Loss (BTFP Elg.)
|
0.89 (0.58)
|
0.68 (0.40)
|
|
|
[1.72]*
|
|
|
|
47
|
4235
|
|
MTM Loss (Total)
|
5.69 (5.66)
|
5.46 (5.31)
|
|
|
[0.72]
|
|
|
|
47
|
4235
|
|
Adjusted Equity
|
2.51 (2.44)
|
4.70 (3.64)
|
|
|
[-3.70]***
|
|
|
|
47
|
4235
|
|
Adjusted Equity < 0
|
23.40 (0.00)
|
19.22 (0.00)
|
|
|
[0.67]
|
|
|
|
11
|
814
|
|
Adj. Tier1 Equity
|
3.67 (2.90)
|
6.33 (5.06)
|
|
|
[-6.67]***
|
|
|
|
47
|
4235
|
|
Adj. Tier1 Equity < 0
|
4.26 (0.00)
|
3.31 (0.00)
|
|
|
[0.32]
|
|
|
|
2
|
140
|
|
Adj. Common equity tier1
|
3.66 (2.90)
|
6.28 (5.05)
|
|
|
[-6.60]***
|
|
|
|
47
|
4179
|
|
Adj. Common equity tier1 < 0
|
4.26 (0.00)
|
3.25 (0.00)
|
|
|
[0.33]
|
|
|
|
2
|
136
|
|
Uninsured Leverage
|
29.88 (28.54)
|
23.54 (22.22)
|
|
|
[3.44]***
|
|
|
|
47
|
4245
|
|
MTM Insolvent
|
23.40 (0.00)
|
19.22 (0.00)
|
|
|
[0.67]
|
|
|
|
11
|
814
|
|
Solvent and Liquid
|
10.64 (0.00)
|
22.42 (0.00)
|
|
|
[-2.57]**
|
|
|
|
5
|
951
|
|
Solvent and Illiquid
|
29.79 (0.00)
|
26.56 (0.00)
|
|
|
[0.48]
|
|
|
|
14
|
1126
|
|
Insolvent and Liquid
|
19.15 (0.00)
|
26.55 (0.00)
|
|
|
[-1.27]
|
|
|
|
9
|
1126
|
|
Insolvent and Illiquid
|
40.43 (0.00)
|
24.30 (0.00)
|
|
|
[2.22]**
|
|
|
|
19
|
1030
|
|
IDCR Insolvent (s=0.5)
|
2.13 (0.00)
|
4.23 (0.00)
|
|
|
[-0.98]
|
|
|
|
1
|
178
|
|
IDCR Insolvent (s=1.0)
|
34.04 (0.00)
|
28.40 (0.00)
|
|
|
[0.80]
|
|
|
|
16
|
1194
|
|
Capital Insolvent (s=0.5)
|
4.26 (0.00)
|
2.17 (0.00)
|
|
|
[0.70]
|
|
|
|
2
|
92
|
|
Capital Insolvent (s=1.0)
|
17.02 (0.00)
|
7.51 (0.00)
|
|
|
[1.71]*
|
|
|
|
8
|
318
|
|
Available Liquidity Ratio
|
3.27 (2.25)
|
9.36 (5.94)
|
|
|
[-13.94]***
|
|
|
|
47
|
4245
|
|
Change Uninsured Deposits (Fwd Q)
|
-13.11 (-11.89)
|
0.18 (-4.54)
|
|
|
[-4.14]***
|
|
|
|
47
|
4181
|
|
Change Insured Deposits (Fwd Q)
|
5.35 (2.14)
|
3.83 (1.48)
|
|
|
[0.97]
|
|
|
|
47
|
4187
|
|
Abnormal Insured Outflow (10%)
|
6.38 (0.00)
|
7.51 (0.00)
|
|
|
[-0.31]
|
|
|
|
3
|
319
|
|
Abnormal Insured Outflow (5%)
|
0.00 (0.00)
|
2.69 (0.00)
|
|
|
[-10.82]***
|
|
|
|
0
|
114
|
|
Abnormal Uninsured Outflow (10%)
|
42.55 (0.00)
|
21.25 (0.00)
|
|
|
[2.91]***
|
|
|
|
20
|
902
|
|
Abnormal Uninsured Outflow (5%)
|
25.53 (0.00)
|
9.07 (0.00)
|
|
|
[2.55]**
|
|
|
|
12
|
385
|
# Export
export_table(
table1,
"table1_dw_mar10",
caption = "Pre-Crisis Bank Characteristics: DW Borrowers vs Non-Borrowers (March 10, 2023)",
label = "tab:dw_mar10",
note = "Bank characteristics from 2022Q4 Call Reports. Values shown as Mean (Median) with N observations below. Continuous variables in percentage points. Dummy variables show proportion (\\%) with value = 1. DW borrowers identified as banks with Discount Window loans on March 10, 2023 only. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table1_dw_mar10.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table1_dw_mar10.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table1_dw_mar10.csv
Table 2: March 10-13,
2023 - DW Borrowers vs Non-Borrowers
# ==============================================================================
# TABLE 2: March 10-13, 2023 - DW Borrowers vs Non-Borrowers
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 2: March 10-13, 2023 - DW Borrowers vs Non-Borrowers\n")
## TABLE 2: March 10-13, 2023 - DW Borrowers vs Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
dw_mar10_13 <- dw_loans_raw %>%
filter(dw_loan_date >= as.Date("2023-03-10") & dw_loan_date <= as.Date("2023-03-13")) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat("DW borrowers March 10-13:", length(dw_mar10_13), "\n")
## DW borrowers March 10-13: 98
table2_data <- baseline_q %>%
mutate(
borrower_type = if_else(idrssd %in% dw_mar10_13, "DW Borrower", "Non-Borrower")
)
table2 <- create_summary_table_v2(table2_data, "borrower_type",
group_levels = c("DW Borrower", "Non-Borrower"))
# Display
table2 %>%
select(-Row_Type) %>%
kable(caption = "Table 2: Pre-Crisis Bank Characteristics - DW Borrowers vs Non-Borrowers (March 10-13, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 2: Pre-Crisis Bank Characteristics - DW Borrowers vs Non-Borrowers
(March 10-13, 2023)
|
Variable
|
DW Borrower
|
Non-Borrower
|
|
N
|
90
|
4202
|
|
Book Equity Ratio
|
8.55 (8.46)
|
10.26 (8.85)
|
|
|
[-5.17]***
|
|
|
|
90
|
4202
|
|
MTM Loss (HTM)
|
0.24 (0.00)
|
0.20 (0.00)
|
|
|
[0.55]
|
|
|
|
90
|
4192
|
|
MTM Loss (BTFP Elg.)
|
0.84 (0.55)
|
0.68 (0.40)
|
|
|
[1.92]*
|
|
|
|
90
|
4192
|
|
MTM Loss (Total)
|
5.54 (5.61)
|
5.47 (5.31)
|
|
|
[0.34]
|
|
|
|
90
|
4192
|
|
Adjusted Equity
|
3.01 (2.72)
|
4.71 (3.64)
|
|
|
[-3.86]***
|
|
|
|
90
|
4192
|
|
Adjusted Equity < 0
|
20.00 (0.00)
|
19.25 (0.00)
|
|
|
[0.17]
|
|
|
|
18
|
807
|
|
Adj. Tier1 Equity
|
4.03 (3.75)
|
6.35 (5.07)
|
|
|
[-7.80]***
|
|
|
|
90
|
4192
|
|
Adj. Tier1 Equity < 0
|
3.33 (0.00)
|
3.32 (0.00)
|
|
|
[0.01]
|
|
|
|
3
|
139
|
|
Adj. Common equity tier1
|
3.99 (3.82)
|
6.30 (5.06)
|
|
|
[-7.99]***
|
|
|
|
87
|
4139
|
|
Adj. Common equity tier1 < 0
|
3.45 (0.00)
|
3.26 (0.00)
|
|
|
[0.09]
|
|
|
|
3
|
135
|
|
Uninsured Leverage
|
32.99 (30.99)
|
23.41 (22.12)
|
|
|
[6.81]***
|
|
|
|
90
|
4202
|
|
MTM Insolvent
|
20.00 (0.00)
|
19.25 (0.00)
|
|
|
[0.17]
|
|
|
|
18
|
807
|
|
Solvent and Liquid
|
10.00 (0.00)
|
22.56 (0.00)
|
|
|
[-3.87]***
|
|
|
|
9
|
947
|
|
Solvent and Illiquid
|
33.33 (0.00)
|
26.45 (0.00)
|
|
|
[1.36]
|
|
|
|
30
|
1110
|
|
Insolvent and Liquid
|
12.22 (0.00)
|
26.77 (0.00)
|
|
|
[-4.11]***
|
|
|
|
11
|
1124
|
|
Insolvent and Illiquid
|
44.44 (0.00)
|
24.05 (0.00)
|
|
|
[3.84]***
|
|
|
|
40
|
1009
|
|
IDCR Insolvent (s=0.5)
|
5.56 (0.00)
|
4.18 (0.00)
|
|
|
[0.56]
|
|
|
|
5
|
174
|
|
IDCR Insolvent (s=1.0)
|
34.44 (0.00)
|
28.33 (0.00)
|
|
|
[1.20]
|
|
|
|
31
|
1179
|
|
Capital Insolvent (s=0.5)
|
5.56 (0.00)
|
2.12 (0.00)
|
|
|
[1.41]
|
|
|
|
5
|
89
|
|
Capital Insolvent (s=1.0)
|
16.67 (0.00)
|
7.42 (0.00)
|
|
|
[2.33]**
|
|
|
|
15
|
311
|
|
Available Liquidity Ratio
|
4.30 (2.86)
|
9.40 (5.97)
|
|
|
[-10.23]***
|
|
|
|
90
|
4202
|
|
Change Uninsured Deposits (Fwd Q)
|
-10.14 (-8.93)
|
0.25 (-4.45)
|
|
|
[-3.97]***
|
|
|
|
90
|
4138
|
|
Change Insured Deposits (Fwd Q)
|
8.03 (2.39)
|
3.76 (1.45)
|
|
|
[1.48]
|
|
|
|
90
|
4144
|
|
Abnormal Insured Outflow (10%)
|
5.56 (0.00)
|
7.54 (0.00)
|
|
|
[-0.81]
|
|
|
|
5
|
317
|
|
Abnormal Insured Outflow (5%)
|
1.11 (0.00)
|
2.69 (0.00)
|
|
|
[-1.39]
|
|
|
|
1
|
113
|
|
Abnormal Uninsured Outflow (10%)
|
41.11 (0.00)
|
21.06 (0.00)
|
|
|
[3.82]***
|
|
|
|
37
|
885
|
|
Abnormal Uninsured Outflow (5%)
|
22.22 (0.00)
|
8.97 (0.00)
|
|
|
[2.99]***
|
|
|
|
20
|
377
|
# Export
export_table(
table2,
"table2_dw_mar10_13",
caption = "Pre-Crisis Bank Characteristics: DW Borrowers vs Non-Borrowers (March 10--13, 2023)",
label = "tab:dw_mar10_13",
note = "Bank characteristics from 2022Q4 Call Reports. Values shown as Mean (Median) with N observations below. DW borrowers identified as banks with Discount Window loans between March 10--13, 2023. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table2_dw_mar10_13.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table2_dw_mar10_13.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table2_dw_mar10_13.csv
Table 3: March 9-14,
2023 - DW Borrowers vs Non-Borrowers
# ==============================================================================
# TABLE 3: March 9-14, 2023 - DW Borrowers vs Non-Borrowers
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 3: March 9-14, 2023 - DW Borrowers vs Non-Borrowers\n")
## TABLE 3: March 9-14, 2023 - DW Borrowers vs Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
dw_mar9_14 <- dw_loans_raw %>%
filter(dw_loan_date >= as.Date("2023-03-09") & dw_loan_date <= as.Date("2023-03-14")) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat("DW borrowers March 9-14:", length(dw_mar9_14), "\n")
## DW borrowers March 9-14: 137
table3_data <- baseline_q %>%
mutate(
borrower_type = if_else(idrssd %in% dw_mar9_14, "DW Borrower", "Non-Borrower")
)
table3 <- create_summary_table_v2(table3_data, "borrower_type",
group_levels = c("DW Borrower", "Non-Borrower"))
# Display
table3 %>%
select(-Row_Type) %>%
kable(caption = "Table 3: Pre-Crisis Bank Characteristics - DW Borrowers vs Non-Borrowers (March 9-14, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 3: Pre-Crisis Bank Characteristics - DW Borrowers vs Non-Borrowers
(March 9-14, 2023)
|
Variable
|
DW Borrower
|
Non-Borrower
|
|
N
|
124
|
4168
|
|
Book Equity Ratio
|
9.01 (8.64)
|
10.26 (8.85)
|
|
|
[-3.59]***
|
|
|
|
124
|
4168
|
|
MTM Loss (HTM)
|
0.19 (0.00)
|
0.20 (0.00)
|
|
|
[-0.25]
|
|
|
|
124
|
4158
|
|
MTM Loss (BTFP Elg.)
|
0.77 (0.52)
|
0.68 (0.40)
|
|
|
[1.30]
|
|
|
|
124
|
4158
|
|
MTM Loss (Total)
|
5.50 (5.58)
|
5.47 (5.31)
|
|
|
[0.17]
|
|
|
|
124
|
4158
|
|
Adjusted Equity
|
3.51 (2.91)
|
4.71 (3.64)
|
|
|
[-2.72]***
|
|
|
|
124
|
4158
|
|
Adjusted Equity < 0
|
20.16 (0.00)
|
19.24 (0.00)
|
|
|
[0.25]
|
|
|
|
25
|
800
|
|
Adj. Tier1 Equity
|
4.58 (3.98)
|
6.35 (5.07)
|
|
|
[-5.05]***
|
|
|
|
124
|
4158
|
|
Adj. Tier1 Equity < 0
|
3.23 (0.00)
|
3.32 (0.00)
|
|
|
[-0.06]
|
|
|
|
4
|
138
|
|
Adj. Common equity tier1
|
4.56 (3.98)
|
6.30 (5.06)
|
|
|
[-4.95]***
|
|
|
|
121
|
4105
|
|
Adj. Common equity tier1 < 0
|
3.31 (0.00)
|
3.26 (0.00)
|
|
|
[0.03]
|
|
|
|
4
|
134
|
|
Uninsured Leverage
|
31.30 (29.52)
|
23.38 (22.08)
|
|
|
[6.50]***
|
|
|
|
124
|
4168
|
|
MTM Insolvent
|
20.16 (0.00)
|
19.24 (0.00)
|
|
|
[0.25]
|
|
|
|
25
|
800
|
|
Solvent and Liquid
|
11.29 (0.00)
|
22.62 (0.00)
|
|
|
[-3.87]***
|
|
|
|
14
|
942
|
|
Solvent and Illiquid
|
33.87 (0.00)
|
26.38 (0.00)
|
|
|
[1.73]*
|
|
|
|
42
|
1098
|
|
Insolvent and Liquid
|
14.52 (0.00)
|
26.83 (0.00)
|
|
|
[-3.79]***
|
|
|
|
18
|
1117
|
|
Insolvent and Illiquid
|
40.32 (0.00)
|
24.00 (0.00)
|
|
|
[3.65]***
|
|
|
|
50
|
999
|
|
IDCR Insolvent (s=0.5)
|
5.65 (0.00)
|
4.17 (0.00)
|
|
|
[0.70]
|
|
|
|
7
|
172
|
|
IDCR Insolvent (s=1.0)
|
35.48 (0.00)
|
28.25 (0.00)
|
|
|
[1.65]
|
|
|
|
44
|
1166
|
|
Capital Insolvent (s=0.5)
|
4.84 (0.00)
|
2.12 (0.00)
|
|
|
[1.40]
|
|
|
|
6
|
88
|
|
Capital Insolvent (s=1.0)
|
15.32 (0.00)
|
7.38 (0.00)
|
|
|
[2.43]**
|
|
|
|
19
|
307
|
|
Available Liquidity Ratio
|
5.31 (3.31)
|
9.42 (6.00)
|
|
|
[-7.31]***
|
|
|
|
124
|
4168
|
|
Change Uninsured Deposits (Fwd Q)
|
-7.45 (-8.04)
|
0.26 (-4.46)
|
|
|
[-2.97]***
|
|
|
|
124
|
4104
|
|
Change Insured Deposits (Fwd Q)
|
7.31 (2.63)
|
3.74 (1.44)
|
|
|
[1.62]
|
|
|
|
124
|
4110
|
|
Abnormal Insured Outflow (10%)
|
6.45 (0.00)
|
7.53 (0.00)
|
|
|
[-0.48]
|
|
|
|
8
|
314
|
|
Abnormal Insured Outflow (5%)
|
2.42 (0.00)
|
2.66 (0.00)
|
|
|
[-0.17]
|
|
|
|
3
|
111
|
|
Abnormal Uninsured Outflow (10%)
|
37.10 (0.00)
|
21.02 (0.00)
|
|
|
[3.65]***
|
|
|
|
46
|
876
|
|
Abnormal Uninsured Outflow (5%)
|
18.55 (0.00)
|
8.97 (0.00)
|
|
|
[2.71]***
|
|
|
|
23
|
374
|
# Export
export_table(
table3,
"table3_dw_mar9_14",
caption = "Pre-Crisis Bank Characteristics: DW Borrowers vs Non-Borrowers (March 9--14, 2023)",
label = "tab:dw_mar9_14",
note = "Bank characteristics from 2022Q4 Call Reports. Values shown as Mean (Median) with N observations below. DW borrowers identified as banks with Discount Window loans between March 9--14, 2023. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table3_dw_mar9_14.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table3_dw_mar9_14.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table3_dw_mar9_14.csv
Table 4: Acute Period
- BTFP, DW, Both, Non-Borrowers
# ==============================================================================
# TABLE 4: Acute Period (March 13 - May 1, 2023)
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 4: Acute Period - BTFP, DW, Both, Non-Borrowers\n")
## TABLE 4: Acute Period - BTFP, DW, Both, Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
acute_start <- as.Date("2023-03-13")
acute_end <- as.Date("2023-05-01")
btfp_acute <- btfp_loans_raw %>%
filter(btfp_loan_date >= acute_start & btfp_loan_date <= acute_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
dw_acute <- dw_loans_raw %>%
filter(dw_loan_date >= acute_start & dw_loan_date <= acute_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat("BTFP borrowers (Acute):", length(btfp_acute), "\n")
## BTFP borrowers (Acute): 492
cat("DW borrowers (Acute):", length(dw_acute), "\n")
## DW borrowers (Acute): 424
cat("Both:", length(intersect(btfp_acute, dw_acute)), "\n")
## Both: 103
table4_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_acute,
dw_user = idrssd %in% dw_acute,
borrower_type = case_when(
btfp_user & dw_user ~ "Both",
btfp_user & !dw_user ~ "BTFP Only",
!btfp_user & dw_user ~ "DW Only",
TRUE ~ "Non-Borrower"
)
)
table4 <- create_summary_table_v2(table4_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "Both", "Non-Borrower"))
# Display
table4 %>%
select(-Row_Type) %>%
kable(caption = "Table 4: Pre-Crisis Bank Characteristics by Borrower Type (Acute Period: March 13 - May 1, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 4: Pre-Crisis Bank Characteristics by Borrower Type (Acute Period:
March 13 - May 1, 2023)
|
Variable
|
BTFP Only
|
DW Only
|
Both
|
Non-Borrower
|
|
N
|
368
|
299
|
94
|
3531
|
|
Book Equity Ratio
|
8.18 (8.08)
|
9.05 (8.82)
|
8.19 (8.23)
|
10.59 (8.96)
|
|
|
[-10.58]***
|
[-6.25]***
|
[-7.48]***
|
|
|
|
368
|
299
|
94
|
3531
|
|
MTM Loss (HTM)
|
0.21 (0.00)
|
0.22 (0.00)
|
0.32 (0.00)
|
0.20 (0.00)
|
|
|
[0.37]
|
[0.64]
|
[1.64]
|
|
|
|
368
|
299
|
94
|
3521
|
|
MTM Loss (BTFP Elg.)
|
0.88 (0.61)
|
0.74 (0.48)
|
0.92 (0.61)
|
0.65 (0.38)
|
|
|
[4.32]***
|
[1.85]*
|
[2.68]***
|
|
|
|
368
|
299
|
94
|
3521
|
|
MTM Loss (Total)
|
6.18 (6.13)
|
5.75 (5.67)
|
5.86 (5.75)
|
5.36 (5.18)
|
|
|
[7.42]***
|
[3.19]***
|
[2.60]**
|
|
|
|
368
|
299
|
94
|
3521
|
|
Adjusted Equity
|
2.00 (2.03)
|
3.30 (3.01)
|
2.33 (2.70)
|
5.13 (3.89)
|
|
|
[-11.32]***
|
[-6.16]***
|
[-6.43]***
|
|
|
|
368
|
299
|
94
|
3521
|
|
Adjusted Equity < 0
|
30.43 (0.00)
|
19.06 (0.00)
|
21.28 (0.00)
|
18.06 (0.00)
|
|
|
[4.97]***
|
[0.42]
|
[0.75]
|
|
|
|
112
|
57
|
20
|
636
|
|
Adj. Tier1 Equity
|
4.13 (3.77)
|
4.71 (4.15)
|
3.76 (3.70)
|
6.73 (5.31)
|
|
|
[-11.55]***
|
[-8.16]***
|
[-9.80]***
|
|
|
|
368
|
299
|
94
|
3521
|
|
Adj. Tier1 Equity < 0
|
4.62 (0.00)
|
3.34 (0.00)
|
5.32 (0.00)
|
3.12 (0.00)
|
|
|
[1.32]
|
[0.20]
|
[0.94]
|
|
|
|
17
|
10
|
5
|
110
|
|
Adj. Common equity tier1
|
4.11 (3.77)
|
4.71 (4.19)
|
3.65 (3.58)
|
6.67 (5.29)
|
|
|
[-11.42]***
|
[-8.03]***
|
[-9.79]***
|
|
|
|
361
|
293
|
88
|
3484
|
|
Adj. Common equity tier1 < 0
|
4.71 (0.00)
|
2.73 (0.00)
|
5.68 (0.00)
|
3.10 (0.00)
|
|
|
[1.39]
|
[-0.37]
|
[1.03]
|
|
|
|
17
|
8
|
5
|
108
|
|
Uninsured Leverage
|
26.21 (25.09)
|
26.85 (25.28)
|
32.63 (30.81)
|
22.83 (21.44)
|
|
|
[5.33]***
|
[5.78]***
|
[6.67]***
|
|
|
|
368
|
299
|
94
|
3531
|
|
MTM Insolvent
|
30.43 (0.00)
|
19.06 (0.00)
|
21.28 (0.00)
|
18.06 (0.00)
|
|
|
[4.97]***
|
[0.42]
|
[0.75]
|
|
|
|
112
|
57
|
20
|
636
|
|
Solvent and Liquid
|
11.41 (0.00)
|
11.37 (0.00)
|
7.45 (0.00)
|
24.75 (0.00)
|
|
|
[-7.36]***
|
[-6.77]***
|
[-6.14]***
|
|
|
|
42
|
34
|
7
|
873
|
|
Solvent and Illiquid
|
22.01 (0.00)
|
29.10 (0.00)
|
30.85 (0.00)
|
26.75 (0.00)
|
|
|
[-2.07]**
|
[0.86]
|
[0.85]
|
|
|
|
81
|
87
|
29
|
943
|
|
Insolvent and Liquid
|
26.09 (0.00)
|
24.75 (0.00)
|
12.77 (0.00)
|
27.02 (0.00)
|
|
|
[-0.39]
|
[-0.87]
|
[-4.03]***
|
|
|
|
96
|
74
|
12
|
953
|
|
Insolvent and Illiquid
|
40.49 (0.00)
|
34.78 (0.00)
|
48.94 (0.00)
|
21.28 (0.00)
|
|
|
[7.24]***
|
[4.75]***
|
[5.29]***
|
|
|
|
149
|
104
|
46
|
750
|
|
IDCR Insolvent (s=0.5)
|
3.53 (0.00)
|
7.02 (0.00)
|
3.19 (0.00)
|
4.07 (0.00)
|
|
|
[-0.53]
|
[1.95]*
|
[-0.47]
|
|
|
|
13
|
21
|
3
|
142
|
|
IDCR Insolvent (s=1.0)
|
29.08 (0.00)
|
33.11 (0.00)
|
24.47 (0.00)
|
28.11 (0.00)
|
|
|
[0.39]
|
[1.77]*
|
[-0.81]
|
|
|
|
107
|
99
|
23
|
981
|
|
Capital Insolvent (s=0.5)
|
1.63 (0.00)
|
3.68 (0.00)
|
7.45 (0.00)
|
1.99 (0.00)
|
|
|
[-0.51]
|
[1.52]
|
[2.00]**
|
|
|
|
6
|
11
|
7
|
70
|
|
Capital Insolvent (s=1.0)
|
9.78 (0.00)
|
11.71 (0.00)
|
11.70 (0.00)
|
6.93 (0.00)
|
|
|
[1.77]*
|
[2.50]**
|
[1.42]
|
|
|
|
36
|
35
|
11
|
244
|
|
Available Liquidity Ratio
|
5.15 (3.63)
|
6.97 (4.15)
|
4.97 (2.85)
|
10.04 (6.53)
|
|
|
[-15.65]***
|
[-6.79]***
|
[-8.39]***
|
|
|
|
368
|
299
|
94
|
3531
|
|
Change Uninsured Deposits (Fwd Q)
|
-6.40 (-7.40)
|
-4.28 (-5.30)
|
-6.38 (-6.48)
|
1.26 (-4.09)
|
|
|
[-3.01]***
|
[-2.15]**
|
[-2.74]***
|
|
|
|
367
|
299
|
94
|
3468
|
|
Change Insured Deposits (Fwd Q)
|
3.58 (1.54)
|
4.25 (2.10)
|
6.92 (1.90)
|
3.76 (1.40)
|
|
|
[-0.21]
|
[0.58]
|
[1.12]
|
|
|
|
368
|
299
|
94
|
3473
|
|
Abnormal Insured Outflow (10%)
|
11.96 (0.00)
|
4.68 (0.00)
|
5.32 (0.00)
|
7.34 (0.00)
|
|
|
[2.64]***
|
[-2.04]**
|
[-0.85]
|
|
|
|
44
|
14
|
5
|
259
|
|
Abnormal Insured Outflow (5%)
|
4.35 (0.00)
|
1.00 (0.00)
|
3.19 (0.00)
|
2.61 (0.00)
|
|
|
[1.59]
|
[-2.52]**
|
[0.32]
|
|
|
|
16
|
3
|
3
|
92
|
|
Abnormal Uninsured Outflow (10%)
|
26.90 (0.00)
|
27.76 (0.00)
|
34.04 (0.00)
|
20.05 (0.00)
|
|
|
[2.84]***
|
[2.88]***
|
[2.82]***
|
|
|
|
99
|
83
|
32
|
708
|
|
Abnormal Uninsured Outflow (5%)
|
12.50 (0.00)
|
12.37 (0.00)
|
14.89 (0.00)
|
8.50 (0.00)
|
|
|
[2.24]**
|
[1.97]**
|
[1.72]*
|
|
|
|
46
|
37
|
14
|
300
|
# Export
export_table(
table4,
"table4_acute_period",
caption = "Pre-Crisis Bank Characteristics by Borrower Type: Acute Crisis Period",
label = "tab:acute_period",
note = "Bank characteristics from 2022Q4 Call Reports. Acute crisis period: March 13 -- May 1, 2023. Banks classified by facility usage during this period. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table4_acute_period.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table4_acute_period.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table4_acute_period.csv
Table 5A: Q1 2023 -
All Facilities (10% Threshold)
# ==============================================================================
# TABLE 5A: Q1 2023 (Jan 1 - Mar 31) - BTFP, DW, FHLB (10% Threshold)
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 5A: Q1 2023 - BTFP, DW, FHLB (10%), Combinations, Non-Borrowers\n")
## TABLE 5A: Q1 2023 - BTFP, DW, FHLB (10%), Combinations, Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
q1_start <- as.Date("2023-01-01")
q1_end <- as.Date("2023-03-31")
btfp_q1 <- btfp_loans_raw %>%
filter(btfp_loan_date >= q1_start & btfp_loan_date <= q1_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
dw_q1 <- dw_loans_raw %>%
filter(dw_loan_date >= q1_start & dw_loan_date <= q1_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
# Define FHLB borrowers using 10% threshold (banks with abnormal FHLB advances in 2023Q1)
fhlb_borrowers_10pct <- baseline_q %>%
filter(!is.na(abnormal_fhlb_borrowing_10pct) & abnormal_fhlb_borrowing_10pct > 0) %>%
pull(idrssd)
cat("BTFP borrowers (Q1 2023):", length(btfp_q1), "\n")
## BTFP borrowers (Q1 2023): 302
cat("DW borrowers (Q1 2023):", length(dw_q1), "\n")
## DW borrowers (Q1 2023): 479
cat("FHLB borrowers (Q1 2023, 10%):", length(fhlb_borrowers_10pct), "\n")
## FHLB borrowers (Q1 2023, 10%): 302
table5a_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_q1,
dw_user = idrssd %in% dw_q1,
fhlb_user = idrssd %in% fhlb_borrowers_10pct,
borrower_type = case_when(
btfp_user & dw_user & fhlb_user ~ "All Three",
btfp_user & dw_user & !fhlb_user ~ "BTFP+DW",
btfp_user & !dw_user & fhlb_user ~ "BTFP+FHLB",
!btfp_user & dw_user & fhlb_user ~ "DW+FHLB",
btfp_user & !dw_user & !fhlb_user ~ "BTFP Only",
!btfp_user & dw_user & !fhlb_user ~ "DW Only",
!btfp_user & !dw_user & fhlb_user ~ "FHLB Only",
TRUE ~ "Non-Borrower"
)
)
table5a <- create_summary_table_v2(table5a_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "FHLB Only",
"BTFP+DW", "BTFP+FHLB", "DW+FHLB",
"All Three", "Non-Borrower"))
# Display
table5a %>%
select(-Row_Type) %>%
kable(caption = "Table 5A: Pre-Crisis Bank Characteristics by Borrower Type (Q1 2023: Jan 1 - Mar 31) - 10% FHLB Threshold") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
scroll_box(width = "100%")
Table 5A: Pre-Crisis Bank Characteristics by Borrower Type (Q1 2023: Jan
1 - Mar 31) - 10% FHLB Threshold
|
Variable
|
BTFP Only
|
DW Only
|
FHLB Only
|
BTFP+DW
|
BTFP+FHLB
|
DW+FHLB
|
All Three
|
Non-Borrower
|
|
N
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3385
|
|
Book Equity Ratio
|
8.19 (8.06)
|
8.85 (8.58)
|
9.82 (9.28)
|
8.01 (8.09)
|
8.89 (8.36)
|
11.00 (10.55)
|
9.36 (9.47)
|
10.55 (8.90)
|
|
|
[-8.78]***
|
[-6.62]***
|
[-2.78]***
|
[-5.75]***
|
[-1.80]*
|
[0.68]
|
[-1.75]
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3385
|
|
MTM Loss (HTM)
|
0.18 (0.00)
|
0.24 (0.00)
|
0.14 (0.00)
|
0.38 (0.00)
|
0.15 (0.00)
|
0.12 (0.00)
|
0.08 (0.00)
|
0.20 (0.00)
|
|
|
[-0.55]
|
[0.95]
|
[-2.33]**
|
[1.62]
|
[-0.81]
|
[-1.37]
|
[-2.33]**
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3375
|
|
MTM Loss (BTFP Elg.)
|
0.81 (0.53)
|
0.85 (0.55)
|
0.53 (0.28)
|
0.98 (0.65)
|
0.77 (0.87)
|
0.46 (0.23)
|
0.54 (0.34)
|
0.66 (0.39)
|
|
|
[2.61]***
|
[3.53]***
|
[-3.19]***
|
[2.43]**
|
[0.75]
|
[-1.39]
|
[-0.80]
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3375
|
|
MTM Loss (Total)
|
6.09 (6.03)
|
5.66 (5.64)
|
5.69 (5.26)
|
5.94 (5.82)
|
6.37 (6.54)
|
5.13 (5.07)
|
6.10 (5.66)
|
5.38 (5.23)
|
|
|
[5.05]***
|
[2.33]**
|
[2.13]**
|
[2.34]**
|
[1.96]*
|
[-0.65]
|
[0.79]
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3375
|
|
Adjusted Equity
|
2.11 (2.08)
|
3.19 (2.91)
|
4.13 (4.12)
|
2.06 (2.27)
|
2.52 (1.53)
|
5.87 (6.33)
|
3.26 (3.04)
|
5.07 (3.79)
|
|
|
[-8.88]***
|
[-6.00]***
|
[-2.93]***
|
[-5.22]***
|
[-1.96]*
|
[0.94]
|
[-1.33]
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3375
|
|
Adjusted Equity < 0
|
29.65 (0.00)
|
19.36 (0.00)
|
14.23 (0.00)
|
28.33 (0.00)
|
33.33 (0.00)
|
4.76 (0.00)
|
33.33 (0.00)
|
18.87 (0.00)
|
|
|
[3.25]***
|
[0.22]
|
[-2.04]**
|
[1.60]
|
[1.02]
|
[-2.93]***
|
[0.87]
|
|
|
|
59
|
67
|
37
|
17
|
4
|
1
|
3
|
637
|
|
Adj. Tier1 Equity
|
4.16 (3.82)
|
4.72 (4.21)
|
5.32 (5.01)
|
3.63 (3.28)
|
4.13 (3.49)
|
5.61 (5.57)
|
3.31 (4.04)
|
6.73 (5.24)
|
|
|
[-9.62]***
|
[-7.55]***
|
[-5.29]***
|
[-7.48]***
|
[-3.69]***
|
[-1.70]
|
[-3.27]**
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3375
|
|
Adj. Tier1 Equity < 0
|
4.52 (0.00)
|
4.62 (0.00)
|
5.00 (0.00)
|
6.67 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
22.22 (0.00)
|
2.90 (0.00)
|
|
|
[1.08]
|
[1.47]
|
[1.51]
|
[1.15]
|
[-10.04]***
|
[-10.04]***
|
[1.31]
|
|
|
|
9
|
16
|
13
|
4
|
0
|
0
|
2
|
98
|
|
Adj. Common equity tier1
|
4.13 (3.82)
|
4.80 (4.26)
|
5.31 (5.01)
|
3.54 (3.18)
|
3.83 (3.21)
|
5.61 (5.57)
|
3.31 (4.04)
|
6.66 (5.21)
|
|
|
[-9.41]***
|
[-6.99]***
|
[-5.06]***
|
[-7.28]***
|
[-4.06]***
|
[-1.59]
|
[-3.20]**
|
|
|
|
193
|
333
|
258
|
57
|
11
|
21
|
9
|
3344
|
|
Adj. Common equity tier1 < 0
|
4.66 (0.00)
|
3.30 (0.00)
|
5.04 (0.00)
|
7.02 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
22.22 (0.00)
|
2.96 (0.00)
|
|
|
[1.10]
|
[0.33]
|
[1.49]
|
[1.18]
|
[-10.10]***
|
[-10.10]***
|
[1.31]
|
|
|
|
9
|
11
|
13
|
4
|
0
|
0
|
2
|
99
|
|
Uninsured Leverage
|
26.66 (24.86)
|
27.17 (25.28)
|
23.71 (22.82)
|
32.21 (29.91)
|
31.75 (28.72)
|
30.18 (30.05)
|
28.58 (31.00)
|
22.82 (21.42)
|
|
|
[4.82]***
|
[6.27]***
|
[1.26]
|
[5.13]***
|
[2.73]**
|
[2.62]**
|
[1.26]
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3385
|
|
MTM Insolvent
|
29.65 (0.00)
|
19.36 (0.00)
|
14.23 (0.00)
|
28.33 (0.00)
|
33.33 (0.00)
|
4.76 (0.00)
|
33.33 (0.00)
|
18.87 (0.00)
|
|
|
[3.25]***
|
[0.22]
|
[-2.04]**
|
[1.60]
|
[1.02]
|
[-2.93]***
|
[0.87]
|
|
|
|
59
|
67
|
37
|
17
|
4
|
1
|
3
|
637
|
|
Solvent and Liquid
|
10.55 (0.00)
|
10.98 (0.00)
|
19.62 (0.00)
|
5.00 (0.00)
|
0.00 (0.00)
|
14.29 (0.00)
|
0.00 (0.00)
|
24.84 (0.00)
|
|
|
[-6.20]***
|
[-7.53]***
|
[-2.03]**
|
[-6.77]***
|
[-33.43]***
|
[-1.34]
|
[-33.43]***
|
|
|
|
21
|
38
|
51
|
3
|
0
|
3
|
0
|
840
|
|
Solvent and Illiquid
|
23.12 (0.00)
|
30.92 (0.00)
|
30.38 (0.00)
|
30.00 (0.00)
|
25.00 (0.00)
|
42.86 (0.00)
|
44.44 (0.00)
|
25.87 (0.00)
|
|
|
[-0.89]
|
[1.95]*
|
[1.53]
|
[0.69]
|
[-0.07]
|
[1.53]
|
[1.06]
|
|
|
|
46
|
107
|
79
|
18
|
3
|
9
|
4
|
874
|
|
Insolvent and Liquid
|
24.12 (0.00)
|
26.30 (0.00)
|
26.92 (0.00)
|
11.67 (0.00)
|
16.67 (0.00)
|
14.29 (0.00)
|
33.33 (0.00)
|
26.94 (0.00)
|
|
|
[-0.90]
|
[-0.26]
|
[-0.01]
|
[-3.60]***
|
[-0.91]
|
[-1.61]
|
[0.38]
|
|
|
|
48
|
91
|
70
|
7
|
2
|
3
|
3
|
911
|
|
Insolvent and Illiquid
|
42.21 (0.00)
|
31.79 (0.00)
|
23.08 (0.00)
|
53.33 (100.00)
|
58.33 (100.00)
|
28.57 (0.00)
|
22.22 (0.00)
|
22.14 (0.00)
|
|
|
[5.60]***
|
[3.70]***
|
[0.35]
|
[4.77]***
|
[2.43]**
|
[0.64]
|
[0.01]
|
|
|
|
84
|
110
|
60
|
32
|
7
|
6
|
2
|
748
|
|
IDCR Insolvent (s=0.5)
|
4.02 (0.00)
|
5.49 (0.00)
|
4.62 (0.00)
|
3.33 (0.00)
|
0.00 (0.00)
|
4.76 (0.00)
|
11.11 (0.00)
|
4.07 (0.00)
|
|
|
[-0.03]
|
[1.12]
|
[0.41]
|
[-0.31]
|
[-11.90]***
|
[0.15]
|
[0.63]
|
|
|
|
8
|
19
|
12
|
2
|
0
|
1
|
1
|
136
|
|
IDCR Insolvent (s=1.0)
|
28.14 (0.00)
|
29.77 (0.00)
|
27.31 (0.00)
|
21.67 (0.00)
|
8.33 (0.00)
|
14.29 (0.00)
|
33.33 (0.00)
|
28.71 (0.00)
|
|
|
[-0.17]
|
[0.41]
|
[-0.49]
|
[-1.30]
|
[-2.43]**
|
[-1.83]*
|
[0.28]
|
|
|
|
56
|
103
|
71
|
13
|
1
|
3
|
3
|
960
|
|
Capital Insolvent (s=0.5)
|
2.01 (0.00)
|
2.89 (0.00)
|
3.08 (0.00)
|
6.67 (0.00)
|
0.00 (0.00)
|
4.76 (0.00)
|
11.11 (0.00)
|
1.96 (0.00)
|
|
|
[0.05]
|
[1.00]
|
[1.02]
|
[1.45]
|
[-8.20]***
|
[0.59]
|
[0.82]
|
|
|
|
4
|
10
|
8
|
4
|
0
|
1
|
1
|
66
|
|
Capital Insolvent (s=1.0)
|
12.06 (0.00)
|
11.56 (0.00)
|
7.31 (0.00)
|
8.33 (0.00)
|
0.00 (0.00)
|
4.76 (0.00)
|
11.11 (0.00)
|
6.99 (0.00)
|
|
|
[2.15]**
|
[2.57]**
|
[0.19]
|
[0.37]
|
[-15.93]***
|
[-0.47]
|
[0.37]
|
|
|
|
24
|
40
|
19
|
5
|
0
|
1
|
1
|
236
|
|
Available Liquidity Ratio
|
5.20 (3.79)
|
6.47 (3.75)
|
5.43 (4.31)
|
4.02 (2.59)
|
4.30 (3.76)
|
4.95 (3.49)
|
2.87 (2.22)
|
10.28 (6.70)
|
|
|
[-12.76]***
|
[-9.19]***
|
[-16.41]***
|
[-8.54]***
|
[-6.25]***
|
[-6.11]***
|
[-12.18]***
|
|
|
|
199
|
346
|
260
|
60
|
12
|
21
|
9
|
3385
|
|
Change Uninsured Deposits (Fwd Q)
|
-6.23 (-6.25)
|
-5.34 (-5.75)
|
-6.08 (-7.06)
|
-9.13 (-8.59)
|
-10.34 (-12.20)
|
-3.51 (-4.59)
|
-17.22 (-12.22)
|
1.71 (-3.71)
|
|
|
[-2.96]***
|
[-2.67]***
|
[-2.85]***
|
[-3.76]***
|
[-2.43]**
|
[-1.54]
|
[-2.78]**
|
|
|
|
199
|
344
|
260
|
60
|
12
|
21
|
9
|
3323
|
|
Change Insured Deposits (Fwd Q)
|
3.31 (1.97)
|
4.62 (2.13)
|
1.92 (0.96)
|
8.70 (2.08)
|
6.32 (0.94)
|
4.53 (3.66)
|
9.39 (7.84)
|
3.84 (1.42)
|
|
|
[-0.56]
|
[0.89]
|
[-2.27]**
|
[1.14]
|
[0.45]
|
[0.44]
|
[2.14]*
|
|
|
|
199
|
344
|
260
|
60
|
12
|
21
|
9
|
3329
|
|
Abnormal Insured Outflow (10%)
|
13.57 (0.00)
|
4.62 (0.00)
|
9.62 (0.00)
|
8.33 (0.00)
|
8.33 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
7.33 (0.00)
|
|
|
[2.52]**
|
[-2.22]**
|
[1.21]
|
[0.28]
|
[0.12]
|
[-16.36]***
|
[-16.36]***
|
|
|
|
27
|
16
|
25
|
5
|
1
|
0
|
0
|
248
|
|
Abnormal Insured Outflow (5%)
|
5.03 (0.00)
|
1.45 (0.00)
|
2.69 (0.00)
|
1.67 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
2.69 (0.00)
|
|
|
[1.48]
|
[-1.78]*
|
[0.00]
|
[-0.60]
|
[-9.67]***
|
[-9.67]***
|
[-9.67]***
|
|
|
|
10
|
5
|
7
|
1
|
0
|
0
|
0
|
91
|
|
Abnormal Uninsured Outflow (10%)
|
25.13 (0.00)
|
29.19 (0.00)
|
29.23 (0.00)
|
43.33 (0.00)
|
41.67 (0.00)
|
38.10 (0.00)
|
55.56 (100.00)
|
19.23 (0.00)
|
|
|
[1.87]*
|
[3.92]***
|
[3.44]***
|
[3.72]***
|
[1.51]
|
[1.73]*
|
[2.07]*
|
|
|
|
50
|
101
|
76
|
26
|
5
|
8
|
5
|
651
|
|
Abnormal Uninsured Outflow (5%)
|
8.54 (0.00)
|
11.85 (0.00)
|
12.69 (0.00)
|
25.00 (0.00)
|
33.33 (0.00)
|
9.52 (0.00)
|
22.22 (0.00)
|
8.36 (0.00)
|
|
|
[0.09]
|
[1.93]*
|
[2.04]**
|
[2.94]***
|
[1.76]
|
[0.18]
|
[0.94]
|
|
|
|
17
|
41
|
33
|
15
|
4
|
2
|
2
|
283
|
# Export
export_table(
table5a,
"table5a_q1_2023_10pct",
caption = "Pre-Crisis Bank Characteristics by Borrower Type: Q1 2023 (10\\% FHLB Threshold)",
label = "tab:q1_2023_10pct",
note = "Bank characteristics from 2022Q4 Call Reports. Q1 2023: January 1 -- March 31, 2023. FHLB borrowers identified as banks with abnormal FHLB advances at the 90th percentile. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table5a_q1_2023_10pct.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table5a_q1_2023_10pct.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table5a_q1_2023_10pct.csv
Table 5B: Q1 2023 -
All Facilities (5% Threshold)
# ==============================================================================
# TABLE 5B: Q1 2023 (Jan 1 - Mar 31) - BTFP, DW, FHLB (5% Threshold)
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 5B: Q1 2023 - BTFP, DW, FHLB (5%), Combinations, Non-Borrowers\n")
## TABLE 5B: Q1 2023 - BTFP, DW, FHLB (5%), Combinations, Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
# Define FHLB borrowers using 5% threshold (banks with abnormal FHLB advances in 2023Q1)
fhlb_borrowers_5pct <- baseline_q %>%
filter(!is.na(abnormal_fhlb_borrowing_5pct) & abnormal_fhlb_borrowing_5pct > 0) %>%
pull(idrssd)
cat("BTFP borrowers (Q1 2023):", length(btfp_q1), "\n")
## BTFP borrowers (Q1 2023): 302
cat("DW borrowers (Q1 2023):", length(dw_q1), "\n")
## DW borrowers (Q1 2023): 479
cat("FHLB borrowers (Q1 2023, 5%):", length(fhlb_borrowers_5pct), "\n")
## FHLB borrowers (Q1 2023, 5%): 221
table5b_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_q1,
dw_user = idrssd %in% dw_q1,
fhlb_user = idrssd %in% fhlb_borrowers_5pct,
borrower_type = case_when(
btfp_user & dw_user & fhlb_user ~ "All Three",
btfp_user & dw_user & !fhlb_user ~ "BTFP+DW",
btfp_user & !dw_user & fhlb_user ~ "BTFP+FHLB",
!btfp_user & dw_user & fhlb_user ~ "DW+FHLB",
btfp_user & !dw_user & !fhlb_user ~ "BTFP Only",
!btfp_user & dw_user & !fhlb_user ~ "DW Only",
!btfp_user & !dw_user & fhlb_user ~ "FHLB Only",
TRUE ~ "Non-Borrower"
)
)
table5b <- create_summary_table_v2(table5b_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "FHLB Only",
"BTFP+DW", "BTFP+FHLB", "DW+FHLB",
"All Three", "Non-Borrower"))
# Display
table5b %>%
select(-Row_Type) %>%
kable(caption = "Table 5B: Pre-Crisis Bank Characteristics by Borrower Type (Q1 2023: Jan 1 - Mar 31) - 5% FHLB Threshold") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
scroll_box(width = "100%")
Table 5B: Pre-Crisis Bank Characteristics by Borrower Type (Q1 2023: Jan
1 - Mar 31) - 5% FHLB Threshold
|
Variable
|
BTFP Only
|
DW Only
|
FHLB Only
|
BTFP+DW
|
BTFP+FHLB
|
DW+FHLB
|
All Three
|
Non-Borrower
|
|
N
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3453
|
|
Book Equity Ratio
|
8.18 (8.04)
|
8.88 (8.61)
|
9.80 (9.36)
|
8.01 (7.93)
|
9.42 (8.67)
|
11.24 (10.89)
|
10.44 (9.62)
|
10.54 (8.90)
|
|
|
[-8.89]***
|
[-6.56]***
|
[-2.66]***
|
[-6.04]***
|
[-1.06]
|
[0.82]
|
[-0.11]
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3453
|
|
MTM Loss (HTM)
|
0.17 (0.00)
|
0.24 (0.00)
|
0.16 (0.00)
|
0.36 (0.00)
|
0.18 (0.01)
|
0.17 (0.04)
|
0.11 (0.00)
|
0.20 (0.00)
|
|
|
[-0.55]
|
[0.91]
|
[-1.29]
|
[1.53]
|
[-0.21]
|
[-0.42]
|
[-1.03]
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3443
|
|
MTM Loss (BTFP Elg.)
|
0.82 (0.54)
|
0.84 (0.53)
|
0.52 (0.28)
|
0.96 (0.65)
|
0.64 (0.52)
|
0.57 (0.37)
|
0.35 (0.23)
|
0.66 (0.38)
|
|
|
[2.78]***
|
[3.40]***
|
[-2.91]***
|
[2.47]**
|
[-0.12]
|
[-0.47]
|
[-2.27]*
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3443
|
|
MTM Loss (Total)
|
6.08 (6.04)
|
5.66 (5.64)
|
5.60 (5.14)
|
5.93 (5.78)
|
6.59 (6.26)
|
5.00 (5.07)
|
6.35 (6.57)
|
5.39 (5.23)
|
|
|
[4.97]***
|
[2.23]**
|
[1.27]
|
[2.35]**
|
[2.11]*
|
[-1.14]
|
[0.61]
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3443
|
|
Adjusted Equity
|
2.10 (2.06)
|
3.22 (2.92)
|
4.20 (4.30)
|
2.07 (2.39)
|
2.82 (1.53)
|
6.24 (6.33)
|
4.09 (3.04)
|
5.04 (3.79)
|
|
|
[-8.92]***
|
[-5.92]***
|
[-2.42]**
|
[-5.46]***
|
[-1.46]
|
[1.19]
|
[-0.40]
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3443
|
|
Adjusted Equity < 0
|
29.70 (0.00)
|
19.32 (0.00)
|
12.50 (0.00)
|
28.12 (0.00)
|
33.33 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
18.88 (0.00)
|
|
|
[3.29]***
|
[0.20]
|
[-2.57]**
|
[1.62]
|
[0.87]
|
[-28.30]***
|
[0.86]
|
|
|
|
60
|
68
|
24
|
18
|
3
|
0
|
2
|
650
|
|
Adj. Tier1 Equity
|
4.16 (3.81)
|
4.73 (4.24)
|
5.25 (5.01)
|
3.59 (3.28)
|
4.12 (3.78)
|
5.85 (5.39)
|
3.59 (4.63)
|
6.71 (5.23)
|
|
|
[-9.66]***
|
[-7.56]***
|
[-5.16]***
|
[-7.89]***
|
[-3.17]**
|
[-1.09]
|
[-1.71]
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3443
|
|
Adj. Tier1 Equity < 0
|
4.46 (0.00)
|
4.55 (0.00)
|
4.69 (0.00)
|
6.25 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
2.96 (0.00)
|
|
|
[1.01]
|
[1.38]
|
[1.11]
|
[1.07]
|
[-10.25]***
|
[-10.25]***
|
[1.51]
|
|
|
|
9
|
16
|
9
|
4
|
0
|
0
|
2
|
102
|
|
Adj. Common equity tier1
|
4.11 (3.80)
|
4.81 (4.29)
|
5.24 (5.00)
|
3.50 (3.18)
|
4.12 (3.78)
|
5.84 (5.39)
|
3.59 (4.63)
|
6.63 (5.21)
|
|
|
[-9.50]***
|
[-6.99]***
|
[-4.96]***
|
[-7.71]***
|
[-3.09]**
|
[-1.01]
|
[-1.67]
|
|
|
|
195
|
339
|
191
|
61
|
9
|
15
|
5
|
3411
|
|
Adj. Common equity tier1 < 0
|
4.62 (0.00)
|
3.24 (0.00)
|
4.71 (0.00)
|
6.56 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
3.02 (0.00)
|
|
|
[1.04]
|
[0.22]
|
[1.08]
|
[1.10]
|
[-10.30]***
|
[-10.30]***
|
[1.51]
|
|
|
|
9
|
11
|
9
|
4
|
0
|
0
|
2
|
103
|
|
Uninsured Leverage
|
26.81 (25.02)
|
27.21 (25.31)
|
24.65 (23.17)
|
32.36 (30.12)
|
30.11 (26.15)
|
30.56 (30.05)
|
23.81 (22.44)
|
22.79 (21.40)
|
|
|
[5.06]***
|
[6.43]***
|
[2.33]**
|
[5.44]***
|
[1.95]*
|
[2.28]**
|
[0.18]
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3453
|
|
MTM Insolvent
|
29.70 (0.00)
|
19.32 (0.00)
|
12.50 (0.00)
|
28.12 (0.00)
|
33.33 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
18.88 (0.00)
|
|
|
[3.29]***
|
[0.20]
|
[-2.57]**
|
[1.62]
|
[0.87]
|
[-28.30]***
|
[0.86]
|
|
|
|
60
|
68
|
24
|
18
|
3
|
0
|
2
|
650
|
|
Solvent and Liquid
|
10.40 (0.00)
|
10.80 (0.00)
|
19.27 (0.00)
|
4.69 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
0.00 (0.00)
|
24.76 (0.00)
|
|
|
[-6.31]***
|
[-7.71]***
|
[-1.86]*
|
[-7.27]***
|
[-33.69]***
|
[-0.44]
|
[-33.69]***
|
|
|
|
21
|
38
|
37
|
3
|
0
|
3
|
0
|
854
|
|
Solvent and Illiquid
|
23.27 (0.00)
|
31.25 (0.00)
|
33.33 (0.00)
|
31.25 (0.00)
|
22.22 (0.00)
|
40.00 (0.00)
|
40.00 (0.00)
|
25.79 (0.00)
|
|
|
[-0.82]
|
[2.11]**
|
[2.16]**
|
[0.93]
|
[-0.24]
|
[1.08]
|
[0.58]
|
|
|
|
47
|
110
|
64
|
20
|
2
|
6
|
2
|
889
|
|
Insolvent and Liquid
|
23.76 (0.00)
|
26.42 (0.00)
|
23.44 (0.00)
|
12.50 (0.00)
|
22.22 (0.00)
|
6.67 (0.00)
|
40.00 (0.00)
|
27.14 (0.00)
|
|
|
[-1.09]
|
[-0.29]
|
[-1.17]
|
[-3.46]***
|
[-0.33]
|
[-3.05]***
|
[0.52]
|
|
|
|
48
|
93
|
45
|
8
|
2
|
1
|
2
|
936
|
|
Insolvent and Illiquid
|
42.57 (0.00)
|
31.53 (0.00)
|
23.96 (0.00)
|
51.56 (100.00)
|
55.56 (100.00)
|
33.33 (0.00)
|
20.00 (0.00)
|
22.11 (0.00)
|
|
|
[5.75]***
|
[3.66]***
|
[0.58]
|
[4.65]***
|
[1.90]*
|
[0.89]
|
[-0.11]
|
|
|
|
86
|
111
|
46
|
33
|
5
|
5
|
1
|
762
|
|
IDCR Insolvent (s=0.5)
|
3.96 (0.00)
|
5.68 (0.00)
|
3.65 (0.00)
|
3.12 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
4.13 (0.00)
|
|
|
[-0.12]
|
[1.21]
|
[-0.35]
|
[-0.45]
|
[-12.13]***
|
[-12.13]***
|
[0.79]
|
|
|
|
8
|
20
|
7
|
2
|
0
|
0
|
1
|
141
|
|
IDCR Insolvent (s=1.0)
|
28.22 (0.00)
|
29.83 (0.00)
|
27.60 (0.00)
|
21.88 (0.00)
|
0.00 (0.00)
|
6.67 (0.00)
|
40.00 (0.00)
|
28.66 (0.00)
|
|
|
[-0.14]
|
[0.46]
|
[-0.32]
|
[-1.29]
|
[-37.02]***
|
[-3.28]***
|
[0.46]
|
|
|
|
57
|
105
|
53
|
14
|
0
|
1
|
2
|
978
|
|
Capital Insolvent (s=0.5)
|
1.98 (0.00)
|
3.12 (0.00)
|
3.12 (0.00)
|
6.25 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
1.98 (0.00)
|
|
|
[0.01]
|
[1.20]
|
[0.90]
|
[1.40]
|
[-8.33]***
|
[-8.33]***
|
[0.90]
|
|
|
|
4
|
11
|
6
|
4
|
0
|
0
|
1
|
68
|
|
Capital Insolvent (s=1.0)
|
11.88 (0.00)
|
11.65 (0.00)
|
7.81 (0.00)
|
7.81 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
6.97 (0.00)
|
|
|
[2.11]**
|
[2.65]***
|
[0.42]
|
[0.25]
|
[-16.06]***
|
[-16.06]***
|
[0.65]
|
|
|
|
24
|
41
|
15
|
5
|
0
|
0
|
1
|
240
|
|
Available Liquidity Ratio
|
5.20 (3.81)
|
6.41 (3.70)
|
5.35 (4.38)
|
3.92 (2.49)
|
3.95 (3.59)
|
5.66 (4.04)
|
3.24 (3.59)
|
10.19 (6.66)
|
|
|
[-12.67]***
|
[-9.25]***
|
[-15.40]***
|
[-9.04]***
|
[-6.73]***
|
[-3.94]***
|
[-9.94]***
|
|
|
|
202
|
352
|
192
|
64
|
9
|
15
|
5
|
3453
|
|
Change Uninsured Deposits (Fwd Q)
|
-6.13 (-6.27)
|
-5.29 (-5.75)
|
-6.10 (-6.21)
|
-10.11 (-8.59)
|
-14.10 (-13.96)
|
-3.95 (-4.59)
|
-11.14 (-12.22)
|
1.56 (-3.89)
|
|
|
[-2.91]***
|
[-2.64]***
|
[-2.83]***
|
[-3.97]***
|
[-4.72]***
|
[-1.51]
|
[-3.57]***
|
|
|
|
202
|
350
|
192
|
64
|
9
|
15
|
5
|
3391
|
|
Change Insured Deposits (Fwd Q)
|
3.59 (1.86)
|
4.62 (2.19)
|
1.49 (0.78)
|
8.98 (2.15)
|
1.07 (0.75)
|
4.47 (3.66)
|
6.42 (4.81)
|
3.82 (1.43)
|
|
|
[-0.24]
|
[0.92]
|
[-2.94]***
|
[1.29]
|
[-1.49]
|
[0.33]
|
[0.80]
|
|
|
|
202
|
350
|
192
|
64
|
9
|
15
|
5
|
3397
|
|
Abnormal Insured Outflow (10%)
|
13.37 (0.00)
|
4.55 (0.00)
|
8.33 (0.00)
|
7.81 (0.00)
|
11.11 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
7.44 (0.00)
|
|
|
[2.43]**
|
[-2.42]**
|
[0.43]
|
[0.11]
|
[0.33]
|
[-16.66]***
|
[-16.66]***
|
|
|
|
27
|
16
|
16
|
5
|
1
|
0
|
0
|
257
|
|
Abnormal Insured Outflow (5%)
|
4.95 (0.00)
|
1.42 (0.00)
|
2.08 (0.00)
|
1.56 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
2.72 (0.00)
|
|
|
[1.43]
|
[-1.89]*
|
[-0.60]
|
[-0.73]
|
[-9.83]***
|
[-9.83]***
|
[-9.83]***
|
|
|
|
10
|
5
|
4
|
1
|
0
|
0
|
0
|
94
|
|
Abnormal Uninsured Outflow (10%)
|
25.25 (0.00)
|
29.26 (0.00)
|
30.21 (0.00)
|
43.75 (0.00)
|
44.44 (0.00)
|
40.00 (0.00)
|
60.00 (100.00)
|
19.37 (0.00)
|
|
|
[1.87]*
|
[3.92]***
|
[3.20]***
|
[3.88]***
|
[1.43]
|
[1.57]
|
[1.66]
|
|
|
|
51
|
103
|
58
|
28
|
4
|
6
|
3
|
669
|
|
Abnormal Uninsured Outflow (5%)
|
8.91 (0.00)
|
11.93 (0.00)
|
14.06 (0.00)
|
25.00 (0.00)
|
33.33 (0.00)
|
6.67 (0.00)
|
20.00 (0.00)
|
8.37 (0.00)
|
|
|
[0.26]
|
[1.99]**
|
[2.22]**
|
[3.04]***
|
[1.50]
|
[-0.25]
|
[0.58]
|
|
|
|
18
|
42
|
27
|
16
|
3
|
1
|
1
|
289
|
# Export
export_table(
table5b,
"table5b_q1_2023_5pct",
caption = "Pre-Crisis Bank Characteristics by Borrower Type: Q1 2023 (5\\% FHLB Threshold)",
label = "tab:q1_2023_5pct",
note = "Bank characteristics from 2022Q4 Call Reports. Q1 2023: January 1 -- March 31, 2023. FHLB borrowers identified as banks with abnormal FHLB advances at the 95th percentile. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table5b_q1_2023_5pct.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table5b_q1_2023_5pct.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table5b_q1_2023_5pct.csv
Table 6: Arbitrage
Period - BTFP, DW, Both, Non-Borrowers
# ==============================================================================
# TABLE 6: Arbitrage Period (Nov 1, 2023 - Jan 24, 2024)
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 6: Arbitrage Period - BTFP, DW, Both, Non-Borrowers\n")
## TABLE 6: Arbitrage Period - BTFP, DW, Both, Non-Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
arb_start <- as.Date("2023-11-01")
arb_end <- as.Date("2024-01-24")
btfp_arb <- btfp_loans_raw %>%
filter(btfp_loan_date >= arb_start & btfp_loan_date <= arb_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
# Note: DW data ends 2023-12-31, so only partial coverage
dw_arb <- dw_loans_raw %>%
filter(dw_loan_date >= arb_start & dw_loan_date <= min(arb_end, DW_DATA_END)) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat("BTFP borrowers (Arbitrage):", length(btfp_arb), "\n")
## BTFP borrowers (Arbitrage): 801
cat("DW borrowers (Arbitrage, partial):", length(dw_arb), "\n")
## DW borrowers (Arbitrage, partial): 481
cat("Note: DW data ends", as.character(DW_DATA_END), "\n")
## Note: DW data ends 2023-12-31
table6_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_arb,
dw_user = idrssd %in% dw_arb,
borrower_type = case_when(
btfp_user & dw_user ~ "Both",
btfp_user & !dw_user ~ "BTFP Only",
!btfp_user & dw_user ~ "DW Only",
TRUE ~ "Non-Borrower"
)
)
table6 <- create_summary_table_v2(table6_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "Both", "Non-Borrower"))
# Display
table6 %>%
select(-Row_Type) %>%
kable(caption = "Table 6: Pre-Crisis Bank Characteristics by Borrower Type (Arbitrage Period: Nov 1, 2023 - Jan 24, 2024)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 6: Pre-Crisis Bank Characteristics by Borrower Type (Arbitrage
Period: Nov 1, 2023 - Jan 24, 2024)
|
Variable
|
BTFP Only
|
DW Only
|
Both
|
Non-Borrower
|
|
N
|
623
|
302
|
143
|
3224
|
|
Book Equity Ratio
|
8.59 (8.31)
|
9.27 (9.17)
|
8.15 (8.08)
|
10.72 (9.01)
|
|
|
[-9.58]***
|
[-5.74]***
|
[-8.93]***
|
|
|
|
623
|
302
|
143
|
3224
|
|
MTM Loss (HTM)
|
0.25 (0.00)
|
0.17 (0.00)
|
0.21 (0.00)
|
0.20 (0.00)
|
|
|
[1.37]
|
[-1.29]
|
[0.17]
|
|
|
|
623
|
302
|
143
|
3214
|
|
MTM Loss (BTFP Elg.)
|
0.87 (0.60)
|
0.69 (0.51)
|
0.76 (0.49)
|
0.64 (0.36)
|
|
|
[6.02]***
|
[1.15]
|
[1.74]*
|
|
|
|
623
|
302
|
143
|
3214
|
|
MTM Loss (Total)
|
6.17 (5.93)
|
5.36 (5.22)
|
6.13 (6.12)
|
5.31 (5.16)
|
|
|
[9.76]***
|
[0.38]
|
[4.53]***
|
|
|
|
623
|
302
|
143
|
3214
|
|
Adjusted Equity
|
2.41 (2.28)
|
3.91 (3.75)
|
2.02 (1.93)
|
5.30 (3.93)
|
|
|
[-11.47]***
|
[-4.44]***
|
[-8.39]***
|
|
|
|
623
|
302
|
143
|
3214
|
|
Adjusted Equity < 0
|
26.97 (0.00)
|
15.56 (0.00)
|
32.17 (0.00)
|
17.55 (0.00)
|
|
|
[4.95]***
|
[-0.90]
|
[3.68]***
|
|
|
|
168
|
47
|
46
|
564
|
|
Adj. Tier1 Equity
|
4.48 (4.07)
|
5.23 (4.91)
|
3.71 (3.66)
|
6.87 (5.32)
|
|
|
[-11.09]***
|
[-6.18]***
|
[-10.92]***
|
|
|
|
623
|
302
|
143
|
3214
|
|
Adj. Tier1 Equity < 0
|
5.62 (0.00)
|
3.97 (0.00)
|
7.69 (0.00)
|
2.61 (0.00)
|
|
|
[3.11]***
|
[1.17]
|
[2.25]**
|
|
|
|
35
|
12
|
11
|
84
|
|
Adj. Common equity tier1
|
4.46 (4.07)
|
5.27 (4.93)
|
3.66 (3.63)
|
6.80 (5.31)
|
|
|
[-10.99]***
|
[-5.77]***
|
[-10.75]***
|
|
|
|
619
|
290
|
137
|
3180
|
|
Adj. Common equity tier1 < 0
|
5.82 (0.00)
|
3.79 (0.00)
|
8.03 (0.00)
|
2.52 (0.00)
|
|
|
[3.36]***
|
[1.10]
|
[2.35]**
|
|
|
|
36
|
11
|
11
|
80
|
|
Uninsured Leverage
|
25.43 (23.98)
|
26.41 (25.24)
|
28.22 (26.52)
|
22.79 (21.42)
|
|
|
[5.35]***
|
[4.72]***
|
[5.19]***
|
|
|
|
623
|
302
|
143
|
3224
|
|
MTM Insolvent
|
26.97 (0.00)
|
15.56 (0.00)
|
32.17 (0.00)
|
17.55 (0.00)
|
|
|
[4.95]***
|
[-0.90]
|
[3.68]***
|
|
|
|
168
|
47
|
46
|
564
|
|
Solvent and Liquid
|
11.88 (0.00)
|
18.21 (0.00)
|
8.39 (0.00)
|
25.31 (0.00)
|
|
|
[-8.92]***
|
[-3.02]***
|
[-6.91]***
|
|
|
|
74
|
55
|
12
|
815
|
|
Solvent and Illiquid
|
22.47 (0.00)
|
32.78 (0.00)
|
31.47 (0.00)
|
26.60 (0.00)
|
|
|
[-2.24]**
|
[2.20]**
|
[1.22]
|
|
|
|
140
|
99
|
45
|
856
|
|
Insolvent and Liquid
|
29.70 (0.00)
|
22.52 (0.00)
|
24.48 (0.00)
|
26.30 (0.00)
|
|
|
[1.70]*
|
[-1.50]
|
[-0.50]
|
|
|
|
185
|
68
|
35
|
847
|
|
Insolvent and Illiquid
|
35.96 (0.00)
|
26.49 (0.00)
|
35.66 (0.00)
|
21.57 (0.00)
|
|
|
[7.00]***
|
[1.86]*
|
[3.45]***
|
|
|
|
224
|
80
|
51
|
694
|
|
IDCR Insolvent (s=0.5)
|
4.82 (0.00)
|
3.97 (0.00)
|
2.80 (0.00)
|
4.18 (0.00)
|
|
|
[0.69]
|
[-0.17]
|
[-0.97]
|
|
|
|
30
|
12
|
4
|
133
|
|
IDCR Insolvent (s=1.0)
|
32.10 (0.00)
|
29.47 (0.00)
|
32.17 (0.00)
|
27.49 (0.00)
|
|
|
[2.27]**
|
[0.72]
|
[1.17]
|
|
|
|
200
|
89
|
46
|
875
|
|
Capital Insolvent (s=0.5)
|
1.77 (0.00)
|
4.97 (0.00)
|
5.59 (0.00)
|
1.87 (0.00)
|
|
|
[-0.17]
|
[2.43]**
|
[1.92]*
|
|
|
|
11
|
15
|
8
|
60
|
|
Capital Insolvent (s=1.0)
|
8.99 (0.00)
|
11.26 (0.00)
|
13.29 (0.00)
|
6.75 (0.00)
|
|
|
[1.82]*
|
[2.40]**
|
[2.27]**
|
|
|
|
56
|
34
|
19
|
217
|
|
Available Liquidity Ratio
|
5.33 (3.74)
|
7.07 (4.63)
|
4.96 (3.44)
|
10.47 (6.86)
|
|
|
[-18.84]***
|
[-7.13]***
|
[-13.84]***
|
|
|
|
623
|
302
|
143
|
3224
|
|
Change Uninsured Deposits (Fwd Q)
|
-1.15 (-5.82)
|
-5.39 (-6.07)
|
-2.18 (-3.91)
|
0.88 (-4.09)
|
|
|
[-0.48]
|
[-2.26]**
|
[-1.08]
|
|
|
|
623
|
301
|
143
|
3161
|
|
Change Insured Deposits (Fwd Q)
|
3.72 (1.65)
|
5.93 (2.87)
|
4.14 (1.81)
|
3.66 (1.31)
|
|
|
[0.06]
|
[2.16]**
|
[0.39]
|
|
|
|
623
|
302
|
143
|
3166
|
|
Abnormal Insured Outflow (10%)
|
7.38 (0.00)
|
4.97 (0.00)
|
7.69 (0.00)
|
7.75 (0.00)
|
|
|
[-0.32]
|
[-2.08]**
|
[-0.03]
|
|
|
|
46
|
15
|
11
|
250
|
|
Abnormal Insured Outflow (5%)
|
2.41 (0.00)
|
1.99 (0.00)
|
2.80 (0.00)
|
2.76 (0.00)
|
|
|
[-0.52]
|
[-0.91]
|
[0.03]
|
|
|
|
15
|
6
|
4
|
89
|
|
Abnormal Uninsured Outflow (10%)
|
26.97 (0.00)
|
27.48 (0.00)
|
23.78 (0.00)
|
19.76 (0.00)
|
|
|
[3.77]***
|
[2.90]***
|
[1.10]
|
|
|
|
168
|
83
|
34
|
637
|
|
Abnormal Uninsured Outflow (5%)
|
12.68 (0.00)
|
11.59 (0.00)
|
9.79 (0.00)
|
8.34 (0.00)
|
|
|
[3.05]***
|
[1.70]*
|
[0.57]
|
|
|
|
79
|
35
|
14
|
269
|
# Export
export_table(
table6,
"table6_arbitrage_period",
caption = "Pre-Crisis Bank Characteristics by Borrower Type: Arbitrage Period",
label = "tab:arbitrage_period",
note = "Bank characteristics from 2022Q4 Call Reports. Arbitrage period: November 1, 2023 -- January 24, 2024 (BTFP rate below IORB). Note: DW data available only through December 31, 2023. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table6_arbitrage_period.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table6_arbitrage_period.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table6_arbitrage_period.csv
# ==============================================================================
# TABLE 6b: Arbitrage Period (Nov 1, 2023 - Jan 24, 2024)
# UPDATED: Uses 2023Q4 baseline instead of 2022Q4
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE 6b: Arbitrage Period - BTFP, DW, Both, Non-Borrowers\n")
## TABLE 6b: Arbitrage Period - BTFP, DW, Both, Non-Borrowers
cat("Using 2023Q4 as baseline\n")
## Using 2023Q4 as baseline
cat(strrep("=", 60), "\n")
## ============================================================
# Create 2023Q4 baseline data
baseline_q4_2023 <- call_q %>%
filter(period == '2023Q4') %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0
)
# Step 3: Calculate medians for cutoffs (BEFORE adding derived variables)
medians_q4 <- baseline_q4_2023 %>%
summarise(
median_uninsured = median(uninsured_deposit_to_total_asset, na.rm = TRUE),
median_mtm = median(mtm_loss_to_total_asset, na.rm = TRUE),
q75_uninsured = quantile(uninsured_deposit_to_total_asset, 0.75, na.rm = TRUE),
q75_mtm = quantile(mtm_loss_to_total_asset, 0.75, na.rm = TRUE)
)
cat("Median uninsured ratio:", round(medians_q4$median_uninsured, 2), "%\n")
## Median uninsured ratio: 19.94 %
cat("Median MTM loss ratio:", round(medians_q4$median_mtm, 2), "%\n")
## Median MTM loss ratio: 5.13 %
cat("Q75 uninsured ratio:", round(medians_q4$q75_uninsured, 2), "%\n")
## Q75 uninsured ratio: 27.17 %
cat("Q75 MTM loss ratio:", round(medians_q4$q75_mtm, 2), "%\n")
## Q75 MTM loss ratio: 6.81 %
# Step 4: Add ALL derived variables to baseline
baseline_q4_2023 <- baseline_q4_2023 %>%
mutate(
# Market value adjustment: (Book Asset / MV Asset) - 1
cet1_ratio = safe_div(cet1, total_asset) * 100,
mv_asset = mm_asset,
mv_adjustment = if_else(mv_asset == 0 | is.na(mv_asset), NA_real_,
(total_asset / mv_asset) - 1),
# IDCR: (MV_Asset - s*Uninsured - Insured) / Insured
idcr_s50 = safe_div(mv_asset - 0.5 * uninsured_deposit - insured_deposit, insured_deposit),
idcr_s100 = safe_div(mv_asset - 1.0 * uninsured_deposit - insured_deposit, insured_deposit),
# Capital Insolvency: (Equity - s*Uninsured*MVAdj) / Assets
cap_insolvency_s50 = safe_div((total_asset - total_liability) - 0.5 * uninsured_deposit * mv_adjustment, total_asset),
cap_insolvency_s100 = safe_div((total_asset - total_liability) - 1.0 * uninsured_deposit * mv_adjustment, total_asset),
# Adjusted Equity (book equity ratio - MTM loss ratio, both in %)
adjusted_equity = book_equity_to_total_asset - mtm_loss_to_total_asset,
adjusted_tier1 = tier1cap_to_total_asset - mtm_loss_to_total_asset,
adjusted_cet1 = cet1_ratio - mtm_loss_to_total_asset,
# MTM Insolvent dummy (adjusted equity < 0)
mtm_insolvent = as.integer(adjusted_equity < 0),
mtm_insolvent_tier1 = as.integer(adjusted_tier1 < 0),
mtm_insolvent_cet1 = as.integer(adjusted_cet1 < 0),
adjusted_book_value = mm_asset - total_liability,
mv_insolvent = as.integer(adjusted_book_value < 0),
# Uninsured leverage (uninsured deposit / book equity)
uninsured_leverage = uninsured_deposit_to_total_asset,
liquidity_available = safe_div(cash + rerepo + fed_fund_sold, total_asset) * 100,
# Run risk dummies
# a. Solvent and Liquid (both uninsured and MTM below median)
run_risk_1 = as.integer(
uninsured_deposit_to_total_asset < medians_q4$median_uninsured &
mtm_loss_to_total_asset < medians_q4$median_mtm
),
# b. Solvent and Illiquid
run_risk_2 = as.integer(
uninsured_deposit_to_total_asset > medians_q4$median_uninsured &
mtm_loss_to_total_asset < medians_q4$median_mtm
),
# c. Insolvent and Liquid
run_risk_3 = as.integer(
uninsured_deposit_to_total_asset < medians_q4$median_uninsured &
mtm_loss_to_total_asset > medians_q4$median_mtm
),
# d. Insolvent and ILLiquid (both uninsured and MTM above median)
run_risk_4 = as.integer(
uninsured_deposit_to_total_asset > medians_q4$median_uninsured &
mtm_loss_to_total_asset > medians_q4$median_mtm
),
# IDCR insolvency dummies
idcr_insolvent_s50 = as.integer(idcr_s50 < 0),
idcr_insolvent_s100 = as.integer(idcr_s100 < 0),
# Capital insolvency dummies
cap_insolvent_s50 = as.integer(cap_insolvency_s50 < 0),
cap_insolvent_s100 = as.integer(cap_insolvency_s100 < 0)
) %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0)
cat("2023Q4 baseline observations:", nrow(baseline_q4_2023), "\n")
## 2023Q4 baseline observations: 4197
arb_start <- as.Date("2023-11-01")
arb_end <- as.Date("2024-01-24")
btfp_arb <- btfp_loans_raw %>%
filter(btfp_loan_date >= arb_start & btfp_loan_date <= arb_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
# Note: DW data ends 2023-12-31, so only partial coverage
dw_arb <- dw_loans_raw %>%
filter(dw_loan_date >= arb_start & dw_loan_date <= min(arb_end, DW_DATA_END)) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat("BTFP borrowers (Arbitrage):", length(btfp_arb), "\n")
## BTFP borrowers (Arbitrage): 801
cat("DW borrowers (Arbitrage, partial):", length(dw_arb), "\n")
## DW borrowers (Arbitrage, partial): 481
cat("Note: DW data ends", as.character(DW_DATA_END), "\n")
## Note: DW data ends 2023-12-31
table6b_data <- baseline_q4_2023 %>%
mutate(
btfp_user = idrssd %in% btfp_arb,
dw_user = idrssd %in% dw_arb,
borrower_type = case_when(
btfp_user & dw_user ~ "Both",
btfp_user & !dw_user ~ "BTFP Only",
!btfp_user & dw_user ~ "DW Only",
TRUE ~ "Non-Borrower"
)
)
table6b <- create_summary_table_v2(table6b_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "Both", "Non-Borrower"))
# Display
table6b %>%
select(-Row_Type) %>%
kable(caption = "Table 6b: Bank Characteristics by Borrower Type (Arbitrage Period: Nov 1, 2023 - Jan 24, 2024) - 2023Q4 Baseline") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table 6b: Bank Characteristics by Borrower Type (Arbitrage Period: Nov
1, 2023 - Jan 24, 2024) - 2023Q4 Baseline
|
Variable
|
BTFP Only
|
DW Only
|
Both
|
Non-Borrower
|
|
N
|
632
|
302
|
141
|
3122
|
|
Book Equity Ratio
|
9.06 (8.74)
|
9.84 (9.75)
|
8.75 (8.65)
|
11.46 (9.56)
|
|
|
[-11.05]***
|
[-6.57]***
|
[-9.96]***
|
|
|
|
632
|
302
|
141
|
3122
|
|
MTM Loss (HTM)
|
0.24 (0.00)
|
0.16 (0.00)
|
0.21 (0.00)
|
0.20 (0.00)
|
|
|
[1.25]
|
[-1.40]
|
[0.17]
|
|
|
|
632
|
302
|
141
|
3104
|
|
MTM Loss (BTFP Elg.)
|
0.84 (0.56)
|
0.66 (0.49)
|
0.75 (0.48)
|
0.63 (0.35)
|
|
|
[5.61]***
|
[0.86]
|
[1.79]*
|
|
|
|
632
|
302
|
141
|
3104
|
|
MTM Loss (Total)
|
5.92 (5.69)
|
5.17 (5.06)
|
5.86 (5.76)
|
5.16 (4.99)
|
|
|
[8.61]***
|
[0.13]
|
[3.93]***
|
|
|
|
632
|
302
|
141
|
3104
|
|
Adjusted Equity
|
3.14 (3.12)
|
4.66 (4.57)
|
2.89 (2.94)
|
6.11 (4.69)
|
|
|
[-12.19]***
|
[-4.75]***
|
[-8.64]***
|
|
|
|
632
|
302
|
141
|
3104
|
|
Adjusted Equity < 0
|
20.41 (0.00)
|
11.26 (0.00)
|
22.70 (0.00)
|
12.21 (0.00)
|
|
|
[4.80]***
|
[-0.50]
|
[2.92]***
|
|
|
|
129
|
34
|
32
|
379
|
|
Adj. Tier1 Equity
|
4.71 (4.40)
|
5.61 (5.24)
|
4.12 (3.97)
|
7.26 (5.71)
|
|
|
[-12.25]***
|
[-6.36]***
|
[-10.83]***
|
|
|
|
632
|
302
|
141
|
3104
|
|
Adj. Tier1 Equity < 0
|
3.32 (0.00)
|
3.64 (0.00)
|
7.09 (0.00)
|
2.16 (0.00)
|
|
|
[1.53]
|
[1.34]
|
[2.26]**
|
|
|
|
21
|
11
|
10
|
67
|
|
Adj. Common equity tier1
|
4.68 (4.38)
|
5.59 (5.25)
|
4.06 (3.87)
|
7.19 (5.69)
|
|
|
[-12.15]***
|
[-6.17]***
|
[-10.63]***
|
|
|
|
627
|
288
|
135
|
3072
|
|
Adj. Common equity tier1 < 0
|
3.51 (0.00)
|
3.47 (0.00)
|
7.41 (0.00)
|
2.15 (0.00)
|
|
|
[1.74]*
|
[1.19]
|
[2.31]**
|
|
|
|
22
|
10
|
10
|
66
|
|
Uninsured Leverage
|
22.06 (20.68)
|
22.63 (21.30)
|
24.60 (23.23)
|
20.84 (19.45)
|
|
|
[2.71]***
|
[2.71]***
|
[3.84]***
|
|
|
|
632
|
302
|
141
|
3122
|
|
MTM Insolvent
|
20.41 (0.00)
|
11.26 (0.00)
|
22.70 (0.00)
|
12.21 (0.00)
|
|
|
[4.80]***
|
[-0.50]
|
[2.92]***
|
|
|
|
129
|
34
|
32
|
379
|
|
Solvent and Liquid
|
15.82 (0.00)
|
21.85 (0.00)
|
14.18 (0.00)
|
25.50 (0.00)
|
|
|
[-5.87]***
|
[-1.45]
|
[-3.71]***
|
|
|
|
100
|
66
|
20
|
794
|
|
Solvent and Illiquid
|
22.94 (0.00)
|
29.80 (0.00)
|
26.95 (0.00)
|
26.86 (0.00)
|
|
|
[-2.12]**
|
[1.07]
|
[0.02]
|
|
|
|
145
|
90
|
38
|
836
|
|
Insolvent and Liquid
|
31.01 (0.00)
|
21.85 (0.00)
|
26.24 (0.00)
|
26.04 (0.00)
|
|
|
[2.48]**
|
[-1.67]*
|
[0.05]
|
|
|
|
196
|
66
|
37
|
811
|
|
Insolvent and Illiquid
|
30.06 (0.00)
|
26.49 (0.00)
|
32.62 (0.00)
|
21.27 (0.00)
|
|
|
[4.47]***
|
[1.97]**
|
[2.82]***
|
|
|
|
190
|
80
|
46
|
662
|
|
IDCR Insolvent (s=0.5)
|
10.92 (0.00)
|
15.56 (0.00)
|
10.64 (0.00)
|
11.64 (0.00)
|
|
|
[-0.53]
|
[1.81]*
|
[-0.38]
|
|
|
|
69
|
47
|
15
|
358
|
|
IDCR Insolvent (s=1.0)
|
34.81 (0.00)
|
37.75 (0.00)
|
41.13 (0.00)
|
36.36 (0.00)
|
|
|
[-0.74]
|
[0.48]
|
[1.12]
|
|
|
|
220
|
114
|
58
|
1118
|
|
Capital Insolvent (s=0.5)
|
3.80 (0.00)
|
5.63 (0.00)
|
5.67 (0.00)
|
3.41 (0.00)
|
|
|
[0.46]
|
[1.62]
|
[1.14]
|
|
|
|
24
|
17
|
8
|
106
|
|
Capital Insolvent (s=1.0)
|
12.03 (0.00)
|
12.91 (0.00)
|
17.73 (0.00)
|
10.76 (0.00)
|
|
|
[0.90]
|
[1.07]
|
[2.13]**
|
|
|
|
76
|
39
|
25
|
334
|
|
Available Liquidity Ratio
|
5.77 (4.25)
|
6.75 (4.95)
|
5.18 (4.11)
|
10.12 (7.25)
|
|
|
[-16.63]***
|
[-7.98]***
|
[-13.57]***
|
|
|
|
632
|
302
|
141
|
3122
|
|
Change Uninsured Deposits (Fwd Q)
|
0.81 (0.31)
|
0.62 (0.71)
|
2.17 (1.39)
|
20.41 (-0.31)
|
|
|
[-1.27]
|
[-1.29]
|
[-1.19]
|
|
|
|
629
|
301
|
141
|
3073
|
|
Change Insured Deposits (Fwd Q)
|
1.99 (1.09)
|
2.30 (1.74)
|
2.02 (1.00)
|
1.83 (1.23)
|
|
|
[0.57]
|
[1.26]
|
[0.37]
|
|
|
|
629
|
301
|
141
|
3076
|
|
Abnormal Insured Outflow (10%)
|
8.86 (0.00)
|
7.28 (0.00)
|
10.64 (0.00)
|
7.85 (0.00)
|
|
|
[0.82]
|
[-0.36]
|
[1.05]
|
|
|
|
56
|
22
|
15
|
245
|
|
Abnormal Insured Outflow (5%)
|
5.06 (0.00)
|
3.97 (0.00)
|
5.67 (0.00)
|
4.93 (0.00)
|
|
|
[0.14]
|
[-0.81]
|
[0.37]
|
|
|
|
32
|
12
|
8
|
154
|
|
Abnormal Uninsured Outflow (10%)
|
11.23 (0.00)
|
9.93 (0.00)
|
4.96 (0.00)
|
10.95 (0.00)
|
|
|
[0.20]
|
[-0.56]
|
[-3.12]***
|
|
|
|
71
|
30
|
7
|
342
|
|
Abnormal Uninsured Outflow (5%)
|
6.49 (0.00)
|
5.63 (0.00)
|
3.55 (0.00)
|
6.21 (0.00)
|
|
|
[0.26]
|
[-0.42]
|
[-1.65]
|
|
|
|
41
|
17
|
5
|
194
|
# Export
export_table(
table6b,
"table6b_arbitrage_period_2023q4",
caption = "Bank Characteristics by Borrower Type: Arbitrage Period (2023Q4 Baseline)",
label = "tab:arbitrage_period_2023q4",
note = "Bank characteristics from 2023Q4 Call Reports. Arbitrage period: November 1, 2023 -- January 24, 2024 (BTFP rate below IORB). Note: DW data available only through December 31, 2023. Sample excludes G-SIBs and failed banks."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table6b_arbitrage_period_2023q4.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table6b_arbitrage_period_2023q4.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table6b_arbitrage_period_2023q4.csv
Table 7: FHLB Borrower
Characteristics (5% Threshold)
# ==============================================================================
# TABLE 7: FHLB Borrower Characteristics - 5% Threshold (Q1 2023)
# ==============================================================================
# First, identify banks with abnormal FHLB borrowing at 5% threshold
fhlb_borrower_5pct <- baseline_q %>%
filter(!is.na(abnormal_fhlb_borrowing_5pct) & abnormal_fhlb_borrowing_5pct > 0) %>%
pull(idrssd)
# Create FHLB summary table function with custom variables (WITH T-STATS)
create_fhlb_summary_table <- function(data, group_var, group_levels = NULL, reference_group = "Non-Borrower") {
# Define variable specifications for FHLB table
var_specs <- tribble(
~var_name, ~var_label, ~is_dummy,
# Basic fundamentals
"book_equity_to_total_asset", "Book Equity Ratio", FALSE,
"loss_asset_htm_only", "MTM Loss (HTM)", FALSE,
"mtm_loss_omo_eligible_to_total_asset", "MTM Loss (BTFP Elg.)", FALSE,
"mtm_loss_to_total_asset", "MTM Loss (Total)", FALSE,
"adjusted_equity", "Adjusted Equity", FALSE,
"mtm_insolvent", "Adjusted Equity < 0", TRUE,
"adjusted_tier1", "Adj. Tier1 Equity", FALSE,
"mtm_insolvent_tier1", "Adj. Tier1 Equity < 0", TRUE,
"adjusted_cet1", " Adj. Common equity tier1",FALSE,
"mtm_insolvent_cet1", "Adj. Common equity tier1 < 0", TRUE,
"uninsured_leverage", "Uninsured Leverage", FALSE,
"mtm_insolvent", "MTM Insolvent", TRUE,
"run_risk_1", "Solvent and Liquid", TRUE,
"run_risk_2", "Solvent and Illiquid", TRUE,
"run_risk_3", "Insolvent and Liquid", TRUE,
"run_risk_4", "Insolvent and Illiquid", TRUE,
"idcr_insolvent_s50", "IDCR Insolvent (s=0.5)", TRUE,
"idcr_insolvent_s100", "IDCR Insolvent (s=1.0)", TRUE,
"cap_insolvent_s50", "Capital Insolvent (s=0.5)", TRUE,
"cap_insolvent_s100", "Capital Insolvent (s=1.0)", TRUE,
"liquidity_available", "Available Liquidity Ratio", FALSE,
"change_uninsured_fwd_q", "Change Uninsured Deposits (Fwd Q)", FALSE,
"change_insured_deposit_fwd_q", "Change Insured Deposits (Fwd Q)", FALSE,
"abnormal_insured_outflow_10pct", "Abnormal Insured Outflow (10%)", TRUE,
"abnormal_insured_outflow_5pct", "Abnormal Insured Outflow (5%)", TRUE,
"abnormal_uninsured_outflow_10pct", "Abnormal Uninsured Outflow (10%)", TRUE,
"abnormal_uninsured_outflow_5pct", "Abnormal Uninsured Outflow (5%)", TRUE
)
# Get unique groups
if (is.null(group_levels)) {
group_levels <- unique(data[[group_var]])
}
# Calculate N for each group
n_by_group <- data %>%
group_by(.data[[group_var]]) %>%
summarise(N = n(), .groups = "drop")
# Get reference group data for T-stat calculation
ref_data <- data %>% filter(.data[[group_var]] == reference_group)
# Initialize output list
output_rows <- list()
# Add N row first
n_row <- c(Variable = "N", Row_Type = "count")
for (g in group_levels) {
n_val <- n_by_group %>% filter(.data[[group_var]] == g) %>% pull(N)
n_row[g] <- as.character(if(length(n_val) == 0) 0 else n_val)
}
output_rows[[1]] <- n_row
row_idx <- 2
# Process each variable
for (i in seq_len(nrow(var_specs))) {
v <- var_specs$var_name[i]
label <- var_specs$var_label[i]
is_dummy <- var_specs$is_dummy[i]
# Stats row: Mean (Median)
stats_row <- c(Variable = label, Row_Type = "stats")
# T-stat row (below stats)
tstat_row <- c(Variable = "", Row_Type = "tstat")
# N row (below t-stat)
obs_row <- c(Variable = "", Row_Type = "n")
# Get reference group values for T-stat
ref_vals <- if (v %in% names(ref_data)) ref_data[[v]] else numeric(0)
ref_vals <- ref_vals[!is.na(ref_vals)]
for (g in group_levels) {
group_data <- data %>% filter(.data[[group_var]] == g)
# Check if variable exists
if (!v %in% names(group_data)) {
stats_row[g] <- "—"
tstat_row[g] <- ""
obs_row[g] <- "0"
next
}
vals <- group_data[[v]]
vals <- vals[!is.na(vals)]
if (length(vals) == 0) {
stats_row[g] <- "—"
tstat_row[g] <- ""
obs_row[g] <- "0"
} else {
mean_val <- mean(vals, na.rm = TRUE)
median_val <- median(vals, na.rm = TRUE)
if (is_dummy) {
# For dummies: mean is proportion, show as percentage
# N shows count of 1s (banks with dummy = 1)
stats_row[g] <- sprintf("%.2f (%.2f)", mean_val * 100, median_val * 100)
n_val <- sum(vals) # Count of banks where dummy = 1
} else if (v == "total_asset") {
# For total assets: show in millions
stats_row[g] <- sprintf("%.0f (%.0f)", mean_val / 1e6, median_val / 1e6)
n_val <- length(vals)
} else {
stats_row[g] <- sprintf("%.2f (%.2f)", mean_val, median_val)
n_val <- length(vals) # Total non-NA observations
}
# Calculate T-stat vs reference group (skip for reference group itself)
if (g == reference_group) {
tstat_row[g] <- ""
} else {
t_stat <- calc_tstat(vals, ref_vals)
if (!is.na(t_stat) && is.finite(t_stat)) {
tstat_row[g] <- sprintf("[%.2f]", t_stat)
} else {
tstat_row[g] <- ""
}
}
obs_row[g] <- as.character(n_val)
}
}
output_rows[[row_idx]] <- stats_row
output_rows[[row_idx + 1]] <- tstat_row
output_rows[[row_idx + 2]] <- obs_row
row_idx <- row_idx + 3
}
# Convert to data frame
result_df <- bind_rows(lapply(output_rows, function(x) as_tibble_row(x)))
return(result_df)
}
# Prepare data with FHLB variables (5% threshold)
table7_data <- baseline_q %>%
mutate(
# Categorize by FHLB usage (5% threshold)
fhlb_user = idrssd %in% fhlb_borrower_5pct,
btfp_user = idrssd %in% btfp_q1,
dw_user = idrssd %in% dw_q1,
borrower_type = case_when(
fhlb_user & btfp_user & dw_user ~ "FHLB+BTFP+DW",
fhlb_user & btfp_user & !dw_user ~ "FHLB+BTFP",
fhlb_user & !btfp_user & dw_user ~ "FHLB+DW",
fhlb_user & !btfp_user & !dw_user ~ "FHLB Only",
!fhlb_user & (btfp_user | dw_user) ~ "Fed Only",
TRUE ~ "Non-Borrower"
)
)
# Count by category
table7_data %>%
count(borrower_type) %>%
arrange(desc(n)) %>%
pander(caption = "FHLB Borrower Breakdown (5% Threshold)")
FHLB Borrower Breakdown (5% Threshold)
| Non-Borrower |
3453 |
| Fed Only |
618 |
| FHLB Only |
192 |
| FHLB+DW |
15 |
| FHLB+BTFP |
9 |
| FHLB+BTFP+DW |
5 |
table7 <- create_fhlb_summary_table(table7_data, "borrower_type",
group_levels = c("FHLB Only", "FHLB+BTFP", "FHLB+DW",
"FHLB+BTFP+DW", "Fed Only", "Non-Borrower"))
# Display
table7 %>%
select(-Row_Type) %>%
kable(caption = "Table 7: Bank Characteristics by FHLB Borrower Type - 5% Threshold (Q1 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
scroll_box(width = "100%")
Table 7: Bank Characteristics by FHLB Borrower Type - 5% Threshold (Q1
2023)
|
Variable
|
FHLB Only
|
FHLB+BTFP
|
FHLB+DW
|
FHLB+BTFP+DW
|
Fed Only
|
Non-Borrower
|
|
N
|
192
|
9
|
15
|
5
|
618
|
3453
|
|
Book Equity Ratio
|
9.80 (9.36)
|
9.42 (8.67)
|
11.24 (10.89)
|
10.44 (9.62)
|
8.56 (8.36)
|
10.54 (8.90)
|
|
|
[-2.66]
|
[-1.06]
|
[0.82]
|
[-0.11]
|
[-9.28]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3453
|
|
MTM Loss (HTM)
|
0.16 (0.00)
|
0.18 (0.01)
|
0.17 (0.04)
|
0.11 (0.00)
|
0.23 (0.00)
|
0.20 (0.00)
|
|
|
[-1.29]
|
[-0.21]
|
[-0.42]
|
[-1.03]
|
[0.85]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3443
|
|
MTM Loss (BTFP Elg.)
|
0.52 (0.28)
|
0.64 (0.52)
|
0.57 (0.37)
|
0.35 (0.23)
|
0.84 (0.56)
|
0.66 (0.38)
|
|
|
[-2.91]
|
[-0.12]
|
[-0.47]
|
[-2.27]
|
[4.74]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3443
|
|
MTM Loss (Total)
|
5.60 (5.14)
|
6.59 (6.26)
|
5.00 (5.07)
|
6.35 (6.57)
|
5.83 (5.83)
|
5.39 (5.23)
|
|
|
[1.27]
|
[2.11]
|
[-1.14]
|
[0.61]
|
[4.81]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3443
|
|
Adjusted Equity
|
4.20 (4.30)
|
2.82 (1.53)
|
6.24 (6.33)
|
4.09 (3.04)
|
2.73 (2.47)
|
5.04 (3.79)
|
|
|
[-2.42]
|
[-1.46]
|
[1.19]
|
[-0.40]
|
[-9.20]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3443
|
|
Adjusted Equity < 0
|
12.50 (0.00)
|
33.33 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
23.62 (0.00)
|
18.88 (0.00)
|
|
|
[-2.57]
|
[0.87]
|
[-28.30]
|
[0.86]
|
[2.59]
|
|
|
|
24
|
3
|
0
|
2
|
146
|
650
|
|
Adj. Tier1 Equity
|
5.25 (5.01)
|
4.12 (3.78)
|
5.85 (5.39)
|
3.59 (4.63)
|
4.42 (3.99)
|
6.71 (5.23)
|
|
|
[-5.16]
|
[-3.17]
|
[-1.09]
|
[-1.71]
|
[-10.67]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3443
|
|
Adj. Tier1 Equity < 0
|
4.69 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
4.69 (0.00)
|
2.96 (0.00)
|
|
|
[1.11]
|
[-10.25]
|
[-10.25]
|
[1.51]
|
[1.92]
|
|
|
|
9
|
0
|
0
|
2
|
29
|
102
|
|
Adj. Common equity tier1
|
5.24 (5.00)
|
4.12 (3.78)
|
5.84 (5.39)
|
3.59 (4.63)
|
4.45 (4.00)
|
6.63 (5.21)
|
|
|
[-4.96]
|
[-3.09]
|
[-1.01]
|
[-1.67]
|
[-10.26]
|
|
|
|
191
|
9
|
15
|
5
|
595
|
3411
|
|
Adj. Common equity tier1 < 0
|
4.71 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
4.03 (0.00)
|
3.02 (0.00)
|
|
|
[1.08]
|
[-10.30]
|
[-10.30]
|
[1.51]
|
[1.18]
|
|
|
|
9
|
0
|
0
|
2
|
24
|
103
|
|
Uninsured Leverage
|
24.65 (23.17)
|
30.11 (26.15)
|
30.56 (30.05)
|
23.81 (22.44)
|
27.61 (25.53)
|
22.79 (21.40)
|
|
|
[2.33]
|
[1.95]
|
[2.28]
|
[0.18]
|
[9.10]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3453
|
|
MTM Insolvent
|
12.50 (0.00)
|
33.33 (0.00)
|
0.00 (0.00)
|
40.00 (0.00)
|
23.62 (0.00)
|
18.88 (0.00)
|
|
|
[-2.57]
|
[0.87]
|
[-28.30]
|
[0.86]
|
[2.59]
|
|
|
|
24
|
3
|
0
|
2
|
146
|
650
|
|
Solvent and Liquid
|
19.27 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
0.00 (0.00)
|
10.03 (0.00)
|
24.76 (0.00)
|
|
|
[-1.86]
|
[-33.69]
|
[-0.44]
|
[-33.69]
|
[-10.41]
|
|
|
|
37
|
0
|
3
|
0
|
62
|
854
|
|
Solvent and Illiquid
|
33.33 (0.00)
|
22.22 (0.00)
|
40.00 (0.00)
|
40.00 (0.00)
|
28.64 (0.00)
|
25.79 (0.00)
|
|
|
[2.16]
|
[-0.24]
|
[1.08]
|
[0.58]
|
[1.45]
|
|
|
|
64
|
2
|
6
|
2
|
177
|
889
|
|
Insolvent and Liquid
|
23.44 (0.00)
|
22.22 (0.00)
|
6.67 (0.00)
|
40.00 (0.00)
|
24.11 (0.00)
|
27.14 (0.00)
|
|
|
[-1.17]
|
[-0.33]
|
[-3.05]
|
[0.52]
|
[-1.61]
|
|
|
|
45
|
2
|
1
|
2
|
149
|
936
|
|
Insolvent and Illiquid
|
23.96 (0.00)
|
55.56 (100.00)
|
33.33 (0.00)
|
20.00 (0.00)
|
37.22 (0.00)
|
22.11 (0.00)
|
|
|
[0.58]
|
[1.90]
|
[0.89]
|
[-0.11]
|
[7.30]
|
|
|
|
46
|
5
|
5
|
1
|
230
|
762
|
|
IDCR Insolvent (s=0.5)
|
3.65 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
4.85 (0.00)
|
4.13 (0.00)
|
|
|
[-0.35]
|
[-12.13]
|
[-12.13]
|
[0.79]
|
[0.78]
|
|
|
|
7
|
0
|
0
|
1
|
30
|
141
|
|
IDCR Insolvent (s=1.0)
|
27.60 (0.00)
|
0.00 (0.00)
|
6.67 (0.00)
|
40.00 (0.00)
|
28.48 (0.00)
|
28.66 (0.00)
|
|
|
[-0.32]
|
[-37.02]
|
[-3.28]
|
[0.46]
|
[-0.09]
|
|
|
|
53
|
0
|
1
|
2
|
176
|
978
|
|
Capital Insolvent (s=0.5)
|
3.12 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
3.07 (0.00)
|
1.98 (0.00)
|
|
|
[0.90]
|
[-8.33]
|
[-8.33]
|
[0.90]
|
[1.50]
|
|
|
|
6
|
0
|
0
|
1
|
19
|
68
|
|
Capital Insolvent (s=1.0)
|
7.81 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
20.00 (0.00)
|
11.33 (0.00)
|
6.97 (0.00)
|
|
|
[0.42]
|
[-16.06]
|
[-16.06]
|
[0.65]
|
[3.23]
|
|
|
|
15
|
0
|
0
|
1
|
70
|
240
|
|
Available Liquidity Ratio
|
5.35 (4.38)
|
3.95 (3.59)
|
5.66 (4.04)
|
3.24 (3.59)
|
5.76 (3.57)
|
10.19 (6.66)
|
|
|
[-15.40]
|
[-6.73]
|
[-3.94]
|
[-9.94]
|
[-14.39]
|
|
|
|
192
|
9
|
15
|
5
|
618
|
3453
|
|
Change Uninsured Deposits (Fwd Q)
|
-6.10 (-6.21)
|
-14.10 (-13.96)
|
-3.95 (-4.59)
|
-11.14 (-12.22)
|
-6.06 (-6.30)
|
1.56 (-3.89)
|
|
|
[-2.83]
|
[-4.72]
|
[-1.51]
|
[-3.57]
|
[-3.01]
|
|
|
|
192
|
9
|
15
|
5
|
616
|
3391
|
|
Change Insured Deposits (Fwd Q)
|
1.49 (0.78)
|
1.07 (0.75)
|
4.47 (3.66)
|
6.42 (4.81)
|
4.73 (2.05)
|
3.82 (1.43)
|
|
|
[-2.94]
|
[-1.49]
|
[0.33]
|
[0.80]
|
[1.03]
|
|
|
|
192
|
9
|
15
|
5
|
616
|
3397
|
|
Abnormal Insured Outflow (10%)
|
8.33 (0.00)
|
11.11 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
7.77 (0.00)
|
7.44 (0.00)
|
|
|
[0.43]
|
[0.33]
|
[-16.66]
|
[-16.66]
|
[0.28]
|
|
|
|
16
|
1
|
0
|
0
|
48
|
257
|
|
Abnormal Insured Outflow (5%)
|
2.08 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
2.59 (0.00)
|
2.72 (0.00)
|
|
|
[-0.60]
|
[-9.83]
|
[-9.83]
|
[-9.83]
|
[-0.19]
|
|
|
|
4
|
0
|
0
|
0
|
16
|
94
|
|
Abnormal Uninsured Outflow (10%)
|
30.21 (0.00)
|
44.44 (0.00)
|
40.00 (0.00)
|
60.00 (100.00)
|
29.45 (0.00)
|
19.37 (0.00)
|
|
|
[3.20]
|
[1.43]
|
[1.57]
|
[1.66]
|
[5.16]
|
|
|
|
58
|
4
|
6
|
3
|
182
|
669
|
|
Abnormal Uninsured Outflow (5%)
|
14.06 (0.00)
|
33.33 (0.00)
|
6.67 (0.00)
|
20.00 (0.00)
|
12.30 (0.00)
|
8.37 (0.00)
|
|
|
[2.22]
|
[1.50]
|
[-0.25]
|
[0.58]
|
[2.80]
|
|
|
|
27
|
3
|
1
|
1
|
76
|
289
|
# Export (silently)
invisible(export_table(
table7,
"table7_fhlb_borrowers_5pct",
caption = "Bank Characteristics by FHLB Borrower Type: Q1 2023 (5\\% Threshold)",
label = "tab:fhlb_borrowers_5pct",
note = "Bank characteristics from 2022Q4 Call Reports. FHLB borrowers identified as banks with abnormal FHLB advances at the 95th percentile in 2023Q1. Abnormal FHLB borrowing is measured using Z-scores calculated as (current quarter change $-$ mean) / std, where mean and standard deviation are computed from the prior 8 quarters (2021Q1--2022Q4). Abnormal FHLB (5\\%) indicates Z $>$ 1.65 (top 5 percentile). Fed Only = BTFP and/or DW but no abnormal FHLB increase. Sample excludes G-SIBs and failed banks."
))
LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State
University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table7_fhlb_borrowers_5pct.tex
HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State
University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table7_fhlb_borrowers_5pct.html
CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State
University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table7_fhlb_borrowers_5pct.csv
Table 8: FHLB Borrower
Characteristics (10% Threshold)
# ==============================================================================
# TABLE 8: FHLB Borrower Characteristics - 10% Threshold (Q1 2023)
# ==============================================================================
# Identify banks with abnormal FHLB borrowing at 10% threshold
fhlb_borrower_10pct <- baseline_q %>%
filter(!is.na(abnormal_fhlb_borrowing_10pct) & abnormal_fhlb_borrowing_10pct > 0) %>%
pull(idrssd)
# Prepare data with FHLB variables (10% threshold)
table8_data <- baseline_q %>%
mutate(
# Categorize by FHLB usage (10% threshold)
fhlb_user = idrssd %in% fhlb_borrower_10pct,
btfp_user = idrssd %in% btfp_q1,
dw_user = idrssd %in% dw_q1,
borrower_type = case_when(
fhlb_user & btfp_user & dw_user ~ "FHLB+BTFP+DW",
fhlb_user & btfp_user & !dw_user ~ "FHLB+BTFP",
fhlb_user & !btfp_user & dw_user ~ "FHLB+DW",
fhlb_user & !btfp_user & !dw_user ~ "FHLB Only",
!fhlb_user & (btfp_user | dw_user) ~ "Fed Only",
TRUE ~ "Non-Borrower"
)
)
# Count by category
table8_data %>%
count(borrower_type) %>%
arrange(desc(n)) %>%
pander(caption = "FHLB Borrower Breakdown (10% Threshold)")
FHLB Borrower Breakdown (10% Threshold)
| Non-Borrower |
3385 |
| Fed Only |
605 |
| FHLB Only |
260 |
| FHLB+DW |
21 |
| FHLB+BTFP |
12 |
| FHLB+BTFP+DW |
9 |
table8 <- create_fhlb_summary_table(table8_data, "borrower_type",
group_levels = c("FHLB Only", "FHLB+BTFP", "FHLB+DW",
"FHLB+BTFP+DW", "Fed Only", "Non-Borrower"))
# Display
table8 %>%
select(-Row_Type) %>%
kable(caption = "Table 8: Bank Characteristics by FHLB Borrower Type - 10% Threshold (Q1 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
scroll_box(width = "100%")
Table 8: Bank Characteristics by FHLB Borrower Type - 10% Threshold (Q1
2023)
|
Variable
|
FHLB Only
|
FHLB+BTFP
|
FHLB+DW
|
FHLB+BTFP+DW
|
Fed Only
|
Non-Borrower
|
|
N
|
260
|
12
|
21
|
9
|
605
|
3385
|
|
Book Equity Ratio
|
9.82 (9.28)
|
8.89 (8.36)
|
11.00 (10.55)
|
9.36 (9.47)
|
8.55 (8.35)
|
10.55 (8.90)
|
|
|
[-2.78]
|
[-1.80]
|
[0.68]
|
[-1.75]
|
[-9.22]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3385
|
|
MTM Loss (HTM)
|
0.14 (0.00)
|
0.15 (0.00)
|
0.12 (0.00)
|
0.08 (0.00)
|
0.23 (0.00)
|
0.20 (0.00)
|
|
|
[-2.33]
|
[-0.81]
|
[-1.37]
|
[-2.33]
|
[0.90]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3375
|
|
MTM Loss (BTFP Elg.)
|
0.53 (0.28)
|
0.77 (0.87)
|
0.46 (0.23)
|
0.54 (0.34)
|
0.85 (0.56)
|
0.66 (0.39)
|
|
|
[-3.19]
|
[0.75]
|
[-1.39]
|
[-0.80]
|
[4.74]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3375
|
|
MTM Loss (Total)
|
5.69 (5.26)
|
6.37 (6.54)
|
5.13 (5.07)
|
6.10 (5.66)
|
5.83 (5.83)
|
5.38 (5.23)
|
|
|
[2.13]
|
[1.96]
|
[-0.65]
|
[0.79]
|
[4.92]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3375
|
|
Adjusted Equity
|
4.13 (4.12)
|
2.52 (1.53)
|
5.87 (6.33)
|
3.26 (3.04)
|
2.72 (2.44)
|
5.07 (3.79)
|
|
|
[-2.93]
|
[-1.96]
|
[0.94]
|
[-1.33]
|
[-9.19]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3375
|
|
Adjusted Equity < 0
|
14.23 (0.00)
|
33.33 (0.00)
|
4.76 (0.00)
|
33.33 (0.00)
|
23.64 (0.00)
|
18.87 (0.00)
|
|
|
[-2.04]
|
[1.02]
|
[-2.93]
|
[0.87]
|
[2.57]
|
|
|
|
37
|
4
|
1
|
3
|
143
|
637
|
|
Adj. Tier1 Equity
|
5.32 (5.01)
|
4.13 (3.49)
|
5.61 (5.57)
|
3.31 (4.04)
|
4.43 (3.99)
|
6.73 (5.24)
|
|
|
[-5.29]
|
[-3.69]
|
[-1.70]
|
[-3.27]
|
[-10.58]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3375
|
|
Adj. Tier1 Equity < 0
|
5.00 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
22.22 (0.00)
|
4.79 (0.00)
|
2.90 (0.00)
|
|
|
[1.51]
|
[-10.04]
|
[-10.04]
|
[1.31]
|
[2.06]
|
|
|
|
13
|
0
|
0
|
2
|
29
|
98
|
|
Adj. Common equity tier1
|
5.31 (5.01)
|
3.83 (3.21)
|
5.61 (5.57)
|
3.31 (4.04)
|
4.46 (4.00)
|
6.66 (5.21)
|
|
|
[-5.06]
|
[-4.06]
|
[-1.59]
|
[-3.20]
|
[-10.15]
|
|
|
|
258
|
11
|
21
|
9
|
583
|
3344
|
|
Adj. Common equity tier1 < 0
|
5.04 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
22.22 (0.00)
|
4.12 (0.00)
|
2.96 (0.00)
|
|
|
[1.49]
|
[-10.10]
|
[-10.10]
|
[1.31]
|
[1.32]
|
|
|
|
13
|
0
|
0
|
2
|
24
|
99
|
|
Uninsured Leverage
|
23.71 (22.82)
|
31.75 (28.72)
|
30.18 (30.05)
|
28.58 (31.00)
|
27.51 (25.38)
|
22.82 (21.42)
|
|
|
[1.26]
|
[2.73]
|
[2.62]
|
[1.26]
|
[8.75]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3385
|
|
MTM Insolvent
|
14.23 (0.00)
|
33.33 (0.00)
|
4.76 (0.00)
|
33.33 (0.00)
|
23.64 (0.00)
|
18.87 (0.00)
|
|
|
[-2.04]
|
[1.02]
|
[-2.93]
|
[0.87]
|
[2.57]
|
|
|
|
37
|
4
|
1
|
3
|
143
|
637
|
|
Solvent and Liquid
|
19.62 (0.00)
|
0.00 (0.00)
|
14.29 (0.00)
|
0.00 (0.00)
|
10.25 (0.00)
|
24.84 (0.00)
|
|
|
[-2.03]
|
[-33.43]
|
[-1.34]
|
[-33.43]
|
[-10.13]
|
|
|
|
51
|
0
|
3
|
0
|
62
|
840
|
|
Solvent and Illiquid
|
30.38 (0.00)
|
25.00 (0.00)
|
42.86 (0.00)
|
44.44 (0.00)
|
28.26 (0.00)
|
25.87 (0.00)
|
|
|
[1.53]
|
[-0.07]
|
[1.53]
|
[1.06]
|
[1.21]
|
|
|
|
79
|
3
|
9
|
4
|
171
|
874
|
|
Insolvent and Liquid
|
26.92 (0.00)
|
16.67 (0.00)
|
14.29 (0.00)
|
33.33 (0.00)
|
24.13 (0.00)
|
26.94 (0.00)
|
|
|
[-0.01]
|
[-0.91]
|
[-1.61]
|
[0.38]
|
[-1.48]
|
|
|
|
70
|
2
|
3
|
3
|
146
|
911
|
|
Insolvent and Illiquid
|
23.08 (0.00)
|
58.33 (100.00)
|
28.57 (0.00)
|
22.22 (0.00)
|
37.36 (0.00)
|
22.14 (0.00)
|
|
|
[0.35]
|
[2.43]
|
[0.64]
|
[0.01]
|
[7.27]
|
|
|
|
60
|
7
|
6
|
2
|
226
|
748
|
|
IDCR Insolvent (s=0.5)
|
4.62 (0.00)
|
0.00 (0.00)
|
4.76 (0.00)
|
11.11 (0.00)
|
4.79 (0.00)
|
4.07 (0.00)
|
|
|
[0.41]
|
[-11.90]
|
[0.15]
|
[0.63]
|
[0.78]
|
|
|
|
12
|
0
|
1
|
1
|
29
|
136
|
|
IDCR Insolvent (s=1.0)
|
27.31 (0.00)
|
8.33 (0.00)
|
14.29 (0.00)
|
33.33 (0.00)
|
28.43 (0.00)
|
28.71 (0.00)
|
|
|
[-0.49]
|
[-2.43]
|
[-1.83]
|
[0.28]
|
[-0.14]
|
|
|
|
71
|
1
|
3
|
3
|
172
|
960
|
|
Capital Insolvent (s=0.5)
|
3.08 (0.00)
|
0.00 (0.00)
|
4.76 (0.00)
|
11.11 (0.00)
|
2.98 (0.00)
|
1.96 (0.00)
|
|
|
[1.02]
|
[-8.20]
|
[0.59]
|
[0.82]
|
[1.39]
|
|
|
|
8
|
0
|
1
|
1
|
18
|
66
|
|
Capital Insolvent (s=1.0)
|
7.31 (0.00)
|
0.00 (0.00)
|
4.76 (0.00)
|
11.11 (0.00)
|
11.40 (0.00)
|
6.99 (0.00)
|
|
|
[0.19]
|
[-15.93]
|
[-0.47]
|
[0.37]
|
[3.23]
|
|
|
|
19
|
0
|
1
|
1
|
69
|
236
|
|
Available Liquidity Ratio
|
5.43 (4.31)
|
4.30 (3.76)
|
4.95 (3.49)
|
2.87 (2.22)
|
5.81 (3.57)
|
10.28 (6.70)
|
|
|
[-16.41]
|
[-6.25]
|
[-6.11]
|
[-12.18]
|
[-14.28]
|
|
|
|
260
|
12
|
21
|
9
|
605
|
3385
|
|
Change Uninsured Deposits (Fwd Q)
|
-6.08 (-7.06)
|
-10.34 (-12.20)
|
-3.51 (-4.59)
|
-17.22 (-12.22)
|
-6.01 (-6.29)
|
1.71 (-3.71)
|
|
|
[-2.85]
|
[-2.43]
|
[-1.54]
|
[-2.78]
|
[-3.00]
|
|
|
|
260
|
12
|
21
|
9
|
603
|
3323
|
|
Change Insured Deposits (Fwd Q)
|
1.92 (0.96)
|
6.32 (0.94)
|
4.53 (3.66)
|
9.39 (7.84)
|
4.59 (2.02)
|
3.84 (1.42)
|
|
|
[-2.27]
|
[0.45]
|
[0.44]
|
[2.14]
|
[0.84]
|
|
|
|
260
|
12
|
21
|
9
|
603
|
3329
|
|
Abnormal Insured Outflow (10%)
|
9.62 (0.00)
|
8.33 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
7.93 (0.00)
|
7.33 (0.00)
|
|
|
[1.21]
|
[0.12]
|
[-16.36]
|
[-16.36]
|
[0.51]
|
|
|
|
25
|
1
|
0
|
0
|
48
|
248
|
|
Abnormal Insured Outflow (5%)
|
2.69 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
0.00 (0.00)
|
2.64 (0.00)
|
2.69 (0.00)
|
|
|
[0.00]
|
[-9.67]
|
[-9.67]
|
[-9.67]
|
[-0.06]
|
|
|
|
7
|
0
|
0
|
0
|
16
|
91
|
|
Abnormal Uninsured Outflow (10%)
|
29.23 (0.00)
|
41.67 (0.00)
|
38.10 (0.00)
|
55.56 (100.00)
|
29.26 (0.00)
|
19.23 (0.00)
|
|
|
[3.44]
|
[1.51]
|
[1.73]
|
[2.07]
|
[5.09]
|
|
|
|
76
|
5
|
8
|
5
|
177
|
651
|
|
Abnormal Uninsured Outflow (5%)
|
12.69 (0.00)
|
33.33 (0.00)
|
9.52 (0.00)
|
22.22 (0.00)
|
12.07 (0.00)
|
8.36 (0.00)
|
|
|
[2.04]
|
[1.76]
|
[0.18]
|
[0.94]
|
[2.63]
|
|
|
|
33
|
4
|
2
|
2
|
73
|
283
|
# Export (silently)
invisible(export_table(
table8,
"table8_fhlb_borrowers_10pct",
caption = "Bank Characteristics by FHLB Borrower Type: Q1 2023 (10\\% Threshold)",
label = "tab:fhlb_borrowers_10pct",
note = "Bank characteristics from 2022Q4 Call Reports. FHLB borrowers identified as banks with abnormal FHLB advances at the 90th percentile in 2023Q1. Abnormal FHLB borrowing is measured using Z-scores calculated as (current quarter change $-$ mean) / std, where mean and standard deviation are computed from the prior 8 quarters (2021Q1--2022Q4). Abnormal FHLB (10\\%) indicates Z $>$ 1.28 (top 10 percentile). Fed Only = BTFP and/or DW but no abnormal FHLB increase. Sample excludes G-SIBs and failed banks."
))
LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State
University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table8_fhlb_borrowers_10pct.tex
HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State
University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table8_fhlb_borrowers_10pct.html
CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State
University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table8_fhlb_borrowers_10pct.csv
Summary
Statistics
# ==============================================================================
# SUMMARY OF BORROWER COUNTS
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("SUMMARY OF BORROWER COUNTS\n")
## SUMMARY OF BORROWER COUNTS
cat(strrep("=", 60), "\n")
## ============================================================
summary_counts <- tribble(
~Table, ~Period, ~Baseline, ~Description, ~N_Borrowers, ~N_Total,
"Table 1", "March 10, 2023", "2022Q4", "DW only",
sum(baseline_q$idrssd %in% dw_mar10), nrow(baseline_q),
"Table 2", "March 10-13, 2023", "2022Q4", "DW only",
sum(baseline_q$idrssd %in% dw_mar10_13), nrow(baseline_q),
"Table 3", "March 9-14, 2023", "2022Q4", "DW only",
sum(baseline_q$idrssd %in% dw_mar9_14), nrow(baseline_q),
"Table 4", "Acute (Mar 13 - May 1)", "2022Q4", "BTFP + DW",
sum(baseline_q$idrssd %in% union(btfp_acute, dw_acute)), nrow(baseline_q),
"Table 5A", "Q1 2023 (Jan-Mar)", "2022Q4", "BTFP + DW + FHLB (10%)",
sum(baseline_q$idrssd %in% union(union(btfp_q1, dw_q1), fhlb_borrowers_10pct)), nrow(baseline_q),
"Table 5B", "Q1 2023 (Jan-Mar)", "2022Q4", "BTFP + DW + FHLB (5%)",
sum(baseline_q$idrssd %in% union(union(btfp_q1, dw_q1), fhlb_borrowers_5pct)), nrow(baseline_q),
"Table 6", "Arbitrage (Nov 1 - Jan 24)", "2022Q4", "BTFP + DW",
sum(baseline_q$idrssd %in% union(btfp_arb, dw_arb)), nrow(baseline_q),
"Table 6b", "Arbitrage (Nov 1 - Jan 24)", "2023Q4", "BTFP + DW",
sum(baseline_q4_2023$idrssd %in% union(btfp_arb, dw_arb)), nrow(baseline_q4_2023),
"Table 7", "Q1 2023", "2022Q4", "FHLB focus (5%)",
sum(baseline_q$idrssd %in% fhlb_borrower_5pct), nrow(baseline_q),
"Table 8", "Q1 2023", "2022Q4", "FHLB focus (10%)",
sum(baseline_q$idrssd %in% fhlb_borrower_10pct), nrow(baseline_q)
)
summary_counts %>%
kable(caption = "Summary of Borrower Counts Across Tables") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Summary of Borrower Counts Across Tables
|
Table
|
Period
|
Baseline
|
Description
|
N_Borrowers
|
N_Total
|
|
Table 1
|
March 10, 2023
|
2022Q4
|
DW only
|
47
|
4292
|
|
Table 2
|
March 10-13, 2023
|
2022Q4
|
DW only
|
90
|
4292
|
|
Table 3
|
March 9-14, 2023
|
2022Q4
|
DW only
|
124
|
4292
|
|
Table 4
|
Acute (Mar 13 - May 1)
|
2022Q4
|
BTFP + DW
|
761
|
4292
|
|
Table 5A
|
Q1 2023 (Jan-Mar)
|
2022Q4
|
BTFP + DW + FHLB (10%)
|
907
|
4292
|
|
Table 5B
|
Q1 2023 (Jan-Mar)
|
2022Q4
|
BTFP + DW + FHLB (5%)
|
839
|
4292
|
|
Table 6
|
Arbitrage (Nov 1 - Jan 24)
|
2022Q4
|
BTFP + DW
|
1068
|
4292
|
|
Table 6b
|
Arbitrage (Nov 1 - Jan 24)
|
2023Q4
|
BTFP + DW
|
1075
|
4197
|
|
Table 7
|
Q1 2023
|
2022Q4
|
FHLB focus (5%)
|
221
|
4292
|
|
Table 8
|
Q1 2023
|
2022Q4
|
FHLB focus (10%)
|
302
|
4292
|
# Save summary
write_csv(summary_counts, file.path(TABLE_PATH, "summary_borrower_counts.csv"))
cat("\n=== ALL TABLES EXPORTED ===\n")
##
## === ALL TABLES EXPORTED ===
cat("Output directory:", TABLE_PATH, "\n")
## Output directory: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables
cat("Files created:\n")
## Files created:
list.files(TABLE_PATH, pattern = "\\.(tex|html|csv)$") %>%
paste(" -", .) %>%
cat(sep = "\n")
## - borrower_size_insolvency_2024q1.tex
## - borrower_size_insolvency_acute.tex
## - insolvency_size_2024q1.tex
## - insolvency_size_acute.tex
## - summary_borrower_counts.csv
## - table_beta1_dw_mar10.csv
## - table_beta1_dw_mar10.html
## - table_beta1_dw_mar10.tex
## - table_beta2_dw_mar10_13.csv
## - table_beta2_dw_mar10_13.html
## - table_beta2_dw_mar10_13.tex
## - table_beta3_acute.csv
## - table_beta3_acute.html
## - table_beta3_acute.tex
## - table_beta4_q1_2023.csv
## - table_beta4_q1_2023.html
## - table_beta4_q1_2023.tex
## - table_beta5_arbitrage.csv
## - table_beta5_arbitrage.html
## - table_beta5_arbitrage.tex
## - table1_dw_mar10.csv
## - table1_dw_mar10.html
## - table1_dw_mar10.tex
## - table2_dw_mar10_13.csv
## - table2_dw_mar10_13.html
## - table2_dw_mar10_13.tex
## - table3_dw_mar9_14.csv
## - table3_dw_mar9_14.html
## - table3_dw_mar9_14.tex
## - table4_acute_period.csv
## - table4_acute_period.html
## - table4_acute_period.tex
## - table5a_q1_2023_10pct.csv
## - table5a_q1_2023_10pct.html
## - table5a_q1_2023_10pct.tex
## - table5b_q1_2023_5pct.csv
## - table5b_q1_2023_5pct.html
## - table5b_q1_2023_5pct.tex
## - table6_arbitrage_period.csv
## - table6_arbitrage_period.html
## - table6_arbitrage_period.tex
## - table6b_arbitrage_period_2023q4.csv
## - table6b_arbitrage_period_2023q4.html
## - table6b_arbitrage_period_2023q4.tex
## - table7_fhlb_borrowers_5pct.csv
## - table7_fhlb_borrowers_5pct.html
## - table7_fhlb_borrowers_5pct.tex
## - table8_fhlb_borrowers_10pct.csv
## - table8_fhlb_borrowers_10pct.html
## - table8_fhlb_borrowers_10pct.tex
## - variable_definitions.csv
## - variable_definitions.tex
# ==============================================================================
# DEPOSIT BETA ANALYSIS
# ==============================================================================
# Load deposit beta data
deposit_beta <- read_csv(file.path(DATA_PROC, "deposit_beta_yearly.csv"), show_col_types = FALSE) %>%
mutate(rssd_id = as.character(rssd_id))
cat("Deposit beta observations:", nrow(deposit_beta), "\n")
## Deposit beta observations: 4781
# Merge with baseline data
baseline_q <- baseline_q %>%
left_join(deposit_beta, by = c("idrssd" = "rssd_id"))
cat("Banks with deposit beta data:", sum(!is.na(baseline_q$beta_2022)), "\n")
## Banks with deposit beta data: 4221
# ==============================================================================
# DEPOSIT BETA SUMMARY TABLE FUNCTION
# ==============================================================================
create_deposit_beta_table <- function(data, group_var, group_levels = NULL, reference_group = "Non-Borrower") {
# Define variable specifications for deposit beta
var_specs <- tribble(
~var_name, ~var_label, ~is_dummy,
# 2022 Betas (Pre-Crisis)
"beta_2022", "Deposit Beta (2022)", FALSE,
"rsquared_2022", "R-squared (2022)", FALSE,
# 2023 Betas (Crisis Year)
"beta_2023", "Deposit Beta (2023)", FALSE,
"rsquared_2023", "R-squared (2023)", FALSE,
# 2024 Betas (Post-Crisis)
"beta_2024", "Deposit Beta (2024)", FALSE,
"rsquared_2024", "R-squared (2024)", FALSE,
# Beta Changes
"beta_change_2022_2023", "Δ Beta (2022→2023)", FALSE,
"beta_change_2023_2024", "Δ Beta (2023→2024)", FALSE,
"beta_change_2022_2024", "Δ Beta (2022→2024)", FALSE
)
# Get unique groups
if (is.null(group_levels)) {
group_levels <- unique(data[[group_var]])
}
# Calculate N for each group (with beta data)
n_by_group <- data %>%
filter(!is.na(beta_2022)) %>%
group_by(.data[[group_var]]) %>%
summarise(N = n(), .groups = "drop")
# Get reference group data for T-stat calculation
ref_data <- data %>% filter(.data[[group_var]] == reference_group)
# Initialize output list
output_rows <- list()
# Add N row first
n_row <- c(Variable = "N (with beta data)", Row_Type = "count")
for (g in group_levels) {
n_val <- n_by_group %>% filter(.data[[group_var]] == g) %>% pull(N)
n_row[g] <- as.character(if(length(n_val) == 0) 0 else n_val)
}
output_rows[[1]] <- n_row
row_idx <- 2
# Process each variable
for (i in seq_len(nrow(var_specs))) {
v <- var_specs$var_name[i]
label <- var_specs$var_label[i]
is_dummy <- var_specs$is_dummy[i]
# Stats row: Mean (Median)
stats_row <- c(Variable = label, Row_Type = "stats")
# T-stat row
tstat_row <- c(Variable = "", Row_Type = "tstat")
# N row
obs_row <- c(Variable = "", Row_Type = "n")
# Get reference group values
ref_vals <- if (v %in% names(ref_data)) ref_data[[v]] else numeric(0)
ref_vals <- ref_vals[!is.na(ref_vals)]
for (g in group_levels) {
group_data <- data %>% filter(.data[[group_var]] == g)
if (!v %in% names(group_data)) {
stats_row[g] <- "—"
tstat_row[g] <- ""
obs_row[g] <- "0"
next
}
vals <- group_data[[v]]
vals <- vals[!is.na(vals)]
if (length(vals) == 0) {
stats_row[g] <- "—"
tstat_row[g] <- ""
obs_row[g] <- "0"
} else {
mean_val <- mean(vals, na.rm = TRUE)
median_val <- median(vals, na.rm = TRUE)
n_val <- length(vals)
stats_row[g] <- sprintf("%.3f (%.3f)", mean_val, median_val)
if (g == reference_group) {
tstat_row[g] <- ""
} else {
tstat_result <- calc_tstat_with_stars(vals, ref_vals)
if (!is.na(tstat_result$tstat) && is.finite(tstat_result$tstat)) {
tstat_row[g] <- sprintf("[%.2f]%s", tstat_result$tstat, tstat_result$stars)
} else {
tstat_row[g] <- ""
}
}
obs_row[g] <- as.character(n_val)
}
}
output_rows[[row_idx]] <- stats_row
output_rows[[row_idx + 1]] <- tstat_row
output_rows[[row_idx + 2]] <- obs_row
row_idx <- row_idx + 3
}
result_df <- bind_rows(lapply(output_rows, function(x) as_tibble_row(x)))
return(result_df)
}
# ==============================================================================
# CREATE BETA CHANGE VARIABLES
# ==============================================================================
baseline_q <- baseline_q %>%
mutate(
beta_change_2022_2023 = beta_2023 - beta_2022,
beta_change_2023_2024 = beta_2024 - beta_2023,
beta_change_2022_2024 = beta_2024 - beta_2022
)
# ==============================================================================
# TABLE B1: Deposit Beta - March 10, 2023 DW Borrowers
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE B1: Deposit Beta - March 10, 2023 DW Borrowers\n")
## TABLE B1: Deposit Beta - March 10, 2023 DW Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
table_beta1_data <- baseline_q %>%
mutate(
borrower_type = if_else(idrssd %in% dw_mar10, "DW Borrower", "Non-Borrower")
)
table_beta1 <- create_deposit_beta_table(table_beta1_data, "borrower_type",
group_levels = c("DW Borrower", "Non-Borrower"))
table_beta1 %>%
select(-Row_Type) %>%
kable(caption = "Table B1: Deposit Beta - DW Borrowers vs Non-Borrowers (March 10, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table B1: Deposit Beta - DW Borrowers vs Non-Borrowers (March 10, 2023)
|
Variable
|
DW Borrower
|
Non-Borrower
|
|
N (with beta data)
|
47
|
4174
|
|
Deposit Beta (2022)
|
0.314 (0.246)
|
0.213 (0.170)
|
|
|
[2.38]**
|
|
|
|
47
|
4174
|
|
R-squared (2022)
|
0.676 (0.746)
|
0.609 (0.619)
|
|
|
[1.75]*
|
|
|
|
47
|
4174
|
|
Deposit Beta (2023)
|
0.251 (0.232)
|
0.132 (0.103)
|
|
|
[2.60]**
|
|
|
|
47
|
4109
|
|
R-squared (2023)
|
0.462 (0.462)
|
0.430 (0.403)
|
|
|
[0.64]
|
|
|
|
47
|
4109
|
|
Deposit Beta (2024)
|
0.336 (0.315)
|
0.277 (0.265)
|
|
|
[1.34]
|
|
|
|
46
|
4025
|
|
R-squared (2024)
|
0.534 (0.651)
|
0.542 (0.592)
|
|
|
[-0.16]
|
|
|
|
46
|
4025
|
|
Δ Beta (2022→2023)
|
-0.063 (-0.056)
|
-0.081 (-0.077)
|
|
|
[0.45]
|
|
|
|
47
|
4085
|
|
Δ Beta (2023→2024)
|
0.093 (0.117)
|
0.147 (0.153)
|
|
|
[-0.91]
|
|
|
|
46
|
4010
|
|
Δ Beta (2022→2024)
|
0.022 (0.025)
|
0.066 (0.072)
|
|
|
[-0.81]
|
|
|
|
46
|
3994
|
export_table(
table_beta1,
"table_beta1_dw_mar10",
caption = "Deposit Beta: DW Borrowers vs Non-Borrowers (March 10, 2023)",
label = "tab:beta_dw_mar10",
note = "Deposit beta measures interest rate sensitivity of deposits. Higher beta indicates more rate-sensitive deposits. Beta estimated from quarterly deposit growth regressed on Fed Funds rate changes."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta1_dw_mar10.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta1_dw_mar10.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta1_dw_mar10.csv
# ==============================================================================
# TABLE B2: Deposit Beta - March 10-13, 2023 DW Borrowers
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE B2: Deposit Beta - March 10-13, 2023 DW Borrowers\n")
## TABLE B2: Deposit Beta - March 10-13, 2023 DW Borrowers
cat(strrep("=", 60), "\n")
## ============================================================
table_beta2_data <- baseline_q %>%
mutate(
borrower_type = if_else(idrssd %in% dw_mar10_13, "DW Borrower", "Non-Borrower")
)
table_beta2 <- create_deposit_beta_table(table_beta2_data, "borrower_type",
group_levels = c("DW Borrower", "Non-Borrower"))
table_beta2 %>%
select(-Row_Type) %>%
kable(caption = "Table B2: Deposit Beta - DW Borrowers vs Non-Borrowers (March 10-13, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table B2: Deposit Beta - DW Borrowers vs Non-Borrowers (March 10-13,
2023)
|
Variable
|
DW Borrower
|
Non-Borrower
|
|
N (with beta data)
|
90
|
4131
|
|
Deposit Beta (2022)
|
0.309 (0.271)
|
0.212 (0.169)
|
|
|
[3.85]***
|
|
|
|
90
|
4131
|
|
R-squared (2022)
|
0.686 (0.720)
|
0.608 (0.617)
|
|
|
[3.10]***
|
|
|
|
90
|
4131
|
|
Deposit Beta (2023)
|
0.267 (0.218)
|
0.131 (0.102)
|
|
|
[4.34]***
|
|
|
|
90
|
4066
|
|
R-squared (2023)
|
0.457 (0.460)
|
0.429 (0.402)
|
|
|
[0.75]
|
|
|
|
90
|
4066
|
|
Deposit Beta (2024)
|
0.356 (0.348)
|
0.276 (0.264)
|
|
|
[2.38]**
|
|
|
|
87
|
3984
|
|
R-squared (2024)
|
0.560 (0.686)
|
0.542 (0.591)
|
|
|
[0.49]
|
|
|
|
87
|
3984
|
|
Δ Beta (2022→2023)
|
-0.043 (-0.059)
|
-0.081 (-0.077)
|
|
|
[1.47]
|
|
|
|
90
|
4042
|
|
Δ Beta (2023→2024)
|
0.093 (0.109)
|
0.148 (0.153)
|
|
|
[-1.37]
|
|
|
|
87
|
3969
|
|
Δ Beta (2022→2024)
|
0.045 (0.044)
|
0.066 (0.072)
|
|
|
[-0.54]
|
|
|
|
87
|
3953
|
export_table(
table_beta2,
"table_beta2_dw_mar10_13",
caption = "Deposit Beta: DW Borrowers vs Non-Borrowers (March 10--13, 2023)",
label = "tab:beta_dw_mar10_13",
note = "Deposit beta measures interest rate sensitivity of deposits. Higher beta indicates more rate-sensitive deposits."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta2_dw_mar10_13.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta2_dw_mar10_13.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta2_dw_mar10_13.csv
# ==============================================================================
# TABLE B3: Deposit Beta - Acute Period by Facility Choice
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE B3: Deposit Beta - Acute Period by Facility Choice\n")
## TABLE B3: Deposit Beta - Acute Period by Facility Choice
cat(strrep("=", 60), "\n")
## ============================================================
table_beta3_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_acute,
dw_user = idrssd %in% dw_acute,
borrower_type = case_when(
btfp_user & dw_user ~ "Both",
btfp_user & !dw_user ~ "BTFP Only",
!btfp_user & dw_user ~ "DW Only",
TRUE ~ "Non-Borrower"
)
)
table_beta3 <- create_deposit_beta_table(table_beta3_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "Both", "Non-Borrower"))
table_beta3 %>%
select(-Row_Type) %>%
kable(caption = "Table B3: Deposit Beta by Facility Choice (Acute Period: March 13 - May 1, 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table B3: Deposit Beta by Facility Choice (Acute Period: March 13 - May
1, 2023)
|
Variable
|
BTFP Only
|
DW Only
|
Both
|
Non-Borrower
|
|
N (with beta data)
|
365
|
298
|
92
|
3466
|
|
Deposit Beta (2022)
|
0.241 (0.212)
|
0.243 (0.212)
|
0.313 (0.269)
|
0.206 (0.163)
|
|
|
[3.51]***
|
[3.16]***
|
[4.27]***
|
|
|
|
365
|
298
|
92
|
3466
|
|
R-squared (2022)
|
0.612 (0.617)
|
0.647 (0.642)
|
0.691 (0.719)
|
0.604 (0.615)
|
|
|
[0.65]
|
[3.00]***
|
[3.75]***
|
|
|
|
365
|
298
|
92
|
3466
|
|
Deposit Beta (2023)
|
0.144 (0.130)
|
0.172 (0.142)
|
0.220 (0.172)
|
0.127 (0.095)
|
|
|
[1.05]
|
[2.49]**
|
[2.98]***
|
|
|
|
366
|
294
|
93
|
3403
|
|
R-squared (2023)
|
0.417 (0.387)
|
0.421 (0.373)
|
0.446 (0.452)
|
0.432 (0.406)
|
|
|
[-0.89]
|
[-0.55]
|
[0.41]
|
|
|
|
366
|
294
|
93
|
3403
|
|
Deposit Beta (2024)
|
0.284 (0.280)
|
0.311 (0.302)
|
0.334 (0.293)
|
0.272 (0.259)
|
|
|
[0.68]
|
[1.77]*
|
[1.82]*
|
|
|
|
361
|
284
|
92
|
3334
|
|
R-squared (2024)
|
0.553 (0.580)
|
0.552 (0.665)
|
0.609 (0.700)
|
0.539 (0.588)
|
|
|
[0.81]
|
[0.63]
|
[2.00]**
|
|
|
|
361
|
284
|
92
|
3334
|
|
Δ Beta (2022→2023)
|
-0.093 (-0.086)
|
-0.073 (-0.071)
|
-0.093 (-0.104)
|
-0.079 (-0.075)
|
|
|
[-0.92]
|
[0.38]
|
[-0.44]
|
|
|
|
364
|
294
|
92
|
3382
|
|
Δ Beta (2023→2024)
|
0.143 (0.152)
|
0.148 (0.161)
|
0.123 (0.159)
|
0.147 (0.152)
|
|
|
[-0.18]
|
[0.03]
|
[-0.65]
|
|
|
|
360
|
283
|
91
|
3322
|
|
Δ Beta (2022→2024)
|
0.046 (0.061)
|
0.073 (0.073)
|
0.028 (0.025)
|
0.068 (0.074)
|
|
|
[-1.16]
|
[0.26]
|
[-1.20]
|
|
|
|
358
|
283
|
90
|
3309
|
export_table(
table_beta3,
"table_beta3_acute",
caption = "Deposit Beta by Facility Choice: Acute Crisis Period",
label = "tab:beta_acute",
note = "Deposit beta measures interest rate sensitivity of deposits. Acute crisis period: March 13 -- May 1, 2023. Banks classified by facility usage during this period."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta3_acute.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta3_acute.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta3_acute.csv
# ==============================================================================
# TABLE B4: Deposit Beta - Q1 2023 All Facilities
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE B4: Deposit Beta - Q1 2023 All Facilities\n")
## TABLE B4: Deposit Beta - Q1 2023 All Facilities
cat(strrep("=", 60), "\n")
## ============================================================
table_beta4_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_q1,
dw_user = idrssd %in% dw_q1,
fhlb_user = idrssd %in% fhlb_borrowers_10pct,
borrower_type = case_when(
btfp_user & dw_user & fhlb_user ~ "All Three",
btfp_user & dw_user & !fhlb_user ~ "BTFP+DW",
btfp_user & !dw_user & fhlb_user ~ "BTFP+FHLB",
!btfp_user & dw_user & fhlb_user ~ "DW+FHLB",
btfp_user & !dw_user & !fhlb_user ~ "BTFP Only",
!btfp_user & dw_user & !fhlb_user ~ "DW Only",
!btfp_user & !dw_user & fhlb_user ~ "FHLB Only",
TRUE ~ "Non-Borrower"
)
)
table_beta4 <- create_deposit_beta_table(table_beta4_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "FHLB Only",
"BTFP+DW", "BTFP+FHLB", "DW+FHLB",
"All Three", "Non-Borrower"))
table_beta4 %>%
select(-Row_Type) %>%
kable(caption = "Table B4: Deposit Beta by Facility Choice (Q1 2023)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
scroll_box(width = "100%")
Table B4: Deposit Beta by Facility Choice (Q1 2023)
|
Variable
|
BTFP Only
|
DW Only
|
FHLB Only
|
BTFP+DW
|
BTFP+FHLB
|
DW+FHLB
|
All Three
|
Non-Borrower
|
|
N (with beta data)
|
198
|
344
|
258
|
59
|
12
|
21
|
9
|
3320
|
|
Deposit Beta (2022)
|
0.267 (0.237)
|
0.248 (0.219)
|
0.265 (0.225)
|
0.291 (0.272)
|
0.277 (0.273)
|
0.322 (0.269)
|
0.422 (0.334)
|
0.201 (0.158)
|
|
|
[4.76]***
|
[4.16]***
|
[4.94]***
|
[3.48]***
|
[1.74]
|
[3.23]***
|
[2.02]*
|
|
|
|
198
|
344
|
258
|
59
|
12
|
21
|
9
|
3320
|
|
R-squared (2022)
|
0.624 (0.624)
|
0.649 (0.669)
|
0.644 (0.653)
|
0.678 (0.672)
|
0.696 (0.679)
|
0.717 (0.742)
|
0.808 (0.794)
|
0.599 (0.606)
|
|
|
[1.46]
|
[3.65]***
|
[2.81]***
|
[2.61]**
|
[1.59]
|
[2.50]**
|
[3.92]***
|
|
|
|
198
|
344
|
258
|
59
|
12
|
21
|
9
|
3320
|
|
Deposit Beta (2023)
|
0.184 (0.182)
|
0.190 (0.182)
|
0.134 (0.118)
|
0.197 (0.167)
|
0.073 (0.057)
|
0.304 (0.220)
|
0.365 (0.318)
|
0.122 (0.089)
|
|
|
[2.57]**
|
[4.30]***
|
[0.66]
|
[2.23]**
|
[-0.82]
|
[2.14]**
|
[1.75]
|
|
|
|
198
|
335
|
254
|
59
|
12
|
21
|
9
|
3268
|
|
R-squared (2023)
|
0.458 (0.447)
|
0.436 (0.412)
|
0.407 (0.387)
|
0.405 (0.373)
|
0.312 (0.202)
|
0.559 (0.482)
|
0.597 (0.553)
|
0.429 (0.399)
|
|
|
[1.31]
|
[0.38]
|
[-1.09]
|
[-0.53]
|
[-1.43]
|
[2.05]*
|
[2.23]*
|
|
|
|
198
|
335
|
254
|
59
|
12
|
21
|
9
|
3268
|
|
Deposit Beta (2024)
|
0.294 (0.298)
|
0.302 (0.280)
|
0.302 (0.295)
|
0.273 (0.258)
|
0.406 (0.414)
|
0.396 (0.414)
|
0.466 (0.481)
|
0.270 (0.257)
|
|
|
[1.06]
|
[1.75]*
|
[1.54]
|
[0.05]
|
[2.09]*
|
[2.57]**
|
[2.44]**
|
|
|
|
194
|
326
|
249
|
59
|
12
|
20
|
9
|
3202
|
|
R-squared (2024)
|
0.549 (0.599)
|
0.545 (0.639)
|
0.547 (0.590)
|
0.557 (0.653)
|
0.721 (0.775)
|
0.710 (0.793)
|
0.653 (0.763)
|
0.539 (0.584)
|
|
|
[0.41]
|
[0.29]
|
[0.35]
|
[0.41]
|
[2.20]*
|
[2.69]**
|
[1.18]
|
|
|
|
194
|
326
|
249
|
59
|
12
|
20
|
9
|
3202
|
|
Δ Beta (2022→2023)
|
-0.082 (-0.053)
|
-0.062 (-0.062)
|
-0.128 (-0.107)
|
-0.094 (-0.107)
|
-0.204 (-0.164)
|
-0.018 (-0.034)
|
-0.057 (-0.045)
|
-0.078 (-0.077)
|
|
|
[-0.16]
|
[1.19]
|
[-2.69]***
|
[-0.49]
|
[-2.09]*
|
[0.71]
|
[0.17]
|
|
|
|
197
|
335
|
254
|
59
|
12
|
21
|
9
|
3245
|
|
Δ Beta (2023→2024)
|
0.105 (0.131)
|
0.122 (0.133)
|
0.168 (0.172)
|
0.112 (0.120)
|
0.333 (0.348)
|
0.083 (0.141)
|
0.101 (0.025)
|
0.150 (0.153)
|
|
|
[-1.53]
|
[-1.48]
|
[0.72]
|
[-0.89]
|
[2.32]**
|
[-0.82]
|
[-0.34]
|
|
|
|
194
|
324
|
249
|
58
|
12
|
20
|
9
|
3190
|
|
Δ Beta (2022→2024)
|
0.024 (0.060)
|
0.060 (0.061)
|
0.042 (0.057)
|
0.017 (0.013)
|
0.129 (0.145)
|
0.072 (0.094)
|
0.044 (0.018)
|
0.071 (0.074)
|
|
|
[-1.82]*
|
[-0.65]
|
[-1.32]
|
[-1.31]
|
[0.86]
|
[0.02]
|
[-0.26]
|
|
|
|
193
|
324
|
249
|
58
|
12
|
20
|
9
|
3175
|
export_table(
table_beta4,
"table_beta4_q1_2023",
caption = "Deposit Beta by Facility Choice: Q1 2023",
label = "tab:beta_q1_2023",
note = "Deposit beta measures interest rate sensitivity of deposits. Q1 2023: January 1 -- March 31, 2023. FHLB borrowers identified at 10\\% threshold."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta4_q1_2023.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta4_q1_2023.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta4_q1_2023.csv
# ==============================================================================
# TABLE B5: Deposit Beta - Arbitrage Period
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("TABLE B5: Deposit Beta - Arbitrage Period\n")
## TABLE B5: Deposit Beta - Arbitrage Period
cat(strrep("=", 60), "\n")
## ============================================================
table_beta5_data <- baseline_q %>%
mutate(
btfp_user = idrssd %in% btfp_arb,
dw_user = idrssd %in% dw_arb,
borrower_type = case_when(
btfp_user & dw_user ~ "Both",
btfp_user & !dw_user ~ "BTFP Only",
!btfp_user & dw_user ~ "DW Only",
TRUE ~ "Non-Borrower"
)
)
table_beta5 <- create_deposit_beta_table(table_beta5_data, "borrower_type",
group_levels = c("BTFP Only", "DW Only", "Both", "Non-Borrower"))
table_beta5 %>%
select(-Row_Type) %>%
kable(caption = "Table B5: Deposit Beta by Facility Choice (Arbitrage Period: Nov 1, 2023 - Jan 24, 2024)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Table B5: Deposit Beta by Facility Choice (Arbitrage Period: Nov 1, 2023
- Jan 24, 2024)
|
Variable
|
BTFP Only
|
DW Only
|
Both
|
Non-Borrower
|
|
N (with beta data)
|
619
|
300
|
141
|
3161
|
|
Deposit Beta (2022)
|
0.225 (0.193)
|
0.259 (0.209)
|
0.247 (0.224)
|
0.206 (0.162)
|
|
|
[2.48]**
|
[3.84]***
|
[2.67]***
|
|
|
|
619
|
300
|
141
|
3161
|
|
R-squared (2022)
|
0.621 (0.626)
|
0.624 (0.645)
|
0.665 (0.681)
|
0.603 (0.613)
|
|
|
[1.74]*
|
[1.41]
|
[3.25]***
|
|
|
|
619
|
300
|
141
|
3161
|
|
Deposit Beta (2023)
|
0.145 (0.117)
|
0.174 (0.134)
|
0.165 (0.130)
|
0.126 (0.097)
|
|
|
[1.46]
|
[2.56]**
|
[1.67]*
|
|
|
|
618
|
301
|
141
|
3096
|
|
R-squared (2023)
|
0.439 (0.413)
|
0.427 (0.388)
|
0.462 (0.481)
|
0.427 (0.400)
|
|
|
[0.81]
|
[-0.03]
|
[1.19]
|
|
|
|
618
|
301
|
141
|
3096
|
|
Deposit Beta (2024)
|
0.259 (0.267)
|
0.303 (0.314)
|
0.265 (0.258)
|
0.279 (0.260)
|
|
|
[-1.29]
|
[1.06]
|
[-0.55]
|
|
|
|
617
|
296
|
141
|
3017
|
|
R-squared (2024)
|
0.554 (0.607)
|
0.586 (0.682)
|
0.526 (0.569)
|
0.536 (0.582)
|
|
|
[1.23]
|
[2.48]**
|
[-0.36]
|
|
|
|
617
|
296
|
141
|
3017
|
|
Δ Beta (2022→2023)
|
-0.081 (-0.080)
|
-0.085 (-0.087)
|
-0.079 (-0.091)
|
-0.080 (-0.074)
|
|
|
[-0.10]
|
[-0.27]
|
[0.03]
|
|
|
|
617
|
300
|
140
|
3075
|
|
Δ Beta (2023→2024)
|
0.128 (0.156)
|
0.134 (0.131)
|
0.109 (0.125)
|
0.153 (0.157)
|
|
|
[-1.51]
|
[-0.68]
|
[-1.43]
|
|
|
|
612
|
295
|
140
|
3009
|
|
Δ Beta (2022→2024)
|
0.042 (0.057)
|
0.052 (0.074)
|
0.023 (0.043)
|
0.074 (0.074)
|
|
|
[-2.10]**
|
[-0.90]
|
[-1.97]*
|
|
|
|
613
|
294
|
139
|
2994
|
export_table(
table_beta5,
"table_beta5_arbitrage",
caption = "Deposit Beta by Facility Choice: Arbitrage Period",
label = "tab:beta_arbitrage",
note = "Deposit beta measures interest rate sensitivity of deposits. Arbitrage period: November 1, 2023 -- January 24, 2024 (BTFP rate below IORB)."
)
## LaTeX table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta5_arbitrage.tex
## HTML table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta5_arbitrage.html
## CSV table saved: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/table_beta5_arbitrage.csv
# ==============================================================================
# DEPOSIT BETA SUMMARY
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("DEPOSIT BETA SUMMARY\n")
## DEPOSIT BETA SUMMARY
cat(strrep("=", 60), "\n")
## ============================================================
# Summary by acute period facility choice
cat("\n--- Deposit Beta by Facility Choice (Acute Period) ---\n")
##
## --- Deposit Beta by Facility Choice (Acute Period) ---
table_beta3_data %>%
filter(!is.na(beta_2022)) %>%
group_by(borrower_type) %>%
summarise(
N = n(),
Beta_2022_Mean = round(mean(beta_2022, na.rm = TRUE), 3),
Beta_2023_Mean = round(mean(beta_2023, na.rm = TRUE), 3),
Beta_2024_Mean = round(mean(beta_2024, na.rm = TRUE), 3),
Delta_22_23 = round(mean(beta_change_2022_2023, na.rm = TRUE), 3),
Delta_23_24 = round(mean(beta_change_2023_2024, na.rm = TRUE), 3),
.groups = "drop"
) %>%
pander(caption = "Deposit Beta Evolution by Facility Choice")
Deposit Beta Evolution by Facility Choice (continued
below)
| BTFP Only |
365 |
0.241 |
0.148 |
0.289 |
| Both |
92 |
0.313 |
0.22 |
0.342 |
| DW Only |
298 |
0.243 |
0.172 |
0.318 |
| Non-Borrower |
3466 |
0.206 |
0.126 |
0.274 |
| -0.093 |
0.139 |
| -0.093 |
0.12 |
| -0.073 |
0.148 |
| -0.079 |
0.147 |
# T-test: BTFP Only vs DW Only
cat("\n--- T-Tests: BTFP Only vs DW Only ---\n")
##
## --- T-Tests: BTFP Only vs DW Only ---
btfp_data <- table_beta3_data %>% filter(borrower_type == "BTFP Only")
dw_data <- table_beta3_data %>% filter(borrower_type == "DW Only")
for (v in c("beta_2022", "beta_2023", "beta_2024", "beta_change_2022_2023")) {
result <- calc_tstat_with_stars(btfp_data[[v]], dw_data[[v]])
cat(sprintf("%s: t = %.3f%s (p = %.4f)\n", v, result$tstat, result$stars, result$pval))
}
## beta_2022: t = -0.110 (p = 0.9121)
## beta_2023: t = -1.198 (p = 0.2314)
## beta_2024: t = -1.008 (p = 0.3141)
## beta_change_2022_2023: t = -0.947 (p = 0.3439)
Variable
Definitions
# ==============================================================================
# VARIABLE DEFINITIONS TABLE
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("VARIABLE DEFINITIONS\n")
## VARIABLE DEFINITIONS
cat(strrep("=", 60), "\n")
## ============================================================
variable_definitions <- tribble(
~Category, ~Variable, ~Definition, ~Source,
# Solvency Measures
"Solvency", "Book Equity Ratio", "Total equity / Total assets (×100)", "Call Report",
"Solvency", "MTM Loss (HTM)", "Mark-to-market loss on held-to-maturity securities / Total assets (×100)", "Call Report",
"Solvency", "MTM Loss (BTFP Elg.)", "Mark-to-market loss on BTFP-eligible securities (Treasury, Agency, MBS) / Total assets (×100)", "Call Report",
"Solvency", "MTM Loss (Total)", "Total mark-to-market loss on all securities / Total assets (×100)", "Call Report",
"Solvency", "Adjusted Equity", "Book equity ratio − MTM loss ratio (percentage points)", "Derived",
"Solvency", "Adjusted Equity < 0", "Indicator = 1 if adjusted equity < 0", "Derived",
"Solvency", "Adj. Tier1 Equity", "Tier 1 capital ratio − MTM loss ratio (percentage points)", "Derived",
"Solvency", "Adj. Tier1 Equity < 0", "Indicator = 1 if adjusted Tier 1 equity < 0", "Derived",
"Solvency", "Adj. CET1", "Common Equity Tier 1 ratio − MTM loss ratio (percentage points)", "Derived",
"Solvency", "Adj. CET1 < 0", "Indicator = 1 if adjusted CET1 < 0", "Derived",
# Liquidity Measures
"Liquidity", "Uninsured Leverage", "Uninsured deposits / Total assets (×100)", "Call Report",
"Liquidity", "Available Liquidity Ratio", "(Cash + Reverse repo + Fed funds sold) / Total assets (×100)", "Call Report",
# Run Risk Categories
"Run Risk", "Solvent and Liquid", "Indicator = 1 if uninsured ratio < median AND MTM loss < median", "Derived",
"Run Risk", "Solvent and Illiquid", "Indicator = 1 if uninsured ratio > median AND MTM loss < median", "Derived",
"Run Risk", "Insolvent and Liquid", "Indicator = 1 if uninsured ratio < median AND MTM loss > median", "Derived",
"Run Risk", "Insolvent and Illiquid", "Indicator = 1 if uninsured ratio > median AND MTM loss > median", "Derived",
# IDCR Measures
"IDCR", "IDCR Insolvent (s=0.5)", "Indicator = 1 if (MV_Asset − 0.5×Uninsured − Insured)/Insured < 0", "Derived",
"IDCR", "IDCR Insolvent (s=1.0)", "Indicator = 1 if (MV_Asset − Uninsured − Insured)/Insured < 0", "Derived",
# Capital Insolvency
"Capital", "Capital Insolvent (s=0.5)", "Indicator = 1 if (Equity − 0.5×Uninsured×MV_Adj)/Assets < 0", "Derived",
"Capital", "Capital Insolvent (s=1.0)", "Indicator = 1 if (Equity − Uninsured×MV_Adj)/Assets < 0", "Derived",
# Deposit Flow Measures
"Deposit Flows", "Change Uninsured Deposits (Fwd Q)", "Percentage change in uninsured deposits from baseline to next quarter", "Call Report",
"Deposit Flows", "Change Insured Deposits (Fwd Q)", "Percentage change in insured deposits from baseline to next quarter", "Call Report",
"Deposit Flows", "Abnormal Insured Outflow (10%)", "Indicator = 1 if insured deposit outflow Z-score > 1.28 (top 10%)", "Derived",
"Deposit Flows", "Abnormal Insured Outflow (5%)", "Indicator = 1 if insured deposit outflow Z-score > 1.65 (top 5%)", "Derived",
"Deposit Flows", "Abnormal Uninsured Outflow (10%)", "Indicator = 1 if uninsured deposit outflow Z-score > 1.28 (top 10%)", "Derived",
"Deposit Flows", "Abnormal Uninsured Outflow (5%)", "Indicator = 1 if uninsured deposit outflow Z-score > 1.65 (top 5%)", "Derived",
# Deposit Beta Measures
"Deposit Beta", "Deposit Beta (2022)", "Interest rate sensitivity of deposits estimated from 2022 data", "Estimated",
"Deposit Beta", "Deposit Beta (2023)", "Interest rate sensitivity of deposits estimated from 2023 data", "Estimated",
"Deposit Beta", "Deposit Beta (2024)", "Interest rate sensitivity of deposits estimated from 2024 data", "Estimated",
"Deposit Beta", "R-squared", "Goodness of fit from deposit beta regression", "Estimated",
"Deposit Beta", "Δ Beta (2022→2023)", "Change in deposit beta from 2022 to 2023", "Derived",
"Deposit Beta", "Δ Beta (2023→2024)", "Change in deposit beta from 2023 to 2024", "Derived",
"Deposit Beta", "Δ Beta (2022→2024)", "Change in deposit beta from 2022 to 2024", "Derived",
# FHLB Measures
"FHLB", "Abnormal FHLB (10%)", "Indicator = 1 if FHLB borrowing Z-score > 1.28 (top 10%)", "Derived",
"FHLB", "Abnormal FHLB (5%)", "Indicator = 1 if FHLB borrowing Z-score > 1.65 (top 5%)", "Derived",
# Borrower Classifications
"Classification", "BTFP Borrower", "Bank that borrowed from Bank Term Funding Program during specified period", "BTFP Data",
"Classification", "DW Borrower", "Bank that borrowed from Discount Window during specified period", "DW Data",
"Classification", "FHLB Borrower", "Bank with abnormal FHLB advances above specified threshold", "Call Report",
"Classification", "Non-Borrower", "Bank that did not borrow from any emergency facility during specified period", "Derived"
)
# Display variable definitions
variable_definitions %>%
kable(caption = "Table: Variable Definitions",
col.names = c("Category", "Variable", "Definition", "Source")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = TRUE) %>%
collapse_rows(columns = 1, valign = "top")
Table: Variable Definitions
|
Category
|
Variable
|
Definition
|
Source
|
|
Solvency
|
Book Equity Ratio
|
Total equity / Total assets (×100)
|
Call Report
|
|
MTM Loss (HTM)
|
Mark-to-market loss on held-to-maturity securities / Total assets (×100)
|
Call Report
|
|
MTM Loss (BTFP Elg.)
|
Mark-to-market loss on BTFP-eligible securities (Treasury, Agency, MBS)
/ Total assets (×100)
|
Call Report
|
|
MTM Loss (Total)
|
Total mark-to-market loss on all securities / Total assets (×100)
|
Call Report
|
|
Adjusted Equity
|
Book equity ratio − MTM loss ratio (percentage points)
|
Derived
|
|
Adjusted Equity < 0
|
Indicator = 1 if adjusted equity < 0
|
Derived
|
|
Adj. Tier1 Equity
|
Tier 1 capital ratio − MTM loss ratio (percentage points)
|
Derived
|
|
Adj. Tier1 Equity < 0
|
Indicator = 1 if adjusted Tier 1 equity < 0
|
Derived
|
|
Adj. CET1
|
Common Equity Tier 1 ratio − MTM loss ratio (percentage points)
|
Derived
|
|
Adj. CET1 < 0
|
Indicator = 1 if adjusted CET1 < 0
|
Derived
|
|
Liquidity
|
Uninsured Leverage
|
Uninsured deposits / Total assets (×100)
|
Call Report
|
|
Available Liquidity Ratio
|
(Cash + Reverse repo + Fed funds sold) / Total assets (×100)
|
Call Report
|
|
Run Risk
|
Solvent and Liquid
|
Indicator = 1 if uninsured ratio < median AND MTM loss < median
|
Derived
|
|
Solvent and Illiquid
|
Indicator = 1 if uninsured ratio > median AND MTM loss < median
|
Derived
|
|
Insolvent and Liquid
|
Indicator = 1 if uninsured ratio < median AND MTM loss > median
|
Derived
|
|
Insolvent and Illiquid
|
Indicator = 1 if uninsured ratio > median AND MTM loss > median
|
Derived
|
|
IDCR
|
IDCR Insolvent (s=0.5)
|
Indicator = 1 if (MV_Asset − 0.5×Uninsured − Insured)/Insured < 0
|
Derived
|
|
IDCR Insolvent (s=1.0)
|
Indicator = 1 if (MV_Asset − Uninsured − Insured)/Insured < 0
|
Derived
|
|
Capital
|
Capital Insolvent (s=0.5)
|
Indicator = 1 if (Equity − 0.5×Uninsured×MV_Adj)/Assets < 0
|
Derived
|
|
Capital Insolvent (s=1.0)
|
Indicator = 1 if (Equity − Uninsured×MV_Adj)/Assets < 0
|
Derived
|
|
Deposit Flows
|
Change Uninsured Deposits (Fwd Q)
|
Percentage change in uninsured deposits from baseline to next quarter
|
Call Report
|
|
Change Insured Deposits (Fwd Q)
|
Percentage change in insured deposits from baseline to next quarter
|
Call Report
|
|
Abnormal Insured Outflow (10%)
|
Indicator = 1 if insured deposit outflow Z-score > 1.28 (top 10%)
|
Derived
|
|
Abnormal Insured Outflow (5%)
|
Indicator = 1 if insured deposit outflow Z-score > 1.65 (top 5%)
|
Derived
|
|
Abnormal Uninsured Outflow (10%)
|
Indicator = 1 if uninsured deposit outflow Z-score > 1.28 (top 10%)
|
Derived
|
|
Abnormal Uninsured Outflow (5%)
|
Indicator = 1 if uninsured deposit outflow Z-score > 1.65 (top 5%)
|
Derived
|
|
Deposit Beta
|
Deposit Beta (2022)
|
Interest rate sensitivity of deposits estimated from 2022 data
|
Estimated
|
|
Deposit Beta (2023)
|
Interest rate sensitivity of deposits estimated from 2023 data
|
Estimated
|
|
Deposit Beta (2024)
|
Interest rate sensitivity of deposits estimated from 2024 data
|
Estimated
|
|
R-squared
|
Goodness of fit from deposit beta regression
|
Estimated
|
|
Δ Beta (2022→2023)
|
Change in deposit beta from 2022 to 2023
|
Derived
|
|
Δ Beta (2023→2024)
|
Change in deposit beta from 2023 to 2024
|
Derived
|
|
Δ Beta (2022→2024)
|
Change in deposit beta from 2022 to 2024
|
Derived
|
|
FHLB
|
Abnormal FHLB (10%)
|
Indicator = 1 if FHLB borrowing Z-score > 1.28 (top 10%)
|
Derived
|
|
Abnormal FHLB (5%)
|
Indicator = 1 if FHLB borrowing Z-score > 1.65 (top 5%)
|
Derived
|
|
Classification
|
BTFP Borrower
|
Bank that borrowed from Bank Term Funding Program during specified
period
|
BTFP Data
|
|
DW Borrower
|
Bank that borrowed from Discount Window during specified period
|
DW Data
|
|
FHLB Borrower
|
Bank with abnormal FHLB advances above specified threshold
|
Call Report
|
|
Non-Borrower
|
Bank that did not borrow from any emergency facility during specified
period
|
Derived
|
# Export to LaTeX
var_def_latex <- c(
"\\begin{table}[htbp]",
"\\centering",
"\\caption{Variable Definitions}",
"\\label{tab:variable_definitions}",
"\\footnotesize",
"\\begin{tabular}{p{2cm}p{3.5cm}p{7.5cm}p{2cm}}",
"\\toprule",
"Category & Variable & Definition & Source \\\\",
"\\midrule"
)
current_category <- ""
for (i in seq_len(nrow(variable_definitions))) {
row <- variable_definitions[i, ]
cat_display <- if (row$Category != current_category) row$Category else ""
current_category <- row$Category
# Escape special LaTeX characters
def_escaped <- gsub("%", "\\\\%", row$Definition)
def_escaped <- gsub("×", "$\\\\times$", def_escaped)
def_escaped <- gsub("−", "$-$", def_escaped)
var_def_latex <- c(var_def_latex,
sprintf("%s & %s & %s & %s \\\\",
cat_display, row$Variable, def_escaped, row$Source))
# Add midrule between categories
if (i < nrow(variable_definitions) && variable_definitions$Category[i+1] != current_category) {
var_def_latex <- c(var_def_latex, "\\midrule")
}
}
var_def_latex <- c(var_def_latex,
"\\bottomrule",
"\\end{tabular}",
"\\vspace{0.3em}",
"\\begin{minipage}{0.95\\textwidth}",
"\\scriptsize",
"\\textit{Notes:} All ratios expressed as percentages unless otherwise noted. MTM = Mark-to-market. MV = Market value. IDCR = Implied Deposit Coverage Ratio following Jiang et al. (2023). Z-scores calculated as (current value $-$ historical mean) / historical standard deviation using prior 8 quarters (2021Q1--2022Q4). Deposit beta estimated from quarterly deposit growth regressed on Fed Funds rate changes.",
"\\end{minipage}",
"\\end{table}")
writeLines(var_def_latex, file.path(TABLE_PATH, "variable_definitions.tex"))
cat("\nVariable definitions table saved to:", file.path(TABLE_PATH, "variable_definitions.tex"), "\n")
##
## Variable definitions table saved to: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/variable_definitions.tex
# Also save as CSV
write_csv(variable_definitions, file.path(TABLE_PATH, "variable_definitions.csv"))
cat("Variable definitions CSV saved to:", file.path(TABLE_PATH, "variable_definitions.csv"), "\n")
## Variable definitions CSV saved to: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/variable_definitions.csv
Statistical Notes
# ==============================================================================
# STATISTICAL NOTES
# ==============================================================================
cat("\n", strrep("=", 60), "\n")
##
## ============================================================
cat("STATISTICAL NOTES\n")
## STATISTICAL NOTES
cat(strrep("=", 60), "\n")
## ============================================================
statistical_notes <- tribble(
~Item, ~Description,
"T-statistics", "Calculated using Welch's t-test (unequal variances) comparing each borrower group to Non-Borrowers",
"Significance levels", "*** p<0.01, ** p<0.05, * p<0.10 (two-tailed tests)",
"Table format", "Mean (Median) with [T-statistic]significance stars and N observations",
"Dummy variables", "Shown as percentage of banks with indicator = 1; N shows count of such banks",
"Continuous variables", "Shown as percentage points; N shows total non-missing observations",
"Baseline period", "2022Q4 unless otherwise noted (Table 6b uses 2023Q4)",
"Sample", "Excludes G-SIBs and failed banks; includes only banks with BTFP-eligible securities"
)
statistical_notes %>%
kable(caption = "Statistical Notes",
col.names = c("Item", "Description")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = TRUE)
Statistical Notes
|
Item
|
Description
|
|
T-statistics
|
Calculated using Welch’s t-test (unequal variances) comparing each
borrower group to Non-Borrowers
|
|
Significance levels
|
*** p<0.01, ** p<0.05, * p<0.10 (two-tailed tests)
|
|
Table format
|
Mean (Median) with [T-statistic]significance stars and N observations
|
|
Dummy variables
|
Shown as percentage of banks with indicator = 1; N shows count of such
banks
|
|
Continuous variables
|
Shown as percentage points; N shows total non-missing observations
|
|
Baseline period
|
2022Q4 unless otherwise noted (Table 6b uses 2023Q4)
|
|
Sample
|
Excludes G-SIBs and failed banks; includes only banks with BTFP-eligible
securities
|
# ==============================================================================
# INSOLVENCY BY SIZE CATEGORY - TWO PERIODS
# ==============================================================================
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("PREPARING INSOLVENCY DATA BY SIZE CATEGORY\n")
## PREPARING INSOLVENCY DATA BY SIZE CATEGORY
cat(strrep("=", 70), "\n\n")
## ======================================================================
# --------------------------------------------------------------------------
# SIZE CATEGORY DEFINITIONS (from LaTeX table)
# --------------------------------------------------------------------------
create_size_category <- function(assets_thousands) {
# Convert thousands to millions for comparison
assets_millions <- assets_thousands / 1000
case_when(
assets_millions >= 700000 ~ "$700B and Above",
assets_millions >= 250000 ~ "$250B-$700B",
assets_millions >= 100000 ~ "$100B-$250B",
assets_millions >= 50000 ~ "$50B-$100B",
assets_millions >= 20000 ~ "$20B-$50B",
assets_millions >= 10000 ~ "$10B-$20B",
assets_millions >= 5000 ~ "$5B-$10B",
assets_millions >= 3000 ~ "$3B-$5B",
assets_millions >= 1000 ~ "$1B-$3B",
assets_millions >= 500 ~ "$500M-$1B",
TRUE ~ "Below $500M"
)
}
# Define factor levels to ensure proper ordering
size_levels <- c(
"$700B and Above",
"$250B-$700B",
"$100B-$250B",
"$50B-$100B",
"$20B-$50B",
"$10B-$20B",
"$5B-$10B",
"$3B-$5B",
"$1B-$3B",
"$500M-$1B",
"Below $500M"
)
# --------------------------------------------------------------------------
# CALCULATE INSOLVENCY MEASURES FOR BASELINE (2022Q4)
# --------------------------------------------------------------------------
baseline_insolvency <- call_q %>%
filter(period == '2022Q4') %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0
) %>%
mutate(
# Size category (total_asset is in thousands)
size_category = create_size_category(total_asset),
size_category = factor(size_category, levels = size_levels),
# All assets liquidated at market value
adjusted_book_value = mm_asset - total_liability,
mv_insolvent = as.integer(adjusted_book_value < 0),
# Deposit run scenarios
idcr_s50 = safe_div(mm_asset - 0.5 * uninsured_deposit - insured_deposit, insured_deposit),
idcr_s100 = safe_div(mm_asset - 1.0 * uninsured_deposit - insured_deposit, insured_deposit),
idcr_insolvent_s50 = as.integer(idcr_s50 < 0),
idcr_insolvent_s100 = as.integer(idcr_s100 < 0)
) %>%
select(idrssd, size_category, total_asset,
mv_insolvent, idcr_insolvent_s50, idcr_insolvent_s100)
cat("Baseline insolvency data prepared:\n")
## Baseline insolvency data prepared:
cat(sprintf(" Total banks: %d\n", nrow(baseline_insolvency)))
## Total banks: 4292
cat(sprintf(" MV Insolvent: %d\n", sum(baseline_insolvency$mv_insolvent, na.rm = TRUE)))
## MV Insolvent: 2015
cat(sprintf(" IDCR Insolvent (s=1.0): %d\n", sum(baseline_insolvency$idcr_insolvent_s100, na.rm = TRUE)))
## IDCR Insolvent (s=1.0): 1210
cat(sprintf(" IDCR Insolvent (s=0.5): %d\n", sum(baseline_insolvency$idcr_insolvent_s50, na.rm = TRUE)))
## IDCR Insolvent (s=0.5): 179
# --------------------------------------------------------------------------
# TABLE 1: INSOLVENCY BY SIZE - ACUTE PERIOD (March 13 - May 1, 2023)
# --------------------------------------------------------------------------
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("TABLE 1: INSOLVENT BANKS BY SIZE - ACUTE PERIOD (March 13 - May 1, 2023)\n")
## TABLE 1: INSOLVENT BANKS BY SIZE - ACUTE PERIOD (March 13 - May 1, 2023)
cat(strrep("=", 70), "\n\n")
## ======================================================================
# Define acute period
acute_start <- as.Date("2023-03-13")
acute_end <- as.Date("2023-05-01")
# Identify BTFP borrowers in acute period
btfp_acute <- btfp_loans_raw %>%
filter(btfp_loan_date >= acute_start & btfp_loan_date <= acute_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
# Identify DW borrowers in acute period
dw_acute <- dw_loans_raw %>%
filter(dw_loan_date >= acute_start & dw_loan_date <= acute_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat(sprintf("BTFP borrowers in acute period: %d\n", length(btfp_acute)))
## BTFP borrowers in acute period: 492
cat(sprintf("DW borrowers in acute period: %d\n", length(dw_acute)))
## DW borrowers in acute period: 424
# Create summary table by size
table_acute <- baseline_insolvency %>%
group_by(size_category) %>%
summarise(
total_banks = n(),
mv_insolvent = sum(mv_insolvent, na.rm = TRUE),
idcr_insolvent_s100 = sum(idcr_insolvent_s100, na.rm = TRUE),
idcr_insolvent_s50 = sum(idcr_insolvent_s50, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(size_category)
# Calculate percentage (handle case where sum is 0)
total_s50 <- sum(table_acute$idcr_insolvent_s50)
if (total_s50 > 0) {
table_acute <- table_acute %>%
mutate(pct_s50 = 100 * idcr_insolvent_s50 / total_s50)
} else {
table_acute <- table_acute %>%
mutate(pct_s50 = 0)
}
# Display table
print(table_acute)
## # A tibble: 10 × 6
## size_category total_banks mv_insolvent idcr_insolvent_s100 idcr_insolvent_s50
## <fct> <int> <int> <int> <int>
## 1 $250B-$700B 5 2 1 0
## 2 $100B-$250B 13 8 4 1
## 3 $50B-$100B 15 8 4 1
## 4 $20B-$50B 45 18 9 3
## 5 $10B-$20B 57 26 15 4
## 6 $5B-$10B 112 62 33 9
## 7 $3B-$5B 114 66 32 5
## 8 $1B-$3B 562 328 166 28
## 9 $500M-$1B 717 384 237 31
## 10 Below $500M 2652 1113 709 97
## # ℹ 1 more variable: pct_s50 <dbl>
# Calculate totals row
totals_acute <- table_acute %>%
summarise(
size_category = "Total",
total_banks = sum(total_banks),
mv_insolvent = sum(mv_insolvent),
idcr_insolvent_s100 = sum(idcr_insolvent_s100),
idcr_insolvent_s50 = sum(idcr_insolvent_s50),
pct_s50 = 100
)
table_acute_with_totals <- bind_rows(table_acute, totals_acute)
# Format and display with kable
table_acute_with_totals %>%
mutate(pct_s50 = sprintf("%.1f%%", pct_s50)) %>%
kable(
caption = "Table 1: Insolvent Banks by Size - Acute Period (March 13 - May 1, 2023)",
col.names = c("Asset Size", "Total Banks", "All Assets Liquidated",
"100% Uninsured Run", "50% Uninsured Run", "Percentage"),
align = c("l", rep("r", 5)),
format.args = list(big.mark = ",")
) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(nrow(table_acute_with_totals), bold = TRUE)
Table 1: Insolvent Banks by Size - Acute Period (March 13 - May 1, 2023)
|
Asset Size
|
Total Banks
|
All Assets Liquidated
|
100% Uninsured Run
|
50% Uninsured Run
|
Percentage
|
|
$250B-$700B
|
5
|
2
|
1
|
0
|
0.0%
|
|
$100B-$250B
|
13
|
8
|
4
|
1
|
0.6%
|
|
$50B-$100B
|
15
|
8
|
4
|
1
|
0.6%
|
|
$20B-$50B
|
45
|
18
|
9
|
3
|
1.7%
|
|
$10B-$20B
|
57
|
26
|
15
|
4
|
2.2%
|
|
$5B-$10B
|
112
|
62
|
33
|
9
|
5.0%
|
|
$3B-$5B
|
114
|
66
|
32
|
5
|
2.8%
|
|
$1B-$3B
|
562
|
328
|
166
|
28
|
15.6%
|
|
$500M-$1B
|
717
|
384
|
237
|
31
|
17.3%
|
|
Below $500M
|
2,652
|
1,113
|
709
|
97
|
54.2%
|
|
Total
|
4,292
|
2,015
|
1,210
|
179
|
100.0%
|
# Export to LaTeX
latex_acute <- c(
"\\begin{table}[htbp]",
"\\centering",
"\\caption{Insolvent Banks by Asset Size: Acute Period (March 13--May 1, 2023)}",
"\\label{tab:insolvency_size_acute}",
"\\footnotesize",
"",
"\\begin{minipage}{0.95\\textwidth}",
"\\smallskip",
"This table reports the distribution of insolvent banks across asset size categories during",
"the acute crisis period (March 13--May 1, 2023). Column (1) shows the total number of banks in each size bin.",
"Columns (2)--(4) report the number of insolvent banks under three scenarios: (i) full liquidation of all",
"assets at mark-to-market values, (ii) 100\\% uninsured depositor run, and",
"(iii) 50\\% uninsured depositor run. Column (5) reports the percentage of insolvent banks",
"under the 50\\% uninsured depositor run scenario relative to the total number of insolvent",
"banks in that scenario.",
"\\end{minipage}",
"",
"\\medskip",
"\\begin{tabular}{l*{5}{c}}",
"\\hline\\hline",
"& (1) & (2) & (3) & (4) & (5) \\\\",
"Asset Size ",
"& Total Banks ",
"& All Assets ",
"& 100\\% Uninsured",
"& 50\\% Uninsured ",
"& Percentage \\\\",
"",
"& Banks ",
"& Liquidated ",
"&Deposit Run ",
"& Deposit Run ",
"& 50\\% Uninsured run \\\\",
"\\hline",
""
)
for (i in 1:nrow(table_acute)) {
row <- table_acute[i, ]
latex_acute <- c(
latex_acute,
sprintf("%s & %d & %d & %d & %d & %.1f\\%% \\\\",
row$size_category,
row$total_banks,
row$mv_insolvent,
row$idcr_insolvent_s100,
row$idcr_insolvent_s50,
row$pct_s50)
)
}
latex_acute <- c(
latex_acute,
"\\hline",
"",
sprintf("Number of Banks & %d & %d & %d & %d & 100\\%% \\\\",
totals_acute$total_banks,
totals_acute$mv_insolvent,
totals_acute$idcr_insolvent_s100,
totals_acute$idcr_insolvent_s50),
"\\hline\\hline",
"\\end{tabular}",
"",
"\\begin{minipage}{0.95\\textwidth}",
"\\smallskip",
"\\footnotesize",
"\\textit{Note:} Insolvency in Column (2) is defined as mark-to-market (MTM) asset values being",
"insufficient to cover total non-equity liabilities. In Column (3), the assumption is that all",
"Uninsured depositors run; insolvency occurs if remaining insured deposits cannot be repaid from",
"MTM asset values. In Column (4), only 50\\% of uninsured deposits run. The final column shows the",
"distribution of insolvent banks in Column (4) as a percentage of all insolvent banks under that",
"scenario. All insolvency measures are based on 2022Q4 balance sheet data. Sample excludes G-SIBs,",
"failed banks, and banks without BTFP-eligible securities.",
"\\end{minipage}",
"",
"\\end{table}"
)
writeLines(latex_acute, file.path(TABLE_PATH, "insolvency_size_acute.tex"))
cat("\nAcute period table saved to:", file.path(TABLE_PATH, "insolvency_size_acute.tex"), "\n")
##
## Acute period table saved to: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/insolvency_size_acute.tex
# --------------------------------------------------------------------------
# TABLE 2: INSOLVENCY BY SIZE - JANUARY 1 - MARCH 31, 2024
# Includes BTFP, DW, and FHLB (10% threshold) borrowers
# --------------------------------------------------------------------------
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("TABLE 2: INSOLVENT BANKS BY SIZE - JAN 1 - MARCH 31, 2024\n")
## TABLE 2: INSOLVENT BANKS BY SIZE - JAN 1 - MARCH 31, 2024
cat("Includes BTFP, DW, and FHLB (10% threshold) borrowers\n")
## Includes BTFP, DW, and FHLB (10% threshold) borrowers
cat(strrep("=", 70), "\n\n")
## ======================================================================
# Define period
period_2024_start <- as.Date("2024-01-01")
period_2024_end <- as.Date("2024-03-31")
# Identify BTFP borrowers in 2024 period
btfp_2024 <- btfp_loans_raw %>%
filter(btfp_loan_date >= period_2024_start & btfp_loan_date <= period_2024_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
# Identify DW borrowers in 2024 period (if data exists)
dw_2024 <- dw_loans_raw %>%
filter(dw_loan_date >= period_2024_start & dw_loan_date <= period_2024_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
# Identify FHLB borrowers using 10% threshold from 2022Q4 baseline
# Note: FHLB status is from baseline_q, not from date-specific loans
fhlb_borrowers_10pct <- call_q %>%
filter(period == '2022Q4') %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0,
!is.na(abnormal_fhlb_borrowing_10pct) & abnormal_fhlb_borrowing_10pct > 0
) %>%
pull(idrssd)
cat(sprintf("BTFP borrowers in 2024 period: %d\n", length(btfp_2024)))
## BTFP borrowers in 2024 period: 717
cat(sprintf("DW borrowers in 2024 period: %d\n", length(dw_2024)))
## DW borrowers in 2024 period: 0
cat(sprintf("FHLB borrowers (10%% threshold): %d\n", length(fhlb_borrowers_10pct)))
## FHLB borrowers (10% threshold): 302
# Create summary table by size (same insolvency measures as acute period)
table_2024 <- baseline_insolvency %>%
group_by(size_category) %>%
summarise(
total_banks = n(),
mv_insolvent = sum(mv_insolvent, na.rm = TRUE),
idcr_insolvent_s100 = sum(idcr_insolvent_s100, na.rm = TRUE),
idcr_insolvent_s50 = sum(idcr_insolvent_s50, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(size_category)
# Calculate percentage (handle case where sum is 0)
total_s50_2024 <- sum(table_2024$idcr_insolvent_s50)
if (total_s50_2024 > 0) {
table_2024 <- table_2024 %>%
mutate(pct_s50 = 100 * idcr_insolvent_s50 / total_s50_2024)
} else {
table_2024 <- table_2024 %>%
mutate(pct_s50 = 0)
}
# Display table
print(table_2024)
## # A tibble: 10 × 6
## size_category total_banks mv_insolvent idcr_insolvent_s100 idcr_insolvent_s50
## <fct> <int> <int> <int> <int>
## 1 $250B-$700B 5 2 1 0
## 2 $100B-$250B 13 8 4 1
## 3 $50B-$100B 15 8 4 1
## 4 $20B-$50B 45 18 9 3
## 5 $10B-$20B 57 26 15 4
## 6 $5B-$10B 112 62 33 9
## 7 $3B-$5B 114 66 32 5
## 8 $1B-$3B 562 328 166 28
## 9 $500M-$1B 717 384 237 31
## 10 Below $500M 2652 1113 709 97
## # ℹ 1 more variable: pct_s50 <dbl>
# Calculate totals row
totals_2024 <- table_2024 %>%
summarise(
size_category = "Total",
total_banks = sum(total_banks),
mv_insolvent = sum(mv_insolvent),
idcr_insolvent_s100 = sum(idcr_insolvent_s100),
idcr_insolvent_s50 = sum(idcr_insolvent_s50),
pct_s50 = 100
)
table_2024_with_totals <- bind_rows(table_2024, totals_2024)
# Format and display with kable
table_2024_with_totals %>%
mutate(pct_s50 = sprintf("%.1f%%", pct_s50)) %>%
kable(
caption = "Table 2: Insolvent Banks by Size - January 1 - March 31, 2024",
col.names = c("Asset Size", "Total Banks", "All Assets Liquidated",
"100% Uninsured Run", "50% Uninsured Run", "Percentage"),
align = c("l", rep("r", 5)),
format.args = list(big.mark = ",")
) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(nrow(table_2024_with_totals), bold = TRUE)
Table 2: Insolvent Banks by Size - January 1 - March 31, 2024
|
Asset Size
|
Total Banks
|
All Assets Liquidated
|
100% Uninsured Run
|
50% Uninsured Run
|
Percentage
|
|
$250B-$700B
|
5
|
2
|
1
|
0
|
0.0%
|
|
$100B-$250B
|
13
|
8
|
4
|
1
|
0.6%
|
|
$50B-$100B
|
15
|
8
|
4
|
1
|
0.6%
|
|
$20B-$50B
|
45
|
18
|
9
|
3
|
1.7%
|
|
$10B-$20B
|
57
|
26
|
15
|
4
|
2.2%
|
|
$5B-$10B
|
112
|
62
|
33
|
9
|
5.0%
|
|
$3B-$5B
|
114
|
66
|
32
|
5
|
2.8%
|
|
$1B-$3B
|
562
|
328
|
166
|
28
|
15.6%
|
|
$500M-$1B
|
717
|
384
|
237
|
31
|
17.3%
|
|
Below $500M
|
2,652
|
1,113
|
709
|
97
|
54.2%
|
|
Total
|
4,292
|
2,015
|
1,210
|
179
|
100.0%
|
# Export to LaTeX
latex_2024 <- c(
"\\begin{table}[htbp]",
"\\centering",
"\\caption{Insolvent Banks by Asset Size: January 1--March 31, 2024}",
"\\label{tab:insolvency_size_2024q1}",
"\\footnotesize",
"",
"\\begin{minipage}{0.95\\textwidth}",
"\\smallskip",
"This table reports the distribution of insolvent banks across asset size categories during",
"January 1--March 31, 2024. Column (1) shows the total number of banks in each size bin.",
"Columns (2)--(4) report the number of insolvent banks under three scenarios: (i) full liquidation of all",
"assets at mark-to-market values, (ii) 100\\% uninsured depositor run, and",
"(iii) 50\\% uninsured depositor run. Column (5) reports the percentage of insolvent banks",
"under the 50\\% uninsured depositor run scenario relative to the total number of insolvent",
"banks in that scenario.",
"\\end{minipage}",
"",
"\\medskip",
"\\begin{tabular}{l*{5}{c}}",
"\\hline\\hline",
"& (1) & (2) & (3) & (4) & (5) \\\\",
"Asset Size ",
"& Total Banks ",
"& All Assets ",
"& 100\\% Uninsured",
"& 50\\% Uninsured ",
"& Percentage \\\\",
"",
"& Banks ",
"& Liquidated ",
"&Deposit Run ",
"& Deposit Run ",
"& 50\\% Uninsured run \\\\",
"\\hline",
""
)
for (i in 1:nrow(table_2024)) {
row <- table_2024[i, ]
latex_2024 <- c(
latex_2024,
sprintf("%s & %d & %d & %d & %d & %.1f\\%% \\\\",
row$size_category,
row$total_banks,
row$mv_insolvent,
row$idcr_insolvent_s100,
row$idcr_insolvent_s50,
row$pct_s50)
)
}
latex_2024 <- c(
latex_2024,
"\\hline",
"",
sprintf("Number of Banks & %d & %d & %d & %d & 100\\%% \\\\",
totals_2024$total_banks,
totals_2024$mv_insolvent,
totals_2024$idcr_insolvent_s100,
totals_2024$idcr_insolvent_s50),
"\\hline\\hline",
"\\end{tabular}",
"",
"\\begin{minipage}{0.95\\textwidth}",
"\\smallskip",
"\\footnotesize",
"\\textit{Note:} Insolvency in Column (2) is defined as mark-to-market (MTM) asset values being",
"insufficient to cover total non-equity liabilities. In Column (3), the assumption is that all",
"Uninsured depositors run; insolvency occurs if remaining insured deposits cannot be repaid from",
"MTM asset values. In Column (4), only 50\\% of uninsured deposits run. The final column shows the",
"distribution of insolvent banks in Column (4) as a percentage of all insolvent banks under that",
"scenario. All insolvency measures are based on 2022Q4 balance sheet data. Sample excludes G-SIBs,",
"failed banks, and banks without BTFP-eligible securities. This period includes both",
"the Arbitrage period (through January 24) and Wind-down period (January 25 onwards).",
"Borrower identification includes BTFP, DW, and FHLB users (10\\% threshold).",
"\\end{minipage}",
"",
"\\end{table}"
)
writeLines(latex_2024, file.path(TABLE_PATH, "insolvency_size_2024q1.tex"))
cat("\n2024 period table saved to:", file.path(TABLE_PATH, "insolvency_size_2024q1.tex"), "\n")
##
## 2024 period table saved to: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/insolvency_size_2024q1.tex
# --------------------------------------------------------------------------
# SUMMARY STATISTICS
# --------------------------------------------------------------------------
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("SUMMARY STATISTICS\n")
## SUMMARY STATISTICS
cat(strrep("=", 70), "\n\n")
## ======================================================================
cat("--- Acute Period (March 13 - May 1, 2023) ---\n")
## --- Acute Period (March 13 - May 1, 2023) ---
cat(sprintf("Total banks: %d\n", totals_acute$total_banks))
## Total banks: 4292
cat(sprintf("MV Insolvent (All Assets Liquidated): %d (%.1f%%)\n",
totals_acute$mv_insolvent,
100 * totals_acute$mv_insolvent / totals_acute$total_banks))
## MV Insolvent (All Assets Liquidated): 2015 (46.9%)
cat(sprintf("IDCR Insolvent (100%% Uninsured Run): %d (%.1f%%)\n",
totals_acute$idcr_insolvent_s100,
100 * totals_acute$idcr_insolvent_s100 / totals_acute$total_banks))
## IDCR Insolvent (100% Uninsured Run): 1210 (28.2%)
cat(sprintf("IDCR Insolvent (50%% Uninsured Run): %d (%.1f%%)\n\n",
totals_acute$idcr_insolvent_s50,
100 * totals_acute$idcr_insolvent_s50 / totals_acute$total_banks))
## IDCR Insolvent (50% Uninsured Run): 179 (4.2%)
cat("--- January 1 - March 31, 2024 ---\n")
## --- January 1 - March 31, 2024 ---
cat(sprintf("Total banks: %d\n", totals_2024$total_banks))
## Total banks: 4292
cat(sprintf("MV Insolvent (All Assets Liquidated): %d (%.1f%%)\n",
totals_2024$mv_insolvent,
100 * totals_2024$mv_insolvent / totals_2024$total_banks))
## MV Insolvent (All Assets Liquidated): 2015 (46.9%)
cat(sprintf("IDCR Insolvent (100%% Uninsured Run): %d (%.1f%%)\n",
totals_2024$idcr_insolvent_s100,
100 * totals_2024$idcr_insolvent_s100 / totals_2024$total_banks))
## IDCR Insolvent (100% Uninsured Run): 1210 (28.2%)
cat(sprintf("IDCR Insolvent (50%% Uninsured Run): %d (%.1f%%)\n",
totals_2024$idcr_insolvent_s50,
100 * totals_2024$idcr_insolvent_s50 / totals_2024$total_banks))
## IDCR Insolvent (50% Uninsured Run): 179 (4.2%)
cat("\n=== TABLES GENERATED SUCCESSFULLY ===\n")
##
## === TABLES GENERATED SUCCESSFULLY ===
# ==============================================================================
# BORROWERS BY SIZE AND INSOLVENCY CATEGORY - TWO PERIODS
# ==============================================================================
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("BORROWERS BY SIZE AND INSOLVENCY CATEGORY\n")
## BORROWERS BY SIZE AND INSOLVENCY CATEGORY
cat(strrep("=", 70), "\n\n")
## ======================================================================
# --------------------------------------------------------------------------
# SIZE CATEGORY DEFINITIONS (from LaTeX table)
# --------------------------------------------------------------------------
create_size_category <- function(assets_thousands) {
# Convert thousands to millions for comparison
assets_millions <- assets_thousands / 1000
case_when(
assets_millions >= 700000 ~ "$700B and Above",
assets_millions >= 250000 ~ "$250B-$700B",
assets_millions >= 100000 ~ "$100B-$250B",
assets_millions >= 50000 ~ "$50B-$100B",
assets_millions >= 20000 ~ "$20B-$50B",
assets_millions >= 10000 ~ "$10B-$20B",
assets_millions >= 5000 ~ "$5B-$10B",
assets_millions >= 3000 ~ "$3B-$5B",
assets_millions >= 1000 ~ "$1B-$3B",
assets_millions >= 500 ~ "$500M-$1B",
TRUE ~ "Below $500M"
)
}
# Define factor levels to ensure proper ordering
size_levels <- c(
"$700B and Above",
"$250B-$700B",
"$100B-$250B",
"$50B-$100B",
"$20B-$50B",
"$10B-$20B",
"$5B-$10B",
"$3B-$5B",
"$1B-$3B",
"$500M-$1B",
"Below $500M"
)
# --------------------------------------------------------------------------
# PREPARE BASELINE WITH INSOLVENCY MEASURES (2022Q4)
# --------------------------------------------------------------------------
baseline_insolvency <- call_q %>%
filter(period == '2022Q4') %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0
) %>%
mutate(
# Size category
size_category = create_size_category(total_asset),
size_category = factor(size_category, levels = size_levels),
# Insolvency measures
adjusted_book_value = mm_asset - total_liability,
mv_insolvent = as.integer(adjusted_book_value < 0),
idcr_s50 = safe_div(mm_asset - 0.5 * uninsured_deposit - insured_deposit, insured_deposit),
idcr_s100 = safe_div(mm_asset - 1.0 * uninsured_deposit - insured_deposit, insured_deposit),
idcr_insolvent_s50 = as.integer(idcr_s50 < 0),
idcr_insolvent_s100 = as.integer(idcr_s100 < 0)
)
cat("Baseline data prepared:\n")
## Baseline data prepared:
cat(sprintf(" Total banks: %d\n", nrow(baseline_insolvency)))
## Total banks: 4292
cat(sprintf(" MV Insolvent: %d\n", sum(baseline_insolvency$mv_insolvent, na.rm = TRUE)))
## MV Insolvent: 2015
cat(sprintf(" IDCR Insolvent (s=1.0): %d\n", sum(baseline_insolvency$idcr_insolvent_s100, na.rm = TRUE)))
## IDCR Insolvent (s=1.0): 1210
cat(sprintf(" IDCR Insolvent (s=0.5): %d\n", sum(baseline_insolvency$idcr_insolvent_s50, na.rm = TRUE)))
## IDCR Insolvent (s=0.5): 179
# --------------------------------------------------------------------------
# TABLE 1: ACUTE PERIOD (March 13 - May 1, 2023)
# --------------------------------------------------------------------------
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("TABLE 1: BORROWERS BY SIZE AND INSOLVENCY - ACUTE PERIOD\n")
## TABLE 1: BORROWERS BY SIZE AND INSOLVENCY - ACUTE PERIOD
cat(strrep("=", 70), "\n\n")
## ======================================================================
# Define acute period
acute_start <- as.Date("2023-03-13")
acute_end <- as.Date("2023-05-01")
# Identify borrowers
btfp_acute <- btfp_loans_raw %>%
filter(btfp_loan_date >= acute_start & btfp_loan_date <= acute_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
dw_acute <- dw_loans_raw %>%
filter(dw_loan_date >= acute_start & dw_loan_date <= acute_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
cat(sprintf("BTFP borrowers: %d\n", length(btfp_acute)))
## BTFP borrowers: 492
cat(sprintf("DW borrowers: %d\n", length(dw_acute)))
## DW borrowers: 424
# Add borrower classification
acute_data <- baseline_insolvency %>%
mutate(
btfp_user = idrssd %in% btfp_acute,
dw_user = idrssd %in% dw_acute,
borrower_type = case_when(
btfp_user & dw_user ~ "Both",
btfp_user & !dw_user ~ "BTFP Only",
!btfp_user & dw_user ~ "DW Only",
TRUE ~ "Non-Borrower"
),
borrower_type = factor(borrower_type, levels = c("BTFP Only", "DW Only", "Both", "Non-Borrower"))
)
# Create summary tables by size, borrower type, and insolvency status
# Panel A: All Assets Liquidated (MV Insolvent)
table1a <- acute_data %>%
group_by(size_category, borrower_type) %>%
summarise(
total = n(),
insolvent = sum(mv_insolvent, na.rm = TRUE),
.groups = "drop"
) %>%
pivot_wider(
names_from = borrower_type,
values_from = c(total, insolvent),
values_fill = 0
) %>%
arrange(size_category)
cat("\n--- Panel A: All Assets Liquidated (MV Insolvent) ---\n")
##
## --- Panel A: All Assets Liquidated (MV Insolvent) ---
print(table1a)
## # A tibble: 10 × 9
## size_category `total_BTFP Only` `total_DW Only` `total_Non-Borrower`
## <fct> <int> <int> <int>
## 1 $250B-$700B 1 1 3
## 2 $100B-$250B 2 2 7
## 3 $50B-$100B 4 1 8
## 4 $20B-$50B 7 4 27
## 5 $10B-$20B 6 16 26
## 6 $5B-$10B 14 17 74
## 7 $3B-$5B 13 25 73
## 8 $1B-$3B 78 70 387
## 9 $500M-$1B 81 59 563
## 10 Below $500M 162 104 2363
## # ℹ 5 more variables: total_Both <int>, `insolvent_BTFP Only` <int>,
## # `insolvent_DW Only` <int>, `insolvent_Non-Borrower` <int>,
## # insolvent_Both <int>
# Panel B: 100% Uninsured Run (IDCR s=1.0)
table1b <- acute_data %>%
group_by(size_category, borrower_type) %>%
summarise(
total = n(),
insolvent = sum(idcr_insolvent_s100, na.rm = TRUE),
.groups = "drop"
) %>%
pivot_wider(
names_from = borrower_type,
values_from = c(total, insolvent),
values_fill = 0
) %>%
arrange(size_category)
cat("\n--- Panel B: 100% Uninsured Run (IDCR s=1.0) ---\n")
##
## --- Panel B: 100% Uninsured Run (IDCR s=1.0) ---
print(table1b)
## # A tibble: 10 × 9
## size_category `total_BTFP Only` `total_DW Only` `total_Non-Borrower`
## <fct> <int> <int> <int>
## 1 $250B-$700B 1 1 3
## 2 $100B-$250B 2 2 7
## 3 $50B-$100B 4 1 8
## 4 $20B-$50B 7 4 27
## 5 $10B-$20B 6 16 26
## 6 $5B-$10B 14 17 74
## 7 $3B-$5B 13 25 73
## 8 $1B-$3B 78 70 387
## 9 $500M-$1B 81 59 563
## 10 Below $500M 162 104 2363
## # ℹ 5 more variables: total_Both <int>, `insolvent_BTFP Only` <int>,
## # `insolvent_DW Only` <int>, `insolvent_Non-Borrower` <int>,
## # insolvent_Both <int>
# Panel C: 50% Uninsured Run (IDCR s=0.5)
table1c <- acute_data %>%
group_by(size_category, borrower_type) %>%
summarise(
total = n(),
insolvent = sum(idcr_insolvent_s50, na.rm = TRUE),
.groups = "drop"
) %>%
pivot_wider(
names_from = borrower_type,
values_from = c(total, insolvent),
values_fill = 0
) %>%
arrange(size_category)
cat("\n--- Panel C: 50% Uninsured Run (IDCR s=0.5) ---\n")
##
## --- Panel C: 50% Uninsured Run (IDCR s=0.5) ---
print(table1c)
## # A tibble: 10 × 9
## size_category `total_BTFP Only` `total_DW Only` `total_Non-Borrower`
## <fct> <int> <int> <int>
## 1 $250B-$700B 1 1 3
## 2 $100B-$250B 2 2 7
## 3 $50B-$100B 4 1 8
## 4 $20B-$50B 7 4 27
## 5 $10B-$20B 6 16 26
## 6 $5B-$10B 14 17 74
## 7 $3B-$5B 13 25 73
## 8 $1B-$3B 78 70 387
## 9 $500M-$1B 81 59 563
## 10 Below $500M 162 104 2363
## # ℹ 5 more variables: total_Both <int>, `insolvent_BTFP Only` <int>,
## # `insolvent_DW Only` <int>, `insolvent_Non-Borrower` <int>,
## # insolvent_Both <int>
# Create comprehensive table for export
table1_comprehensive <- acute_data %>%
group_by(size_category, borrower_type) %>%
summarise(
N = n(),
MV_Insolvent = sum(mv_insolvent, na.rm = TRUE),
IDCR_s100_Insolvent = sum(idcr_insolvent_s100, na.rm = TRUE),
IDCR_s50_Insolvent = sum(idcr_insolvent_s50, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(size_category, borrower_type)
# Display comprehensive table
cat("\n--- Comprehensive Table: All Insolvency Measures ---\n")
##
## --- Comprehensive Table: All Insolvency Measures ---
table1_comprehensive %>%
kable(
caption = "Table 1: Borrowers by Size and Insolvency Status - Acute Period (March 13 - May 1, 2023)",
col.names = c("Asset Size", "Borrower Type", "N", "MV Insolvent", "IDCR s=1.0", "IDCR s=0.5"),
align = c("l", "l", rep("r", 4))
) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
collapse_rows(columns = 1, valign = "top")
Table 1: Borrowers by Size and Insolvency Status - Acute Period (March
13 - May 1, 2023)
|
Asset Size
|
Borrower Type
|
N
|
MV Insolvent
|
IDCR s=1.0
|
IDCR s=0.5
|
|
$250B-$700B
|
BTFP Only
|
1
|
1
|
0
|
0
|
|
DW Only
|
1
|
0
|
0
|
0
|
|
Non-Borrower
|
3
|
1
|
1
|
0
|
|
$100B-$250B
|
BTFP Only
|
2
|
0
|
0
|
0
|
|
DW Only
|
2
|
2
|
1
|
0
|
|
Both
|
2
|
1
|
0
|
0
|
|
Non-Borrower
|
7
|
5
|
3
|
1
|
|
$50B-$100B
|
BTFP Only
|
4
|
1
|
0
|
0
|
|
DW Only
|
1
|
0
|
0
|
0
|
|
Both
|
2
|
1
|
1
|
0
|
|
Non-Borrower
|
8
|
6
|
3
|
1
|
|
$20B-$50B
|
BTFP Only
|
7
|
5
|
1
|
1
|
|
DW Only
|
4
|
2
|
1
|
0
|
|
Both
|
7
|
3
|
2
|
1
|
|
Non-Borrower
|
27
|
8
|
5
|
1
|
|
$10B-$20B
|
BTFP Only
|
6
|
4
|
1
|
0
|
|
DW Only
|
16
|
7
|
4
|
1
|
|
Both
|
9
|
4
|
2
|
0
|
|
Non-Borrower
|
26
|
11
|
8
|
3
|
|
$5B-$10B
|
BTFP Only
|
14
|
10
|
6
|
2
|
|
DW Only
|
17
|
11
|
8
|
2
|
|
Both
|
7
|
7
|
2
|
1
|
|
Non-Borrower
|
74
|
34
|
17
|
4
|
|
$3B-$5B
|
BTFP Only
|
13
|
7
|
2
|
0
|
|
DW Only
|
25
|
14
|
8
|
3
|
|
Both
|
3
|
2
|
1
|
0
|
|
Non-Borrower
|
73
|
43
|
21
|
2
|
|
$1B-$3B
|
BTFP Only
|
78
|
54
|
26
|
3
|
|
DW Only
|
70
|
39
|
22
|
7
|
|
Both
|
27
|
18
|
6
|
1
|
|
Non-Borrower
|
387
|
217
|
112
|
17
|
|
$500M-$1B
|
BTFP Only
|
81
|
48
|
24
|
3
|
|
DW Only
|
59
|
36
|
21
|
4
|
|
Both
|
14
|
9
|
3
|
0
|
|
Non-Borrower
|
563
|
291
|
189
|
24
|
|
Below $500M
|
BTFP Only
|
162
|
94
|
47
|
4
|
|
DW Only
|
104
|
56
|
34
|
4
|
|
Both
|
23
|
14
|
6
|
0
|
|
Non-Borrower
|
2363
|
949
|
622
|
89
|
# Export to LaTeX
latex_acute <- c(
"\\begin{table}[htbp]",
"\\centering",
"\\caption{Borrowers by Asset Size and Insolvency Status: Acute Period (March 13--May 1, 2023)}",
"\\label{tab:borrower_size_insolvency_acute}",
"\\footnotesize",
"\\begin{tabular}{llrrrr}",
"\\hline\\hline",
"Asset Size & Borrower Type & N & MV Insol. & IDCR s=1.0 & IDCR s=0.5 \\\\",
"\\hline"
)
current_size <- ""
for (i in 1:nrow(table1_comprehensive)) {
row <- table1_comprehensive[i, ]
size_display <- if (row$size_category != current_size) as.character(row$size_category) else ""
current_size <- row$size_category
latex_acute <- c(
latex_acute,
sprintf("%s & %s & %d & %d & %d & %d \\\\",
size_display,
row$borrower_type,
row$N,
row$MV_Insolvent,
row$IDCR_s100_Insolvent,
row$IDCR_s50_Insolvent)
)
# Add midrule between size categories
if (i < nrow(table1_comprehensive) &&
table1_comprehensive$size_category[i+1] != current_size) {
latex_acute <- c(latex_acute, "\\midrule")
}
}
latex_acute <- c(
latex_acute,
"\\hline\\hline",
"\\end{tabular}",
"\\begin{minipage}{0.95\\textwidth}",
"\\smallskip",
"\\footnotesize",
"\\textit{Note:} This table reports the number of banks by asset size, borrower type, and insolvency status",
"during the acute crisis period (March 13--May 1, 2023). MV Insol. = Mark-to-market insolvency",
"(adjusted book value < 0). IDCR s=1.0 = Insolvent under 100\\% uninsured depositor run.",
"IDCR s=0.5 = Insolvent under 50\\% uninsured depositor run. All insolvency measures based on 2022Q4",
"balance sheet data. Sample excludes G-SIBs, failed banks, and banks without BTFP-eligible securities.",
"\\end{minipage}",
"\\end{table}"
)
writeLines(latex_acute, file.path(TABLE_PATH, "borrower_size_insolvency_acute.tex"))
cat("\nAcute period table saved to:", file.path(TABLE_PATH, "borrower_size_insolvency_acute.tex"), "\n")
##
## Acute period table saved to: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/borrower_size_insolvency_acute.tex
# --------------------------------------------------------------------------
# TABLE 2: JANUARY 1 - MARCH 31, 2024
# Includes BTFP, DW, and FHLB (10% threshold)
# --------------------------------------------------------------------------
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("TABLE 2: BORROWERS BY SIZE AND INSOLVENCY - JAN 1 - MARCH 31, 2024\n")
## TABLE 2: BORROWERS BY SIZE AND INSOLVENCY - JAN 1 - MARCH 31, 2024
cat(strrep("=", 70), "\n\n")
## ======================================================================
# Define period
period_2024_start <- as.Date("2024-01-01")
period_2024_end <- as.Date("2024-03-31")
# Identify borrowers
btfp_2024 <- btfp_loans_raw %>%
filter(btfp_loan_date >= period_2024_start & btfp_loan_date <= period_2024_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
dw_2024 <- dw_loans_raw %>%
filter(dw_loan_date >= period_2024_start & dw_loan_date <= period_2024_end) %>%
distinct(rssd_id) %>%
pull(rssd_id)
fhlb_borrowers_10pct <- call_q %>%
filter(period == '2022Q4') %>%
filter(
gsib == 0 | is.na(gsib),
failed_bank == 0 | is.na(failed_bank),
!is.na(omo_eligible) & omo_eligible > 0,
!is.na(abnormal_fhlb_borrowing_10pct) & abnormal_fhlb_borrowing_10pct > 0
) %>%
pull(idrssd)
cat(sprintf("BTFP borrowers: %d\n", length(btfp_2024)))
## BTFP borrowers: 717
cat(sprintf("DW borrowers: %d\n", length(dw_2024)))
## DW borrowers: 0
cat(sprintf("FHLB borrowers (10%% threshold): %d\n", length(fhlb_borrowers_10pct)))
## FHLB borrowers (10% threshold): 302
# Add borrower classification
data_2024 <- baseline_insolvency %>%
mutate(
btfp_user = idrssd %in% btfp_2024,
dw_user = idrssd %in% dw_2024,
fhlb_user = idrssd %in% fhlb_borrowers_10pct,
borrower_type = case_when(
btfp_user & dw_user & fhlb_user ~ "All Three",
btfp_user & dw_user & !fhlb_user ~ "BTFP+DW",
btfp_user & !dw_user & fhlb_user ~ "BTFP+FHLB",
!btfp_user & dw_user & fhlb_user ~ "DW+FHLB",
btfp_user & !dw_user & !fhlb_user ~ "BTFP Only",
!btfp_user & dw_user & !fhlb_user ~ "DW Only",
!btfp_user & !dw_user & fhlb_user ~ "FHLB Only",
TRUE ~ "Non-Borrower"
),
borrower_type = factor(borrower_type,
levels = c("BTFP Only", "DW Only", "FHLB Only",
"BTFP+DW", "BTFP+FHLB", "DW+FHLB",
"All Three", "Non-Borrower"))
)
# Create comprehensive table
table2_comprehensive <- data_2024 %>%
group_by(size_category, borrower_type) %>%
summarise(
N = n(),
MV_Insolvent = sum(mv_insolvent, na.rm = TRUE),
IDCR_s100_Insolvent = sum(idcr_insolvent_s100, na.rm = TRUE),
IDCR_s50_Insolvent = sum(idcr_insolvent_s50, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(size_category, borrower_type)
# Display comprehensive table
cat("\n--- Comprehensive Table: All Insolvency Measures ---\n")
##
## --- Comprehensive Table: All Insolvency Measures ---
table2_comprehensive %>%
kable(
caption = "Table 2: Borrowers by Size and Insolvency Status - January 1 - March 31, 2024",
col.names = c("Asset Size", "Borrower Type", "N", "MV Insolvent", "IDCR s=1.0", "IDCR s=0.5"),
align = c("l", "l", rep("r", 4))
) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
collapse_rows(columns = 1, valign = "top") %>%
scroll_box(width = "100%")
Table 2: Borrowers by Size and Insolvency Status - January 1 - March 31,
2024
|
Asset Size
|
Borrower Type
|
N
|
MV Insolvent
|
IDCR s=1.0
|
IDCR s=0.5
|
|
$250B-$700B
|
BTFP Only
|
1
|
0
|
0
|
0
|
|
Non-Borrower
|
4
|
2
|
1
|
0
|
|
$100B-$250B
|
FHLB Only
|
1
|
0
|
0
|
0
|
|
Non-Borrower
|
12
|
8
|
4
|
1
|
|
$50B-$100B
|
BTFP Only
|
1
|
0
|
0
|
0
|
|
FHLB Only
|
2
|
1
|
1
|
0
|
|
Non-Borrower
|
12
|
7
|
3
|
1
|
|
$20B-$50B
|
BTFP Only
|
10
|
5
|
3
|
1
|
|
FHLB Only
|
7
|
4
|
1
|
0
|
|
BTFP+FHLB
|
1
|
0
|
0
|
0
|
|
Non-Borrower
|
27
|
9
|
5
|
2
|
|
$10B-$20B
|
BTFP Only
|
13
|
6
|
4
|
0
|
|
FHLB Only
|
7
|
2
|
2
|
0
|
|
BTFP+FHLB
|
2
|
1
|
0
|
0
|
|
Non-Borrower
|
35
|
17
|
9
|
4
|
|
$5B-$10B
|
BTFP Only
|
29
|
15
|
7
|
2
|
|
FHLB Only
|
11
|
4
|
4
|
1
|
|
BTFP+FHLB
|
3
|
1
|
0
|
0
|
|
Non-Borrower
|
69
|
42
|
22
|
6
|
|
$3B-$5B
|
BTFP Only
|
24
|
14
|
2
|
0
|
|
FHLB Only
|
8
|
3
|
3
|
0
|
|
BTFP+FHLB
|
2
|
1
|
0
|
0
|
|
Non-Borrower
|
80
|
48
|
27
|
5
|
|
$1B-$3B
|
BTFP Only
|
124
|
77
|
37
|
4
|
|
FHLB Only
|
31
|
14
|
9
|
3
|
|
BTFP+FHLB
|
19
|
10
|
5
|
0
|
|
Non-Borrower
|
388
|
227
|
115
|
21
|
|
$500M-$1B
|
BTFP Only
|
137
|
86
|
51
|
7
|
|
FHLB Only
|
40
|
23
|
11
|
1
|
|
BTFP+FHLB
|
17
|
8
|
6
|
2
|
|
Non-Borrower
|
523
|
267
|
169
|
21
|
|
Below $500M
|
BTFP Only
|
281
|
157
|
92
|
11
|
|
FHLB Only
|
131
|
49
|
30
|
5
|
|
BTFP+FHLB
|
20
|
12
|
6
|
2
|
|
Non-Borrower
|
2220
|
895
|
581
|
79
|
# Export to LaTeX
latex_2024 <- c(
"\\begin{table}[htbp]",
"\\centering",
"\\caption{Borrowers by Asset Size and Insolvency Status: January 1--March 31, 2024}",
"\\label{tab:borrower_size_insolvency_2024q1}",
"\\footnotesize",
"\\begin{tabular}{llrrrr}",
"\\hline\\hline",
"Asset Size & Borrower Type & N & MV Insol. & IDCR s=1.0 & IDCR s=0.5 \\\\",
"\\hline"
)
current_size <- ""
for (i in 1:nrow(table2_comprehensive)) {
row <- table2_comprehensive[i, ]
size_display <- if (row$size_category != current_size) as.character(row$size_category) else ""
current_size <- row$size_category
latex_2024 <- c(
latex_2024,
sprintf("%s & %s & %d & %d & %d & %d \\\\",
size_display,
row$borrower_type,
row$N,
row$MV_Insolvent,
row$IDCR_s100_Insolvent,
row$IDCR_s50_Insolvent)
)
# Add midrule between size categories
if (i < nrow(table2_comprehensive) &&
table2_comprehensive$size_category[i+1] != current_size) {
latex_2024 <- c(latex_2024, "\\midrule")
}
}
latex_2024 <- c(
latex_2024,
"\\hline\\hline",
"\\end{tabular}",
"\\begin{minipage}{0.95\\textwidth}",
"\\smallskip",
"\\footnotesize",
"\\textit{Note:} This table reports the number of banks by asset size, borrower type, and insolvency status",
"during January 1--March 31, 2024. MV Insol. = Mark-to-market insolvency (adjusted book value < 0).",
"IDCR s=1.0 = Insolvent under 100\\% uninsured depositor run. IDCR s=0.5 = Insolvent under 50\\% uninsured",
"depositor run. All insolvency measures based on 2022Q4 balance sheet data. FHLB borrowers identified",
"using 10\\% threshold (90th percentile). Sample excludes G-SIBs, failed banks, and banks without",
"BTFP-eligible securities.",
"\\end{minipage}",
"\\end{table}"
)
writeLines(latex_2024, file.path(TABLE_PATH, "borrower_size_insolvency_2024q1.tex"))
cat("\n2024 period table saved to:", file.path(TABLE_PATH, "borrower_size_insolvency_2024q1.tex"), "\n")
##
## 2024 period table saved to: C:/Users/mferdo2/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/borrowing_t_stat/tables/borrower_size_insolvency_2024q1.tex
# --------------------------------------------------------------------------
# SUMMARY STATISTICS
# --------------------------------------------------------------------------
cat("\n", strrep("=", 70), "\n")
##
## ======================================================================
cat("SUMMARY STATISTICS BY BORROWER TYPE AND INSOLVENCY\n")
## SUMMARY STATISTICS BY BORROWER TYPE AND INSOLVENCY
cat(strrep("=", 70), "\n\n")
## ======================================================================
cat("--- Acute Period ---\n")
## --- Acute Period ---
acute_summary <- table1_comprehensive %>%
group_by(borrower_type) %>%
summarise(
Total = sum(N),
MV_Insol = sum(MV_Insolvent),
MV_Pct = 100 * MV_Insol / Total,
IDCR_100 = sum(IDCR_s100_Insolvent),
IDCR_100_Pct = 100 * IDCR_100 / Total,
IDCR_50 = sum(IDCR_s50_Insolvent),
IDCR_50_Pct = 100 * IDCR_50 / Total,
.groups = "drop"
)
print(acute_summary)
## # A tibble: 4 × 8
## borrower_type Total MV_Insol MV_Pct IDCR_100 IDCR_100_Pct IDCR_50 IDCR_50_Pct
## <fct> <int> <int> <dbl> <int> <dbl> <int> <dbl>
## 1 BTFP Only 368 224 60.9 107 29.1 13 3.53
## 2 DW Only 299 167 55.9 99 33.1 21 7.02
## 3 Both 94 59 62.8 23 24.5 3 3.19
## 4 Non-Borrower 3531 1565 44.3 981 27.8 142 4.02
cat("\n--- January 1 - March 31, 2024 ---\n")
##
## --- January 1 - March 31, 2024 ---
summary_2024 <- table2_comprehensive %>%
group_by(borrower_type) %>%
summarise(
Total = sum(N),
MV_Insol = sum(MV_Insolvent),
MV_Pct = 100 * MV_Insol / Total,
IDCR_100 = sum(IDCR_s100_Insolvent),
IDCR_100_Pct = 100 * IDCR_100 / Total,
IDCR_50 = sum(IDCR_s50_Insolvent),
IDCR_50_Pct = 100 * IDCR_50 / Total,
.groups = "drop"
)
print(summary_2024)
## # A tibble: 4 × 8
## borrower_type Total MV_Insol MV_Pct IDCR_100 IDCR_100_Pct IDCR_50 IDCR_50_Pct
## <fct> <int> <int> <dbl> <int> <dbl> <int> <dbl>
## 1 BTFP Only 620 360 58.1 196 31.6 25 4.03
## 2 FHLB Only 238 100 42.0 61 25.6 10 4.20
## 3 BTFP+FHLB 64 33 51.6 17 26.6 4 6.25
## 4 Non-Borrower 3370 1522 45.2 936 27.8 140 4.15
cat("\n=== TABLES GENERATED SUCCESSFULLY ===\n")
##
## === TABLES GENERATED SUCCESSFULLY ===