1 Analysis Map

1.1 Main Results: Extensive Margin (Crisis Period)

Four solvency frameworks × four borrower types:

Framework Solvency Definition Columns
A. Full Sample No split (all banks) 4 columns: AnyFed, BTFP, DW, FHLB
B. Jiang MTM AE = Book Equity/TA − MTM/TA ≥ 0 8 columns: 4 × {Solvent, Insolvent}
C. Jiang IDCR-100% (MV Assets − Uninsured − Insured) / Insured ≥ 0 8 columns: 4 × {Solvent, Insolvent}
D. DSSW Franchise AE + DFV ≥ 0, where DFV = (1−β)×D/TA Diagnostic table (prediction: 0 insolvent)

1.2 Additional Tests

Test Description Solvency Splits
Temporal BTFP & DW: Crisis vs. Arbitrage Full + Jiang + IDCR-100%
Deposit Beta Triple interaction: MTM × Uninsured × β^U Full + Jiang + IDCR-100%
Facility Complementarity Multinomial choice, DW→BTFP complement, substitution Full sample

1.3 DSSW Theoretical Note

The DSSW (2023/2025) deposit franchise value for bank \(i\) in cross-section: \[\text{DFV}_i = (1 - \beta_i) \times \frac{D_i}{TA_i}\]

Full formula: \(F = D \times [(1-\beta) - c/r] \times [1 - 1/(1+r)^T]\) where \(c \approx 2\%\), \(r\) = long rate, \(T\) = deposit runoff horizon. Since \(c\), \(r\), \(T\) are constant cross-sectionally, all bank-level variation comes from \(\beta_i\) and \(D_i/TA_i\).

Key insight: DFV exists only in the no-run equilibrium. If depositors run, the uninsured franchise is destroyed. A bank that is DSSW-solvent absent a run can become insolvent during one — this is the panic region.


2 SETUP

2.1 Packages

rm(list = ls())

library(data.table)
library(dplyr)
library(tidyr)
library(stringr)
library(lubridate)
library(purrr)
library(tibble)
library(ggrepel)
library(fixest)
library(marginaleffects)
library(nnet)
library(broom)
library(modelsummary)
library(knitr)
library(kableExtra)
library(DescTools)
library(ggplot2)
library(gridExtra)
library(scales)
library(patchwork)
library(readr)
library(readxl)

cat("All packages loaded.\n")
## All packages loaded.

2.2 Helper Functions

winsorize <- function(x, probs = c(0.025, 0.975)) {

if (all(is.na(x))) return(x)
  q <- quantile(x, probs = probs, na.rm = TRUE, names = FALSE)
  pmax(pmin(x, q[2]), q[1])
}

standardize_z <- function(x) {
  if (all(is.na(x))) return(x)
  (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)
}

safe_div <- function(num, denom, default = NA_real_) {
  ifelse(is.na(denom) | denom == 0, default, num / denom)
}

create_size_category_3 <- function(assets_thousands) {
  assets_millions <- assets_thousands / 1000
  case_when(
    assets_millions >= 100000 ~ "Large (>$100B)",
    assets_millions >= 1000   ~ "Medium ($1B-$100B)",
    TRUE                      ~ "Small (<$1B)"
  )
}
size_levels_3 <- c("Small (<$1B)", "Medium ($1B-$100B)", "Large (>$100B)")

format_pval <- function(p) {
  case_when(is.na(p) ~ "", p < 0.01 ~ "***", p < 0.05 ~ "**", p < 0.10 ~ "*", TRUE ~ "")
}

safe_writeLines <- function(text, con, max_retries = 5, wait_sec = 2) {
  for (i in seq_len(max_retries)) {
    result <- tryCatch(
      { writeLines(text, con); TRUE },
      error = function(e) {
        if (i < max_retries) Sys.sleep(wait_sec)
        FALSE
      }
    )
    if (isTRUE(result)) return(invisible(NULL))
  }
  warning("Failed to write ", con, " after ", max_retries, " attempts.")
}

save_figure <- function(plot_obj, filename, width = 12, height = 8) {
  ggsave(
    file.path(FIG_PATH, paste0(filename, ".pdf")),
    plot = plot_obj, width = width, height = height, device = "pdf"
  )
  message("Saved: ", filename, ".pdf")
}

2.3 Paths

BASE_PATH   <- "C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025"
DATA_PROC   <- file.path(BASE_PATH, "01_data/processed")
OUTPUT_PATH <- file.path(BASE_PATH, "03_documentation/Comprehensive_Analysis")
TABLE_PATH  <- file.path(OUTPUT_PATH, "tables")
FIG_PATH    <- file.path(OUTPUT_PATH, "figures")

for (path in c(TABLE_PATH, FIG_PATH)) {
  if (!dir.exists(path)) dir.create(path, recursive = TRUE)
}

2.4 Key Dates

BASELINE_MAIN <- "2022Q4"
BASELINE_ARB  <- "2023Q3"

CRISIS_START     <- as.Date("2023-03-08")
CRISIS_END       <- as.Date("2023-05-04")
ARB_START        <- as.Date("2023-11-15")
ARB_END          <- as.Date("2024-01-24")
DW_DATA_END      <- as.Date("2023-12-31")

cat("Crisis:", format(CRISIS_START), "to", format(CRISIS_END), "\n")
## Crisis: 2023-03-08 to 2023-05-04
cat("Arbitrage:", format(ARB_START), "to", format(ARB_END), "\n")
## Arbitrage: 2023-11-15 to 2024-01-24

3 DATA LOADING

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))

dssw_betas <- read_csv(file.path(DATA_PROC, "dssw_deposit_betas.csv"), show_col_types = FALSE) %>%
  mutate(idrssd = as.character(idrssd))

dssw_beta_2022q4 <- dssw_betas %>% filter(estimation_date == "2022Q4") %>%
  select(idrssd, beta_overall, beta_insured, beta_uninsured,
         beta_insured_w, beta_uninsured_w, gamma_hat, alpha_hat)

# Public bank flag (from NY Fed CRSP-FRB link via NIC hierarchy)
public_flag <- read_csv(file.path(DATA_PROC, "public_bank_flag.csv"), show_col_types = FALSE) %>%
  mutate(idrssd = as.character(idrssd)) %>%
  select(idrssd, period, is_public)

cat("=== DATA LOADED ===\n")
## === DATA LOADED ===
cat("Call Report:", nrow(call_q), "obs |", n_distinct(call_q$idrssd), "banks\n")
## Call Report: 75989 obs | 5074 banks
cat("BTFP Loans:", nrow(btfp_loans_raw), "\n")
## BTFP Loans: 6734
cat("DW Loans:", nrow(dw_loans_raw), "\n")
## DW Loans: 10008
cat("Public flag:", n_distinct(public_flag$idrssd[public_flag$is_public == 1]), "public banks\n")
## Public flag: 427 public banks

3.1 Exclusions

excluded_banks <- call_q %>%
  filter(period == BASELINE_MAIN, failed_bank == 1 | gsib == 1) %>%
  pull(idrssd)

btfp_loans <- btfp_loans_raw %>% filter(!rssd_id %in% excluded_banks)
dw_loans   <- dw_loans_raw   %>% filter(!rssd_id %in% excluded_banks)

cat("Excluded banks:", length(excluded_banks), "\n")
## Excluded banks: 41

4 BORROWER INDICATORS

create_borrower_indicator <- function(loans_df, date_col, id_col, amount_col,
                                      start_date, end_date, prefix) {
  loans_df %>%
    filter(!!sym(date_col) >= start_date, !!sym(date_col) <= end_date) %>%
    group_by(!!sym(id_col)) %>%
    summarise(
      "{prefix}"       := 1L,
      "{prefix}_amt"   := sum(!!sym(amount_col), na.rm = TRUE),
      "{prefix}_first" := min(!!sym(date_col)),
      .groups = "drop"
    ) %>%
    rename(idrssd = !!sym(id_col))
}

btfp_crisis <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", CRISIS_START, CRISIS_END, "btfp_crisis")
btfp_arb    <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", ARB_START, ARB_END, "btfp_arb")
dw_crisis   <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", CRISIS_START, min(CRISIS_END, DW_DATA_END), "dw_crisis")
dw_arb      <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", ARB_START, DW_DATA_END, "dw_arb")

cat("BTFP Crisis:", nrow(btfp_crisis), "| Arb:", nrow(btfp_arb), "\n")
## BTFP Crisis: 526 | Arb: 780
cat("DW Crisis:", nrow(dw_crisis), "| Arb:", nrow(dw_arb), "\n")
## DW Crisis: 459 | Arb: 389

5 VARIABLE CONSTRUCTION

construct_analysis_vars <- function(baseline_data) {
  baseline_data %>%
    mutate(
      # === RAW VARIABLES ===
      mtm_total_raw         = mtm_loss_to_total_asset,
      mtm_btfp_raw          = mtm_loss_omo_eligible_to_total_asset,
      mtm_other_raw         = mtm_loss_non_omo_eligible_to_total_asset,
      uninsured_lev_raw     = uninsured_deposit_to_total_asset,
      insured_lev_raw       = r_insured_deposit,
      uninsured_share_raw   = uninsured_to_deposit,
      ln_assets_raw         = log(total_asset),
      cash_ratio_raw        = cash_to_total_asset,
      securities_ratio_raw  = security_to_total_asset,
      loan_ratio_raw        = total_loan_to_total_asset,
      book_equity_ratio_raw = book_equity_to_total_asset,
      roa_raw               = roa,
      fhlb_ratio_raw        = fhlb_to_total_asset,
      loan_to_deposit_raw   = loan_to_deposit,
      wholesale_raw = safe_div(
        fed_fund_purchase + repo + replace_na(other_borrowed_less_than_1yr, 0),
        total_liability, 0) * 100,

      # === SOLVENCY FRAMEWORK A: Jiang MTM Adjusted Equity ===
      adjusted_equity_raw = book_equity_to_total_asset - mtm_loss_to_total_asset,
      mtm_insolvent       = as.integer(adjusted_equity_raw < 0),
      mtm_solvent         = as.integer(adjusted_equity_raw >= 0),

      # === SOLVENCY FRAMEWORK B: Jiang IDCR (100% uninsured run) ===
      mv_assets = total_asset * (1 - mtm_loss_to_total_asset / 100),
      idcr_100  = safe_div(
        mv_assets - uninsured_deposit - insured_deposit,
        insured_deposit, NA_real_
      ),
      insolvent_idcr_100 = as.integer(idcr_100 < 0),
      solvent_idcr_100   = as.integer(idcr_100 >= 0),

      # === SOLVENCY FRAMEWORK C: DSSW Deposit Franchise Value ===
      # DFV_i = (1 - β_i) × D_i / TA_i (cross-sectional DSSW simplification)
      # Full: F = D × [(1-β) - c/r] × [1 - 1/(1+r)^T]; c,r,T constant cross-sectionally
      # CRITICAL: DFV exists ONLY in the no-run equilibrium.
      # If depositors run, uninsured franchise is destroyed → back to Jiang measure.
      dfv_raw = ifelse(!is.na(beta_overall),
        (1 - beta_overall) * (dom_deposit / total_asset) * 100, NA_real_),
      adjusted_equity_dssw_raw = ifelse(!is.na(dfv_raw),
        book_equity_to_total_asset - mtm_loss_to_total_asset + dfv_raw, NA_real_),
      dssw_insolvent = as.integer(!is.na(adjusted_equity_dssw_raw) & adjusted_equity_dssw_raw < 0),
      dssw_solvent   = as.integer(!is.na(adjusted_equity_dssw_raw) & adjusted_equity_dssw_raw >= 0),

      # === UNINSURED DEPOSIT BETA (for triple interaction) ===
      # Use truly raw (unwinsorized) beta from DSSW decomposition;
      # the Rmd's own winsorize() at 2.5/97.5 is the single winsorization step,
      # consistent with all other variables in the pipeline.
      uninsured_beta_raw = ifelse(!is.na(beta_uninsured), beta_uninsured, NA_real_),

      # === WINSORIZED ===
      mtm_total_w         = winsorize(mtm_total_raw),
      mtm_btfp_w          = winsorize(mtm_btfp_raw),
      mtm_other_w         = winsorize(mtm_other_raw),
      uninsured_lev_w     = winsorize(uninsured_lev_raw),
      insured_lev_w       = winsorize(r_insured_deposit),
      adjusted_equity_w   = winsorize(adjusted_equity_raw),
      dfv_w               = winsorize(dfv_raw),
      adjusted_equity_dssw_w = winsorize(adjusted_equity_dssw_raw),
      uninsured_beta_w    = winsorize(uninsured_beta_raw),
      ln_assets_w         = winsorize(ln_assets_raw),
      cash_ratio_w        = winsorize(cash_ratio_raw),
      book_equity_ratio_w = winsorize(book_equity_ratio_raw),
      roa_w               = winsorize(roa_raw),
      loan_to_deposit_w   = winsorize(loan_to_deposit_raw),
      wholesale_w         = winsorize(wholesale_raw),

      # === Z-STANDARDIZED ===
      mtm_total       = standardize_z(mtm_total_w),
      uninsured_lev   = standardize_z(uninsured_lev_w),
      insured_lev     = standardize_z(insured_lev_w),
      adjusted_equity = standardize_z(adjusted_equity_w),
      dfv             = standardize_z(dfv_w),
      adjusted_equity_dssw = standardize_z(adjusted_equity_dssw_w),
      uninsured_beta  = standardize_z(uninsured_beta_w),
      ln_assets       = standardize_z(ln_assets_w),
      cash_ratio      = standardize_z(cash_ratio_w),
      book_equity_ratio = standardize_z(book_equity_ratio_w),
      roa             = standardize_z(roa_w),
      loan_to_deposit = standardize_z(loan_to_deposit_w),
      wholesale       = standardize_z(wholesale_w),

      # === INTERACTIONS ===
      mtm_x_uninsured     = mtm_total * uninsured_lev,
      mtm_x_insured       = mtm_total * insured_lev,
      mtm_x_unins_beta    = mtm_total * uninsured_beta,
      unins_x_unins_beta  = uninsured_lev * uninsured_beta,
      mtm_x_unins_x_beta  = mtm_total * uninsured_lev * uninsured_beta,

      # === PAR BENEFIT & COLLATERAL ===
      par_benefit_raw = safe_div(mtm_btfp_raw,
        mtm_btfp_raw + 100 * safe_div(omo_eligible, total_asset * 1000, 0), NA_real_),
      collateral_capacity_raw = safe_div(omo_eligible, total_asset * 1000, 0) * 100,

      size_cat = factor(create_size_category_3(total_asset), levels = size_levels_3)
    ) %>%
    mutate(
      par_benefit_w       = winsorize(par_benefit_raw),
      par_benefit         = standardize_z(par_benefit_w),
      collateral_capacity_w = winsorize(collateral_capacity_raw),
      collateral_capacity = standardize_z(collateral_capacity_w),
      par_x_uninsured     = par_benefit * uninsured_lev,

      # === PAR RECAPITALIZATION (BTFP par lending − market value) / TA ===
      # This is the actual capital injection from BTFP's face-value lending:
      # a bank pledging OMO-eligible securities with MTM losses gets
      # par_recap dollars of extra liquidity per dollar of TA vs. market lending (DW).
      par_recap           = standardize_z(mtm_btfp_w),
      par_recap_x_unins   = par_recap * uninsured_lev,
      par_recap_x_mtm_ui  = par_recap * mtm_x_uninsured
    )
}

6 BUILD DATASETS

df_2022q4 <- call_q %>%
  filter(period == BASELINE_MAIN, !idrssd %in% excluded_banks,
         !is.na(omo_eligible) & omo_eligible > 0) %>%
  left_join(dssw_beta_2022q4, by = "idrssd") %>%
  left_join(public_flag %>% filter(period == "2022Q4") %>% select(idrssd, is_public),
            by = "idrssd") %>%
  mutate(is_public = replace_na(is_public, 0L)) %>%
  construct_analysis_vars()

df_2023q3 <- call_q %>%
  filter(period == BASELINE_ARB, !idrssd %in% excluded_banks,
         !is.na(omo_eligible) & omo_eligible > 0) %>%
  left_join(dssw_beta_2022q4, by = "idrssd") %>%
  left_join(public_flag %>% filter(period == "2023Q3") %>% select(idrssd, is_public),
            by = "idrssd") %>%
  mutate(is_public = replace_na(is_public, 0L)) %>%
  construct_analysis_vars()

cat("=== BASELINES ===\n")
## === BASELINES ===
cat("2022Q4:", nrow(df_2022q4), "banks\n")
## 2022Q4: 4292 banks
cat("  MTM Insolvent:", sum(df_2022q4$mtm_insolvent, na.rm=TRUE), "\n")
##   MTM Insolvent: 825
cat("  IDCR-100% Insolvent:", sum(df_2022q4$insolvent_idcr_100, na.rm=TRUE), "\n")
##   IDCR-100% Insolvent: 364
cat("  DSSW Insolvent:", sum(df_2022q4$dssw_insolvent, na.rm=TRUE), "\n")
##   DSSW Insolvent: 0
cat("  Beta coverage:", sum(!is.na(df_2022q4$beta_overall)), "\n")
##   Beta coverage: 4226
cat("  Public banks:", sum(df_2022q4$is_public, na.rm=TRUE), "\n")
##   Public banks: 311
cat("  Non-public banks:", sum(df_2022q4$is_public == 0, na.rm=TRUE), "\n")
##   Non-public banks: 3981
join_all_borrowers <- function(df_base, btfp_df, dw_df, btfp_var, dw_var) {
  df_base %>%
    left_join(btfp_df %>% select(idrssd, starts_with(btfp_var)), by = "idrssd") %>%
    left_join(dw_df   %>% select(idrssd, starts_with(dw_var)),   by = "idrssd") %>%
    mutate(
      "{btfp_var}" := replace_na(!!sym(btfp_var), 0L),
      "{dw_var}"   := replace_na(!!sym(dw_var),   0L),
      fhlb_user = as.integer(abnormal_fhlb_borrowing_10pct == 1),
      any_fed  = as.integer(!!sym(btfp_var) == 1 | !!sym(dw_var) == 1),
      both_fed = as.integer(!!sym(btfp_var) == 1 & !!sym(dw_var) == 1),
      user_group = factor(case_when(
        both_fed == 1 ~ "Both",
        !!sym(btfp_var) == 1 ~ "BTFP_Only",
        !!sym(dw_var)   == 1 ~ "DW_Only",
        TRUE ~ "Neither"
      ), levels = c("Neither", "BTFP_Only", "DW_Only", "Both")),
      non_user = as.integer(any_fed == 0 & fhlb_user == 0)
    )
}

# Crisis
df_crisis <- join_all_borrowers(df_2022q4, btfp_crisis, dw_crisis, "btfp_crisis", "dw_crisis") %>%
  mutate(
    btfp_pct = ifelse(btfp_crisis == 1 & btfp_crisis_amt > 0,
      100 * btfp_crisis_amt / (total_asset * 1000), NA_real_),
    dw_pct = ifelse(dw_crisis == 1 & dw_crisis_amt > 0,
      100 * dw_crisis_amt / (total_asset * 1000), NA_real_)
  )

# Arbitrage
df_arb <- df_2023q3 %>%
  left_join(btfp_arb %>% select(idrssd, btfp_arb, btfp_arb_amt), by = "idrssd") %>%
  left_join(dw_arb   %>% select(idrssd, dw_arb),                 by = "idrssd") %>%
  mutate(
    btfp_arb  = replace_na(btfp_arb, 0L),
    dw_arb    = replace_na(dw_arb, 0L),
    fhlb_user = as.integer(abnormal_fhlb_borrowing_10pct == 1),
    any_fed   = as.integer(btfp_arb == 1 | dw_arb == 1),
    non_user  = as.integer(any_fed == 0 & fhlb_user == 0),
    user_group = factor(case_when(
      btfp_arb == 1 & dw_arb == 1 ~ "Both",
      btfp_arb == 1 ~ "BTFP_Only",
      dw_arb   == 1 ~ "DW_Only",
      TRUE ~ "Neither"
    ), levels = c("Neither", "BTFP_Only", "DW_Only", "Both"))
  )

cat("=== PERIOD COUNTS ===\n")
## === PERIOD COUNTS ===
cat("Crisis:", nrow(df_crisis), "| BTFP:", sum(df_crisis$btfp_crisis),
    "| DW:", sum(df_crisis$dw_crisis), "| Any:", sum(df_crisis$any_fed), "\n")
## Crisis: 4292 | BTFP: 501 | DW: 433 | Any: 828
cat("Arb:", nrow(df_arb), "| BTFP:", sum(df_arb$btfp_arb),
    "| DW:", sum(df_arb$dw_arb), "\n")
## Arb: 4214 | BTFP: 749 | DW: 362

7 REGRESSION INFRASTRUCTURE

CONTROLS <- "ln_assets + cash_ratio + loan_to_deposit + book_equity_ratio + wholesale + roa"

EXPL_BASE <- "mtm_total + uninsured_lev + mtm_x_uninsured"

# Triple interaction for deposit beta channel
EXPL_BETA_FULL <- paste0(
  "mtm_total + uninsured_lev + uninsured_beta + ",
  "mtm_x_uninsured + mtm_x_unins_beta + unins_x_unins_beta + ",
  "mtm_x_unins_x_beta")

EXPL_BETA_NESTED <- paste0(
  "mtm_total + uninsured_lev + uninsured_beta + ",
  "mtm_x_uninsured + mtm_x_unins_beta + unins_x_unins_beta")

# Facility choice
EXPL_FACILITY <- "mtm_total + uninsured_lev + mtm_x_uninsured + par_benefit + collateral_capacity"

setFixest_dict(c(
  mtm_total           = "MTM Loss (z)",
  uninsured_lev       = "Uninsured Leverage (z)",
  insured_lev         = "Insured Leverage (z)",
  uninsured_beta      = "Uninsured $\\beta$ (z)",
  mtm_x_uninsured     = "MTM $\\times$ Uninsured",
  mtm_x_insured       = "MTM $\\times$ Insured",
  mtm_x_unins_beta    = "MTM $\\times$ Unins. $\\beta$",
  unins_x_unins_beta  = "Uninsured $\\times$ Unins. $\\beta$",
  mtm_x_unins_x_beta  = "MTM $\\times$ Uninsured $\\times$ $\\beta^U$",
  par_benefit         = "Par Benefit (z)",
  collateral_capacity = "OMO Collateral (z)",
  par_x_uninsured     = "Par $\\times$ Uninsured",
  par_recap           = "Par Recap (z)",
  par_recap_x_unins   = "Par Recap $\\times$ Uninsured",
  par_recap_x_mtm_ui  = "Par Recap $\\times$ MTM $\\times$ UI",
  btfp_util           = "BTFP Utilization (z)",
  btfp_exhausted      = "BTFP Exhausted (>80\\%)",
  also_btfp           = "Also BTFP",
  also_dw             = "Also DW",
  adv_rate_z          = "Advance Rate (z)",
  dw_share_omo_z      = "DW OMO Share (z)",
  dw_share_loans_z    = "DW Loan Share (z)",
  ln_assets           = "Log(Assets)",
  cash_ratio          = "Cash Ratio",
  loan_to_deposit     = "Loan-to-Deposit",
  book_equity_ratio   = "Book Equity Ratio",
  wholesale           = "Wholesale Funding",
  roa                 = "ROA"
))

COEF_ORDER <- c("Constant", "MTM Loss", "Uninsured Leverage", "Uninsured.*beta",
  "MTM.*Uninsured$", "MTM.*Unins.*beta", "Uninsured.*Unins",
  "MTM.*Uninsured.*beta", "Par Benefit", "OMO Collateral")

# --- Model runner with safety ---
run_model <- function(data, dv, explanatory, family_type = "lpm", controls = CONTROLS) {
  ff <- as.formula(paste(dv, "~", explanatory, "+", controls))
  if (family_type == "lpm") {
    feols(ff, data = data, vcov = "hetero")
  } else {
    feglm(ff, data = data, family = binomial("logit"), vcov = "hetero")
  }
}

safe_run <- function(data, dv, explanatory, family_type = "lpm",
                     controls = CONTROLS, min_n = 30, min_dv1 = 5) {
  n_obs <- sum(!is.na(data[[dv]]))
  n_dv1 <- sum(data[[dv]] == 1, na.rm = TRUE)
  if (n_obs < min_n || n_dv1 < min_dv1) {
    message("  Skip: N=", n_obs, " DV=1:", n_dv1, " for ", dv)
    return(NULL)
  }
  tryCatch(
    run_model(data, dv, explanatory, family_type, controls),
    error = function(e) { message("  Error: ", e$message); NULL }
  )
}

# --- Save etable ---
save_etable <- function(models, filename, title_text, notes_text,
                        fitstat_use = ~ n + r2, extra_lines = NULL) {
  models <- models[!sapply(models, is.null)]
  if (length(models) == 0) { message("No models for ", filename); return(invisible(NULL)) }
  # Auto-compute N(DV=1) for each model
  dv1_counts <- sapply(models, function(m) {
    dv_vec <- tryCatch(model.matrix(m, type = "lhs"), error = function(e) NULL)
    if (!is.null(dv_vec)) sum(dv_vec == 1, na.rm = TRUE) else "—"
  })
  dv1_line <- c("N(DV=1)", dv1_counts)
  extra_lines <- c(list(dv1_line), extra_lines)
  etable(models, title = title_text, notes = notes_text,
    fitstat = fitstat_use, order = COEF_ORDER, extralines = extra_lines,
    se.below = TRUE, tex = TRUE,
    file = file.path(TABLE_PATH, paste0(filename, ".tex")),
    replace = TRUE, style.tex = style.tex("aer"))
  message("Saved: ", filename, ".tex")
}

theme_paper <- theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", size = 13, hjust = 0),
    plot.subtitle = element_text(size = 10, color = "grey40", hjust = 0),
    legend.position = "bottom", panel.grid.minor = element_blank(),
    strip.text = element_text(face = "bold", size = 11))

cat("=== INFRASTRUCTURE READY ===\n")
## === INFRASTRUCTURE READY ===

8 REGRESSION SAMPLES

# === Pure comparison samples (Crisis) ===
df_btfp_s   <- df_crisis %>% filter(btfp_crisis == 1 | non_user == 1)
df_dw_s     <- df_crisis %>% filter(dw_crisis   == 1 | non_user == 1)
df_anyfed_s <- df_crisis %>% filter(any_fed     == 1 | non_user == 1)
df_fhlb_s   <- df_crisis %>% filter(fhlb_user   == 1 | non_user == 1)

# === Arbitrage samples ===
df_btfp_arb_s <- df_arb %>% filter(btfp_arb == 1 | non_user == 1)
df_dw_arb_s   <- df_arb %>% filter(dw_arb   == 1 | non_user == 1)

cat("=== CRISIS SAMPLES ===\n")
## === CRISIS SAMPLES ===
cat("BTFP:", nrow(df_btfp_s), "(", sum(df_btfp_s$btfp_crisis), "borrowers)\n")
## BTFP: 3727 ( 501 borrowers)
cat("DW:", nrow(df_dw_s), "(", sum(df_dw_s$dw_crisis), "borrowers)\n")
## DW: 3659 ( 433 borrowers)
cat("AnyFed:", nrow(df_anyfed_s), "(", sum(df_anyfed_s$any_fed), "borrowers)\n")
## AnyFed: 4054 ( 828 borrowers)
cat("FHLB:", nrow(df_fhlb_s), "(", sum(df_fhlb_s$fhlb_user), "borrowers)\n")
## FHLB: 3528 ( 302 borrowers)
# === Solvency sub-sample counts ===
cat("\n=== SOLVENCY DISTRIBUTIONS IN ANYFED SAMPLE ===\n")
## 
## === SOLVENCY DISTRIBUTIONS IN ANYFED SAMPLE ===
cat("Jiang MTM:   Solvent=", sum(df_anyfed_s$mtm_solvent, na.rm=T),
    " Insolvent=", sum(df_anyfed_s$mtm_insolvent, na.rm=T), "\n")
## Jiang MTM:   Solvent= 3252  Insolvent= 792
cat("IDCR-100%:   Solvent=", sum(df_anyfed_s$solvent_idcr_100, na.rm=T),
    " Insolvent=", sum(df_anyfed_s$insolvent_idcr_100, na.rm=T), "\n")
## IDCR-100%:   Solvent= 3661  Insolvent= 352
cat("DSSW:        Solvent=", sum(df_anyfed_s$dssw_solvent, na.rm=T),
    " Insolvent=", sum(df_anyfed_s$dssw_insolvent, na.rm=T), "\n")
## DSSW:        Solvent= 3991  Insolvent= 0

9 MAIN RESULTS A: Full Sample (No Solvency Split)

cat("=== MAIN A: FULL SAMPLE (CRISIS) ===\n")
## === MAIN A: FULL SAMPLE (CRISIS) ===
mod_A_any  <- run_model(df_anyfed_s, "any_fed",     EXPL_BASE)
mod_A_btfp <- run_model(df_btfp_s,   "btfp_crisis", EXPL_BASE)
mod_A_dw   <- run_model(df_dw_s,     "dw_crisis",   EXPL_BASE)
mod_A_fhlb <- run_model(df_fhlb_s,   "fhlb_user",   EXPL_BASE)

models_A <- list(
  "Any Fed" = mod_A_any, "BTFP" = mod_A_btfp,
  "DW" = mod_A_dw, "FHLB" = mod_A_fhlb)

save_etable(models_A, "MainA_full_sample",
  title_text = "Main Results A: Full Sample — Extensive Margin (Crisis Period)",
  notes_text = "LPM. DV=1 if borrowed, 0 if pure non-borrower. Crisis: Mar 8--May 4, 2023. FHLB: falsification. Robust SEs. z-standardized.",
  extra_lines = list(
    c("Borrowers", sum(df_anyfed_s$any_fed), sum(df_btfp_s$btfp_crisis),
      sum(df_dw_s$dw_crisis), sum(df_fhlb_s$fhlb_user)),
    c("Mean DV", round(mean(df_anyfed_s$any_fed),3), round(mean(df_btfp_s$btfp_crisis),3),
      round(mean(df_dw_s$dw_crisis),3), round(mean(df_fhlb_s$fhlb_user),3))))

etable(models_A, fitstat = ~ n + r2, se.below = TRUE)
##                           Any Fed        BTFP         DW       FHLB
## Dependent Var.:           any_fed btfp_crisis  dw_crisis  fhlb_user
##                                                                    
## Constant                0.2081***   0.1435***  0.1272***  0.0908***
##                        (0.0060)    (0.0056)   (0.0054)   (0.0050)  
## MTM Loss (z)            0.0300***   0.0249***  0.0158**   0.0039   
##                        (0.0070)    (0.0062)   (0.0061)   (0.0056)  
## Uninsured Leverage (z)  0.0198**    0.0214**   0.0126     0.0064   
##                        (0.0076)    (0.0070)   (0.0067)   (0.0051)  
## MTM $\times$ Uninsured  0.0199***   0.0193***  0.0170*** -0.0039   
##                        (0.0057)    (0.0052)   (0.0051)   (0.0043)  
## Log(Assets)             0.1064***   0.0713***  0.0920***  0.0266***
##                        (0.0082)    (0.0077)   (0.0077)   (0.0065)  
## Cash Ratio             -0.0246***  -0.0285*** -0.0043    -0.0214***
##                        (0.0061)    (0.0048)   (0.0053)   (0.0039)  
## Loan-to-Deposit        -0.0035     -0.0107    -0.0007     0.0244***
##                        (0.0067)    (0.0057)   (0.0057)   (0.0050)  
## Book Equity Ratio      -0.0135*    -0.0118*   -0.0006     0.0101*  
##                        (0.0055)    (0.0047)   (0.0044)   (0.0041)  
## Wholesale Funding       0.0297***   0.0263***  0.0204**   0.0019   
##                        (0.0069)    (0.0065)   (0.0063)   (0.0051)  
## ROA                    -0.0019     -0.0059    -0.0029    -0.0091*  
##                        (0.0057)    (0.0049)   (0.0048)   (0.0043)  
## ______________________ __________ ___________ __________ __________
## S.E. type              Hete.-rob. Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                4,044       3,717      3,649      3,518
## R2                        0.12097     0.09615    0.10314    0.04090
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

10 MAIN RESULTS B: Jiang MTM Solvent vs. Insolvent

cat("=== MAIN B: JIANG MTM SOLVENCY SPLIT ===\n")
## === MAIN B: JIANG MTM SOLVENCY SPLIT ===
# Solvent
mod_B_any_sol  <- safe_run(df_anyfed_s %>% filter(mtm_solvent==1), "any_fed",     EXPL_BASE)
mod_B_btfp_sol <- safe_run(df_btfp_s   %>% filter(mtm_solvent==1), "btfp_crisis", EXPL_BASE)
mod_B_dw_sol   <- safe_run(df_dw_s     %>% filter(mtm_solvent==1), "dw_crisis",   EXPL_BASE)
mod_B_fhlb_sol <- safe_run(df_fhlb_s   %>% filter(mtm_solvent==1), "fhlb_user",   EXPL_BASE)

# Insolvent
mod_B_any_ins  <- safe_run(df_anyfed_s %>% filter(mtm_insolvent==1), "any_fed",     EXPL_BASE)
mod_B_btfp_ins <- safe_run(df_btfp_s   %>% filter(mtm_insolvent==1), "btfp_crisis", EXPL_BASE)
mod_B_dw_ins   <- safe_run(df_dw_s     %>% filter(mtm_insolvent==1), "dw_crisis",   EXPL_BASE)
mod_B_fhlb_ins <- safe_run(df_fhlb_s   %>% filter(mtm_insolvent==1), "fhlb_user",   EXPL_BASE)

models_B <- list(
  "Any (Sol)" = mod_B_any_sol, "Any (Ins)" = mod_B_any_ins,
  "BTFP (Sol)" = mod_B_btfp_sol, "BTFP (Ins)" = mod_B_btfp_ins,
  "DW (Sol)" = mod_B_dw_sol, "DW (Ins)" = mod_B_dw_ins,
  "FHLB (Sol)" = mod_B_fhlb_sol, "FHLB (Ins)" = mod_B_fhlb_ins)

save_etable(models_B, "MainB_jiang_mtm_solvency",
  title_text = "Main Results B: Jiang MTM Solvency Split (Crisis Period)",
  notes_text = "LPM. Solvency: Adj. Equity = Book Equity/TA $-$ MTM/TA. Solvent: AE $\\geq$ 0. Insolvent: AE $<$ 0. Robust SEs. z-standardized.",
  extra_lines = list(
    c("Solvency", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins")))

etable(models_B[!sapply(models_B, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                         Any (Sol)  Any (Ins)  BTFP (Sol)  BTFP (Ins)   DW (Sol)
## Dependent Var.:           any_fed    any_fed btfp_crisis btfp_crisis  dw_crisis
##                                                                                
## Constant                0.2096***  0.0909      0.1420***   0.0364     0.1322***
##                        (0.0075)   (0.0589)    (0.0070)    (0.0558)   (0.0068)  
## MTM Loss (z)            0.0376***  0.0162      0.0286***   0.0172     0.0238** 
##                        (0.0085)   (0.0280)    (0.0073)    (0.0266)   (0.0076)  
## Uninsured Leverage (z)  0.0263**  -0.0357      0.0290***  -0.0295     0.0168*  
##                        (0.0091)   (0.0301)    (0.0083)    (0.0276)   (0.0081)  
## MTM $\times$ Uninsured  0.0213**   0.0549*     0.0213***   0.0478*    0.0185** 
##                        (0.0069)   (0.0243)    (0.0061)    (0.0231)   (0.0062)  
## Log(Assets)             0.1001***  0.1368***   0.0647***   0.1045***  0.0882***
##                        (0.0088)   (0.0222)    (0.0082)    (0.0219)   (0.0083)  
## Cash Ratio             -0.0202**  -0.0789***  -0.0254***  -0.0738*** -0.0019   
##                        (0.0063)   (0.0234)    (0.0048)    (0.0211)   (0.0055)  
## Loan-to-Deposit        -0.0024     0.0126     -0.0099      0.0106    -0.0017   
##                        (0.0071)   (0.0220)    (0.0059)    (0.0206)   (0.0061)  
## Book Equity Ratio      -0.0109    -0.1328**   -0.0073     -0.1300**  -0.0021   
##                        (0.0058)   (0.0434)    (0.0048)    (0.0414)   (0.0048)  
## Wholesale Funding       0.0298***  0.0219      0.0259***   0.0199     0.0211** 
##                        (0.0077)   (0.0150)    (0.0072)    (0.0148)   (0.0070)  
## ROA                     0.0029    -0.0344*    -0.0022     -0.0316*    0.0016   
##                        (0.0060)   (0.0167)    (0.0051)    (0.0153)   (0.0051)  
## ______________________ __________ __________ ___________ ___________ __________
## S.E. type              Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob. Hete.-rob.
## Observations                3,252        792       2,986         731      2,977
## R2                        0.12422    0.11947     0.09650     0.09592    0.10686
## 
##                          DW (Ins) FHLB (Sol) FHLB (I..
## Dependent Var.:         dw_crisis  fhlb_user fhlb_user
##                                                       
## Constant                0.0413     0.0918***   0.0777 
##                        (0.0487)   (0.0060)    (0.0414)
## MTM Loss (z)            0.0132     0.0015      0.0298 
##                        (0.0236)   (0.0067)    (0.0187)
## Uninsured Leverage (z) -0.0197     0.0046      0.0076 
##                        (0.0247)   (0.0065)    (0.0178)
## MTM $\times$ Uninsured  0.0400    -0.0049      0.0021 
##                        (0.0204)   (0.0055)    (0.0156)
## Log(Assets)             0.1086***  0.0285***   0.0128 
##                        (0.0206)   (0.0072)    (0.0139)
## Cash Ratio             -0.0370*   -0.0229***  -0.0106 
##                        (0.0185)   (0.0041)    (0.0153)
## Loan-to-Deposit         0.0079     0.0219***   0.0263*
##                        (0.0179)   (0.0056)    (0.0129)
## Book Equity Ratio      -0.0715*    0.0081      0.0268 
##                        (0.0347)   (0.0045)    (0.0303)
## Wholesale Funding       0.0149     0.0023      0.0010 
##                        (0.0143)   (0.0058)    (0.0103)
## ROA                    -0.0319*   -0.0090     -0.0096 
##                        (0.0140)   (0.0046)    (0.0109)
## ______________________ __________ __________ _________
## S.E. type              Hete.-rob. Hete.-rob. Het.-rob.
## Observations                  672      2,886       632
## R2                        0.10868    0.04299   0.03281
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

11 MAIN RESULTS C: Jiang IDCR-100% Solvent vs. Insolvent

cat("=== MAIN C: JIANG IDCR-100% SOLVENCY SPLIT ===\n")
## === MAIN C: JIANG IDCR-100% SOLVENCY SPLIT ===
cat("IDCR-100%: If 100% of uninsured depositors run, can the bank pay insured depositors?\n")
## IDCR-100%: If 100% of uninsured depositors run, can the bank pay insured depositors?
cat("IDCR = (MV_Assets - Uninsured - Insured) / Insured\n\n")
## IDCR = (MV_Assets - Uninsured - Insured) / Insured
# Solvent
mod_C_any_sol  <- safe_run(df_anyfed_s %>% filter(solvent_idcr_100==1), "any_fed",     EXPL_BASE)
mod_C_btfp_sol <- safe_run(df_btfp_s   %>% filter(solvent_idcr_100==1), "btfp_crisis", EXPL_BASE)
mod_C_dw_sol   <- safe_run(df_dw_s     %>% filter(solvent_idcr_100==1), "dw_crisis",   EXPL_BASE)
mod_C_fhlb_sol <- safe_run(df_fhlb_s   %>% filter(solvent_idcr_100==1), "fhlb_user",   EXPL_BASE)

# Insolvent
mod_C_any_ins  <- safe_run(df_anyfed_s %>% filter(insolvent_idcr_100==1), "any_fed",     EXPL_BASE)
mod_C_btfp_ins <- safe_run(df_btfp_s   %>% filter(insolvent_idcr_100==1), "btfp_crisis", EXPL_BASE)
mod_C_dw_ins   <- safe_run(df_dw_s     %>% filter(insolvent_idcr_100==1), "dw_crisis",   EXPL_BASE)
mod_C_fhlb_ins <- safe_run(df_fhlb_s   %>% filter(insolvent_idcr_100==1), "fhlb_user",   EXPL_BASE)

models_C <- list(
  "Any (Sol)" = mod_C_any_sol, "Any (Ins)" = mod_C_any_ins,
  "BTFP (Sol)" = mod_C_btfp_sol, "BTFP (Ins)" = mod_C_btfp_ins,
  "DW (Sol)" = mod_C_dw_sol, "DW (Ins)" = mod_C_dw_ins,
  "FHLB (Sol)" = mod_C_fhlb_sol, "FHLB (Ins)" = mod_C_fhlb_ins)

save_etable(models_C, "MainC_idcr100_solvency",
  title_text = "Main Results C: IDCR-100\\% Solvency Split (Crisis Period)",
  notes_text = paste0(
    "LPM. Solvency: IDCR = (MV Assets $-$ Uninsured $-$ Insured) / Insured. ",
    "This measures whether the bank can pay ALL depositors after a 100\\% uninsured run. ",
    "Solvent: IDCR $\\geq$ 0. Insolvent: IDCR $<$ 0. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Solvency", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins")))

etable(models_C[!sapply(models_C, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                         Any (Sol)  Any (Ins)  BTFP (Sol)  BTFP (Ins)   DW (Sol)
## Dependent Var.:           any_fed    any_fed btfp_crisis btfp_crisis  dw_crisis
##                                                                                
## Constant                0.2095***  0.1523      0.1432***     0.0743   0.1299***
##                        (0.0065)   (0.0831)    (0.0061)      (0.0830) (0.0059)  
## MTM Loss (z)            0.0332***  0.0241      0.0258***     0.0321   0.0191** 
##                        (0.0076)   (0.0363)    (0.0067)      (0.0346) (0.0068)  
## Uninsured Leverage (z)  0.0234**  -0.0106      0.0235**     -0.0071   0.0156*  
##                        (0.0083)   (0.0409)    (0.0077)      (0.0355) (0.0074)  
## MTM $\times$ Uninsured  0.0205**   0.0308      0.0187**      0.0365   0.0187** 
##                        (0.0064)   (0.0317)    (0.0059)      (0.0284) (0.0059)  
## Log(Assets)             0.1038***  0.1395***   0.0712***     0.0728*  0.0895***
##                        (0.0086)   (0.0328)    (0.0080)      (0.0316) (0.0081)  
## Cash Ratio             -0.0229*** -0.0598*    -0.0269***    -0.0570* -0.0035   
##                        (0.0065)   (0.0270)    (0.0051)      (0.0252) (0.0057)  
## Loan-to-Deposit        -0.0018    -0.0033     -0.0085       -0.0017  -0.0009   
##                        (0.0073)   (0.0345)    (0.0063)      (0.0322) (0.0064)  
## Book Equity Ratio      -0.0165**  -0.0459     -0.0138**     -0.0657  -0.0036   
##                        (0.0062)   (0.0571)    (0.0053)      (0.0561) (0.0051)  
## Wholesale Funding       0.0296*** -0.0120      0.0265***     0.0169   0.0200** 
##                        (0.0070)   (0.0839)    (0.0066)      (0.0821) (0.0064)  
## ROA                    -0.0017    -0.0255     -0.0067       -0.0176  -0.0019   
##                        (0.0062)   (0.0231)    (0.0053)      (0.0213) (0.0053)  
## ______________________ __________ __________ ___________ ___________ __________
## S.E. type              Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob. Hete.-rob.
## Observations                3,661        352       3,355         331      3,314
## R2                        0.12227    0.10801     0.09933     0.06647    0.10116
## 
##                          DW (Ins) FHLB (Sol) FHLB (I..
## Dependent Var.:         dw_crisis  fhlb_user fhlb_user
##                                                       
## Constant                0.0743     0.0916***   0.0107 
##                        (0.0658)   (0.0053)    (0.0408)
## MTM Loss (z)            0.0191     0.0047      0.0229 
##                        (0.0268)   (0.0063)    (0.0162)
## Uninsured Leverage (z)  0.0061     0.0065      0.0060 
##                        (0.0330)   (0.0058)    (0.0170)
## MTM $\times$ Uninsured  0.0110    -0.0052      0.0019 
##                        (0.0247)   (0.0051)    (0.0132)
## Log(Assets)             0.1268***  0.0273***   0.0064 
##                        (0.0305)   (0.0070)    (0.0135)
## Cash Ratio             -0.0208    -0.0223***  -0.0101 
##                        (0.0187)   (0.0043)    (0.0095)
## Loan-to-Deposit        -0.0024     0.0246***   0.0316*
##                        (0.0253)   (0.0058)    (0.0144)
## Book Equity Ratio      -0.0076     0.0078     -0.0328 
##                        (0.0423)   (0.0048)    (0.0315)
## Wholesale Funding      -0.0466     0.0014     -0.0009 
##                        (0.0568)   (0.0052)    (0.0478)
## ROA                    -0.0245    -0.0098*    -0.0125 
##                        (0.0203)   (0.0047)    (0.0154)
## ______________________ __________ __________ _________
## S.E. type              Hete.-rob. Hete.-rob. Het.-rob.
## Observations                  304      3,200       287
## R2                        0.14081    0.04044   0.02156
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

12 MAIN RESULTS D: DSSW Deposit Franchise Diagnostic

# ==============================================================================
# DSSW DIAGNOSTIC: Why zero banks are DSSW-insolvent, and why this matters
#
# Key finding: DFV ≈ 68% of assets at the median bank, far exceeding
# average MTM losses of ~5.5%. This makes every bank DSSW-solvent.
#
# Interpretation: The deposit franchise exists ONLY in the no-run equilibrium.
# If depositors run, the uninsured franchise is destroyed, and banks revert
# to Jiang-style insolvency. That 828 banks sought emergency liquidity
# despite being DSSW-solvent is direct evidence that the coordination
# problem — not fundamental insolvency — drove borrowing.
# ==============================================================================

cat("================================================================\n")
## ================================================================
cat("  DSSW DEPOSIT FRANCHISE VALUE DIAGNOSTIC\n")
##   DSSW DEPOSIT FRANCHISE VALUE DIAGNOSTIC
cat("================================================================\n\n")
## ================================================================
# Coverage
n_total <- nrow(df_2022q4)
n_beta  <- sum(!is.na(df_2022q4$beta_overall))
cat(sprintf("Beta coverage: %d / %d (%.1f%%)\n\n", n_beta, n_total, 100 * n_beta / n_total))
## Beta coverage: 4226 / 4292 (98.5%)
# DFV distribution
cat("--- DFV Distribution (% of assets) ---\n")
## --- DFV Distribution (% of assets) ---
print(summary(df_2022q4$dfv_raw))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##  -0.777  70.831  79.506  77.080  86.093 102.266      66
cat("\n--- DSSW Adjusted Equity Distribution (%) ---\n")
## 
## --- DSSW Adjusted Equity Distribution (%) ---
print(summary(df_2022q4$adjusted_equity_dssw_raw))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   16.31   75.08   83.42   81.19   89.51  107.34      66
# The key result
n_dssw_insol <- sum(df_2022q4$dssw_insolvent, na.rm = TRUE)
n_jiang_insol <- sum(df_2022q4$mtm_insolvent, na.rm = TRUE)
n_idcr_insol  <- sum(df_2022q4$insolvent_idcr_100, na.rm = TRUE)

cat("\n================================================================\n")
## 
## ================================================================
cat("  SOLVENCY CLASSIFICATION COMPARISON\n")
##   SOLVENCY CLASSIFICATION COMPARISON
cat("================================================================\n")
## ================================================================
cat(sprintf("  Jiang MTM insolvent:    %d banks\n", n_jiang_insol))
##   Jiang MTM insolvent:    825 banks
cat(sprintf("  IDCR-100%% insolvent:    %d banks\n", n_idcr_insol))
##   IDCR-100% insolvent:    364 banks
cat(sprintf("  DSSW insolvent:         %d banks\n", n_dssw_insol))
##   DSSW insolvent:         0 banks
cat(sprintf("  Rescued by DFV (Jiang→DSSW solvent): %d banks\n",
    sum(df_2022q4$mtm_insolvent == 1 & df_2022q4$dssw_solvent == 1, na.rm = TRUE)))
##   Rescued by DFV (Jiang→DSSW solvent): 813 banks
cat("\n--- Why? Mean DFV vs. Mean MTM Loss ---\n")
## 
## --- Why? Mean DFV vs. Mean MTM Loss ---
cat(sprintf("  Mean DFV:      %.2f%% of assets\n", mean(df_2022q4$dfv_raw, na.rm = TRUE)))
##   Mean DFV:      77.08% of assets
cat(sprintf("  Mean MTM Loss: %.2f%% of assets\n", mean(df_2022q4$mtm_total_raw, na.rm = TRUE)))
##   Mean MTM Loss: 5.47% of assets
cat(sprintf("  Mean Book Eq:  %.2f%% of assets\n", mean(df_2022q4$book_equity_ratio_raw, na.rm = TRUE)))
##   Mean Book Eq:  10.22% of assets
cat("  → DFV dwarfs MTM losses. Every bank is DSSW-solvent absent a run.\n")
##   → DFV dwarfs MTM losses. Every bank is DSSW-solvent absent a run.
# Cross-tabulation
cat("\n--- Jiang × DSSW Cross-Tab ---\n")
## 
## --- Jiang × DSSW Cross-Tab ---
df_2022q4 %>%
  filter(!is.na(dssw_solvent)) %>%
  count(
    Jiang = ifelse(mtm_insolvent == 1, "Insolvent", "Solvent"),
    DSSW  = ifelse(dssw_insolvent == 1, "Insolvent", "Solvent")
  ) %>%
  print()
## # A tibble: 3 × 3
##   Jiang     DSSW        n
##   <chr>     <chr>   <int>
## 1 Insolvent Solvent   825
## 2 Solvent   Solvent  3457
## 3 <NA>      Solvent    10
# Among emergency borrowers
cat("\n--- Among Crisis Emergency Borrowers ---\n")
## 
## --- Among Crisis Emergency Borrowers ---
crisis_borrowers <- df_crisis %>% filter(any_fed == 1)
cat(sprintf("  Total emergency borrowers: %d\n", nrow(crisis_borrowers)))
##   Total emergency borrowers: 828
cat(sprintf("  DSSW-solvent among them:   %d (%.1f%%)\n",
    sum(crisis_borrowers$dssw_solvent, na.rm = TRUE),
    100 * mean(crisis_borrowers$dssw_solvent, na.rm = TRUE)))
##   DSSW-solvent among them:   822 (99.3%)
cat("  → Every bank that borrowed was solvent in the no-run equilibrium.\n")
##   → Every bank that borrowed was solvent in the no-run equilibrium.
cat("  → Borrowing was driven by coordination failure, not fundamental insolvency.\n")
##   → Borrowing was driven by coordination failure, not fundamental insolvency.

12.0.1 DSSW Visualization

df_scatter <- df_crisis %>%
  filter(!is.na(adjusted_equity_dssw_raw)) %>%
  mutate(Borrower = case_when(
    any_fed == 1 ~ "Emergency Borrower", fhlb_user == 1 ~ "FHLB", TRUE ~ "Non-Borrower"))

p_scatter <- ggplot(df_scatter,
  aes(x = adjusted_equity_raw, y = adjusted_equity_dssw_raw,
      color = Borrower, alpha = Borrower)) +
  geom_point(size = 1.5) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "grey50") +
  geom_hline(yintercept = 0, linetype = "dotted", color = "red") +
  geom_vline(xintercept = 0, linetype = "dotted", color = "red") +
  scale_color_manual(values = c("Emergency Borrower" = "#003049",
    "FHLB" = "#F77F00", "Non-Borrower" = "grey70")) +
  scale_alpha_manual(values = c("Emergency Borrower" = 0.8,
    "FHLB" = 0.6, "Non-Borrower" = 0.3)) +
  labs(
    title = "Jiang vs. DSSW Adjusted Equity: All Banks Are DSSW-Solvent",
    subtitle = "DFV ≈ 68% of assets rescues every Jiang-insolvent bank. But franchise exists only if depositors stay.",
    x = "Jiang Adjusted Equity (Book Eq. − MTM, %)",
    y = "DSSW Adjusted Equity (Book Eq. − MTM + DFV, %)"
  ) +
  theme_paper +
  annotate("rect", xmin = -Inf, xmax = 0, ymin = 0, ymax = Inf,
    fill = "darkgreen", alpha = 0.05) +
  annotate("text", x = -3, y = 50, label = "Panic Region:\nJiang-insolvent but\nDSSW-solvent",
    color = "darkgreen", fontface = "italic", size = 3.5)

p_scatter

save_figure(p_scatter, "Fig_Jiang_vs_DSSW_Scatter", width = 10, height = 6)

13 TEMPORAL ROBUSTNESS: Crisis vs. Arbitrage

13.1 Full Sample

# ==============================================================================
# TEMPORAL: FULL SAMPLE (no solvency split)
# ==============================================================================

cat("=== TEMPORAL: CRISIS VS ARBITRAGE (FULL SAMPLE) ===\n")
## === TEMPORAL: CRISIS VS ARBITRAGE (FULL SAMPLE) ===
mod_T_btfp_cr  <- run_model(df_btfp_s,     "btfp_crisis", EXPL_BASE)
mod_T_btfp_arb <- run_model(df_btfp_arb_s, "btfp_arb",    EXPL_BASE)
mod_T_dw_cr    <- run_model(df_dw_s,       "dw_crisis",   EXPL_BASE)
mod_T_dw_arb   <- safe_run(df_dw_arb_s,   "dw_arb",      EXPL_BASE)

models_T_full <- list(
  "BTFP Crisis" = mod_T_btfp_cr, "BTFP Arb" = mod_T_btfp_arb,
  "DW Crisis"   = mod_T_dw_cr,   "DW Arb"   = mod_T_dw_arb)

save_etable(models_T_full, "Temporal_full_sample",
  title_text = "Temporal Robustness: Full Sample — Crisis vs. Arbitrage",
  notes_text = paste0(
    "LPM. Crisis: Mar 8--May 4, 2023 (2022Q4 baseline). ",
    "Arbitrage: Nov 15, 2023--Jan 24, 2024 (2023Q3 baseline). ",
    "DW data through Dec 31, 2023. ",
    "Prediction: MTM $\\times$ Uninsured strong in crisis, weak in arbitrage. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Period", "Crisis", "Arb", "Crisis", "Arb"),
    c("Facility", "BTFP", "BTFP", "DW", "DW")))

etable(models_T_full[!sapply(models_T_full, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                        BTFP Crisis   BTFP Arb  DW Crisis     DW Arb
## Dependent Var.:        btfp_crisis   btfp_arb  dw_crisis     dw_arb
##                                                                    
## Constant                 0.1435***  0.2019***  0.1272***  0.1164***
##                         (0.0056)   (0.0060)   (0.0054)   (0.0056)  
## MTM Loss (z)             0.0249***  0.0217**   0.0158**  -0.0037   
##                         (0.0062)   (0.0072)   (0.0061)   (0.0065)  
## Uninsured Leverage (z)   0.0214**   0.0103     0.0126    -0.0097   
##                         (0.0070)   (0.0070)   (0.0067)   (0.0063)  
## MTM $\times$ Uninsured   0.0193***  0.0075     0.0170***  0.0009   
##                         (0.0052)   (0.0054)   (0.0051)   (0.0051)  
## Log(Assets)              0.0713***  0.0644***  0.0920***  0.0771***
##                         (0.0077)   (0.0076)   (0.0077)   (0.0074)  
## Cash Ratio              -0.0285*** -0.0371*** -0.0043    -0.0103*  
##                         (0.0048)   (0.0059)   (0.0053)   (0.0051)  
## Loan-to-Deposit         -0.0107    -0.0025    -0.0007    -0.0007   
##                         (0.0057)   (0.0064)   (0.0057)   (0.0052)  
## Book Equity Ratio       -0.0118*   -0.0058    -0.0006    -0.0052   
##                         (0.0047)   (0.0058)   (0.0044)   (0.0046)  
## Wholesale Funding        0.0263***  0.1088***  0.0204**   0.0324***
##                         (0.0065)   (0.0079)   (0.0063)   (0.0072)  
## ROA                     -0.0059    -0.0242*** -0.0029    -0.0081   
##                         (0.0049)   (0.0059)   (0.0048)   (0.0048)  
## ______________________ ___________ __________ __________ __________
## S.E. type              Heter.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                 3,717      3,794      3,649      3,407
## R2                         0.09615    0.16301    0.10314    0.08057
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

13.2 Jiang MTM Solvency Split

# ==============================================================================
# TEMPORAL × JIANG MTM SOLVENCY
#
# GP theory prediction:
#   Solvent (panic region): Interaction strong in crisis, vanishes in arb
#   Insolvent (below θ̲):   Interaction weak in BOTH periods
#
# This is a Solvency × Period difference-in-differences argument.
# ==============================================================================

cat("=== TEMPORAL × JIANG MTM SOLVENCY ===\n")
## === TEMPORAL × JIANG MTM SOLVENCY ===
# --- BTFP: Crisis × Solvency ---
mod_T_btfp_cr_sol <- safe_run(df_btfp_s %>% filter(mtm_solvent==1), "btfp_crisis", EXPL_BASE)
mod_T_btfp_cr_ins <- safe_run(df_btfp_s %>% filter(mtm_insolvent==1), "btfp_crisis", EXPL_BASE)

# --- BTFP: Arb × Solvency ---
mod_T_btfp_arb_sol <- safe_run(df_btfp_arb_s %>% filter(mtm_solvent==1), "btfp_arb", EXPL_BASE)
mod_T_btfp_arb_ins <- safe_run(df_btfp_arb_s %>% filter(mtm_insolvent==1), "btfp_arb", EXPL_BASE)

# --- DW: Crisis × Solvency ---
mod_T_dw_cr_sol <- safe_run(df_dw_s %>% filter(mtm_solvent==1), "dw_crisis", EXPL_BASE)
mod_T_dw_cr_ins <- safe_run(df_dw_s %>% filter(mtm_insolvent==1), "dw_crisis", EXPL_BASE)

# --- DW: Arb × Solvency ---
mod_T_dw_arb_sol <- safe_run(df_dw_arb_s %>% filter(mtm_solvent==1), "dw_arb", EXPL_BASE)
mod_T_dw_arb_ins <- safe_run(df_dw_arb_s %>% filter(mtm_insolvent==1), "dw_arb", EXPL_BASE)

models_T_jiang <- list(
  "BTFP Cr (Sol)" = mod_T_btfp_cr_sol, "BTFP Cr (Ins)" = mod_T_btfp_cr_ins,
  "BTFP Arb (Sol)" = mod_T_btfp_arb_sol, "BTFP Arb (Ins)" = mod_T_btfp_arb_ins,
  "DW Cr (Sol)" = mod_T_dw_cr_sol, "DW Cr (Ins)" = mod_T_dw_cr_ins,
  "DW Arb (Sol)" = mod_T_dw_arb_sol, "DW Arb (Ins)" = mod_T_dw_arb_ins)

save_etable(models_T_jiang, "Temporal_jiang_solvency",
  title_text = "Temporal $\\times$ Jiang MTM Solvency: Crisis vs. Arbitrage",
  notes_text = paste0(
    "LPM. Jiang solvency: Adj.\\ Equity = Book Equity/TA $-$ MTM/TA $\\geq$ 0. ",
    "GP prediction: Among solvent banks (panic region), MTM $\\times$ Uninsured ",
    "should be strong in crisis and vanish in arbitrage. Among insolvent banks ",
    "(below $\\underline{\\theta}$), the interaction should be weak in both periods ",
    "because withdrawal is a dominant strategy regardless of coordination. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Period",   "Crisis", "Crisis", "Arb", "Arb", "Crisis", "Crisis", "Arb", "Arb"),
    c("Solvency", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins"),
    c("Facility",  "BTFP", "BTFP", "BTFP", "BTFP", "DW", "DW", "DW", "DW")))

etable(models_T_jiang[!sapply(models_T_jiang, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                        BTFP Cr (.. BTFP Cr (...1 BTFP Arb.. BTFP Arb...1
## Dependent Var.:        btfp_crisis   btfp_crisis   btfp_arb     btfp_arb
##                                                                         
## Constant                 0.1420***     0.0364     0.2015***    0.1900** 
##                         (0.0070)      (0.0558)   (0.0073)     (0.0619)  
## MTM Loss (z)             0.0286***     0.0172     0.0215**     0.0170   
##                         (0.0073)      (0.0266)   (0.0081)     (0.0287)  
## Uninsured Leverage (z)   0.0290***    -0.0295     0.0187*     -0.0316   
##                         (0.0083)      (0.0276)   (0.0082)     (0.0294)  
## MTM $\times$ Uninsured   0.0213***     0.0478*    0.0122       0.0303   
##                         (0.0061)      (0.0231)   (0.0062)     (0.0240)  
## Log(Assets)              0.0647***     0.1045***  0.0611***    0.0783***
##                         (0.0082)      (0.0219)   (0.0082)     (0.0217)  
## Cash Ratio              -0.0254***    -0.0738*** -0.0343***   -0.0791***
##                         (0.0048)      (0.0211)   (0.0061)     (0.0193)  
## Loan-to-Deposit         -0.0099        0.0106    -0.0113       0.0551*  
##                         (0.0059)      (0.0206)   (0.0067)     (0.0229)  
## Book Equity Ratio       -0.0073       -0.1300**  -0.0040      -0.0546   
##                         (0.0048)      (0.0414)   (0.0061)     (0.0452)  
## Wholesale Funding        0.0259***     0.0199     0.1150***    0.0850***
##                         (0.0072)      (0.0148)   (0.0092)     (0.0160)  
## ROA                     -0.0022       -0.0316*   -0.0242***   -0.0316   
##                         (0.0051)      (0.0153)   (0.0061)     (0.0198)  
## ______________________ ___________   ___________ __________   __________
## S.E. type              Heter.-rob.   Heter.-rob. Hete.-rob.   Hete.-rob.
## Observations                 2,986           731      3,048          746
## R2                         0.09650       0.09592    0.16995      0.13907
## 
##                        DW Cr (S.. DW Cr (I.. DW Arb (.. DW Arb (...1
## Dependent Var.:         dw_crisis  dw_crisis     dw_arb       dw_arb
##                                                                     
## Constant                0.1322***  0.0413     0.1162***    0.0448   
##                        (0.0068)   (0.0487)   (0.0068)     (0.0503)  
## MTM Loss (z)            0.0238**   0.0132    -0.0081       0.0374   
##                        (0.0076)   (0.0236)   (0.0075)     (0.0257)  
## Uninsured Leverage (z)  0.0168*   -0.0197    -0.0091      -0.0187   
##                        (0.0081)   (0.0247)   (0.0075)     (0.0278)  
## MTM $\times$ Uninsured  0.0185**   0.0400     0.0006       0.0104   
##                        (0.0062)   (0.0204)   (0.0061)     (0.0230)  
## Log(Assets)             0.0882***  0.1086***  0.0766***    0.0771***
##                        (0.0083)   (0.0206)   (0.0080)     (0.0211)  
## Cash Ratio             -0.0019    -0.0370*   -0.0099      -0.0281   
##                        (0.0055)   (0.0185)   (0.0053)     (0.0151)  
## Loan-to-Deposit        -0.0017     0.0079    -0.0054       0.0280   
##                        (0.0061)   (0.0179)   (0.0052)     (0.0202)  
## Book Equity Ratio      -0.0021    -0.0715*   -0.0066      -0.0431   
##                        (0.0048)   (0.0347)   (0.0051)     (0.0369)  
## Wholesale Funding       0.0211**   0.0149     0.0343***    0.0247   
##                        (0.0070)   (0.0143)   (0.0083)     (0.0145)  
## ROA                     0.0016    -0.0319*   -0.0083      -0.0124   
##                        (0.0051)   (0.0140)   (0.0051)     (0.0149)  
## ______________________ __________ __________ __________   __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob.   Hete.-rob.
## Observations                2,977        672      2,799          608
## R2                        0.10686    0.10868    0.08295      0.08754
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

13.3 IDCR-100% Solvency Split

# ==============================================================================
# TEMPORAL × IDCR-100% SOLVENCY
# Same logic as Jiang split but using stricter run-scenario measure
# ==============================================================================

cat("=== TEMPORAL × IDCR-100% SOLVENCY ===\n")
## === TEMPORAL × IDCR-100% SOLVENCY ===
# --- BTFP ---
mod_T_btfp_cr_idcr_sol  <- safe_run(df_btfp_s %>% filter(solvent_idcr_100==1), "btfp_crisis", EXPL_BASE)
mod_T_btfp_cr_idcr_ins  <- safe_run(df_btfp_s %>% filter(insolvent_idcr_100==1), "btfp_crisis", EXPL_BASE)
mod_T_btfp_arb_idcr_sol <- safe_run(df_btfp_arb_s %>% filter(solvent_idcr_100==1), "btfp_arb", EXPL_BASE)
mod_T_btfp_arb_idcr_ins <- safe_run(df_btfp_arb_s %>% filter(insolvent_idcr_100==1), "btfp_arb", EXPL_BASE)

# --- DW ---
mod_T_dw_cr_idcr_sol  <- safe_run(df_dw_s %>% filter(solvent_idcr_100==1), "dw_crisis", EXPL_BASE)
mod_T_dw_cr_idcr_ins  <- safe_run(df_dw_s %>% filter(insolvent_idcr_100==1), "dw_crisis", EXPL_BASE)
mod_T_dw_arb_idcr_sol <- safe_run(df_dw_arb_s %>% filter(solvent_idcr_100==1), "dw_arb", EXPL_BASE)
mod_T_dw_arb_idcr_ins <- safe_run(df_dw_arb_s %>% filter(insolvent_idcr_100==1), "dw_arb", EXPL_BASE)

models_T_idcr <- list(
  "BTFP Cr (Sol)" = mod_T_btfp_cr_idcr_sol, "BTFP Cr (Ins)" = mod_T_btfp_cr_idcr_ins,
  "BTFP Arb (Sol)" = mod_T_btfp_arb_idcr_sol, "BTFP Arb (Ins)" = mod_T_btfp_arb_idcr_ins,
  "DW Cr (Sol)" = mod_T_dw_cr_idcr_sol, "DW Cr (Ins)" = mod_T_dw_cr_idcr_ins,
  "DW Arb (Sol)" = mod_T_dw_arb_idcr_sol, "DW Arb (Ins)" = mod_T_dw_arb_idcr_ins)

save_etable(models_T_idcr, "Temporal_idcr100_solvency",
  title_text = "Temporal $\\times$ IDCR-100\\% Solvency: Crisis vs. Arbitrage",
  notes_text = paste0(
    "LPM. IDCR-100\\% solvency: (MV Assets $-$ Uninsured $-$ Insured) / Insured $\\geq$ 0. ",
    "Same GP prediction as Jiang split: interaction present only among solvent banks in crisis. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Period",   "Crisis", "Crisis", "Arb", "Arb", "Crisis", "Crisis", "Arb", "Arb"),
    c("Solvency", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins"),
    c("Facility",  "BTFP", "BTFP", "BTFP", "BTFP", "DW", "DW", "DW", "DW")))

etable(models_T_idcr[!sapply(models_T_idcr, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                        BTFP Cr (.. BTFP Cr (...1 BTFP Arb.. BTFP Ar..
## Dependent Var.:        btfp_crisis   btfp_crisis   btfp_arb  btfp_arb
##                                                                      
## Constant                 0.1432***       0.0743   0.2038***  0.2812**
##                         (0.0061)        (0.0830) (0.0064)   (0.0980) 
## MTM Loss (z)             0.0258***       0.0321   0.0255*** -0.0137  
##                         (0.0067)        (0.0346) (0.0077)   (0.0437) 
## Uninsured Leverage (z)   0.0235**       -0.0071   0.0142    -0.0384  
##                         (0.0077)        (0.0355) (0.0077)   (0.0355) 
## MTM $\times$ Uninsured   0.0187**        0.0365   0.0072     0.0440  
##                         (0.0059)        (0.0284) (0.0062)   (0.0313) 
## Log(Assets)              0.0712***       0.0728*  0.0647***  0.0340  
##                         (0.0080)        (0.0316) (0.0080)   (0.0289) 
## Cash Ratio              -0.0269***      -0.0570* -0.0353*** -0.0727**
##                         (0.0051)        (0.0252) (0.0063)   (0.0230) 
## Loan-to-Deposit         -0.0085         -0.0017  -0.0031     0.0612  
##                         (0.0063)        (0.0322) (0.0070)   (0.0361) 
## Book Equity Ratio       -0.0138**       -0.0657  -0.0109    -0.0326  
##                         (0.0053)        (0.0561) (0.0064)   (0.0647) 
## Wholesale Funding        0.0265***       0.0169   0.1061***  0.2066**
##                         (0.0066)        (0.0821) (0.0080)   (0.0724) 
## ROA                     -0.0067         -0.0176  -0.0273***  0.0103  
##                         (0.0053)        (0.0213) (0.0062)   (0.0212) 
## ______________________ ___________   ___________ __________ _________
## S.E. type              Heter.-rob.   Heter.-rob. Hete.-rob. Het.-rob.
## Observations                 3,355           331      3,510       255
## R2                         0.09933       0.06647    0.16767   0.11883
## 
##                        DW Cr (S.. DW Cr (I.. DW Arb (..  DW Arb..
## Dependent Var.:         dw_crisis  dw_crisis     dw_arb    dw_arb
##                                                                  
## Constant                0.1299***  0.0743     0.1168***   0.1062 
##                        (0.0059)   (0.0658)   (0.0058)    (0.0834)
## MTM Loss (z)            0.0191**   0.0191    -0.0035      0.0034 
##                        (0.0068)   (0.0268)   (0.0070)    (0.0378)
## Uninsured Leverage (z)  0.0156*    0.0061    -0.0116     -0.0221 
##                        (0.0074)   (0.0330)   (0.0069)    (0.0374)
## MTM $\times$ Uninsured  0.0187**   0.0110    -0.0017      0.0255 
##                        (0.0059)   (0.0247)   (0.0058)    (0.0310)
## Log(Assets)             0.0895***  0.1268***  0.0791***   0.0387 
##                        (0.0081)   (0.0305)   (0.0077)    (0.0310)
## Cash Ratio             -0.0035    -0.0208    -0.0081     -0.0327 
##                        (0.0057)   (0.0187)   (0.0054)    (0.0207)
## Loan-to-Deposit        -0.0009    -0.0024     0.0010     -0.0448 
##                        (0.0064)   (0.0253)   (0.0056)    (0.0346)
## Book Equity Ratio      -0.0036    -0.0076    -0.0086      0.0597 
##                        (0.0051)   (0.0423)   (0.0052)    (0.0531)
## Wholesale Funding       0.0200**  -0.0466     0.0316***   0.0233 
##                        (0.0064)   (0.0568)   (0.0073)    (0.0581)
## ROA                    -0.0019    -0.0245    -0.0096      0.0132 
##                        (0.0053)   (0.0203)   (0.0051)    (0.0171)
## ______________________ __________ __________ __________  ________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Het.-rob.
## Observations                3,314        304      3,148       230
## R2                        0.10116    0.14081    0.08255   0.05624
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

14 DEPOSIT BETA CHANNEL: Triple Interaction

14.1 Full Sample

# ==============================================================================
# DEPOSIT BETA CHANNEL — FULL SAMPLE
#
# DSSW predicts: panic region is wider when uninsured deposits are more
# rate-sensitive (higher β^U). The triple interaction MTM × Uninsured × β^U
# tests whether panic amplification is stronger for banks with flightier
# deposits. This is the empirical test of the DSSW franchise-run mechanism.
# ==============================================================================

cat("=== DEPOSIT BETA CHANNEL (FULL SAMPLE) ===\n")
## === DEPOSIT BETA CHANNEL (FULL SAMPLE) ===
df_beta_any  <- df_anyfed_s %>% filter(!is.na(uninsured_beta_w))
df_beta_btfp <- df_btfp_s   %>% filter(!is.na(uninsured_beta_w))
df_beta_dw   <- df_dw_s     %>% filter(!is.na(uninsured_beta_w))
df_beta_fhlb <- df_fhlb_s   %>% filter(!is.na(uninsured_beta_w))

cat("Beta coverage: AnyFed:", nrow(df_beta_any), "| BTFP:", nrow(df_beta_btfp),
    "| DW:", nrow(df_beta_dw), "| FHLB:", nrow(df_beta_fhlb), "\n")
## Beta coverage: AnyFed: 3991 | BTFP: 3665 | DW: 3599 | FHLB: 3468
# Nested (without triple) and full (with triple) for comparison
mod_beta_any_n  <- safe_run(df_beta_any,  "any_fed",     EXPL_BETA_NESTED)
mod_beta_any_f  <- safe_run(df_beta_any,  "any_fed",     EXPL_BETA_FULL)
mod_beta_btfp_n <- safe_run(df_beta_btfp, "btfp_crisis", EXPL_BETA_NESTED)
mod_beta_btfp_f <- safe_run(df_beta_btfp, "btfp_crisis", EXPL_BETA_FULL)
mod_beta_dw_n   <- safe_run(df_beta_dw,   "dw_crisis",   EXPL_BETA_NESTED)
mod_beta_dw_f   <- safe_run(df_beta_dw,   "dw_crisis",   EXPL_BETA_FULL)
mod_beta_fhlb_f <- safe_run(df_beta_fhlb, "fhlb_user",   EXPL_BETA_FULL)

models_beta_full <- list(
  "Any (nested)"  = mod_beta_any_n,  "Any (full)"  = mod_beta_any_f,
  "BTFP (nested)" = mod_beta_btfp_n, "BTFP (full)" = mod_beta_btfp_f,
  "DW (nested)"   = mod_beta_dw_n,   "DW (full)"   = mod_beta_dw_f,
  "FHLB (full)"   = mod_beta_fhlb_f)

save_etable(models_beta_full, "DepositBeta_full_sample",
  title_text = "Deposit Beta Channel: Full Sample — Triple Interaction",
  notes_text = paste0(
    "LPM. $\\beta^U$ is the bank's uninsured deposit beta (DSSW 2017/2021). ",
    "Triple: MTM $\\times$ Uninsured $\\times$ $\\beta^U$ tests whether ",
    "panic amplification is stronger for banks with flightier deposits. ",
    "FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Triple $\\beta^U$", "No", "Yes", "No", "Yes", "No", "Yes", "Yes")))

etable(models_beta_full[!sapply(models_beta_full, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                           Any (nes.. Any (full) BTFP (nes..
## Dependent Var.:                              any_fed    any_fed btfp_crisis
##                                                                            
## Constant                                   0.2079***  0.2076***   0.1436***
##                                           (0.0062)   (0.0062)    (0.0058)  
## MTM Loss (z)                               0.0303***  0.0292***   0.0257***
##                                           (0.0071)   (0.0072)    (0.0063)  
## Uninsured Leverage (z)                     0.0208**   0.0190*     0.0232** 
##                                           (0.0078)   (0.0078)    (0.0071)  
## Uninsured $\beta$ (z)                      0.0069     0.0066      0.0109   
##                                           (0.0074)   (0.0074)    (0.0068)  
## MTM $\times$ Uninsured                     0.0193**   0.0191**    0.0190***
##                                           (0.0060)   (0.0059)    (0.0055)  
## MTM $\times$ Unins. $\beta$                0.0068     0.0071      0.0100   
##                                           (0.0062)   (0.0062)    (0.0056)  
## Uninsured $\times$ Unins. $\beta$         -0.0024    -0.0080     -0.0022   
##                                           (0.0057)   (0.0068)    (0.0053)  
## Log(Assets)                                0.1072***  0.1074***   0.0713***
##                                           (0.0084)   (0.0084)    (0.0079)  
## Cash Ratio                                -0.0244*** -0.0241***  -0.0288***
##                                           (0.0064)   (0.0064)    (0.0051)  
## Loan-to-Deposit                           -0.0031    -0.0035     -0.0110   
##                                           (0.0073)   (0.0073)    (0.0062)  
## Book Equity Ratio                         -0.0145*   -0.0143*    -0.0128*  
##                                           (0.0060)   (0.0060)    (0.0051)  
## Wholesale Funding                          0.0297***  0.0303***   0.0266***
##                                           (0.0069)   (0.0069)    (0.0066)  
## ROA                                       -0.0030    -0.0029     -0.0069   
##                                           (0.0060)   (0.0060)    (0.0052)  
## MTM $\times$ Uninsured $\times$ $\beta^U$            -0.0100               
##                                                      (0.0056)              
## ________________________________________  __________ __________ ___________
## S.E. type                                 Hete.-rob. Hete.-rob. Heter.-rob.
## Observations                                   3,991      3,991       3,665
## R2                                           0.12031    0.12112     0.09721
## 
##                                           BTFP (full) DW (nest..  DW (full)
## Dependent Var.:                           btfp_crisis  dw_crisis  dw_crisis
##                                                                            
## Constant                                    0.1434***  0.1271***  0.1268***
##                                            (0.0058)   (0.0055)   (0.0055)  
## MTM Loss (z)                                0.0251***  0.0153*    0.0144*  
##                                            (0.0064)   (0.0062)   (0.0062)  
## Uninsured Leverage (z)                      0.0224**   0.0120     0.0103   
##                                            (0.0072)   (0.0068)   (0.0068)  
## Uninsured $\beta$ (z)                       0.0107     8.99e-5   -0.0004   
##                                            (0.0068)   (0.0065)   (0.0065)  
## MTM $\times$ Uninsured                      0.0188***  0.0171***  0.0170** 
##                                            (0.0055)   (0.0052)   (0.0052)  
## MTM $\times$ Unins. $\beta$                 0.0099     0.0018     0.0019   
##                                            (0.0057)   (0.0055)   (0.0054)  
## Uninsured $\times$ Unins. $\beta$          -0.0047     0.0029    -0.0028   
##                                            (0.0067)   (0.0052)   (0.0063)  
## Log(Assets)                                 0.0714***  0.0935***  0.0936***
##                                            (0.0079)   (0.0079)   (0.0079)  
## Cash Ratio                                 -0.0286*** -0.0036    -0.0033   
##                                            (0.0051)   (0.0055)   (0.0055)  
## Loan-to-Deposit                            -0.0112    -0.0001    -0.0003   
##                                            (0.0062)   (0.0063)   (0.0063)  
## Book Equity Ratio                          -0.0127*   -0.0010    -0.0008   
##                                            (0.0051)   (0.0048)   (0.0048)  
## Wholesale Funding                           0.0269***  0.0202**   0.0207** 
##                                            (0.0066)   (0.0064)   (0.0063)  
## ROA                                        -0.0069    -0.0032    -0.0032   
##                                            (0.0052)   (0.0052)   (0.0052)  
## MTM $\times$ Uninsured $\times$ $\beta^U$  -0.0044               -0.0094   
##                                            (0.0053)              (0.0051)  
## ________________________________________  ___________ __________ __________
## S.E. type                                 Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                                    3,665      3,599      3,599
## R2                                            0.09742    0.10270    0.10377
## 
##                                           FHLB (fu..
## Dependent Var.:                            fhlb_user
##                                                     
## Constant                                   0.0905***
##                                           (0.0051)  
## MTM Loss (z)                               0.0065   
##                                           (0.0057)  
## Uninsured Leverage (z)                     0.0083   
##                                           (0.0054)  
## Uninsured $\beta$ (z)                      0.0154*  
##                                           (0.0061)  
## MTM $\times$ Uninsured                    -0.0044   
##                                           (0.0046)  
## MTM $\times$ Unins. $\beta$                0.0040   
##                                           (0.0048)  
## Uninsured $\times$ Unins. $\beta$          0.0026   
##                                           (0.0055)  
## Log(Assets)                                0.0245***
##                                           (0.0067)  
## Cash Ratio                                -0.0196***
##                                           (0.0041)  
## Loan-to-Deposit                            0.0216***
##                                           (0.0054)  
## Book Equity Ratio                          0.0088   
##                                           (0.0045)  
## Wholesale Funding                          0.0032   
##                                           (0.0052)  
## ROA                                       -0.0092*  
##                                           (0.0045)  
## MTM $\times$ Uninsured $\times$ $\beta^U$ -0.0026   
##                                           (0.0046)  
## ________________________________________  __________
## S.E. type                                 Hete.-rob.
## Observations                                   3,468
## R2                                           0.04378
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

14.2 Jiang MTM Solvency Split

# ==============================================================================
# DEPOSIT BETA × JIANG MTM SOLVENCY
#
# GP prediction:
#   Solvent (panic region): Triple interaction β^U should be positive —
#     banks with flightier deposits have wider panic region → stronger
#     amplification of MTM × Uninsured
#   Insolvent (below θ̲): Triple should be zero —
#     β^U doesn't matter because withdrawal is dominant strategy
#
# Finding the triple ONLY among solvent banks confirms DSSW mechanism:
# franchise runs occur in the panic region, where franchise fragility (β^U)
# determines whether the good equilibrium holds.
# ==============================================================================

cat("=== DEPOSIT BETA × JIANG MTM SOLVENCY ===\n")
## === DEPOSIT BETA × JIANG MTM SOLVENCY ===
# Solvent samples (panic region)
df_beta_any_sol  <- df_beta_any  %>% filter(mtm_solvent == 1)
df_beta_btfp_sol <- df_beta_btfp %>% filter(mtm_solvent == 1)
df_beta_dw_sol   <- df_beta_dw   %>% filter(mtm_solvent == 1)

# Insolvent samples (below θ̲)
df_beta_any_ins  <- df_beta_any  %>% filter(mtm_insolvent == 1)
df_beta_btfp_ins <- df_beta_btfp %>% filter(mtm_insolvent == 1)
df_beta_dw_ins   <- df_beta_dw   %>% filter(mtm_insolvent == 1)

cat("Jiang Solvent — Any:", nrow(df_beta_any_sol), "| BTFP:", nrow(df_beta_btfp_sol),
    "| DW:", nrow(df_beta_dw_sol), "\n")
## Jiang Solvent — Any: 3210 | BTFP: 2944 | DW: 2936
cat("Jiang Insolvent — Any:", nrow(df_beta_any_ins), "| BTFP:", nrow(df_beta_btfp_ins),
    "| DW:", nrow(df_beta_dw_ins), "\n")
## Jiang Insolvent — Any: 781 | BTFP: 721 | DW: 663
# Solvent: full triple specification
mod_beta_any_sol_f  <- safe_run(df_beta_any_sol,  "any_fed",     EXPL_BETA_FULL)
mod_beta_btfp_sol_f <- safe_run(df_beta_btfp_sol, "btfp_crisis", EXPL_BETA_FULL)
mod_beta_dw_sol_f   <- safe_run(df_beta_dw_sol,   "dw_crisis",   EXPL_BETA_FULL)

# Insolvent: full triple specification
mod_beta_any_ins_f  <- safe_run(df_beta_any_ins,  "any_fed",     EXPL_BETA_FULL)
mod_beta_btfp_ins_f <- safe_run(df_beta_btfp_ins, "btfp_crisis", EXPL_BETA_FULL)
mod_beta_dw_ins_f   <- safe_run(df_beta_dw_ins,   "dw_crisis",   EXPL_BETA_FULL)

models_beta_jiang <- list(
  "Any (Sol)"  = mod_beta_any_sol_f,  "Any (Ins)"  = mod_beta_any_ins_f,
  "BTFP (Sol)" = mod_beta_btfp_sol_f, "BTFP (Ins)" = mod_beta_btfp_ins_f,
  "DW (Sol)"   = mod_beta_dw_sol_f,   "DW (Ins)"   = mod_beta_dw_ins_f)

save_etable(models_beta_jiang, "DepositBeta_jiang_solvency",
  title_text = "Deposit Beta $\\times$ Jiang Solvency: Triple Interaction",
  notes_text = paste0(
    "LPM with full triple interaction MTM $\\times$ Uninsured $\\times$ $\\beta^U$. ",
    "Jiang solvency: AE = Book Equity/TA $-$ MTM/TA $\\geq$ 0. ",
    "GP prediction: triple is positive among solvent (panic region) banks ",
    "and zero among insolvent (below $\\underline{\\theta}$) banks. ",
    "Finding the triple only among solvent banks confirms the DSSW mechanism: ",
    "franchise runs occur where deposit stickiness ($\\beta^U$) determines ",
    "whether the good equilibrium holds. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Solvency", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins")))

etable(models_beta_jiang[!sapply(models_beta_jiang, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                            Any (Sol)  Any (Ins)  BTFP (Sol)
## Dependent Var.:                              any_fed    any_fed btfp_crisis
##                                                                            
## Constant                                   0.2101***  0.1136      0.1431***
##                                           (0.0075)   (0.0622)    (0.0071)  
## MTM Loss (z)                               0.0379***  0.0004      0.0300***
##                                           (0.0087)   (0.0299)    (0.0075)  
## Uninsured Leverage (z)                     0.0266**  -0.0149      0.0303***
##                                           (0.0092)   (0.0355)    (0.0084)  
## Uninsured $\beta$ (z)                      0.0137    -0.0038      0.0174*  
##                                           (0.0087)   (0.0428)    (0.0080)  
## MTM $\times$ Uninsured                     0.0218**   0.0355      0.0216***
##                                           (0.0070)   (0.0279)    (0.0063)  
## MTM $\times$ Unins. $\beta$                0.0113    -0.0060      0.0152*  
##                                           (0.0074)   (0.0314)    (0.0068)  
## Uninsured $\times$ Unins. $\beta$         -0.0141     0.0609     -0.0043   
##                                           (0.0081)   (0.0373)    (0.0079)  
## MTM $\times$ Uninsured $\times$ $\beta^U$ -0.0143*   -0.0524     -0.0033   
##                                           (0.0066)   (0.0286)    (0.0062)  
## Log(Assets)                                0.1005***  0.1404***   0.0643***
##                                           (0.0091)   (0.0221)    (0.0084)  
## Cash Ratio                                -0.0196**  -0.0786**   -0.0258***
##                                           (0.0066)   (0.0240)    (0.0051)  
## Loan-to-Deposit                           -0.0049     0.0152     -0.0129*  
##                                           (0.0078)   (0.0224)    (0.0065)  
## Book Equity Ratio                         -0.0107    -0.1258**   -0.0071   
##                                           (0.0064)   (0.0444)    (0.0053)  
## Wholesale Funding                          0.0315***  0.0196      0.0271***
##                                           (0.0078)   (0.0152)    (0.0072)  
## ROA                                        0.0024    -0.0312     -0.0024   
##                                           (0.0064)   (0.0168)    (0.0054)  
## ________________________________________  __________ __________ ___________
## S.E. type                                 Hete.-rob. Hete.-rob. Heter.-rob.
## Observations                                   3,210        781       2,944
## R2                                           0.12558    0.12320     0.09884
## 
##                                            BTFP (Ins)   DW (Sol)   DW (Ins)
## Dependent Var.:                           btfp_crisis  dw_crisis  dw_crisis
##                                                                            
## Constant                                    0.0571     0.1326***  0.0607   
##                                            (0.0585)   (0.0068)   (0.0500)  
## MTM Loss (z)                                0.0021     0.0235**   0.0010   
##                                            (0.0282)   (0.0077)   (0.0237)  
## Uninsured Leverage (z)                     -0.0181     0.0155    -0.0004   
##                                            (0.0334)   (0.0082)   (0.0282)  
## Uninsured $\beta$ (z)                       0.0118     0.0049    -0.0210   
##                                            (0.0420)   (0.0077)   (0.0303)  
## MTM $\times$ Uninsured                      0.0340     0.0194**   0.0225   
##                                            (0.0262)   (0.0062)   (0.0218)  
## MTM $\times$ Unins. $\beta$                -0.0106     0.0041     0.0015   
##                                            (0.0303)   (0.0067)   (0.0221)  
## Uninsured $\times$ Unins. $\beta$           0.0266    -0.0093     0.0655*  
##                                            (0.0349)   (0.0078)   (0.0278)  
## MTM $\times$ Uninsured $\times$ $\beta^U$  -0.0381    -0.0141*   -0.0478*  
##                                            (0.0273)   (0.0062)   (0.0211)  
## Log(Assets)                                 0.1067***  0.0893***  0.1120***
##                                            (0.0222)   (0.0085)   (0.0207)  
## Cash Ratio                                 -0.0735*** -0.0006    -0.0392*  
##                                            (0.0216)   (0.0058)   (0.0190)  
## Loan-to-Deposit                             0.0125    -0.0029     0.0106   
##                                            (0.0210)   (0.0067)   (0.0180)  
## Book Equity Ratio                          -0.1237**  -0.0019    -0.0622   
##                                            (0.0422)   (0.0054)   (0.0354)  
## Wholesale Funding                           0.0190     0.0223**   0.0119   
##                                            (0.0149)   (0.0071)   (0.0144)  
## ROA                                        -0.0301     0.0013    -0.0272   
##                                            (0.0154)   (0.0055)   (0.0140)  
## ________________________________________  ___________ __________ __________
## S.E. type                                 Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                                      721      2,936        663
## R2                                            0.10031    0.10861    0.11365
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

14.3 IDCR-100% Solvency Split

# ==============================================================================
# DEPOSIT BETA × IDCR-100% SOLVENCY
# Same logic, stricter solvency definition
# ==============================================================================

cat("=== DEPOSIT BETA × IDCR-100% SOLVENCY ===\n")
## === DEPOSIT BETA × IDCR-100% SOLVENCY ===
df_beta_any_idcr_sol  <- df_beta_any  %>% filter(solvent_idcr_100 == 1)
df_beta_any_idcr_ins  <- df_beta_any  %>% filter(insolvent_idcr_100 == 1)
df_beta_btfp_idcr_sol <- df_beta_btfp %>% filter(solvent_idcr_100 == 1)
df_beta_btfp_idcr_ins <- df_beta_btfp %>% filter(insolvent_idcr_100 == 1)
df_beta_dw_idcr_sol   <- df_beta_dw   %>% filter(solvent_idcr_100 == 1)
df_beta_dw_idcr_ins   <- df_beta_dw   %>% filter(insolvent_idcr_100 == 1)

cat("IDCR Solvent — Any:", nrow(df_beta_any_idcr_sol), "| BTFP:", nrow(df_beta_btfp_idcr_sol),
    "| DW:", nrow(df_beta_dw_idcr_sol), "\n")
## IDCR Solvent — Any: 3648 | BTFP: 3343 | DW: 3302
cat("IDCR Insolvent — Any:", nrow(df_beta_any_idcr_ins), "| BTFP:", nrow(df_beta_btfp_idcr_ins),
    "| DW:", nrow(df_beta_dw_idcr_ins), "\n")
## IDCR Insolvent — Any: 343 | BTFP: 322 | DW: 297
mod_beta_any_idcr_sol_f  <- safe_run(df_beta_any_idcr_sol,  "any_fed",     EXPL_BETA_FULL)
mod_beta_any_idcr_ins_f  <- safe_run(df_beta_any_idcr_ins,  "any_fed",     EXPL_BETA_FULL)
mod_beta_btfp_idcr_sol_f <- safe_run(df_beta_btfp_idcr_sol, "btfp_crisis", EXPL_BETA_FULL)
mod_beta_btfp_idcr_ins_f <- safe_run(df_beta_btfp_idcr_ins, "btfp_crisis", EXPL_BETA_FULL)
mod_beta_dw_idcr_sol_f   <- safe_run(df_beta_dw_idcr_sol,   "dw_crisis",   EXPL_BETA_FULL)
mod_beta_dw_idcr_ins_f   <- safe_run(df_beta_dw_idcr_ins,   "dw_crisis",   EXPL_BETA_FULL)

models_beta_idcr <- list(
  "Any (Sol)"  = mod_beta_any_idcr_sol_f,  "Any (Ins)"  = mod_beta_any_idcr_ins_f,
  "BTFP (Sol)" = mod_beta_btfp_idcr_sol_f, "BTFP (Ins)" = mod_beta_btfp_idcr_ins_f,
  "DW (Sol)"   = mod_beta_dw_idcr_sol_f,   "DW (Ins)"   = mod_beta_dw_idcr_ins_f)

save_etable(models_beta_idcr, "DepositBeta_idcr100_solvency",
  title_text = "Deposit Beta $\\times$ IDCR-100\\% Solvency: Triple Interaction",
  notes_text = paste0(
    "LPM with full triple interaction. IDCR-100\\% solvency: ",
    "(MV Assets $-$ Uninsured $-$ Insured) / Insured $\\geq$ 0. ",
    "Same GP prediction as Jiang split. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Solvency", "Sol", "Ins", "Sol", "Ins", "Sol", "Ins")))

etable(models_beta_idcr[!sapply(models_beta_idcr, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                            Any (Sol)  Any (Ins)  BTFP (Sol)
## Dependent Var.:                              any_fed    any_fed btfp_crisis
##                                                                            
## Constant                                   0.2098***  0.1448      0.1443***
##                                           (0.0066)   (0.0827)    (0.0062)  
## MTM Loss (z)                               0.0328***  0.0087      0.0267***
##                                           (0.0078)   (0.0396)    (0.0069)  
## Uninsured Leverage (z)                     0.0229**  -0.0020      0.0244** 
##                                           (0.0084)   (0.0466)    (0.0078)  
## Uninsured $\beta$ (z)                      0.0088    -0.0069      0.0124   
##                                           (0.0079)   (0.0700)    (0.0073)  
## MTM $\times$ Uninsured                     0.0210**   0.0163      0.0197** 
##                                           (0.0064)   (0.0350)    (0.0060)  
## MTM $\times$ Unins. $\beta$                0.0078    -0.0025      0.0114   
##                                           (0.0067)   (0.0506)    (0.0062)  
## Uninsured $\times$ Unins. $\beta$         -0.0085     0.0352     -0.0045   
##                                           (0.0073)   (0.0503)    (0.0072)  
## MTM $\times$ Uninsured $\times$ $\beta^U$ -0.0100    -0.0454     -0.0037   
##                                           (0.0060)   (0.0411)    (0.0057)  
## Log(Assets)                                0.1034***  0.1487***   0.0706***
##                                           (0.0088)   (0.0330)    (0.0082)  
## Cash Ratio                                -0.0227*** -0.0616*    -0.0272***
##                                           (0.0066)   (0.0277)    (0.0052)  
## Loan-to-Deposit                           -0.0045     0.0018     -0.0119   
##                                           (0.0075)   (0.0360)    (0.0064)  
## Book Equity Ratio                         -0.0153*   -0.0443     -0.0124*  
##                                           (0.0063)   (0.0570)    (0.0053)  
## Wholesale Funding                          0.0305*** -0.0797      0.0273***
##                                           (0.0070)   (0.0710)    (0.0066)  
## ROA                                       -0.0013    -0.0239     -0.0061   
##                                           (0.0063)   (0.0233)    (0.0053)  
## ________________________________________  __________ __________ ___________
## S.E. type                                 Hete.-rob. Hete.-rob. Heter.-rob.
## Observations                                   3,648        343       3,343
## R2                                           0.12319    0.12269     0.10145
## 
##                                            BTFP (Ins)   DW (Sol)   DW (Ins)
## Dependent Var.:                           btfp_crisis  dw_crisis  dw_crisis
##                                                                            
## Constant                                      0.0737   0.1302***  0.0838   
##                                              (0.0784) (0.0060)   (0.0640)  
## MTM Loss (z)                                  0.0161   0.0185**   0.0026   
##                                              (0.0368) (0.0069)   (0.0286)  
## Uninsured Leverage (z)                        0.0089   0.0142     0.0058   
##                                              (0.0416) (0.0075)   (0.0422)  
## Uninsured $\beta$ (z)                         0.0051   0.0031    -0.0170   
##                                              (0.0671) (0.0071)   (0.0391)  
## MTM $\times$ Uninsured                        0.0187   0.0194***  0.0003   
##                                              (0.0318) (0.0058)   (0.0288)  
## MTM $\times$ Unins. $\beta$                  -0.0005   0.0037    -0.0161   
##                                              (0.0472) (0.0060)   (0.0308)  
## Uninsured $\times$ Unins. $\beta$             0.0442  -0.0022     0.0201   
##                                              (0.0502) (0.0070)   (0.0378)  
## MTM $\times$ Uninsured $\times$ $\beta^U$    -0.0490  -0.0087    -0.0317   
##                                              (0.0386) (0.0056)   (0.0308)  
## Log(Assets)                                   0.0788*  0.0896***  0.1339***
##                                              (0.0319) (0.0082)   (0.0310)  
## Cash Ratio                                   -0.0571* -0.0028    -0.0247   
##                                              (0.0258) (0.0057)   (0.0182)  
## Loan-to-Deposit                               0.0041  -0.0022    -0.0023   
##                                              (0.0337) (0.0065)   (0.0261)  
## Book Equity Ratio                            -0.0646  -0.0027    -0.0012   
##                                              (0.0531) (0.0052)   (0.0416)  
## Wholesale Funding                            -0.0461   0.0203**  -0.0521   
##                                              (0.0709) (0.0064)   (0.0568)  
## ROA                                          -0.0170  -0.0016    -0.0194   
##                                              (0.0214) (0.0053)   (0.0201)  
## ________________________________________  ___________ __________ __________
## S.E. type                                 Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                                      322      3,302        297
## R2                                            0.07291    0.10160    0.16578
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

14.4 Uninsured Beta Diagnostics

cat("--- Uninsured Beta Distribution ---\n")
## --- Uninsured Beta Distribution ---
print(summary(df_2022q4$uninsured_beta_raw))
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max.     NA's 
## -0.08442  0.26609  0.31059  0.33127  0.37339  1.35983       66
cat("\n--- Mean β^U by Jiang Solvency ---\n")
## 
## --- Mean β^U by Jiang Solvency ---
df_2022q4 %>%
  filter(!is.na(uninsured_beta_raw)) %>%
  group_by(Jiang_Solvent = mtm_solvent) %>%
  summarise(N = n(), Mean_BetaU = round(mean(uninsured_beta_raw, na.rm=T), 4),
    SD = round(sd(uninsured_beta_raw, na.rm=T), 4), .groups = "drop") %>%
  print()
## # A tibble: 2 × 4
##   Jiang_Solvent     N Mean_BetaU    SD
##           <int> <int>      <dbl> <dbl>
## 1             0   813      0.309 0.08 
## 2             1  3413      0.337 0.111
cat("\n--- Correlation Matrix ---\n")
## 
## --- Correlation Matrix ---
cor_df <- df_2022q4 %>%
  select(uninsured_beta_raw, beta_overall, uninsured_lev_raw, mtm_total_raw, dfv_raw) %>%
  drop_na()
if (nrow(cor_df) > 10) print(round(cor(cor_df), 3))
##                    uninsured_beta_raw beta_overall uninsured_lev_raw
## uninsured_beta_raw              1.000        0.925            -0.058
## beta_overall                    0.925        1.000             0.298
## uninsured_lev_raw              -0.058        0.298             1.000
## mtm_total_raw                  -0.134       -0.190            -0.155
## dfv_raw                        -0.765       -0.834            -0.133
##                    mtm_total_raw dfv_raw
## uninsured_beta_raw        -0.134  -0.765
## beta_overall              -0.190  -0.834
## uninsured_lev_raw         -0.155  -0.133
## mtm_total_raw              1.000   0.184
## dfv_raw                    0.184   1.000

15 FACILITY COMPLEMENTARITY (Model 4)

15.1 4a. Multinomial Facility Choice

cat("=== FACILITY COMPLEMENTARITY ===\n\n")
## === FACILITY COMPLEMENTARITY ===
df_emerg <- df_crisis %>%
  filter(any_fed == 1) %>%
  mutate(facility_choice = factor(case_when(
    both_fed == 1    ~ "Both",
    btfp_crisis == 1 ~ "BTFP_Only",
    dw_crisis == 1   ~ "DW_Only"),
    levels = c("DW_Only", "BTFP_Only", "Both")))

cat("Facility choice (Crisis emergency borrowers):\n")
## Facility choice (Crisis emergency borrowers):
print(table(df_emerg$facility_choice))
## 
##   DW_Only BTFP_Only      Both 
##       327       395       106
ff_mnom <- as.formula(paste0("facility_choice ~ mtm_total + uninsured_lev + mtm_x_uninsured + par_benefit + collateral_capacity + ", CONTROLS))

mod4a <- tryCatch(multinom(ff_mnom, data = df_emerg, trace = FALSE),
  error = function(e) { message("Multinom failed: ", e$message); NULL })

if (!is.null(mod4a)) {
  cat("\nAIC:", AIC(mod4a), "\n\n")
  tidy_m <- tidy(mod4a, conf.int = TRUE) %>%
    mutate(stars = case_when(p.value < 0.01 ~ "***", p.value < 0.05 ~ "**",
                             p.value < 0.10 ~ "*", TRUE ~ ""),
           disp = sprintf("%.3f%s (%.3f)", estimate, stars, std.error))

  cat("--- Key Coefficients (Base = DW Only) ---\n")
  tidy_m %>%
    filter(term %in% c("mtm_total", "uninsured_lev", "mtm_x_uninsured",
                        "par_benefit", "collateral_capacity")) %>%
    select(Outcome = y.level, Variable = term, Estimate = disp) %>%
    print(n = 20)
}
## 
## AIC: 1567.913 
## 
## --- Key Coefficients (Base = DW Only) ---
## # A tibble: 10 × 3
##    Outcome   Variable            Estimate         
##    <chr>     <chr>               <chr>            
##  1 BTFP_Only mtm_total           0.120 (0.103)    
##  2 BTFP_Only uninsured_lev       0.120 (0.093)    
##  3 BTFP_Only mtm_x_uninsured     -0.103 (0.086)   
##  4 BTFP_Only par_benefit         -0.342*** (0.131)
##  5 BTFP_Only collateral_capacity 0.240** (0.103)  
##  6 Both      mtm_total           -0.196 (0.172)   
##  7 Both      uninsured_lev       0.286** (0.134)  
##  8 Both      mtm_x_uninsured     0.113 (0.129)    
##  9 Both      par_benefit         0.284 (0.380)    
## 10 Both      collateral_capacity 0.106 (0.149)

15.2 4b. Complementarity: DW Borrowers → Also BTFP?

df_dw_comp <- df_crisis %>%
  filter(dw_crisis == 1) %>%
  mutate(also_btfp = as.integer(btfp_crisis == 1))

cat("DW borrowers:", nrow(df_dw_comp), "| Also BTFP:", sum(df_dw_comp$also_btfp), "\n")
## DW borrowers: 433 | Also BTFP: 106
mod4b_base <- safe_run(df_dw_comp, "also_btfp", EXPL_BASE, min_n = 20)
mod4b_fac  <- safe_run(df_dw_comp, "also_btfp", EXPL_FACILITY, min_n = 20)

models_4b <- list("Base" = mod4b_base, "Facility" = mod4b_fac)

save_etable(models_4b, "M4b_complementarity",
  title_text = "Complementarity: Among DW Borrowers, What Drove Also-BTFP?",
  notes_text = "LPM. Sample: DW borrowers (Crisis). DV=1 if also used BTFP. Robust SEs.")

etable(models_4b[!sapply(models_4b, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                              Base   Facility
## Dependent Var.:         Also BTFP  Also BTFP
##                                             
## Constant                0.1686***  0.1668***
##                        (0.0235)   (0.0231)  
## MTM Loss (z)           -0.0219    -0.0186   
##                        (0.0242)   (0.0246)  
## Uninsured Leverage (z)  0.0490*    0.0499*  
##                        (0.0241)   (0.0243)  
## MTM $\times$ Uninsured  0.0200     0.0200   
##                        (0.0212)   (0.0214)  
## Log(Assets)             0.0590*    0.0563*  
##                        (0.0247)   (0.0253)  
## Cash Ratio             -0.0472    -0.0422   
##                        (0.0263)   (0.0266)  
## Loan-to-Deposit        -0.0270    -0.0103   
##                        (0.0285)   (0.0338)  
## Book Equity Ratio      -0.0502    -0.0517   
##                        (0.0261)   (0.0264)  
## Wholesale Funding       0.0244     0.0217   
##                        (0.0176)   (0.0177)  
## ROA                    -0.0258    -0.0215   
##                        (0.0236)   (0.0240)  
## Par Benefit (z)                    0.0132   
##                                   (0.0154)  
## OMO Collateral (z)                 0.0261   
##                                   (0.0283)  
## ______________________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob.
## Observations                  433        433
## R2                        0.08055    0.08293
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

15.3 4c. Substitution: BTFP-Only vs. DW-Only

df_subst <- df_crisis %>%
  filter(user_group %in% c("BTFP_Only", "DW_Only")) %>%
  mutate(chose_btfp = as.integer(user_group == "BTFP_Only"))

cat("BTFP-only:", sum(df_subst$chose_btfp), "| DW-only:", sum(df_subst$chose_btfp==0), "\n")
## BTFP-only: 395 | DW-only: 327
mod4c_base <- safe_run(df_subst, "chose_btfp", EXPL_BASE, min_n = 20)
mod4c_fac  <- safe_run(df_subst, "chose_btfp", EXPL_FACILITY, min_n = 20)
mod4c_stig <- safe_run(df_subst, "chose_btfp",
  paste0(EXPL_FACILITY, " + par_x_uninsured"), min_n = 20)

models_4c <- list("Base" = mod4c_base, "Facility" = mod4c_fac, "Stigma" = mod4c_stig)

save_etable(models_4c, "M4c_substitution",
  title_text = "Substitution: BTFP-Only vs. DW-Only",
  notes_text = "LPM. Sample: single-facility borrowers (Crisis). DV=1 if BTFP, 0 if DW. Robust SEs.")

etable(models_4c[!sapply(models_4c, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                              Base   Facility     Stigma
## Dependent Var.:        chose_btfp chose_btfp chose_btfp
##                                                        
## Constant                0.5364***  0.5378***  0.5341***
##                        (0.0243)   (0.0242)   (0.0245)  
## MTM Loss (z)            0.0092     0.0277     0.0239   
##                        (0.0240)   (0.0243)   (0.0245)  
## Uninsured Leverage (z)  0.0274     0.0270     0.0257   
##                        (0.0231)   (0.0223)   (0.0225)  
## MTM $\times$ Uninsured -0.0193    -0.0197    -0.0135   
##                        (0.0205)   (0.0199)   (0.0206)  
## Log(Assets)            -0.0808*** -0.0791*** -0.0739** 
##                        (0.0233)   (0.0229)   (0.0236)  
## Cash Ratio             -0.1242*** -0.1201*** -0.1228***
##                        (0.0300)   (0.0285)   (0.0287)  
## Loan-to-Deposit        -0.0466    -0.0115    -0.0174   
##                        (0.0276)   (0.0301)   (0.0304)  
## Book Equity Ratio      -0.0380    -0.0431    -0.0408   
##                        (0.0284)   (0.0287)   (0.0288)  
## Wholesale Funding       0.0058     0.0027     0.0028   
##                        (0.0156)   (0.0155)   (0.0155)  
## ROA                    -0.0080    -0.0037    -0.0005   
##                        (0.0232)   (0.0233)   (0.0234)  
## Par Benefit (z)                   -0.0675**  -0.0505   
##                                   (0.0245)   (0.0314)  
## OMO Collateral (z)                 0.0550*    0.0544*  
##                                   (0.0227)   (0.0228)  
## Par $\times$ Uninsured                       -0.0294   
##                                              (0.0225)  
## ______________________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                  722        722        722
## R2                        0.06253    0.07826    0.08051
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

15.4 4d. Descriptive Evidence

desc_vars <- c("mtm_total_raw", "mtm_btfp_raw", "uninsured_lev_raw",
  "book_equity_ratio_raw", "adjusted_equity_raw", "dfv_raw",
  "ln_assets_raw", "cash_ratio_raw", "par_benefit_raw", "collateral_capacity_raw")

cat("--- Mean Characteristics by Facility Choice ---\n")
## --- Mean Characteristics by Facility Choice ---
df_emerg %>%
  group_by(facility_choice) %>%
  summarise(N = n(), across(all_of(desc_vars), ~round(mean(., na.rm=T), 3)), .groups = "drop") %>%
  print(width = Inf)
## # A tibble: 3 × 12
##   facility_choice     N mtm_total_raw mtm_btfp_raw uninsured_lev_raw
##   <fct>           <int>         <dbl>        <dbl>             <dbl>
## 1 DW_Only           327          5.72        0.728              26.8
## 2 BTFP_Only         395          6.18        0.875              26.2
## 3 Both              106          5.83        0.924              32.0
##   book_equity_ratio_raw adjusted_equity_raw dfv_raw ln_assets_raw cash_ratio_raw
##                   <dbl>               <dbl>   <dbl>         <dbl>          <dbl>
## 1                  9.10                3.38    74.6          13.8           6.15
## 2                  8.19                2.01    75.6          13.5           4.69
## 3                  8.14                2.31    70.0          14.6           4.62
##   par_benefit_raw collateral_capacity_raw
##             <dbl>                   <dbl>
## 1           0.962                   0.009
## 2           0.933                   0.012
## 3           0.978                   0.011
# T-tests: BTFP-only vs DW-only
cat("\n--- T-Tests: BTFP-Only vs DW-Only ---\n")
## 
## --- T-Tests: BTFP-Only vs DW-Only ---
btfp_only <- df_emerg %>% filter(facility_choice == "BTFP_Only")
dw_only   <- df_emerg %>% filter(facility_choice == "DW_Only")

for (v in desc_vars) {
  tt <- tryCatch(t.test(btfp_only[[v]], dw_only[[v]]), error = function(e) NULL)
  if (!is.null(tt)) {
    stars <- case_when(tt$p.value < 0.01 ~ "***", tt$p.value < 0.05 ~ "**",
                       tt$p.value < 0.10 ~ "*", TRUE ~ "")
    cat(sprintf("  %-28s BTFP=%.3f DW=%.3f diff=%.3f t=%.2f %s\n", v,
      mean(btfp_only[[v]], na.rm=T), mean(dw_only[[v]], na.rm=T),
      mean(btfp_only[[v]], na.rm=T) - mean(dw_only[[v]], na.rm=T),
      tt$statistic, stars))
  }
}
##   mtm_total_raw                BTFP=6.175 DW=5.718 diff=0.458 t=3.07 ***
##   mtm_btfp_raw                 BTFP=0.875 DW=0.728 diff=0.147 t=2.15 **
##   uninsured_lev_raw            BTFP=26.154 DW=26.774 diff=-0.621 t=-0.71 
##   book_equity_ratio_raw        BTFP=8.188 DW=9.097 diff=-0.909 t=-3.82 ***
##   adjusted_equity_raw          BTFP=2.012 DW=3.379 diff=-1.367 t=-4.36 ***
##   dfv_raw                      BTFP=75.609 DW=74.630 diff=0.980 t=1.02 
##   ln_assets_raw                BTFP=13.486 DW=13.833 diff=-0.347 t=-3.22 ***
##   cash_ratio_raw               BTFP=4.686 DW=6.151 diff=-1.465 t=-3.43 ***
##   par_benefit_raw              BTFP=0.933 DW=0.962 diff=-0.029 t=-2.15 **
##   collateral_capacity_raw      BTFP=0.012 DW=0.009 diff=0.002 t=3.15 ***

16 COMPREHENSIVE SOLVENCY COMPARISON

# ==============================================================================
# Three-way solvency cross-tab and visualization
# ==============================================================================

cat("=== SOLVENCY COMPARISON ACROSS FRAMEWORKS ===\n\n")
## === SOLVENCY COMPARISON ACROSS FRAMEWORKS ===
# Full cross-tab
solv_tab <- df_2022q4 %>%
  filter(!is.na(dssw_solvent)) %>%
  count(
    Jiang = ifelse(mtm_insolvent == 1, "Jiang-Ins", "Jiang-Sol"),
    IDCR  = ifelse(insolvent_idcr_100 == 1, "IDCR-Ins", "IDCR-Sol"),
    DSSW  = ifelse(dssw_insolvent == 1, "DSSW-Ins", "DSSW-Sol")
  ) %>%
  arrange(Jiang, IDCR, DSSW)

cat("--- Three-Way Cross-Tab ---\n")
## --- Three-Way Cross-Tab ---
print(solv_tab)
## # A tibble: 6 × 4
##   Jiang     IDCR     DSSW         n
##   <chr>     <chr>    <chr>    <int>
## 1 Jiang-Ins IDCR-Ins DSSW-Sol   355
## 2 Jiang-Ins IDCR-Sol DSSW-Sol   470
## 3 Jiang-Sol IDCR-Ins DSSW-Sol     9
## 4 Jiang-Sol IDCR-Sol DSSW-Sol  3417
## 5 Jiang-Sol <NA>     DSSW-Sol    31
## 6 <NA>      <NA>     DSSW-Sol    10
# Summary
cat("\n--- Classification Summary ---\n")
## 
## --- Classification Summary ---
cat(sprintf("  Jiang-insolvent:  %d (%.1f%%)\n",
    sum(df_2022q4$mtm_insolvent, na.rm=T),
    100 * mean(df_2022q4$mtm_insolvent, na.rm=T)))
##   Jiang-insolvent:  825 (19.3%)
cat(sprintf("  IDCR-insolvent:   %d (%.1f%%)\n",
    sum(df_2022q4$insolvent_idcr_100, na.rm=T),
    100 * mean(df_2022q4$insolvent_idcr_100, na.rm=T)))
##   IDCR-insolvent:   364 (8.6%)
cat(sprintf("  DSSW-insolvent:   %d (%.1f%%)\n",
    sum(df_2022q4$dssw_insolvent, na.rm=T),
    100 * mean(df_2022q4$dssw_insolvent, na.rm=T)))
##   DSSW-insolvent:   0 (0.0%)
# Euler-style summary of how frameworks relate
cat("\n--- Theoretical Interpretation ---\n")
## 
## --- Theoretical Interpretation ---
cat("  Jiang:  Book Equity > MTM losses? (asset-side solvency)\n")
##   Jiang:  Book Equity > MTM losses? (asset-side solvency)
cat("  IDCR:   Can bank pay ALL depositors after 100% uninsured run? (run-scenario)\n")
##   IDCR:   Can bank pay ALL depositors after 100% uninsured run? (run-scenario)
cat("  DSSW:   Include franchise value (no-run equilibrium solvency)\n")
##   DSSW:   Include franchise value (no-run equilibrium solvency)
cat("  → IDCR is stricter than Jiang (accounts for deposit payoff priority)\n")
##   → IDCR is stricter than Jiang (accounts for deposit payoff priority)
cat("  → DSSW is most lenient (adds intangible franchise value)\n")
##   → DSSW is most lenient (adds intangible franchise value)
cat("  → The gap between DSSW-solvent and Jiang/IDCR-insolvent IS the panic region\n")
##   → The gap between DSSW-solvent and Jiang/IDCR-insolvent IS the panic region
# Visualization: Adjusted Equity distributions by framework
df_kde_solv <- df_2022q4 %>%
  filter(!is.na(adjusted_equity_dssw_raw)) %>%
  select(adjusted_equity_raw, adjusted_equity_dssw_raw, idcr_100) %>%
  pivot_longer(cols = c(adjusted_equity_raw, adjusted_equity_dssw_raw),
    names_to = "Framework", values_to = "Value") %>%
  mutate(Framework = case_when(
    Framework == "adjusted_equity_raw" ~ "Jiang (Book Eq. − MTM)",
    Framework == "adjusted_equity_dssw_raw" ~ "DSSW (+ Franchise Value)"))

p_solv <- ggplot(df_kde_solv, aes(x = Value, fill = Framework, color = Framework)) +
  geom_density(alpha = 0.4, linewidth = 0.8) +
  geom_vline(xintercept = 0, linetype = "dotted", color = "red", linewidth = 1) +
  scale_fill_manual(values = c("Jiang (Book Eq. − MTM)" = "#D62828",
    "DSSW (+ Franchise Value)" = "#2A9D8F")) +
  scale_color_manual(values = c("Jiang (Book Eq. − MTM)" = "#D62828",
    "DSSW (+ Franchise Value)" = "#2A9D8F")) +
  labs(title = "Solvency Distributions: Jiang vs. DSSW",
    subtitle = "DSSW shifts the entire distribution rightward by ~68pp. Zero banks are DSSW-insolvent.",
    x = "Adjusted Equity (% of Assets)", y = "Density") +
  theme_paper +
  annotate("text", x = -3, y = 0.08, label = "Jiang\ninsolvent\nzone",
    color = "#D62828", size = 3, fontface = "italic")

p_solv

save_figure(p_solv, "Fig_Solvency_Jiang_vs_DSSW_KDE", width = 10, height = 6)

17 SIZE-SPLIT REGRESSIONS: Small (≤$10B) vs. Large (>$10B)

# ==============================================================================
# SIZE SPLIT: ≤ $10B vs. > $10B total assets
#
# Banks of different sizes face different run dynamics:
#   - Small banks: more reliant on insured deposits, less market scrutiny
#   - Large banks: more uninsured deposits, subject to market discipline
#
# We re-run the main regression for each size group separately.
# ==============================================================================

cat("=== SIZE SPLIT: ≤$10B vs. >$10B ===\n\n")
## === SIZE SPLIT: ≤$10B vs. >$10B ===
# total_asset is in $000s → $10B = 10,000,000 thousands
SIZE_CUTOFF <- 10e6  # $10B in $000s

# --- Create size flag on each sample ---
add_size_flag <- function(df) {
 df %>% mutate(
    size_group = ifelse(total_asset <= SIZE_CUTOFF, "Small (<=10B)", "Large (>10B)"),
    size_group = factor(size_group, levels = c("Small (<=10B)", "Large (>10B)"))
  )
}

df_anyfed_s <- add_size_flag(df_anyfed_s)
df_btfp_s   <- add_size_flag(df_btfp_s)
df_dw_s     <- add_size_flag(df_dw_s)
df_fhlb_s   <- add_size_flag(df_fhlb_s)

# Counts
for (sz in c("Small (<=10B)", "Large (>10B)")) {
  cat(sprintf("  %s:\n", sz))
  cat(sprintf("    AnyFed: N=%d, Borrowers=%d\n",
    sum(df_anyfed_s$size_group == sz),
    sum(df_anyfed_s$any_fed[df_anyfed_s$size_group == sz])))
  cat(sprintf("    BTFP:   N=%d, Borrowers=%d\n",
    sum(df_btfp_s$size_group == sz),
    sum(df_btfp_s$btfp_crisis[df_btfp_s$size_group == sz])))
  cat(sprintf("    DW:     N=%d, Borrowers=%d\n",
    sum(df_dw_s$size_group == sz),
    sum(df_dw_s$dw_crisis[df_dw_s$size_group == sz])))
  cat(sprintf("    FHLB:   N=%d, Borrowers=%d\n",
    sum(df_fhlb_s$size_group == sz),
    sum(df_fhlb_s$fhlb_user[df_fhlb_s$size_group == sz])))
}
##   Small (<=10B):
##     AnyFed: N=3928, Borrowers=759
##     BTFP:   N=3628, Borrowers=459
##     DW:     N=3552, Borrowers=383
##     FHLB:   N=3451, Borrowers=282
##   Large (>10B):
##     AnyFed: N=126, Borrowers=69
##     BTFP:   N=99, Borrowers=42
##     DW:     N=107, Borrowers=50
##     FHLB:   N=77, Borrowers=20

17.1 Small Banks (≤$10B)

cat("=== SMALL BANKS (≤$10B) ===\n")
## === SMALL BANKS (≤$10B) ===
mod_sz_any_sm  <- safe_run(df_anyfed_s %>% filter(size_group == "Small (<=10B)"), "any_fed",     EXPL_BASE)
mod_sz_btfp_sm <- safe_run(df_btfp_s   %>% filter(size_group == "Small (<=10B)"), "btfp_crisis", EXPL_BASE)
mod_sz_dw_sm   <- safe_run(df_dw_s     %>% filter(size_group == "Small (<=10B)"), "dw_crisis",   EXPL_BASE)
mod_sz_fhlb_sm <- safe_run(df_fhlb_s   %>% filter(size_group == "Small (<=10B)"), "fhlb_user",   EXPL_BASE)

models_sz_sm <- list(
  "Any Fed" = mod_sz_any_sm, "BTFP" = mod_sz_btfp_sm,
  "DW" = mod_sz_dw_sm, "FHLB" = mod_sz_fhlb_sm)

save_etable(models_sz_sm, "Size_small_le10B",
  title_text = "Size Split: Small Banks ($\\leq$ \\$10B) — Extensive Margin (Crisis)",
  notes_text = "LPM. Sample restricted to banks with total assets $\\leq$ \\$10B. Robust SEs. z-standardized.",
  extra_lines = list(c("Size Group", "Small", "Small", "Small", "Small")))

etable(models_sz_sm[!sapply(models_sz_sm, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                           Any Fed        BTFP         DW       FHLB
## Dependent Var.:           any_fed btfp_crisis  dw_crisis  fhlb_user
##                                                                    
## Constant                0.2065***   0.1404***  0.1231***  0.0885***
##                        (0.0063)    (0.0059)   (0.0057)   (0.0051)  
## MTM Loss (z)            0.0299***   0.0260***  0.0152*    0.0056   
##                        (0.0070)    (0.0061)   (0.0061)   (0.0055)  
## Uninsured Leverage (z)  0.0110      0.0154*    0.0040     0.0032   
##                        (0.0078)    (0.0071)   (0.0067)   (0.0052)  
## MTM $\times$ Uninsured  0.0202***   0.0192***  0.0162**  -0.0005   
##                        (0.0057)    (0.0052)   (0.0050)   (0.0040)  
## Log(Assets)             0.1068***   0.0668***  0.0869***  0.0211** 
##                        (0.0089)    (0.0081)   (0.0082)   (0.0068)  
## Cash Ratio             -0.0215***  -0.0265*** -0.0014    -0.0199***
##                        (0.0061)    (0.0047)   (0.0052)   (0.0039)  
## Loan-to-Deposit        -0.0042     -0.0105    -0.0005     0.0260***
##                        (0.0067)    (0.0057)   (0.0057)   (0.0051)  
## Book Equity Ratio      -0.0163**   -0.0137**  -0.0050     0.0069   
##                        (0.0054)    (0.0046)   (0.0043)   (0.0040)  
## Wholesale Funding       0.0307***   0.0265***  0.0195**   0.0040   
##                        (0.0070)    (0.0067)   (0.0064)   (0.0052)  
## ROA                    -3.67e-5    -0.0045    -0.0005    -0.0080   
##                        (0.0057)    (0.0048)   (0.0048)   (0.0043)  
## ______________________ __________ ___________ __________ __________
## S.E. type              Hete.-rob. Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                3,918       3,618      3,542      3,441
## R2                        0.10423     0.08245    0.07826    0.03495
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

17.2 Large Banks (>$10B)

cat("=== LARGE BANKS (>$10B) ===\n")
## === LARGE BANKS (>$10B) ===
mod_sz_any_lg  <- safe_run(df_anyfed_s %>% filter(size_group == "Large (>10B)"), "any_fed",     EXPL_BASE)
mod_sz_btfp_lg <- safe_run(df_btfp_s   %>% filter(size_group == "Large (>10B)"), "btfp_crisis", EXPL_BASE)
mod_sz_dw_lg   <- safe_run(df_dw_s     %>% filter(size_group == "Large (>10B)"), "dw_crisis",   EXPL_BASE)
mod_sz_fhlb_lg <- safe_run(df_fhlb_s   %>% filter(size_group == "Large (>10B)"), "fhlb_user",   EXPL_BASE)

models_sz_lg <- list(
  "Any Fed" = mod_sz_any_lg, "BTFP" = mod_sz_btfp_lg,
  "DW" = mod_sz_dw_lg, "FHLB" = mod_sz_fhlb_lg)

save_etable(models_sz_lg, "Size_large_gt10B",
  title_text = "Size Split: Large Banks ($>$ \\$10B) — Extensive Margin (Crisis)",
  notes_text = "LPM. Sample restricted to banks with total assets $>$ \\$10B. Robust SEs. z-standardized.",
  extra_lines = list(c("Size Group", "Large", "Large", "Large", "Large")))

etable(models_sz_lg[!sapply(models_sz_lg, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                           Any Fed        BTFP         DW      FHLB
## Dependent Var.:           any_fed btfp_crisis  dw_crisis fhlb_user
##                                                                   
## Constant                3.932*      3.420      5.001*     0.9506  
##                        (1.907)     (2.704)    (2.056)    (2.876)  
## MTM Loss (z)            0.0169     -0.0193     0.0667     0.0447  
##                        (0.0717)    (0.0713)   (0.0631)   (0.0585) 
## Uninsured Leverage (z)  0.1605***   0.1949***  0.1524***  0.0895* 
##                        (0.0379)    (0.0336)   (0.0393)   (0.0443) 
## MTM $\times$ Uninsured  0.0178      0.0641    -0.0086    -0.0636  
##                        (0.0404)    (0.0414)   (0.0390)   (0.0361) 
## Log(Assets)            -1.382      -1.231     -1.827*    -0.3064  
##                        (0.7402)    (1.044)    (0.7985)   (1.112)  
## Cash Ratio             -0.1297     -0.1123    -0.0946     0.0012  
##                        (0.0684)    (0.0661)   (0.0668)   (0.0616) 
## Loan-to-Deposit         0.0115      0.0034     0.0680     0.0466  
##                        (0.0775)    (0.0737)   (0.0684)   (0.0595) 
## Book Equity Ratio      -0.0742     -0.1288    -0.0739     0.0795  
##                        (0.0702)    (0.0694)   (0.0745)   (0.0758) 
## Wholesale Funding      -0.0078     -0.0181     0.0097    -0.0754**
##                        (0.0369)    (0.0395)   (0.0389)   (0.0275) 
## ROA                     0.0131      0.0546     0.0130     0.0184  
##                        (0.0623)    (0.0632)   (0.0641)   (0.0542) 
## ______________________ __________ ___________ __________ _________
## S.E. type              Hete.-rob. Heter.-rob. Hete.-rob. Het.-rob.
## Observations                  126          99        107        77
## R2                        0.20292     0.21343    0.23015   0.24397
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

17.3 Combined Size Table

models_sz_combined <- list(
  "Any (Sm)" = mod_sz_any_sm, "Any (Lg)" = mod_sz_any_lg,
  "BTFP (Sm)" = mod_sz_btfp_sm, "BTFP (Lg)" = mod_sz_btfp_lg,
  "DW (Sm)" = mod_sz_dw_sm, "DW (Lg)" = mod_sz_dw_lg,
  "FHLB (Sm)" = mod_sz_fhlb_sm, "FHLB (Lg)" = mod_sz_fhlb_lg)

save_etable(models_sz_combined, "Size_combined_10B",
  title_text = "Size Split: Small ($\\leq$ \\$10B) vs. Large ($>$ \\$10B) — Crisis Period",
  notes_text = paste0(
    "LPM. Banks split at \\$10B total assets. Sm = $\\leq$ \\$10B; Lg = $>$ \\$10B. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Size", "Sm", "Lg", "Sm", "Lg", "Sm", "Lg", "Sm", "Lg")))

etable(models_sz_combined[!sapply(models_sz_combined, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                          Any (Sm)   Any (Lg)   BTFP (Sm)   BTFP (Lg)    DW (Sm)
## Dependent Var.:           any_fed    any_fed btfp_crisis btfp_crisis  dw_crisis
##                                                                                
## Constant                0.2065***  3.932*      0.1404***   3.420      0.1231***
##                        (0.0063)   (1.907)     (0.0059)    (2.704)    (0.0057)  
## MTM Loss (z)            0.0299***  0.0169      0.0260***  -0.0193     0.0152*  
##                        (0.0070)   (0.0717)    (0.0061)    (0.0713)   (0.0061)  
## Uninsured Leverage (z)  0.0110     0.1605***   0.0154*     0.1949***  0.0040   
##                        (0.0078)   (0.0379)    (0.0071)    (0.0336)   (0.0067)  
## MTM $\times$ Uninsured  0.0202***  0.0178      0.0192***   0.0641     0.0162** 
##                        (0.0057)   (0.0404)    (0.0052)    (0.0414)   (0.0050)  
## Log(Assets)             0.1068*** -1.382       0.0668***  -1.231      0.0869***
##                        (0.0089)   (0.7402)    (0.0081)    (1.044)    (0.0082)  
## Cash Ratio             -0.0215*** -0.1297     -0.0265***  -0.1123    -0.0014   
##                        (0.0061)   (0.0684)    (0.0047)    (0.0661)   (0.0052)  
## Loan-to-Deposit        -0.0042     0.0115     -0.0105      0.0034    -0.0005   
##                        (0.0067)   (0.0775)    (0.0057)    (0.0737)   (0.0057)  
## Book Equity Ratio      -0.0163**  -0.0742     -0.0137**   -0.1288    -0.0050   
##                        (0.0054)   (0.0702)    (0.0046)    (0.0694)   (0.0043)  
## Wholesale Funding       0.0307*** -0.0078      0.0265***  -0.0181     0.0195** 
##                        (0.0070)   (0.0369)    (0.0067)    (0.0395)   (0.0064)  
## ROA                    -3.67e-5    0.0131     -0.0045      0.0546    -0.0005   
##                        (0.0057)   (0.0623)    (0.0048)    (0.0632)   (0.0048)  
## ______________________ __________ __________ ___________ ___________ __________
## S.E. type              Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob. Hete.-rob.
## Observations                3,918        126       3,618          99      3,542
## R2                        0.10423    0.20292     0.08245     0.21343    0.07826
## 
##                           DW (Lg)  FHLB (Sm) FHLB (Lg)
## Dependent Var.:         dw_crisis  fhlb_user fhlb_user
##                                                       
## Constant                5.001*     0.0885***  0.9506  
##                        (2.056)    (0.0051)   (2.876)  
## MTM Loss (z)            0.0667     0.0056     0.0447  
##                        (0.0631)   (0.0055)   (0.0585) 
## Uninsured Leverage (z)  0.1524***  0.0032     0.0895* 
##                        (0.0393)   (0.0052)   (0.0443) 
## MTM $\times$ Uninsured -0.0086    -0.0005    -0.0636  
##                        (0.0390)   (0.0040)   (0.0361) 
## Log(Assets)            -1.827*     0.0211**  -0.3064  
##                        (0.7985)   (0.0068)   (1.112)  
## Cash Ratio             -0.0946    -0.0199***  0.0012  
##                        (0.0668)   (0.0039)   (0.0616) 
## Loan-to-Deposit         0.0680     0.0260***  0.0466  
##                        (0.0684)   (0.0051)   (0.0595) 
## Book Equity Ratio      -0.0739     0.0069     0.0795  
##                        (0.0745)   (0.0040)   (0.0758) 
## Wholesale Funding       0.0097     0.0040    -0.0754**
##                        (0.0389)   (0.0052)   (0.0275) 
## ROA                     0.0130    -0.0080     0.0184  
##                        (0.0641)   (0.0043)   (0.0542) 
## ______________________ __________ __________ _________
## S.E. type              Hete.-rob. Hete.-rob. Het.-rob.
## Observations                  107      3,441        77
## R2                        0.23015    0.03495   0.24397
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

18 THRESHOLD GRADIENT: Uninsured Tercile Regressions

# ==============================================================================
# THRESHOLD GRADIENT
#
# At low levels of mark-to-market (MTM) losses, banks with higher uninsured
# leverage are expected to borrow more to preempt run risk. We test this
# threshold effect by splitting the sample into Uninsured terciles
# (Low, Medium, High) and estimating the extensive margin separately for
# each group k ∈ {L, M, H}:
#
#   Borrower_i = α^(k) + β^(k) · mtm_loss_i + γ X_i + ε_i
#
# Prediction: β^(H) >> β^(M) > β^(L) — the MTM coefficient should be
# strongest among high-uninsured banks, where run risk is most acute.
# ==============================================================================

cat("=== THRESHOLD GRADIENT: UNINSURED TERCILE REGRESSIONS ===\n\n")
## === THRESHOLD GRADIENT: UNINSURED TERCILE REGRESSIONS ===
# Create terciles on the full crisis sample (before sample splits)
tercile_breaks <- quantile(df_crisis$uninsured_lev_raw, probs = c(1/3, 2/3), na.rm = TRUE)
cat(sprintf("  Uninsured leverage tercile cuts: %.2f%%, %.2f%%\n",
    tercile_breaks[1], tercile_breaks[2]))
##   Uninsured leverage tercile cuts: 17.71%, 26.99%
add_tercile <- function(df) {
  df %>% mutate(
    uninsured_tercile = case_when(
      uninsured_lev_raw <= tercile_breaks[1] ~ "Low",
      uninsured_lev_raw <= tercile_breaks[2] ~ "Medium",
      TRUE ~ "High"
    ),
    uninsured_tercile = factor(uninsured_tercile, levels = c("Low", "Medium", "High"))
  )
}

df_anyfed_s <- add_tercile(df_anyfed_s)
df_btfp_s   <- add_tercile(df_btfp_s)
df_dw_s     <- add_tercile(df_dw_s)
df_fhlb_s   <- add_tercile(df_fhlb_s)

# Tercile-specific regression spec: no interaction, just MTM + controls
EXPL_TERCILE <- "mtm_total"

for (terc in c("Low", "Medium", "High")) {
  cat(sprintf("  %s tercile:\n", terc))
  cat(sprintf("    AnyFed: N=%d, Borrowers=%d\n",
    sum(df_anyfed_s$uninsured_tercile == terc, na.rm=TRUE),
    sum(df_anyfed_s$any_fed[df_anyfed_s$uninsured_tercile == terc], na.rm=TRUE)))
  cat(sprintf("    BTFP:   N=%d, Borrowers=%d\n",
    sum(df_btfp_s$uninsured_tercile == terc, na.rm=TRUE),
    sum(df_btfp_s$btfp_crisis[df_btfp_s$uninsured_tercile == terc], na.rm=TRUE)))
  cat(sprintf("    DW:     N=%d, Borrowers=%d\n",
    sum(df_dw_s$uninsured_tercile == terc, na.rm=TRUE),
    sum(df_dw_s$dw_crisis[df_dw_s$uninsured_tercile == terc], na.rm=TRUE)))
}
##   Low tercile:
##     AnyFed: N=1361, Borrowers=175
##     BTFP:   N=1289, Borrowers=103
##     DW:     N=1272, Borrowers=86
##   Medium tercile:
##     AnyFed: N=1343, Borrowers=286
##     BTFP:   N=1230, Borrowers=173
##     DW:     N=1200, Borrowers=143
##   High tercile:
##     AnyFed: N=1350, Borrowers=367
##     BTFP:   N=1208, Borrowers=225
##     DW:     N=1187, Borrowers=204

18.1 Any Fed — by Tercile

cat("=== TERCILE: ANY FED ===\n")
## === TERCILE: ANY FED ===
mod_terc_any_L <- safe_run(df_anyfed_s %>% filter(uninsured_tercile == "Low"),    "any_fed", EXPL_TERCILE)
mod_terc_any_M <- safe_run(df_anyfed_s %>% filter(uninsured_tercile == "Medium"), "any_fed", EXPL_TERCILE)
mod_terc_any_H <- safe_run(df_anyfed_s %>% filter(uninsured_tercile == "High"),   "any_fed", EXPL_TERCILE)

models_terc_any <- list("Low UI" = mod_terc_any_L, "Med UI" = mod_terc_any_M, "High UI" = mod_terc_any_H)

save_etable(models_terc_any, "Tercile_AnyFed",
  title_text = "Threshold Gradient: Any Fed Borrowing by Uninsured Tercile",
  notes_text = paste0(
    "LPM. Sample split into terciles of uninsured leverage (\\% of assets). ",
    "Each column estimates Borrower$_i = \\alpha^{(k)} + \\beta^{(k)} \\cdot$ MTM$_i + \\gamma \\mathbf{X}_i + \\varepsilon_i$ ",
    "within tercile $k \\in \\{L, M, H\\}$. ",
    "Prediction: $\\beta^{(H)} >> \\beta^{(M)} > \\beta^{(L)}$. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("UI Tercile", "Low", "Medium", "High"),
    c("Mean UI Lev (\\%)",
      round(mean(df_anyfed_s$uninsured_lev_raw[df_anyfed_s$uninsured_tercile=="Low"], na.rm=T), 1),
      round(mean(df_anyfed_s$uninsured_lev_raw[df_anyfed_s$uninsured_tercile=="Medium"], na.rm=T), 1),
      round(mean(df_anyfed_s$uninsured_lev_raw[df_anyfed_s$uninsured_tercile=="High"], na.rm=T), 1))))

etable(models_terc_any[!sapply(models_terc_any, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                       Low UI     Med UI    High UI
## Dependent Var.:      any_fed    any_fed    any_fed
##                                                   
## Constant           0.1826***  0.2023***  0.2167***
##                   (0.0132)   (0.0105)   (0.0126)  
## MTM Loss (z)       0.0138     0.0170     0.0486***
##                   (0.0088)   (0.0128)   (0.0145)  
## Log(Assets)        0.1015***  0.0841***  0.1267***
##                   (0.0135)   (0.0157)   (0.0129)  
## Cash Ratio        -0.0107    -0.0229    -0.0385** 
##                   (0.0084)   (0.0120)   (0.0119)  
## Loan-to-Deposit   -0.0046     0.0044    -0.0115   
##                   (0.0087)   (0.0151)   (0.0139)  
## Book Equity Ratio -0.0144*   -0.0365*   -0.0075   
##                   (0.0064)   (0.0144)   (0.0140)  
## Wholesale Funding  0.0071     0.0585***  0.0257   
##                   (0.0089)   (0.0132)   (0.0138)  
## ROA               -0.0101     0.0146     0.0014   
##                   (0.0080)   (0.0115)   (0.0112)  
## _________________ __________ __________ __________
## S.E. type         Hete.-rob. Hete.-rob. Hete.-rob.
## Observations           1,358      1,342      1,344
## R2                   0.09509    0.08502    0.13289
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

18.2 BTFP — by Tercile

cat("=== TERCILE: BTFP ===\n")
## === TERCILE: BTFP ===
mod_terc_btfp_L <- safe_run(df_btfp_s %>% filter(uninsured_tercile == "Low"),    "btfp_crisis", EXPL_TERCILE)
mod_terc_btfp_M <- safe_run(df_btfp_s %>% filter(uninsured_tercile == "Medium"), "btfp_crisis", EXPL_TERCILE)
mod_terc_btfp_H <- safe_run(df_btfp_s %>% filter(uninsured_tercile == "High"),   "btfp_crisis", EXPL_TERCILE)

models_terc_btfp <- list("Low UI" = mod_terc_btfp_L, "Med UI" = mod_terc_btfp_M, "High UI" = mod_terc_btfp_H)

save_etable(models_terc_btfp, "Tercile_BTFP",
  title_text = "Threshold Gradient: BTFP Borrowing by Uninsured Tercile",
  notes_text = paste0(
    "LPM. Sample split into terciles of uninsured leverage. Robust SEs. z-standardized."),
  extra_lines = list(c("UI Tercile", "Low", "Medium", "High")))

etable(models_terc_btfp[!sapply(models_terc_btfp, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                        Low UI      Med UI     High UI
## Dependent Var.:   btfp_crisis btfp_crisis btfp_crisis
##                                                      
## Constant            0.1203***   0.1338***   0.1583***
##                    (0.0119)    (0.0093)    (0.0118)  
## MTM Loss (z)        0.0099      0.0075      0.0384** 
##                    (0.0072)    (0.0105)    (0.0134)  
## Log(Assets)         0.0718***   0.0576***   0.0855***
##                    (0.0120)    (0.0145)    (0.0132)  
## Cash Ratio         -0.0117     -0.0360***  -0.0408***
##                    (0.0062)    (0.0096)    (0.0099)  
## Loan-to-Deposit    -0.0032     -0.0216     -0.0135   
##                    (0.0072)    (0.0131)    (0.0127)  
## Book Equity Ratio  -0.0097     -0.0263*    -0.0184   
##                    (0.0053)    (0.0128)    (0.0122)  
## Wholesale Funding   0.0028      0.0562***   0.0247   
##                    (0.0067)    (0.0136)    (0.0138)  
## ROA                -0.0121      0.0079     -0.0027   
##                    (0.0066)    (0.0099)    (0.0097)  
## _________________ ___________ ___________ ___________
## S.E. type         Heter.-rob. Heter.-rob. Heter.-rob.
## Observations            1,286       1,229       1,202
## R2                    0.07578     0.07991     0.10071
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

18.3 DW — by Tercile

cat("=== TERCILE: DW ===\n")
## === TERCILE: DW ===
mod_terc_dw_L <- safe_run(df_dw_s %>% filter(uninsured_tercile == "Low"),    "dw_crisis", EXPL_TERCILE)
mod_terc_dw_M <- safe_run(df_dw_s %>% filter(uninsured_tercile == "Medium"), "dw_crisis", EXPL_TERCILE)
mod_terc_dw_H <- safe_run(df_dw_s %>% filter(uninsured_tercile == "High"),   "dw_crisis", EXPL_TERCILE)

models_terc_dw <- list("Low UI" = mod_terc_dw_L, "Med UI" = mod_terc_dw_M, "High UI" = mod_terc_dw_H)

save_etable(models_terc_dw, "Tercile_DW",
  title_text = "Threshold Gradient: DW Borrowing by Uninsured Tercile",
  notes_text = paste0(
    "LPM. Sample split into terciles of uninsured leverage. Robust SEs. z-standardized."),
  extra_lines = list(c("UI Tercile", "Low", "Medium", "High")))

etable(models_terc_dw[!sapply(models_terc_dw, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                       Low UI     Med UI    High UI
## Dependent Var.:    dw_crisis  dw_crisis  dw_crisis
##                                                   
## Constant           0.1070***  0.1207***  0.1212***
##                   (0.0117)   (0.0093)   (0.0105)  
## MTM Loss (z)       0.0014     0.0116     0.0325*  
##                   (0.0070)   (0.0112)   (0.0129)  
## Log(Assets)        0.0684***  0.0690***  0.1280***
##                   (0.0122)   (0.0140)   (0.0126)  
## Cash Ratio        -0.0027     0.0099    -0.0152   
##                   (0.0072)   (0.0106)   (0.0105)  
## Loan-to-Deposit   -0.0070     0.0243    -0.0179   
##                   (0.0069)   (0.0132)   (0.0124)  
## Book Equity Ratio -0.0072    -0.0190     0.0098   
##                   (0.0049)   (0.0109)   (0.0126)  
## Wholesale Funding  0.0061     0.0336*    0.0243   
##                   (0.0076)   (0.0131)   (0.0132)  
## ROA               -0.0041     0.0049    -0.0005   
##                   (0.0067)   (0.0098)   (0.0099)  
## _________________ __________ __________ __________
## S.E. type         Hete.-rob. Hete.-rob. Hete.-rob.
## Observations           1,269      1,199      1,181
## R2                   0.06042    0.05993    0.13873
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

18.4 Combined Tercile Table

models_terc_combined <- list(
  "Any (L)" = mod_terc_any_L, "Any (M)" = mod_terc_any_M, "Any (H)" = mod_terc_any_H,
  "BTFP (L)" = mod_terc_btfp_L, "BTFP (M)" = mod_terc_btfp_M, "BTFP (H)" = mod_terc_btfp_H,
  "DW (L)" = mod_terc_dw_L, "DW (M)" = mod_terc_dw_M, "DW (H)" = mod_terc_dw_H)

save_etable(models_terc_combined, "Tercile_combined",
  title_text = "Threshold Gradient: All Facilities by Uninsured Tercile (Crisis)",
  notes_text = paste0(
    "LPM. Borrower$_i = \\alpha^{(k)} + \\beta^{(k)} \\cdot$ MTM$_i + \\gamma \\mathbf{X}_i + \\varepsilon_i$ ",
    "estimated separately for each uninsured leverage tercile $k$. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("UI Tercile", "L", "M", "H", "L", "M", "H", "L", "M", "H"),
    c("Facility", "Any", "Any", "Any", "BTFP", "BTFP", "BTFP", "DW", "DW", "DW")))

etable(models_terc_combined[!sapply(models_terc_combined, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                      Any (L)    Any (M)    Any (H)    BTFP (L)    BTFP (M)
## Dependent Var.:      any_fed    any_fed    any_fed btfp_crisis btfp_crisis
##                                                                           
## Constant           0.1826***  0.2023***  0.2167***   0.1203***   0.1338***
##                   (0.0132)   (0.0105)   (0.0126)    (0.0119)    (0.0093)  
## MTM Loss (z)       0.0138     0.0170     0.0486***   0.0099      0.0075   
##                   (0.0088)   (0.0128)   (0.0145)    (0.0072)    (0.0105)  
## Log(Assets)        0.1015***  0.0841***  0.1267***   0.0718***   0.0576***
##                   (0.0135)   (0.0157)   (0.0129)    (0.0120)    (0.0145)  
## Cash Ratio        -0.0107    -0.0229    -0.0385**   -0.0117     -0.0360***
##                   (0.0084)   (0.0120)   (0.0119)    (0.0062)    (0.0096)  
## Loan-to-Deposit   -0.0046     0.0044    -0.0115     -0.0032     -0.0216   
##                   (0.0087)   (0.0151)   (0.0139)    (0.0072)    (0.0131)  
## Book Equity Ratio -0.0144*   -0.0365*   -0.0075     -0.0097     -0.0263*  
##                   (0.0064)   (0.0144)   (0.0140)    (0.0053)    (0.0128)  
## Wholesale Funding  0.0071     0.0585***  0.0257      0.0028      0.0562***
##                   (0.0089)   (0.0132)   (0.0138)    (0.0067)    (0.0136)  
## ROA               -0.0101     0.0146     0.0014     -0.0121      0.0079   
##                   (0.0080)   (0.0115)   (0.0112)    (0.0066)    (0.0099)  
## _________________ __________ __________ __________ ___________ ___________
## S.E. type         Hete.-rob. Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob.
## Observations           1,358      1,342      1,344       1,286       1,229
## R2                   0.09509    0.08502    0.13289     0.07578     0.07991
## 
##                      BTFP (H)     DW (L)     DW (M)     DW (H)
## Dependent Var.:   btfp_crisis  dw_crisis  dw_crisis  dw_crisis
##                                                               
## Constant            0.1583***  0.1070***  0.1207***  0.1212***
##                    (0.0118)   (0.0117)   (0.0093)   (0.0105)  
## MTM Loss (z)        0.0384**   0.0014     0.0116     0.0325*  
##                    (0.0134)   (0.0070)   (0.0112)   (0.0129)  
## Log(Assets)         0.0855***  0.0684***  0.0690***  0.1280***
##                    (0.0132)   (0.0122)   (0.0140)   (0.0126)  
## Cash Ratio         -0.0408*** -0.0027     0.0099    -0.0152   
##                    (0.0099)   (0.0072)   (0.0106)   (0.0105)  
## Loan-to-Deposit    -0.0135    -0.0070     0.0243    -0.0179   
##                    (0.0127)   (0.0069)   (0.0132)   (0.0124)  
## Book Equity Ratio  -0.0184    -0.0072    -0.0190     0.0098   
##                    (0.0122)   (0.0049)   (0.0109)   (0.0126)  
## Wholesale Funding   0.0247     0.0061     0.0336*    0.0243   
##                    (0.0138)   (0.0076)   (0.0131)   (0.0132)  
## ROA                -0.0027    -0.0041     0.0049    -0.0005   
##                    (0.0097)   (0.0067)   (0.0098)   (0.0099)  
## _________________ ___________ __________ __________ __________
## S.E. type         Heter.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations            1,202      1,269      1,199      1,181
## R2                    0.10071    0.06042    0.05993    0.13873
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

19 UNINSURED BETA CHANNEL: Low β^U Interaction

# ==============================================================================
# UNINSURED BETA CHANNEL
#
# Banks with low uninsured deposit betas (below median β^U) have deposits
# that are less rate-sensitive — "sticky" uninsured deposits. DSSW shows
# these banks have the highest franchise value but are also the most
# vulnerable to coordination failures: depositors don't leave for higher
# rates, but they WILL leave if they fear the bank is insolvent.
#
# Specification:
#   Borrower_i = α + β₁·mtm + β₂·UI + β₃·UI×low_beta_UI
#                + β₄·mtm×UI×low_beta_UI + γ·X_i + ε_i
#
# where low_beta_UI = 1 if bank's β^U is below the median.
#
# β₃ > 0: banks with sticky uninsured deposits borrow MORE (higher franchise
#          value at risk, hence more precautionary borrowing)
# β₄ > 0: the MTM × Uninsured amplification is STRONGER for low-beta banks
#          (franchise value is larger → more to lose from a run)
# ==============================================================================

cat("=== UNINSURED BETA CHANNEL: LOW β^U INTERACTION ===\n\n")
## === UNINSURED BETA CHANNEL: LOW β^U INTERACTION ===
# Define low_beta_UI = below median uninsured beta
beta_median <- median(df_crisis$uninsured_beta_raw, na.rm = TRUE)
cat(sprintf("  Median uninsured beta (β^U): %.4f\n", beta_median))
##   Median uninsured beta (β^U): 0.3106
add_low_beta <- function(df) {
  df %>% mutate(
    low_beta_UI = as.integer(!is.na(uninsured_beta_raw) & uninsured_beta_raw <= beta_median),
    # Interactions
    UI_x_lowbeta      = uninsured_lev * low_beta_UI,
    mtm_x_UI_x_lowbeta = mtm_total * uninsured_lev * low_beta_UI
  )
}

df_anyfed_s <- add_low_beta(df_anyfed_s)
df_btfp_s   <- add_low_beta(df_btfp_s)
df_dw_s     <- add_low_beta(df_dw_s)
df_fhlb_s   <- add_low_beta(df_fhlb_s)

# Spec: mtm + UI + UI*low_beta + mtm*UI*low_beta
EXPL_LOWBETA <- "mtm_total + uninsured_lev + UI_x_lowbeta + mtm_x_UI_x_lowbeta"

# Register labels
setFixest_dict(c(
  low_beta_UI         = "Low $\\beta^U$ (below median)",
  UI_x_lowbeta        = "Uninsured $\\times$ Low $\\beta^U$",
  mtm_x_UI_x_lowbeta  = "MTM $\\times$ UI $\\times$ Low $\\beta^U$"
))

# Filter to banks with beta coverage
df_lowbeta_any  <- df_anyfed_s %>% filter(!is.na(uninsured_beta_raw))
df_lowbeta_btfp <- df_btfp_s   %>% filter(!is.na(uninsured_beta_raw))
df_lowbeta_dw   <- df_dw_s     %>% filter(!is.na(uninsured_beta_raw))
df_lowbeta_fhlb <- df_fhlb_s   %>% filter(!is.na(uninsured_beta_raw))

cat(sprintf("  Low β^U banks: %d / %d (%.1f%%)\n",
    sum(df_lowbeta_any$low_beta_UI), nrow(df_lowbeta_any),
    100 * mean(df_lowbeta_any$low_beta_UI)))
##   Low β^U banks: 2029 / 3991 (50.8%)
cat(sprintf("  Beta coverage: AnyFed=%d, BTFP=%d, DW=%d, FHLB=%d\n",
    nrow(df_lowbeta_any), nrow(df_lowbeta_btfp),
    nrow(df_lowbeta_dw), nrow(df_lowbeta_fhlb)))
##   Beta coverage: AnyFed=3991, BTFP=3665, DW=3599, FHLB=3468

19.1 Full Sample — Low β^U

cat("=== LOW β^U: FULL SAMPLE ===\n")
## === LOW β^U: FULL SAMPLE ===
mod_lb_any  <- safe_run(df_lowbeta_any,  "any_fed",     EXPL_LOWBETA)
mod_lb_btfp <- safe_run(df_lowbeta_btfp, "btfp_crisis", EXPL_LOWBETA)
mod_lb_dw   <- safe_run(df_lowbeta_dw,   "dw_crisis",   EXPL_LOWBETA)
mod_lb_fhlb <- safe_run(df_lowbeta_fhlb, "fhlb_user",   EXPL_LOWBETA)

models_lb_full <- list(
  "Any Fed" = mod_lb_any, "BTFP" = mod_lb_btfp,
  "DW" = mod_lb_dw, "FHLB" = mod_lb_fhlb)

save_etable(models_lb_full, "LowBeta_full_sample",
  title_text = "Uninsured Beta Channel: Low $\\beta^U$ Interaction (Full Sample, Crisis)",
  notes_text = paste0(
    "LPM. Low $\\beta^U$ = below-median uninsured deposit beta. ",
    "Specification: MTM + UI + UI $\\times$ Low $\\beta^U$ + MTM $\\times$ UI $\\times$ Low $\\beta^U$ + Controls. ",
    "DSSW prediction: banks with sticky uninsured deposits (low $\\beta^U$) have larger franchise value ",
    "but wider panic region. FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Median $\\beta^U$", round(beta_median, 3), round(beta_median, 3),
      round(beta_median, 3), round(beta_median, 3))))

etable(models_lb_full[!sapply(models_lb_full, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                           Any Fed        BTFP         DW
## Dependent Var.:                           any_fed btfp_crisis  dw_crisis
##                                                                         
## Constant                                0.2059***   0.1412***  0.1258***
##                                        (0.0060)    (0.0056)   (0.0054)  
## MTM Loss (z)                            0.0272***   0.0220***  0.0132*  
##                                        (0.0068)    (0.0059)   (0.0058)  
## Uninsured Leverage (z)                  0.0086      0.0130     0.0056   
##                                        (0.0101)    (0.0093)   (0.0090)  
## Uninsured $\times$ Low $\beta^U$        0.0201      0.0153     0.0095   
##                                        (0.0122)    (0.0112)   (0.0109)  
## MTM $\times$ UI $\times$ Low $\beta^U$  0.0296***   0.0270***  0.0239***
##                                        (0.0073)    (0.0069)   (0.0065)  
## Log(Assets)                             0.1079***   0.0726***  0.0934***
##                                        (0.0083)    (0.0078)   (0.0078)  
## Cash Ratio                             -0.0245***  -0.0287*** -0.0039   
##                                        (0.0064)    (0.0050)   (0.0055)  
## Loan-to-Deposit                        -0.0032     -0.0100    -0.0012   
##                                        (0.0071)    (0.0062)   (0.0061)  
## Book Equity Ratio                      -0.0158**   -0.0142**  -0.0019   
##                                        (0.0059)    (0.0050)   (0.0048)  
## Wholesale Funding                       0.0303***   0.0273***  0.0208** 
##                                        (0.0069)    (0.0066)   (0.0063)  
## ROA                                    -0.0030     -0.0071    -0.0029   
##                                        (0.0060)    (0.0052)   (0.0051)  
## ______________________________________ __________ ___________ __________
## S.E. type                              Hete.-rob. Heter.-rob. Hete.-rob.
## Observations                                3,991       3,665      3,599
## R2                                        0.12086     0.09665    0.10290
## 
##                                              FHLB
## Dependent Var.:                         fhlb_user
##                                                  
## Constant                                0.0906***
##                                        (0.0050)  
## MTM Loss (z)                            0.0056   
##                                        (0.0054)  
## Uninsured Leverage (z)                  0.0125   
##                                        (0.0074)  
## Uninsured $\times$ Low $\beta^U$       -0.0094   
##                                        (0.0095)  
## MTM $\times$ UI $\times$ Low $\beta^U$ -0.0016   
##                                        (0.0056)  
## Log(Assets)                             0.0275***
##                                        (0.0065)  
## Cash Ratio                             -0.0202***
##                                        (0.0041)  
## Loan-to-Deposit                         0.0261***
##                                        (0.0054)  
## Book Equity Ratio                       0.0089*  
##                                        (0.0045)  
## Wholesale Funding                       0.0021   
##                                        (0.0051)  
## ROA                                    -0.0105*  
##                                        (0.0045)  
## ______________________________________ __________
## S.E. type                              Hete.-rob.
## Observations                                3,468
## R2                                        0.04081
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

19.2 Small Banks (≤$10B) — Low β^U

cat("=== LOW β^U: SMALL BANKS (≤$10B) ===\n")
## === LOW β^U: SMALL BANKS (≤$10B) ===
mod_lb_any_sm  <- safe_run(df_lowbeta_any  %>% filter(size_group == "Small (<=10B)"), "any_fed",     EXPL_LOWBETA)
mod_lb_btfp_sm <- safe_run(df_lowbeta_btfp %>% filter(size_group == "Small (<=10B)"), "btfp_crisis", EXPL_LOWBETA)
mod_lb_dw_sm   <- safe_run(df_lowbeta_dw   %>% filter(size_group == "Small (<=10B)"), "dw_crisis",   EXPL_LOWBETA)
mod_lb_fhlb_sm <- safe_run(df_lowbeta_fhlb %>% filter(size_group == "Small (<=10B)"), "fhlb_user",   EXPL_LOWBETA)

models_lb_sm <- list(
  "Any Fed" = mod_lb_any_sm, "BTFP" = mod_lb_btfp_sm,
  "DW" = mod_lb_dw_sm, "FHLB" = mod_lb_fhlb_sm)

save_etable(models_lb_sm, "LowBeta_small_le10B",
  title_text = "Low $\\beta^U$ Interaction: Small Banks ($\\leq$ \\$10B)",
  notes_text = "LPM. Banks $\\leq$ \\$10B with uninsured beta coverage. Robust SEs. z-standardized.",
  extra_lines = list(c("Size Group", "Small", "Small", "Small", "Small")))

etable(models_lb_sm[!sapply(models_lb_sm, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                           Any Fed        BTFP         DW
## Dependent Var.:                           any_fed btfp_crisis  dw_crisis
##                                                                         
## Constant                                0.2042***   0.1380***  0.1216***
##                                        (0.0063)    (0.0058)   (0.0056)  
## MTM Loss (z)                            0.0268***   0.0229***  0.0124*  
##                                        (0.0068)    (0.0059)   (0.0058)  
## Uninsured Leverage (z)                 -0.0018      0.0044    -0.0038   
##                                        (0.0103)    (0.0094)   (0.0089)  
## Uninsured $\times$ Low $\beta^U$        0.0229      0.0205     0.0105   
##                                        (0.0124)    (0.0111)   (0.0107)  
## MTM $\times$ UI $\times$ Low $\beta^U$  0.0289***   0.0263***  0.0202** 
##                                        (0.0074)    (0.0068)   (0.0064)  
## Log(Assets)                             0.1083***   0.0679***  0.0882***
##                                        (0.0091)    (0.0082)   (0.0083)  
## Cash Ratio                             -0.0219***  -0.0271*** -0.0015   
##                                        (0.0063)    (0.0050)   (0.0054)  
## Loan-to-Deposit                        -0.0044     -0.0101    -0.0013   
##                                        (0.0072)    (0.0062)   (0.0061)  
## Book Equity Ratio                      -0.0181**   -0.0157**  -0.0059   
##                                        (0.0059)    (0.0050)   (0.0047)  
## Wholesale Funding                       0.0313***   0.0275***  0.0198** 
##                                        (0.0070)    (0.0067)   (0.0064)  
## ROA                                    -0.0008     -0.0056    -0.0001   
##                                        (0.0060)    (0.0051)   (0.0051)  
## ______________________________________ __________ ___________ __________
## S.E. type                              Hete.-rob. Heter.-rob. Hete.-rob.
## Observations                                3,866       3,567      3,493
## R2                                        0.10365     0.08271    0.07700
## 
##                                              FHLB
## Dependent Var.:                         fhlb_user
##                                                  
## Constant                                0.0877***
##                                        (0.0051)  
## MTM Loss (z)                            0.0061   
##                                        (0.0054)  
## Uninsured Leverage (z)                  0.0051   
##                                        (0.0074)  
## Uninsured $\times$ Low $\beta^U$       -0.0030   
##                                        (0.0092)  
## MTM $\times$ UI $\times$ Low $\beta^U$ -0.0021   
##                                        (0.0055)  
## Log(Assets)                             0.0222** 
##                                        (0.0069)  
## Cash Ratio                             -0.0192***
##                                        (0.0040)  
## Loan-to-Deposit                         0.0272***
##                                        (0.0055)  
## Book Equity Ratio                       0.0054   
##                                        (0.0043)  
## Wholesale Funding                       0.0044   
##                                        (0.0053)  
## ROA                                    -0.0091*  
##                                        (0.0045)  
## ______________________________________ __________
## S.E. type                              Hete.-rob.
## Observations                                3,392
## R2                                        0.03474
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

19.3 Large Banks (>$10B) — Low β^U

cat("=== LOW β^U: LARGE BANKS (>$10B) ===\n")
## === LOW β^U: LARGE BANKS (>$10B) ===
mod_lb_any_lg  <- safe_run(df_lowbeta_any  %>% filter(size_group == "Large (>10B)"), "any_fed",     EXPL_LOWBETA)
mod_lb_btfp_lg <- safe_run(df_lowbeta_btfp %>% filter(size_group == "Large (>10B)"), "btfp_crisis", EXPL_LOWBETA)
mod_lb_dw_lg   <- safe_run(df_lowbeta_dw   %>% filter(size_group == "Large (>10B)"), "dw_crisis",   EXPL_LOWBETA)
mod_lb_fhlb_lg <- safe_run(df_lowbeta_fhlb %>% filter(size_group == "Large (>10B)"), "fhlb_user",   EXPL_LOWBETA)

models_lb_lg <- list(
  "Any Fed" = mod_lb_any_lg, "BTFP" = mod_lb_btfp_lg,
  "DW" = mod_lb_dw_lg, "FHLB" = mod_lb_fhlb_lg)

save_etable(models_lb_lg, "LowBeta_large_gt10B",
  title_text = "Low $\\beta^U$ Interaction: Large Banks ($>$ \\$10B)",
  notes_text = "LPM. Banks $>$ \\$10B with uninsured beta coverage. Robust SEs. z-standardized.",
  extra_lines = list(c("Size Group", "Large", "Large", "Large", "Large")))

etable(models_lb_lg[!sapply(models_lb_lg, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                          Any Fed        BTFP        DW
## Dependent Var.:                          any_fed btfp_crisis dw_crisis
##                                                                       
## Constant                                3.242      3.096      3.961   
##                                        (2.039)    (2.741)    (2.311)  
## MTM Loss (z)                            0.0288     0.0007     0.0640  
##                                        (0.0747)   (0.0782)   (0.0685) 
## Uninsured Leverage (z)                  0.1368**   0.1506***  0.1373**
##                                        (0.0414)   (0.0432)   (0.0408) 
## Uninsured $\times$ Low $\beta^U$        0.0956     0.0796     0.1255  
##                                        (0.0554)   (0.0676)   (0.0746) 
## MTM $\times$ UI $\times$ Low $\beta^U$ -0.0155     0.0063    -0.0411  
##                                        (0.0511)   (0.0654)   (0.0700) 
## Log(Assets)                            -1.121     -1.109     -1.434   
##                                        (0.7912)   (1.060)    (0.8965) 
## Cash Ratio                             -0.1171    -0.1097    -0.0856  
##                                        (0.0754)   (0.0772)   (0.0727) 
## Loan-to-Deposit                         0.0232     0.0202     0.0761  
##                                        (0.0756)   (0.0787)   (0.0669) 
## Book Equity Ratio                      -0.0728    -0.1164    -0.0844  
##                                        (0.0703)   (0.0751)   (0.0770) 
## Wholesale Funding                      -0.0084    -0.0092     0.0045  
##                                        (0.0365)   (0.0407)   (0.0371) 
## ROA                                     0.0252     0.0694     0.0221  
##                                        (0.0634)   (0.0658)   (0.0653) 
## ______________________________________ _________ ___________ _________
## S.E. type                              Het.-rob. Heter.-rob. Het.-rob.
## Observations                                 125          98       106
## R2                                       0.20759     0.19790   0.24392
## 
##                                             FHLB
## Dependent Var.:                        fhlb_user
##                                                 
## Constant                                0.6629  
##                                        (3.138)  
## MTM Loss (z)                            0.0283  
##                                        (0.0720) 
## Uninsured Leverage (z)                  0.1309**
##                                        (0.0405) 
## Uninsured $\times$ Low $\beta^U$        0.0316  
##                                        (0.1013) 
## MTM $\times$ UI $\times$ Low $\beta^U$ -0.0608  
##                                        (0.1148) 
## Log(Assets)                            -0.1943  
##                                        (1.212)  
## Cash Ratio                              0.0142  
##                                        (0.0733) 
## Loan-to-Deposit                         0.0269  
##                                        (0.0650) 
## Book Equity Ratio                       0.0672  
##                                        (0.0790) 
## Wholesale Funding                      -0.0835**
##                                        (0.0280) 
## ROA                                     0.0269  
##                                        (0.0541) 
## ______________________________________ _________
## S.E. type                              Het.-rob.
## Observations                                  76
## R2                                       0.21737
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

19.4 Combined Low β^U × Size Table

models_lb_combined <- list(
  "Any (Full)" = mod_lb_any,     "Any (Sm)" = mod_lb_any_sm,     "Any (Lg)" = mod_lb_any_lg,
  "BTFP (Full)" = mod_lb_btfp,   "BTFP (Sm)" = mod_lb_btfp_sm,   "BTFP (Lg)" = mod_lb_btfp_lg,
  "DW (Full)" = mod_lb_dw,       "DW (Sm)" = mod_lb_dw_sm,       "DW (Lg)" = mod_lb_dw_lg)

save_etable(models_lb_combined, "LowBeta_combined_size",
  title_text = "Low $\\beta^U$ Interaction: Full Sample $\\times$ Size Split (Crisis)",
  notes_text = paste0(
    "LPM. Low $\\beta^U$ = below-median uninsured deposit beta (median = ",
    round(beta_median, 3), "). ",
    "Full = all banks; Sm = $\\leq$ \\$10B; Lg = $>$ \\$10B. ",
    "DSSW prediction: MTM $\\times$ UI $\\times$ Low $\\beta^U > 0$ — panic amplification ",
    "is stronger for banks with stickier (lower-beta) uninsured deposits. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Sample", "Full", "Sm", "Lg", "Full", "Sm", "Lg", "Full", "Sm", "Lg"),
    c("Facility", "Any", "Any", "Any", "BTFP", "BTFP", "BTFP", "DW", "DW", "DW")))

etable(models_lb_combined[!sapply(models_lb_combined, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                        Any (Full)   Any (Sm)  Any (Lg)
## Dependent Var.:                           any_fed    any_fed   any_fed
##                                                                       
## Constant                                0.2059***  0.2042***  3.242   
##                                        (0.0060)   (0.0063)   (2.039)  
## MTM Loss (z)                            0.0272***  0.0268***  0.0288  
##                                        (0.0068)   (0.0068)   (0.0747) 
## Uninsured Leverage (z)                  0.0086    -0.0018     0.1368**
##                                        (0.0101)   (0.0103)   (0.0414) 
## Uninsured $\times$ Low $\beta^U$        0.0201     0.0229     0.0956  
##                                        (0.0122)   (0.0124)   (0.0554) 
## MTM $\times$ UI $\times$ Low $\beta^U$  0.0296***  0.0289*** -0.0155  
##                                        (0.0073)   (0.0074)   (0.0511) 
## Log(Assets)                             0.1079***  0.1083*** -1.121   
##                                        (0.0083)   (0.0091)   (0.7912) 
## Cash Ratio                             -0.0245*** -0.0219*** -0.1171  
##                                        (0.0064)   (0.0063)   (0.0754) 
## Loan-to-Deposit                        -0.0032    -0.0044     0.0232  
##                                        (0.0071)   (0.0072)   (0.0756) 
## Book Equity Ratio                      -0.0158**  -0.0181**  -0.0728  
##                                        (0.0059)   (0.0059)   (0.0703) 
## Wholesale Funding                       0.0303***  0.0313*** -0.0084  
##                                        (0.0069)   (0.0070)   (0.0365) 
## ROA                                    -0.0030    -0.0008     0.0252  
##                                        (0.0060)   (0.0060)   (0.0634) 
## ______________________________________ __________ __________ _________
## S.E. type                              Hete.-rob. Hete.-rob. Het.-rob.
## Observations                                3,991      3,866       125
## R2                                        0.12086    0.10365   0.20759
## 
##                                        BTFP (Full)   BTFP (Sm)   BTFP (Lg)
## Dependent Var.:                        btfp_crisis btfp_crisis btfp_crisis
##                                                                           
## Constant                                 0.1412***   0.1380***   3.096    
##                                         (0.0056)    (0.0058)    (2.741)   
## MTM Loss (z)                             0.0220***   0.0229***   0.0007   
##                                         (0.0059)    (0.0059)    (0.0782)  
## Uninsured Leverage (z)                   0.0130      0.0044      0.1506***
##                                         (0.0093)    (0.0094)    (0.0432)  
## Uninsured $\times$ Low $\beta^U$         0.0153      0.0205      0.0796   
##                                         (0.0112)    (0.0111)    (0.0676)  
## MTM $\times$ UI $\times$ Low $\beta^U$   0.0270***   0.0263***   0.0063   
##                                         (0.0069)    (0.0068)    (0.0654)  
## Log(Assets)                              0.0726***   0.0679***  -1.109    
##                                         (0.0078)    (0.0082)    (1.060)   
## Cash Ratio                              -0.0287***  -0.0271***  -0.1097   
##                                         (0.0050)    (0.0050)    (0.0772)  
## Loan-to-Deposit                         -0.0100     -0.0101      0.0202   
##                                         (0.0062)    (0.0062)    (0.0787)  
## Book Equity Ratio                       -0.0142**   -0.0157**   -0.1164   
##                                         (0.0050)    (0.0050)    (0.0751)  
## Wholesale Funding                        0.0273***   0.0275***  -0.0092   
##                                         (0.0066)    (0.0067)    (0.0407)  
## ROA                                     -0.0071     -0.0056      0.0694   
##                                         (0.0052)    (0.0051)    (0.0658)  
## ______________________________________ ___________ ___________ ___________
## S.E. type                              Heter.-rob. Heter.-rob. Heter.-rob.
## Observations                                 3,665       3,567          98
## R2                                         0.09665     0.08271     0.19790
## 
##                                         DW (Full)    DW (Sm)   DW (Lg)
## Dependent Var.:                         dw_crisis  dw_crisis dw_crisis
##                                                                       
## Constant                                0.1258***  0.1216***  3.961   
##                                        (0.0054)   (0.0056)   (2.311)  
## MTM Loss (z)                            0.0132*    0.0124*    0.0640  
##                                        (0.0058)   (0.0058)   (0.0685) 
## Uninsured Leverage (z)                  0.0056    -0.0038     0.1373**
##                                        (0.0090)   (0.0089)   (0.0408) 
## Uninsured $\times$ Low $\beta^U$        0.0095     0.0105     0.1255  
##                                        (0.0109)   (0.0107)   (0.0746) 
## MTM $\times$ UI $\times$ Low $\beta^U$  0.0239***  0.0202**  -0.0411  
##                                        (0.0065)   (0.0064)   (0.0700) 
## Log(Assets)                             0.0934***  0.0882*** -1.434   
##                                        (0.0078)   (0.0083)   (0.8965) 
## Cash Ratio                             -0.0039    -0.0015    -0.0856  
##                                        (0.0055)   (0.0054)   (0.0727) 
## Loan-to-Deposit                        -0.0012    -0.0013     0.0761  
##                                        (0.0061)   (0.0061)   (0.0669) 
## Book Equity Ratio                      -0.0019    -0.0059    -0.0844  
##                                        (0.0048)   (0.0047)   (0.0770) 
## Wholesale Funding                       0.0208**   0.0198**   0.0045  
##                                        (0.0063)   (0.0064)   (0.0371) 
## ROA                                    -0.0029    -0.0001     0.0221  
##                                        (0.0051)   (0.0051)   (0.0653) 
## ______________________________________ __________ __________ _________
## S.E. type                              Hete.-rob. Hete.-rob. Het.-rob.
## Observations                                3,599      3,493       106
## R2                                        0.10290    0.07700   0.24392
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

20 PUBLIC vs. NON-PUBLIC BANKS

# ==============================================================================
# PUBLIC vs. NON-PUBLIC BANK SPLIT
#
# Public banks (traded on equity markets) face dual market discipline:
#   1. Equity market: stock price declines signal distress → may trigger runs
#   2. Deposit market: uninsured depositors withdraw
#
# Non-public banks face only the deposit channel. If the coordination
# failure story holds, the MTM × Uninsured interaction should be strong
# across BOTH groups — the fundamental mechanism is depositor coordination,
# not equity market signaling.
#
# However, public banks may show STRONGER effects because equity price
# declines provide a publicly visible signal that helps depositors
# coordinate on the "run" equilibrium.
#
# Public status identified via NY Fed CRSP-FRB Link → NIC BHC hierarchy
# → CRSP PERMCO match (time-valid).
# ==============================================================================

cat("=== PUBLIC vs. NON-PUBLIC BANKS ===\n\n")
## === PUBLIC vs. NON-PUBLIC BANKS ===
# Ensure is_public is available on regression samples
cat(sprintf("  Crisis sample (df_crisis): %d public, %d non-public\n",
    sum(df_crisis$is_public == 1, na.rm = TRUE),
    sum(df_crisis$is_public == 0, na.rm = TRUE)))
##   Crisis sample (df_crisis): 311 public, 3981 non-public
# Counts per regression sample
for (nm in c("df_anyfed_s", "df_btfp_s", "df_dw_s", "df_fhlb_s")) {
  d <- get(nm)
  cat(sprintf("  %s: %d public (borrowers: %d), %d non-public (borrowers: %d)\n",
    nm,
    sum(d$is_public == 1, na.rm = TRUE),
    sum(d$is_public == 1 & d[[ifelse(nm == "df_anyfed_s", "any_fed",
      ifelse(nm == "df_btfp_s", "btfp_crisis",
        ifelse(nm == "df_dw_s", "dw_crisis", "fhlb_user")))]] == 1, na.rm = TRUE),
    sum(d$is_public == 0, na.rm = TRUE),
    sum(d$is_public == 0 & d[[ifelse(nm == "df_anyfed_s", "any_fed",
      ifelse(nm == "df_btfp_s", "btfp_crisis",
        ifelse(nm == "df_dw_s", "dw_crisis", "fhlb_user")))]] == 1, na.rm = TRUE)))
}
##   df_anyfed_s: 288 public (borrowers: 106), 3766 non-public (borrowers: 722)
##   df_btfp_s: 230 public (borrowers: 48), 3497 non-public (borrowers: 453)
##   df_dw_s: 265 public (borrowers: 83), 3394 non-public (borrowers: 350)
##   df_fhlb_s: 222 public (borrowers: 40), 3306 non-public (borrowers: 262)

20.1 Public Banks

cat("=== PUBLIC BANKS ===\n")
## === PUBLIC BANKS ===
mod_pub_any  <- safe_run(df_anyfed_s %>% filter(is_public == 1), "any_fed",     EXPL_BASE)
mod_pub_btfp <- safe_run(df_btfp_s   %>% filter(is_public == 1), "btfp_crisis", EXPL_BASE)
mod_pub_dw   <- safe_run(df_dw_s     %>% filter(is_public == 1), "dw_crisis",   EXPL_BASE)
mod_pub_fhlb <- safe_run(df_fhlb_s   %>% filter(is_public == 1), "fhlb_user",   EXPL_BASE)

models_pub <- list(
  "Any Fed" = mod_pub_any, "BTFP" = mod_pub_btfp,
  "DW" = mod_pub_dw, "FHLB" = mod_pub_fhlb)

save_etable(models_pub, "Public_banks_crisis",
  title_text = "Public Banks: Extensive Margin (Crisis Period)",
  notes_text = paste0(
    "LPM. Sample restricted to publicly traded banks (NY Fed CRSP-FRB Link via NIC hierarchy). ",
    "Public banks face dual discipline: equity market price signals AND depositor runs. ",
    "FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Listed", "Yes", "Yes", "Yes", "Yes")))

etable(models_pub[!sapply(models_pub, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                           Any Fed        BTFP         DW      FHLB
## Dependent Var.:           any_fed btfp_crisis  dw_crisis fhlb_user
##                                                                   
## Constant                0.0994      -0.0580    0.0936     0.0026  
##                        (0.0645)     (0.0526)  (0.0631)   (0.0494) 
## MTM Loss (z)            0.0605       0.0463    0.0384     0.0259  
##                        (0.0311)     (0.0290)  (0.0296)   (0.0260) 
## Uninsured Leverage (z)  0.1158***    0.0828**  0.1062***  0.0546* 
##                        (0.0280)     (0.0277)  (0.0282)   (0.0234) 
## MTM $\times$ Uninsured  0.0087      -0.0028    0.0253    -0.0142  
##                        (0.0246)     (0.0235)  (0.0238)   (0.0173) 
## Log(Assets)             0.1005**     0.1060**  0.0875*    0.0659* 
##                        (0.0350)     (0.0320)  (0.0341)   (0.0303) 
## Cash Ratio             -0.0767      -0.0634   -0.0721    -0.0523* 
##                        (0.0443)     (0.0341)  (0.0425)   (0.0263) 
## Loan-to-Deposit        -0.0356      -0.0237   -0.0444     0.0080  
##                        (0.0309)     (0.0271)  (0.0302)   (0.0231) 
## Book Equity Ratio       0.0500       0.0183    0.0493     0.1062**
##                        (0.0397)     (0.0364)  (0.0390)   (0.0336) 
## Wholesale Funding       0.0157       0.0191    0.0238    -0.0185  
##                        (0.0296)     (0.0282)  (0.0302)   (0.0276) 
## ROA                    -0.0210       0.0412   -0.0414    -0.0235  
##                        (0.0425)     (0.0359)  (0.0404)   (0.0374) 
## ______________________ __________ ___________ __________ _________
## S.E. type              Hete.-rob. Heter.-rob. Hete.-rob. Het.-rob.
## Observations                  288         230        265       222
## R2                        0.13486     0.13655    0.12435   0.09231
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

20.2 Non-Public Banks

cat("=== NON-PUBLIC BANKS ===\n")
## === NON-PUBLIC BANKS ===
mod_npub_any  <- safe_run(df_anyfed_s %>% filter(is_public == 0), "any_fed",     EXPL_BASE)
mod_npub_btfp <- safe_run(df_btfp_s   %>% filter(is_public == 0), "btfp_crisis", EXPL_BASE)
mod_npub_dw   <- safe_run(df_dw_s     %>% filter(is_public == 0), "dw_crisis",   EXPL_BASE)
mod_npub_fhlb <- safe_run(df_fhlb_s   %>% filter(is_public == 0), "fhlb_user",   EXPL_BASE)

models_npub <- list(
  "Any Fed" = mod_npub_any, "BTFP" = mod_npub_btfp,
  "DW" = mod_npub_dw, "FHLB" = mod_npub_fhlb)

save_etable(models_npub, "NonPublic_banks_crisis",
  title_text = "Non-Public Banks: Extensive Margin (Crisis Period)",
  notes_text = paste0(
    "LPM. Sample restricted to non-publicly-traded banks. ",
    "These banks face only the deposit channel (no equity price signal). ",
    "If MTM $\\times$ Uninsured is significant here, the coordination problem ",
    "operates through depositor-level information, not equity market signals. ",
    "FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Listed", "No", "No", "No", "No")))

etable(models_npub[!sapply(models_npub, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                           Any Fed        BTFP         DW       FHLB
## Dependent Var.:           any_fed btfp_crisis  dw_crisis  fhlb_user
##                                                                    
## Constant                0.2130***   0.1504***  0.1243***  0.0879***
##                        (0.0066)    (0.0062)   (0.0060)   (0.0053)  
## MTM Loss (z)            0.0268***   0.0230***  0.0127*    0.0039   
##                        (0.0072)    (0.0063)   (0.0061)   (0.0057)  
## Uninsured Leverage (z)  0.0098      0.0149*    0.0027     0.0027   
##                        (0.0079)    (0.0073)   (0.0069)   (0.0053)  
## MTM $\times$ Uninsured  0.0202***   0.0212***  0.0145**  -0.0040   
##                        (0.0059)    (0.0053)   (0.0051)   (0.0043)  
## Log(Assets)             0.1191***   0.0851***  0.0905***  0.0213** 
##                        (0.0093)    (0.0088)   (0.0087)   (0.0070)  
## Cash Ratio             -0.0228***  -0.0282*** -0.0012    -0.0197***
##                        (0.0062)    (0.0049)   (0.0052)   (0.0039)  
## Loan-to-Deposit        -0.0042     -0.0122*    0.0010     0.0252***
##                        (0.0068)    (0.0059)   (0.0058)   (0.0052)  
## Book Equity Ratio      -0.0153**   -0.0115*   -0.0049     0.0055   
##                        (0.0055)    (0.0047)   (0.0043)   (0.0041)  
## Wholesale Funding       0.0292***   0.0256***  0.0180**   0.0027   
##                        (0.0071)    (0.0067)   (0.0064)   (0.0052)  
## ROA                    -0.0007     -0.0065    -0.0002    -0.0080   
##                        (0.0058)    (0.0049)   (0.0049)   (0.0043)  
## ______________________ __________ ___________ __________ __________
## S.E. type              Hete.-rob. Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                3,756       3,487      3,384      3,296
## R2                        0.11435     0.09783    0.08008    0.03363
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

20.3 Combined Public/Non-Public Table

models_pub_combined <- list(
  "Any (Pub)" = mod_pub_any, "Any (NP)" = mod_npub_any,
  "BTFP (Pub)" = mod_pub_btfp, "BTFP (NP)" = mod_npub_btfp,
  "DW (Pub)" = mod_pub_dw, "DW (NP)" = mod_npub_dw,
  "FHLB (Pub)" = mod_pub_fhlb, "FHLB (NP)" = mod_npub_fhlb)

save_etable(models_pub_combined, "Public_NonPublic_combined",
  title_text = "Public vs. Non-Public Banks: Extensive Margin (Crisis Period)",
  notes_text = paste0(
    "LPM. Pub = publicly traded (CRSP-linked); NP = non-public. ",
    "Public banks face dual discipline (equity + deposits); non-public face deposits only. ",
    "If MTM $\\times$ Uninsured is significant among non-public banks, the coordination ",
    "failure operates through depositor-level information rather than equity market signals. ",
    "FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Listed", "Pub", "NP", "Pub", "NP", "Pub", "NP", "Pub", "NP")))

etable(models_pub_combined[!sapply(models_pub_combined, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                         Any (Pub)   Any (NP)  BTFP (Pub)   BTFP (NP)   DW (Pub)
## Dependent Var.:           any_fed    any_fed btfp_crisis btfp_crisis  dw_crisis
##                                                                                
## Constant                0.0994     0.2130***   -0.0580     0.1504***  0.0936   
##                        (0.0645)   (0.0066)     (0.0526)   (0.0062)   (0.0631)  
## MTM Loss (z)            0.0605     0.0268***    0.0463     0.0230***  0.0384   
##                        (0.0311)   (0.0072)     (0.0290)   (0.0063)   (0.0296)  
## Uninsured Leverage (z)  0.1158***  0.0098       0.0828**   0.0149*    0.1062***
##                        (0.0280)   (0.0079)     (0.0277)   (0.0073)   (0.0282)  
## MTM $\times$ Uninsured  0.0087     0.0202***   -0.0028     0.0212***  0.0253   
##                        (0.0246)   (0.0059)     (0.0235)   (0.0053)   (0.0238)  
## Log(Assets)             0.1005**   0.1191***    0.1060**   0.0851***  0.0875*  
##                        (0.0350)   (0.0093)     (0.0320)   (0.0088)   (0.0341)  
## Cash Ratio             -0.0767    -0.0228***   -0.0634    -0.0282*** -0.0721   
##                        (0.0443)   (0.0062)     (0.0341)   (0.0049)   (0.0425)  
## Loan-to-Deposit        -0.0356    -0.0042      -0.0237    -0.0122*   -0.0444   
##                        (0.0309)   (0.0068)     (0.0271)   (0.0059)   (0.0302)  
## Book Equity Ratio       0.0500    -0.0153**     0.0183    -0.0115*    0.0493   
##                        (0.0397)   (0.0055)     (0.0364)   (0.0047)   (0.0390)  
## Wholesale Funding       0.0157     0.0292***    0.0191     0.0256***  0.0238   
##                        (0.0296)   (0.0071)     (0.0282)   (0.0067)   (0.0302)  
## ROA                    -0.0210    -0.0007       0.0412    -0.0065    -0.0414   
##                        (0.0425)   (0.0058)     (0.0359)   (0.0049)   (0.0404)  
## ______________________ __________ __________ ___________ ___________ __________
## S.E. type              Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob. Hete.-rob.
## Observations                  288      3,756         230       3,487        265
## R2                        0.13486    0.11435     0.13655     0.09783    0.12435
## 
##                           DW (NP) FHLB (P..  FHLB (NP)
## Dependent Var.:         dw_crisis fhlb_user  fhlb_user
##                                                       
## Constant                0.1243***  0.0026    0.0879***
##                        (0.0060)   (0.0494)  (0.0053)  
## MTM Loss (z)            0.0127*    0.0259    0.0039   
##                        (0.0061)   (0.0260)  (0.0057)  
## Uninsured Leverage (z)  0.0027     0.0546*   0.0027   
##                        (0.0069)   (0.0234)  (0.0053)  
## MTM $\times$ Uninsured  0.0145**  -0.0142   -0.0040   
##                        (0.0051)   (0.0173)  (0.0043)  
## Log(Assets)             0.0905***  0.0659*   0.0213** 
##                        (0.0087)   (0.0303)  (0.0070)  
## Cash Ratio             -0.0012    -0.0523*  -0.0197***
##                        (0.0052)   (0.0263)  (0.0039)  
## Loan-to-Deposit         0.0010     0.0080    0.0252***
##                        (0.0058)   (0.0231)  (0.0052)  
## Book Equity Ratio      -0.0049     0.1062**  0.0055   
##                        (0.0043)   (0.0336)  (0.0041)  
## Wholesale Funding       0.0180**  -0.0185    0.0027   
##                        (0.0064)   (0.0276)  (0.0052)  
## ROA                    -0.0002    -0.0235   -0.0080   
##                        (0.0049)   (0.0374)  (0.0043)  
## ______________________ __________ _________ __________
## S.E. type              Hete.-rob. Het.-rob. Hete.-rob.
## Observations                3,384       222      3,296
## R2                        0.08008   0.09231    0.03363
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

20.4 Public/Non-Public Descriptive Comparison

cat("--- Mean Characteristics: Public vs. Non-Public (2022Q4 Baseline) ---\n\n")
## --- Mean Characteristics: Public vs. Non-Public (2022Q4 Baseline) ---
desc_pub_vars <- c("mtm_total_raw", "uninsured_lev_raw", "uninsured_beta_raw",
  "adjusted_equity_raw", "dfv_raw", "ln_assets_raw", "cash_ratio_raw",
  "book_equity_ratio_raw", "roa_raw", "wholesale_raw")

pub_desc <- df_2022q4 %>%
  group_by(Public = ifelse(is_public == 1, "Public", "Non-Public")) %>%
  summarise(
    N = n(),
    across(all_of(desc_pub_vars), ~round(mean(., na.rm = TRUE), 3)),
    .groups = "drop"
  )

print(pub_desc, width = Inf)
## # A tibble: 2 × 12
##   Public         N mtm_total_raw uninsured_lev_raw uninsured_beta_raw
##   <chr>      <int>         <dbl>             <dbl>              <dbl>
## 1 Non-Public  3981          5.48              23.0              0.328
## 2 Public       311          5.28              31.7              0.372
##   adjusted_equity_raw dfv_raw ln_assets_raw cash_ratio_raw book_equity_ratio_raw
##                 <dbl>   <dbl>         <dbl>          <dbl>                 <dbl>
## 1                4.58    77.8          12.7           8.42                  10.2
## 2                5.82    68.0          15.5           4.63                  11.1
##   roa_raw wholesale_raw
##     <dbl>         <dbl>
## 1    1.13         0.983
## 2    1.62         1.23
# T-tests
cat("\n--- T-Tests: Public vs. Non-Public ---\n")
## 
## --- T-Tests: Public vs. Non-Public ---
df_pub  <- df_2022q4 %>% filter(is_public == 1)
df_npub <- df_2022q4 %>% filter(is_public == 0)

for (v in desc_pub_vars) {
  tt <- tryCatch(t.test(df_pub[[v]], df_npub[[v]]), error = function(e) NULL)
  if (!is.null(tt)) {
    stars <- case_when(tt$p.value < 0.01 ~ "***", tt$p.value < 0.05 ~ "**",
                       tt$p.value < 0.10 ~ "*", TRUE ~ "")
    cat(sprintf("  %-25s Pub=%.3f NP=%.3f diff=%.3f t=%.2f %s\n", v,
      mean(df_pub[[v]], na.rm = TRUE), mean(df_npub[[v]], na.rm = TRUE),
      mean(df_pub[[v]], na.rm = TRUE) - mean(df_npub[[v]], na.rm = TRUE),
      tt$statistic, stars))
  }
}
##   mtm_total_raw             Pub=5.276 NP=5.482 diff=-0.207 t=-1.67 *
##   uninsured_lev_raw         Pub=31.738 NP=22.976 diff=8.762 t=11.65 ***
##   uninsured_beta_raw        Pub=0.372 NP=0.328 diff=0.044 t=5.88 ***
##   adjusted_equity_raw       Pub=5.824 NP=4.581 diff=1.242 t=2.00 **
##   dfv_raw                   Pub=67.979 NP=77.788 diff=-9.809 t=-12.09 ***
##   ln_assets_raw             Pub=15.544 NP=12.674 diff=2.870 t=33.48 ***
##   cash_ratio_raw            Pub=4.626 NP=8.423 diff=-3.797 t=-8.64 ***
##   book_equity_ratio_raw     Pub=11.099 NP=10.152 diff=0.948 t=1.63 
##   roa_raw                   Pub=1.619 NP=1.128 diff=0.491 t=2.08 **
##   wholesale_raw             Pub=1.227 NP=0.983 diff=0.245 t=1.57
# Borrowing rates by public status
cat("\n--- Borrowing Rates by Public Status (Crisis) ---\n")
## 
## --- Borrowing Rates by Public Status (Crisis) ---
df_crisis %>%
  group_by(Public = ifelse(is_public == 1, "Public", "Non-Public")) %>%
  summarise(
    N = n(),
    AnyFed_pct = round(100 * mean(any_fed, na.rm = TRUE), 2),
    BTFP_pct   = round(100 * mean(btfp_crisis, na.rm = TRUE), 2),
    DW_pct     = round(100 * mean(dw_crisis, na.rm = TRUE), 2),
    FHLB_pct   = round(100 * mean(fhlb_user, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  print()
## # A tibble: 2 × 6
##   Public         N AnyFed_pct BTFP_pct DW_pct FHLB_pct
##   <chr>      <int>      <dbl>    <dbl>  <dbl>    <dbl>
## 1 Non-Public  3981       18.1     11.4   8.79     6.58
## 2 Public       311       34.1     15.4  26.7     12.9

21 SVB CASE STUDY: Deposit Beta Anatomy

21.1 SVB Reference & Beta Decomposition

# ==============================================================================
# SVB CASE STUDY
#
# Silicon Valley Bank (RSSD = 802866) is the defining case of the 2023
# banking crisis. Excluded from regressions as a failed bank, but its
# pre-crisis characteristics illustrate the model's predictions.
#
# This section:
#   1. SVB reference values and beta decomposition
#   2. Original SVB-like regressions (β^U × uninsured share)
#   3. Improved Approach 1: Redefined indicator (orthogonal to interaction)
#   4. Improved Approach 2: Continuous Mahalanobis proximity
#   5. Approach 2b: Euclidean robustness
#   6. Summary comparison table
#   7. Visualizations
# ==============================================================================

SVB_RSSD <- "802866"
svb_call <- call_q %>% filter(idrssd == SVB_RSSD, period == "2022Q4")
svb_beta <- dssw_betas %>% filter(idrssd == SVB_RSSD, estimation_date == "2022Q4")

stopifnot(nrow(svb_call) == 1, nrow(svb_beta) == 1)

svb_ref <- list(
  beta_u         = svb_beta$beta_uninsured,
  beta_o         = svb_beta$beta_overall,
  beta_i         = svb_beta$beta_insured,
  s_u            = svb_beta$uninsured_share,
  securities_rat = svb_call$security_to_total_asset,
  cash_rat       = svb_call$cash_to_total_asset,
  mtm_omo_rat    = svb_call$mtm_loss_omo_eligible_to_total_asset,
  mtm_total_rat  = svb_call$mtm_loss_to_total_asset,
  uninsured_lev  = svb_call$uninsured_deposit_to_total_asset,
  book_eq        = svb_call$book_equity_to_total_asset,
  total_assets   = svb_call$total_asset
)

cat("=== SVB REFERENCE VALUES (2022Q4) ===\n\n")
## === SVB REFERENCE VALUES (2022Q4) ===
cat(sprintf("  Total assets:       $%.1fB\n", svb_ref$total_assets / 1e6))
##   Total assets:       $209.0B
cat(sprintf("  MTM loss / TA:      %.2f%%\n", svb_ref$mtm_total_rat))
##   MTM loss / TA:      7.40%
cat(sprintf("  Uninsured / TA:     %.2f%%\n", svb_ref$uninsured_lev))
##   Uninsured / TA:     70.52%
cat(sprintf("  Book equity / TA:   %.2f%%\n", svb_ref$book_eq))
##   Book equity / TA:   7.39%
cat(sprintf("  β_overall:          %.4f\n", svb_ref$beta_o))
##   β_overall:          0.3410
cat(sprintf("  β_insured:          %.4f\n", svb_ref$beta_i))
##   β_insured:          0.0535
cat(sprintf("  β_uninsured:        %.4f\n", svb_ref$beta_u))
##   β_uninsured:        0.3661
cat(sprintf("  Uninsured share:    %.1f%%\n", svb_ref$s_u * 100))
##   Uninsured share:    92.0%
cat(sprintf("  Securities / TA:    %.2f%%\n", svb_ref$securities_rat))
##   Securities / TA:    54.20%
cat(sprintf("  Cash / TA:          %.2f%%\n", svb_ref$cash_rat))
##   Cash / TA:          5.99%
# DSSW decomposition check
cat(sprintf("\n  DSSW check: s_U×β^U + (1-s_U)×β^I = %.4f×%.4f + %.4f×%.4f = %.4f\n",
    svb_ref$s_u, svb_ref$beta_u, 1 - svb_ref$s_u, svb_ref$beta_i,
    svb_ref$s_u * svb_ref$beta_u + (1 - svb_ref$s_u) * svb_ref$beta_i))
## 
##   DSSW check: s_U×β^U + (1-s_U)×β^I = 0.9198×0.3661 + 0.0802×0.0535 = 0.3410
cat(sprintf("  β_overall = %.4f  ✓\n", svb_ref$beta_o))
##   β_overall = 0.3410  ✓
# Solvency
d_ta <- svb_call$dom_deposit[1] / svb_call$total_asset[1]
dfv_svb  <- (1 - svb_ref$beta_o) * d_ta * 100
ae_jiang <- svb_ref$book_eq - svb_ref$mtm_total_rat
ae_dssw  <- ae_jiang + dfv_svb

cat(sprintf("\n  DFV (DSSW)  = (1 - %.4f) × %.2f%% = %.2f%% of TA\n",
    svb_ref$beta_o, d_ta * 100, dfv_svb))
## 
##   DFV (DSSW)  = (1 - 0.3410) × 77.25% = 50.91% of TA
cat(sprintf("  Jiang AE    = %.2f%% → %s\n", ae_jiang,
    ifelse(ae_jiang < 0, "INSOLVENT", "Solvent")))
##   Jiang AE    = -0.00% → INSOLVENT
cat(sprintf("  DSSW AE     = %.2f%% → %s\n", ae_dssw,
    ifelse(ae_dssw < 0, "INSOLVENT", "Solvent")))
##   DSSW AE     = 50.91% → Solvent
cat("\n  KEY: SVB was DSSW-solvent in the no-run equilibrium.\n")
## 
##   KEY: SVB was DSSW-solvent in the no-run equilibrium.
cat("  Its extreme uninsured share (92%) made the franchise fragile.\n")
##   Its extreme uninsured share (92%) made the franchise fragile.
cat("  Once depositors coordinated, the franchise was destroyed.\n")
##   Once depositors coordinated, the franchise was destroyed.

21.2 SVB-Like Regressions (β^U × Uninsured Share)

# ==============================================================================
# ORIGINAL SVB-LIKE DEFINITION
# SVB-like = above-median β^U AND above-median uninsured share
#
# Known issue: uninsured share ≈ uninsured leverage, which is IN the
# interaction term. This mechanically restricts within-group variation.
# Kept for comparison with improved approaches below.
# ==============================================================================

cat("=== ORIGINAL SVB-LIKE REGRESSIONS ===\n\n")
## === ORIGINAL SVB-LIKE REGRESSIONS ===
med_beta_u   <- median(df_crisis$uninsured_beta_raw, na.rm = TRUE)
med_ui_share <- median(df_crisis$uninsured_share_raw, na.rm = TRUE)

cat(sprintf("  Median β^U:             %.4f\n", med_beta_u))
##   Median β^U:             0.3106
cat(sprintf("  Median uninsured share: %.4f (%.1f%%)\n\n", med_ui_share, med_ui_share * 100))
##   Median uninsured share: 25.8006 (2580.1%)
add_svb_like <- function(df) {
  df %>% mutate(
    svb_like = case_when(
      is.na(uninsured_beta_raw) | is.na(uninsured_share_raw) ~ NA_integer_,
      uninsured_beta_raw > med_beta_u & uninsured_share_raw > med_ui_share ~ 1L,
      TRUE ~ 0L
    )
  )
}

df_anyfed_s <- add_svb_like(df_anyfed_s)
df_btfp_s   <- add_svb_like(df_btfp_s)
df_dw_s     <- add_svb_like(df_dw_s)
df_fhlb_s   <- add_svb_like(df_fhlb_s)
df_crisis   <- add_svb_like(df_crisis)

for (grp in c("SVB-like (1)", "SVB-unlike (0)")) {
  val <- ifelse(grp == "SVB-like (1)", 1L, 0L)
  cat(sprintf("  %s:\n", grp))
  cat(sprintf("    AnyFed: N=%d, Borrowers=%d\n",
    sum(df_anyfed_s$svb_like == val, na.rm = TRUE),
    sum(df_anyfed_s$any_fed[df_anyfed_s$svb_like == val], na.rm = TRUE)))
  cat(sprintf("    BTFP:   N=%d, Borrowers=%d\n",
    sum(df_btfp_s$svb_like == val, na.rm = TRUE),
    sum(df_btfp_s$btfp_crisis[df_btfp_s$svb_like == val], na.rm = TRUE)))
}
##   SVB-like (1):
##     AnyFed: N=967, Borrowers=281
##     BTFP:   N=862, Borrowers=176
##   SVB-unlike (0):
##     AnyFed: N=3024, Borrowers=541
##     BTFP:   N=2803, Borrowers=320
# --- Uninsured leverage variation diagnostic (shows the problem) ---
cat("\n--- Uninsured Leverage Variation by Original SVB-Like ---\n")
## 
## --- Uninsured Leverage Variation by Original SVB-Like ---
cat("  (Low SD in Like group = restriction-of-range problem)\n")
##   (Low SD in Like group = restriction-of-range problem)
df_crisis %>%
  filter(!is.na(svb_like)) %>%
  group_by(SVB_Like = ifelse(svb_like == 1, "Like", "Unlike")) %>%
  summarise(N = n(), Mean_UI = round(mean(uninsured_lev_raw, na.rm=T), 2),
            SD_UI = round(sd(uninsured_lev_raw, na.rm=T), 2),
            P10_UI = round(quantile(uninsured_lev_raw, .10, na.rm=T), 2),
            P90_UI = round(quantile(uninsured_lev_raw, .90, na.rm=T), 2),
            .groups = "drop") %>% print()
## # A tibble: 2 × 6
##   SVB_Like     N Mean_UI SD_UI P10_UI P90_UI
##   <chr>    <int>   <dbl> <dbl>  <dbl>  <dbl>
## 1 Like      1046    32.6  10.1  23.3    45.1
## 2 Unlike    3180    20.9  11.1   8.67   35.8
# --- Regressions ---
mod_svb_any_like    <- safe_run(df_anyfed_s %>% filter(svb_like == 1), "any_fed",     EXPL_BASE)
mod_svb_btfp_like   <- safe_run(df_btfp_s   %>% filter(svb_like == 1), "btfp_crisis", EXPL_BASE)
mod_svb_dw_like     <- safe_run(df_dw_s     %>% filter(svb_like == 1), "dw_crisis",   EXPL_BASE)
mod_svb_fhlb_like   <- safe_run(df_fhlb_s   %>% filter(svb_like == 1), "fhlb_user",   EXPL_BASE)

mod_svb_any_unlike  <- safe_run(df_anyfed_s %>% filter(svb_like == 0), "any_fed",     EXPL_BASE)
mod_svb_btfp_unlike <- safe_run(df_btfp_s   %>% filter(svb_like == 0), "btfp_crisis", EXPL_BASE)
mod_svb_dw_unlike   <- safe_run(df_dw_s     %>% filter(svb_like == 0), "dw_crisis",   EXPL_BASE)
mod_svb_fhlb_unlike <- safe_run(df_fhlb_s   %>% filter(svb_like == 0), "fhlb_user",   EXPL_BASE)

models_svb_combined <- list(
  "Any (Like)" = mod_svb_any_like, "Any (Unlike)" = mod_svb_any_unlike,
  "BTFP (Like)" = mod_svb_btfp_like, "BTFP (Unlike)" = mod_svb_btfp_unlike,
  "DW (Like)" = mod_svb_dw_like, "DW (Unlike)" = mod_svb_dw_unlike,
  "FHLB (Like)" = mod_svb_fhlb_like, "FHLB (Unlike)" = mod_svb_fhlb_unlike)

save_etable(models_svb_combined, "SVB_like_unlike_combined_original",
  title_text = "Original SVB-Like vs. SVB-Unlike Banks (Crisis Period)",
  notes_text = paste0(
    "LPM. Original definition: SVB-like = above-median $\\beta^U$ AND above-median uninsured share. ",
    "Known restriction-of-range problem: uninsured share $\\approx$ uninsured leverage (in the interaction). ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("SVB-Like", "Yes", "No", "Yes", "No", "Yes", "No", "Yes", "No")))

etable(models_svb_combined[!sapply(models_svb_combined, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                        Any (Like) Any (Unl.. BTFP (Like) BTFP (Unl..  DW (Like)
## Dependent Var.:           any_fed    any_fed btfp_crisis btfp_crisis  dw_crisis
##                                                                                
## Constant                0.2239***  0.2062***   0.1594***   0.1382***  0.1181***
##                        (0.0205)   (0.0076)    (0.0195)    (0.0071)   (0.0188)  
## MTM Loss (z)            0.0412     0.0279***   0.0266      0.0212**   0.0203   
##                        (0.0225)   (0.0082)    (0.0197)    (0.0073)   (0.0207)  
## Uninsured Leverage (z)  0.0005     0.0220*     0.0086      0.0211**   0.0034   
##                        (0.0220)   (0.0089)    (0.0219)    (0.0081)   (0.0207)  
## MTM $\times$ Uninsured  0.0033     0.0192**    0.0181      0.0152*    0.0058   
##                        (0.0209)   (0.0066)    (0.0191)    (0.0063)   (0.0198)  
## Log(Assets)             0.1060***  0.1082***   0.0774***   0.0694***  0.1062***
##                        (0.0169)   (0.0096)    (0.0169)    (0.0087)   (0.0164)  
## Cash Ratio             -0.0355    -0.0226***  -0.0337*    -0.0278*** -0.0103   
##                        (0.0184)   (0.0068)    (0.0156)    (0.0052)   (0.0166)  
## Loan-to-Deposit        -0.0121     0.0004     -0.0175     -0.0068    -0.0039   
##                        (0.0186)   (0.0077)    (0.0170)    (0.0065)   (0.0172)  
## Book Equity Ratio      -0.0126    -0.0145*    -0.0174     -0.0126*    0.0049   
##                        (0.0177)   (0.0063)    (0.0157)    (0.0053)   (0.0158)  
## Wholesale Funding       0.0644***  0.0174*     0.0668***   0.0126     0.0430*  
##                        (0.0159)   (0.0075)    (0.0165)    (0.0066)   (0.0171)  
## ROA                     0.0086    -0.0062     -0.0038     -0.0071     0.0175   
##                        (0.0142)   (0.0066)    (0.0129)    (0.0056)   (0.0123)  
## ______________________ __________ __________ ___________ ___________ __________
## S.E. type              Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob. Hete.-rob.
## Observations                  967      3,024         862       2,803        838
## R2                        0.10939    0.11169     0.10453     0.08357    0.10223
## 
##                        DW (Unli.. FHLB (Li.. FHLB (Un..
## Dependent Var.:         dw_crisis  fhlb_user  fhlb_user
##                                                        
## Constant                0.1273***  0.1108***  0.0842***
##                        (0.0070)   (0.0167)   (0.0062)  
## MTM Loss (z)            0.0168*    0.0083     0.0099   
##                        (0.0071)   (0.0183)   (0.0062)  
## Uninsured Leverage (z)  0.0158*   -0.0165     0.0063   
##                        (0.0079)   (0.0159)   (0.0060)  
## MTM $\times$ Uninsured  0.0201*** -0.0286    -0.0007   
##                        (0.0058)   (0.0158)   (0.0048)  
## Log(Assets)             0.0883***  0.0363*    0.0218** 
##                        (0.0090)   (0.0152)   (0.0071)  
## Cash Ratio             -0.0035    -0.0372**  -0.0167***
##                        (0.0058)   (0.0131)   (0.0042)  
## Loan-to-Deposit         0.0011     0.0149     0.0260***
##                        (0.0065)   (0.0150)   (0.0057)  
## Book Equity Ratio      -0.0015     0.0072     0.0084   
##                        (0.0050)   (0.0159)   (0.0045)  
## Wholesale Funding       0.0142*    0.0049     0.0016   
##                        (0.0066)   (0.0140)   (0.0055)  
## ROA                    -0.0084    -0.0082    -0.0101*  
##                        (0.0056)   (0.0121)   (0.0047)  
## ______________________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                2,761        792      2,676
## R2                        0.09286    0.03550    0.03544
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

21.3 Approach 1: Redefined SVB-Like (Orthogonal)

# ==============================================================================
# APPROACH 1: REDEFINED SVB-LIKE INDICATOR
#
# SVB-like = above-median β^U AND above-median securities/TA AND below-median cash/TA
#
# Why: These variables are ORTHOGONAL to MTM × Uninsured.
# Uninsured leverage varies freely within each group.
# ==============================================================================

cat("=== APPROACH 1: REDEFINED SVB-LIKE (ORTHOGONAL) ===\n\n")
## === APPROACH 1: REDEFINED SVB-LIKE (ORTHOGONAL) ===
med_beta_u_v2  <- median(df_crisis$uninsured_beta_raw, na.rm = TRUE)
med_sec_ratio  <- median(df_crisis$securities_ratio_raw, na.rm = TRUE)
med_cash_ratio <- median(df_crisis$cash_ratio_raw, na.rm = TRUE)

cat(sprintf("  Median β^U:             %.4f\n", med_beta_u_v2))
##   Median β^U:             0.3106
cat(sprintf("  Median Securities / TA: %.2f%%\n", med_sec_ratio))
##   Median Securities / TA: 23.32%
cat(sprintf("  Median Cash / TA:       %.2f%%\n", med_cash_ratio))
##   Median Cash / TA:       5.03%
cat(sprintf("\n  SVB qualifies? β^U>med: %s | Sec>med: %s | Cash<med: %s → %s\n",
    ifelse(svb_ref$beta_u > med_beta_u_v2, "YES", "NO"),
    ifelse(svb_ref$securities_rat > med_sec_ratio, "YES", "NO"),
    ifelse(svb_ref$cash_rat < med_cash_ratio, "YES", "NO"),
    ifelse(svb_ref$beta_u > med_beta_u_v2 &
           svb_ref$securities_rat > med_sec_ratio &
           svb_ref$cash_rat < med_cash_ratio, "YES ✓", "NO ✗")))
## 
##   SVB qualifies? β^U>med: YES | Sec>med: YES | Cash<med: NO → NO ✗
add_svb_like_v2 <- function(df) {
  df %>% mutate(
    svb_like_v2 = case_when(
      is.na(uninsured_beta_raw) | is.na(securities_ratio_raw) |
        is.na(cash_ratio_raw) ~ NA_integer_,
      uninsured_beta_raw > med_beta_u_v2 &
        securities_ratio_raw > med_sec_ratio &
        cash_ratio_raw < med_cash_ratio ~ 1L,
      TRUE ~ 0L
    )
  )
}

df_anyfed_s <- add_svb_like_v2(df_anyfed_s)
df_btfp_s   <- add_svb_like_v2(df_btfp_s)
df_dw_s     <- add_svb_like_v2(df_dw_s)
df_fhlb_s   <- add_svb_like_v2(df_fhlb_s)
df_crisis   <- add_svb_like_v2(df_crisis)

cat("\n--- SVB-Like v2 Counts ---\n")
## 
## --- SVB-Like v2 Counts ---
for (grp in c("SVB-like (1)", "SVB-unlike (0)")) {
  val <- ifelse(grp == "SVB-like (1)", 1L, 0L)
  cat(sprintf("  %s:\n", grp))
  cat(sprintf("    AnyFed: N=%d, Borrowers=%d\n",
      sum(df_anyfed_s$svb_like_v2 == val, na.rm = TRUE),
      sum(df_anyfed_s$any_fed[df_anyfed_s$svb_like_v2 == val], na.rm = TRUE)))
  cat(sprintf("    BTFP:   N=%d, Borrowers=%d\n",
      sum(df_btfp_s$svb_like_v2 == val, na.rm = TRUE),
      sum(df_btfp_s$btfp_crisis[df_btfp_s$svb_like_v2 == val], na.rm = TRUE)))
}
##   SVB-like (1):
##     AnyFed: N=502, Borrowers=155
##     BTFP:   N=448, Borrowers=101
##   SVB-unlike (0):
##     AnyFed: N=3489, Borrowers=667
##     BTFP:   N=3217, Borrowers=395
# --- Verify uninsured leverage variation is PRESERVED ---
cat("\n--- Uninsured Leverage Variation by SVB-Like v2 ---\n")
## 
## --- Uninsured Leverage Variation by SVB-Like v2 ---
cat("  (SD should be similar across groups — no restriction of range)\n")
##   (SD should be similar across groups — no restriction of range)
df_crisis %>%
  filter(!is.na(svb_like_v2)) %>%
  group_by(SVB_Like_v2 = ifelse(svb_like_v2 == 1, "Like", "Unlike")) %>%
  summarise(N = n(), Mean_UI = round(mean(uninsured_lev_raw, na.rm=T), 2),
            SD_UI = round(sd(uninsured_lev_raw, na.rm=T), 2),
            P10_UI = round(quantile(uninsured_lev_raw, .10, na.rm=T), 2),
            P90_UI = round(quantile(uninsured_lev_raw, .90, na.rm=T), 2),
            .groups = "drop") %>% print()
## # A tibble: 2 × 6
##   SVB_Like_v2     N Mean_UI SD_UI P10_UI P90_UI
##   <chr>       <int>   <dbl> <dbl>  <dbl>  <dbl>
## 1 Like          530    22.6  10.4  10.7    35.2
## 2 Unlike       3696    23.9  12.2   9.74   40.0
# --- Regressions ---
mod_svbv2_any_like   <- safe_run(df_anyfed_s %>% filter(svb_like_v2 == 1), "any_fed",     EXPL_BASE)
mod_svbv2_btfp_like  <- safe_run(df_btfp_s   %>% filter(svb_like_v2 == 1), "btfp_crisis", EXPL_BASE)
mod_svbv2_dw_like    <- safe_run(df_dw_s     %>% filter(svb_like_v2 == 1), "dw_crisis",   EXPL_BASE)
mod_svbv2_fhlb_like  <- safe_run(df_fhlb_s   %>% filter(svb_like_v2 == 1), "fhlb_user",   EXPL_BASE)

mod_svbv2_any_unlike  <- safe_run(df_anyfed_s %>% filter(svb_like_v2 == 0), "any_fed",     EXPL_BASE)
mod_svbv2_btfp_unlike <- safe_run(df_btfp_s   %>% filter(svb_like_v2 == 0), "btfp_crisis", EXPL_BASE)
mod_svbv2_dw_unlike   <- safe_run(df_dw_s     %>% filter(svb_like_v2 == 0), "dw_crisis",   EXPL_BASE)
mod_svbv2_fhlb_unlike <- safe_run(df_fhlb_s   %>% filter(svb_like_v2 == 0), "fhlb_user",   EXPL_BASE)

models_svbv2_combined <- list(
  "Any (Like)"  = mod_svbv2_any_like,  "Any (Unlike)"  = mod_svbv2_any_unlike,
  "BTFP (Like)" = mod_svbv2_btfp_like, "BTFP (Unlike)" = mod_svbv2_btfp_unlike,
  "DW (Like)"   = mod_svbv2_dw_like,   "DW (Unlike)"   = mod_svbv2_dw_unlike,
  "FHLB (Like)" = mod_svbv2_fhlb_like, "FHLB (Unlike)" = mod_svbv2_fhlb_unlike)

save_etable(models_svbv2_combined, "SVBlike_v2_combined",
  title_text = "SVB-Like v2 (Orthogonal): Asset-Side Vulnerability Profile (Crisis)",
  notes_text = paste0(
    "LPM. SVB-like v2 = above-median $\\beta^U$ AND above-median securities/TA ",
    "AND below-median cash/TA. These variables are orthogonal to MTM $\\times$ Uninsured, ",
    "preserving within-group variation in uninsured leverage. ",
    "FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(
    c("SVB-Like v2", "Yes", "No", "Yes", "No", "Yes", "No", "Yes", "No")))

etable(models_svbv2_combined[!sapply(models_svbv2_combined, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                        Any (Like) Any (Unl.. BTFP (Like) BTFP (Unl..  DW (Like)
## Dependent Var.:           any_fed    any_fed btfp_crisis btfp_crisis  dw_crisis
##                                                                                
## Constant                0.1094     0.2001***   0.0165      0.1366***  0.0355   
##                        (0.0933)   (0.0066)    (0.0838)    (0.0061)   (0.0846)  
## MTM Loss (z)            0.0272     0.0303***   0.0233      0.0250***  0.0095   
##                        (0.0246)   (0.0073)    (0.0229)    (0.0064)   (0.0225)  
## Uninsured Leverage (z)  0.0094     0.0210**    0.0209      0.0226**   0.0008   
##                        (0.0256)   (0.0081)    (0.0241)    (0.0075)   (0.0237)  
## MTM $\times$ Uninsured  0.0481*    0.0160**    0.0371      0.0157**   0.0416*  
##                        (0.0221)   (0.0062)    (0.0211)    (0.0057)   (0.0198)  
## Log(Assets)             0.1379***  0.1010***   0.1036***   0.0658***  0.1338***
##                        (0.0258)   (0.0087)    (0.0252)    (0.0081)   (0.0251)  
## Cash Ratio             -0.2371    -0.0208**   -0.2676*    -0.0273*** -0.1801   
##                        (0.1340)   (0.0065)    (0.1221)    (0.0051)   (0.1214)  
## Loan-to-Deposit         0.0518    -0.0013      0.0557     -0.0102     0.0115   
##                        (0.0335)   (0.0074)    (0.0312)    (0.0063)   (0.0305)  
## Book Equity Ratio      -0.0297    -0.0125*    -0.0366*    -0.0098     0.0056   
##                        (0.0221)   (0.0060)    (0.0184)    (0.0052)   (0.0207)  
## Wholesale Funding       0.0302     0.0280***   0.0404*     0.0219**   0.0165   
##                        (0.0172)   (0.0076)    (0.0166)    (0.0070)   (0.0171)  
## ROA                    -0.0273    -0.0002     -0.0319     -0.0046    -0.0283   
##                        (0.0255)   (0.0061)    (0.0234)    (0.0052)   (0.0232)  
## ______________________ __________ __________ ___________ ___________ __________
## S.E. type              Hete.-rob. Hete.-rob. Heter.-rob. Heter.-rob. Hete.-rob.
## Observations                  502      3,489         448       3,217        420
## R2                        0.13608    0.11358     0.13177     0.08769    0.13557
## 
##                        DW (Unli.. FHLB (L.. FHLB (Un..
## Dependent Var.:         dw_crisis fhlb_user  fhlb_user
##                                                       
## Constant                0.1225***   0.1089   0.0890***
##                        (0.0058)    (0.0697) (0.0053)  
## MTM Loss (z)            0.0163*     0.0081   0.0038   
##                        (0.0064)    (0.0199) (0.0059)  
## Uninsured Leverage (z)  0.0128      0.0077   0.0058   
##                        (0.0072)    (0.0192) (0.0056)  
## MTM $\times$ Uninsured  0.0142**    0.0083  -0.0065   
##                        (0.0055)    (0.0149) (0.0048)  
## Log(Assets)             0.0867***   0.0331   0.0273***
##                        (0.0082)    (0.0246) (0.0068)  
## Cash Ratio             -0.0010      0.0091  -0.0213***
##                        (0.0056)    (0.1026) (0.0042)  
## Loan-to-Deposit         0.0023      0.0372   0.0249***
##                        (0.0063)    (0.0244) (0.0056)  
## Book Equity Ratio      -0.0019     -0.0051   0.0097*  
##                        (0.0048)    (0.0152) (0.0047)  
## Wholesale Funding       0.0206**    0.0092   0.0012   
##                        (0.0069)    (0.0133) (0.0056)  
## ROA                    -0.0007     -0.0206  -0.0096*  
##                        (0.0052)    (0.0215) (0.0046)  
## ______________________ __________ _________ __________
## S.E. type              Hete.-rob. Het.-rob. Hete.-rob.
## Observations                3,179       385      3,083
## R2                        0.09766   0.02065    0.04431
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

21.4 Approach 2: Continuous SVB Proximity (Mahalanobis)

# ==============================================================================
# APPROACH 2: CONTINUOUS MAHALANOBIS DISTANCE TO SVB
#
# No sample splitting. Compute each bank's Mahalanobis distance from SVB's
# profile on (β^U, securities/TA, cash/TA) — all orthogonal to interaction.
# Interact this continuous SVB-proximity score with MTM × Uninsured.
# ==============================================================================

cat("=== APPROACH 2: CONTINUOUS SVB-PROXIMITY (MAHALANOBIS) ===\n\n")
## === APPROACH 2: CONTINUOUS SVB-PROXIMITY (MAHALANOBIS) ===
profile_vars <- c("uninsured_beta_raw", "securities_ratio_raw", "cash_ratio_raw")
svb_vec <- c(svb_ref$beta_u, svb_ref$securities_rat, svb_ref$cash_rat)
names(svb_vec) <- profile_vars

cat("SVB reference vector:\n")
## SVB reference vector:
print(round(svb_vec, 4))
##   uninsured_beta_raw securities_ratio_raw       cash_ratio_raw 
##               0.3661              54.2019               5.9854
add_svb_proximity <- function(df) {
  profile_mat <- df %>% select(all_of(profile_vars)) %>% as.matrix()
  complete_idx <- complete.cases(profile_mat)
  Sigma <- cov(profile_mat[complete_idx, ], use = "complete.obs")
  mahal_dist <- rep(NA_real_, nrow(df))
  mahal_dist[complete_idx] <- mahalanobis(
    x = profile_mat[complete_idx, ], center = svb_vec, cov = Sigma)

  df %>% mutate(
    svb_mahal_dist     = mahal_dist,
    svb_prox_raw       = -mahal_dist,
    svb_prox_w         = winsorize(svb_prox_raw),
    svb_prox           = standardize_z(svb_prox_w),
    mtm_x_ui_x_svbprox = mtm_total * uninsured_lev * svb_prox,
    svb_prox_x_mtm     = svb_prox * mtm_total,
    svb_prox_x_ui      = svb_prox * uninsured_lev
  )
}

df_anyfed_s <- add_svb_proximity(df_anyfed_s)
df_btfp_s   <- add_svb_proximity(df_btfp_s)
df_dw_s     <- add_svb_proximity(df_dw_s)
df_fhlb_s   <- add_svb_proximity(df_fhlb_s)
df_crisis   <- add_svb_proximity(df_crisis)

# Diagnostics
cat("\n--- SVB Proximity Distribution (AnyFed sample) ---\n")
## 
## --- SVB Proximity Distribution (AnyFed sample) ---
print(summary(df_anyfed_s$svb_prox))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
## -2.9717 -0.6133  0.1358  0.0000  0.7971  1.3975      63
cat("\n--- Corr(SVB_prox, uninsured_lev) ---\n")
## 
## --- Corr(SVB_prox, uninsured_lev) ---
cat(sprintf("  r = %.3f  (should be modest — profile is orthogonal to UI)\n",
    cor(df_anyfed_s$svb_prox, df_anyfed_s$uninsured_lev, use = "complete.obs")))
##   r = -0.106  (should be modest — profile is orthogonal to UI)
cat("\n--- SVB Proximity by Borrower Status ---\n")
## 
## --- SVB Proximity by Borrower Status ---
df_anyfed_s %>%
  group_by(Borrower = ifelse(any_fed == 1, "Fed Borrower", "Non-Borrower")) %>%
  summarise(N = n(), Mean_Prox = round(mean(svb_prox, na.rm=T), 3),
            Mean_Dist = round(mean(svb_mahal_dist, na.rm=T), 2), .groups = "drop") %>%
  print()
## # A tibble: 2 × 4
##   Borrower         N Mean_Prox Mean_Dist
##   <chr>        <int>     <dbl>     <dbl>
## 1 Fed Borrower   828     0.13       6.27
## 2 Non-Borrower  3226    -0.034      7.23
# Regressions
setFixest_dict(c(
  svb_prox            = "SVB Proximity (z)",
  svb_prox_x_mtm      = "SVB Prox $\\times$ MTM",
  svb_prox_x_ui       = "SVB Prox $\\times$ Uninsured",
  mtm_x_ui_x_svbprox  = "MTM $\\times$ UI $\\times$ SVB Prox"
))

EXPL_SVB_PROX <- paste0(
  "mtm_total + uninsured_lev + mtm_x_uninsured + ",
  "svb_prox + svb_prox_x_mtm + svb_prox_x_ui + ",
  "mtm_x_ui_x_svbprox")

mod_prox_any  <- safe_run(df_anyfed_s, "any_fed",     EXPL_SVB_PROX)
mod_prox_btfp <- safe_run(df_btfp_s,   "btfp_crisis", EXPL_SVB_PROX)
mod_prox_dw   <- safe_run(df_dw_s,     "dw_crisis",   EXPL_SVB_PROX)
mod_prox_fhlb <- safe_run(df_fhlb_s,   "fhlb_user",   EXPL_SVB_PROX)

models_prox <- list("Any Fed" = mod_prox_any, "BTFP" = mod_prox_btfp,
                     "DW" = mod_prox_dw, "FHLB" = mod_prox_fhlb)

save_etable(models_prox, "SVB_proximity_continuous",
  title_text = "SVB Proximity: Continuous Mahalanobis Distance (Crisis Period)",
  notes_text = paste0(
    "LPM. SVB Proximity = negative Mahalanobis distance from SVB's profile ",
    "($\\beta^U$, securities/TA, cash/TA), z-standardized. Higher = more SVB-like. ",
    "Profile is orthogonal to MTM $\\times$ Uninsured. ",
    "FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(c("Sample", "Full", "Full", "Full", "Full")))

etable(models_prox[!sapply(models_prox, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                      Any Fed        BTFP         DW       FHLB
## Dependent Var.:                      any_fed btfp_crisis  dw_crisis  fhlb_user
##                                                                               
## Constant                           0.2027***   0.1372***  0.1261***  0.0898***
##                                   (0.0063)    (0.0058)   (0.0057)   (0.0053)  
## MTM Loss (z)                       0.0284***   0.0226***  0.0150*    0.0035   
##                                   (0.0071)    (0.0063)   (0.0062)   (0.0056)  
## Uninsured Leverage (z)             0.0181*     0.0212**   0.0094     0.0048   
##                                   (0.0081)    (0.0073)   (0.0072)   (0.0057)  
## MTM $\times$ Uninsured             0.0200**    0.0167**   0.0190**  -0.0066   
##                                   (0.0066)    (0.0062)   (0.0059)   (0.0052)  
## SVB Proximity (z)                  0.0220*     0.0240**   0.0067     0.0020   
##                                   (0.0101)    (0.0090)   (0.0088)   (0.0079)  
## SVB Prox $\times$ MTM              0.0118*     0.0143**   0.0016     0.0007   
##                                   (0.0056)    (0.0048)   (0.0050)   (0.0042)  
## SVB Prox $\times$ Uninsured        0.0074      0.0112     0.0012     0.0079   
##                                   (0.0065)    (0.0060)   (0.0059)   (0.0048)  
## MTM $\times$ UI $\times$ SVB Prox  0.0090      0.0084*    0.0061     0.0056   
##                                   (0.0049)    (0.0043)   (0.0045)   (0.0037)  
## Log(Assets)                        0.1084***   0.0725***  0.0943***  0.0283***
##                                   (0.0083)    (0.0078)   (0.0078)   (0.0066)  
## Cash Ratio                        -0.0139     -0.0178*   -0.0004    -0.0202** 
##                                   (0.0092)    (0.0075)   (0.0079)   (0.0064)  
## Loan-to-Deposit                    0.0136      0.0076     0.0041     0.0256***
##                                   (0.0100)    (0.0087)   (0.0085)   (0.0073)  
## Book Equity Ratio                 -0.0143*    -0.0130*   -0.0004     0.0088   
##                                   (0.0060)    (0.0051)   (0.0048)   (0.0045)  
## Wholesale Funding                  0.0277***   0.0247***  0.0197**   0.0025   
##                                   (0.0070)    (0.0066)   (0.0064)   (0.0052)  
## ROA                               -0.0043     -0.0084    -0.0036    -0.0106*  
##                                   (0.0060)    (0.0052)   (0.0051)   (0.0046)  
## _________________________________ __________ ___________ __________ __________
## S.E. type                         Hete.-rob. Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,991       3,665      3,599      3,468
## R2                                   0.12155     0.09876    0.10318    0.04164
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Nested comparison
cat("\n=== NESTED COMPARISON: Base → +Proximity → +Triple ===\n")
## 
## === NESTED COMPARISON: Base → +Proximity → +Triple ===
EXPL_SVB_PROX_NESTED <- paste0(
  "mtm_total + uninsured_lev + mtm_x_uninsured + ",
  "svb_prox + svb_prox_x_mtm + svb_prox_x_ui")

mod_prox_btfp_nested <- safe_run(df_btfp_s, "btfp_crisis", EXPL_SVB_PROX_NESTED)

models_nested <- list(
  "BTFP (Base)"     = mod_A_btfp,
  "BTFP (+ Prox)"   = mod_prox_btfp_nested,
  "BTFP (+ Triple)" = mod_prox_btfp)

save_etable(models_nested, "SVB_proximity_nested",
  title_text = "Nested: BTFP with SVB Proximity (Crisis)",
  notes_text = paste0(
    "LPM. Col 1: baseline. Col 2: + SVB Proximity and two-way interactions. ",
    "Col 3: + triple MTM $\\times$ UI $\\times$ SVB Prox. Robust SEs. z-standardized."))

etable(models_nested[!sapply(models_nested, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                   BTFP (Base) BTFP (+ P.. BTFP (+ T..
## Dependent Var.:                   btfp_crisis btfp_crisis btfp_crisis
##                                                                      
## Constant                            0.1435***   0.1376***   0.1372***
##                                    (0.0056)    (0.0057)    (0.0058)  
## MTM Loss (z)                        0.0249***   0.0230***   0.0226***
##                                    (0.0062)    (0.0063)    (0.0063)  
## Uninsured Leverage (z)              0.0214**    0.0249***   0.0212** 
##                                    (0.0070)    (0.0072)    (0.0073)  
## MTM $\times$ Uninsured              0.0193***   0.0150*     0.0167** 
##                                    (0.0052)    (0.0060)    (0.0062)  
## Log(Assets)                         0.0713***   0.0715***   0.0725***
##                                    (0.0077)    (0.0077)    (0.0078)  
## Cash Ratio                         -0.0285***  -0.0177*    -0.0178*  
##                                    (0.0048)    (0.0075)    (0.0075)  
## Loan-to-Deposit                    -0.0107      0.0073      0.0076   
##                                    (0.0057)    (0.0087)    (0.0087)  
## Book Equity Ratio                  -0.0118*    -0.0138**   -0.0130*  
##                                    (0.0047)    (0.0051)    (0.0051)  
## Wholesale Funding                   0.0263***   0.0248***   0.0247***
##                                    (0.0065)    (0.0066)    (0.0066)  
## ROA                                -0.0059     -0.0080     -0.0084   
##                                    (0.0049)    (0.0052)    (0.0052)  
## SVB Proximity (z)                               0.0220*     0.0240** 
##                                                (0.0088)    (0.0090)  
## SVB Prox $\times$ MTM                           0.0124**    0.0143** 
##                                                (0.0046)    (0.0048)  
## SVB Prox $\times$ Uninsured                     0.0064      0.0112   
##                                                (0.0050)    (0.0060)  
## MTM $\times$ UI $\times$ SVB Prox                           0.0084*  
##                                                            (0.0043)  
## _________________________________ ___________ ___________ ___________
## S.E. type                         Heter.-rob. Heter.-rob. Heter.-rob.
## Observations                            3,717       3,665       3,665
## R2                                    0.09615     0.09797     0.09876
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

21.5 Approach 2b: Euclidean Distance (Robustness)

# ==============================================================================
# APPROACH 2b: EUCLIDEAN DISTANCE ON Z-SCORES (simpler alternative)
# ==============================================================================

cat("=== APPROACH 2b: EUCLIDEAN DISTANCE ===\n\n")
## === APPROACH 2b: EUCLIDEAN DISTANCE ===
add_svb_euclidean <- function(df) {
  beta_u_z <- standardize_z(winsorize(df$uninsured_beta_raw))
  sec_z    <- standardize_z(winsorize(df$securities_ratio_raw))
  cash_z   <- standardize_z(winsorize(df$cash_ratio_raw))

  svb_beta_z <- (svb_ref$beta_u - mean(df$uninsured_beta_raw, na.rm=T)) /
                 sd(df$uninsured_beta_raw, na.rm=T)
  svb_sec_z  <- (svb_ref$securities_rat - mean(df$securities_ratio_raw, na.rm=T)) /
                 sd(df$securities_ratio_raw, na.rm=T)
  svb_cash_z <- (svb_ref$cash_rat - mean(df$cash_ratio_raw, na.rm=T)) /
                 sd(df$cash_ratio_raw, na.rm=T)

  euc_dist <- sqrt((beta_u_z - svb_beta_z)^2 + (sec_z - svb_sec_z)^2 + (cash_z - svb_cash_z)^2)

  df %>% mutate(
    svb_euc_dist       = euc_dist,
    svb_euc_prox_raw   = -euc_dist,
    svb_euc_prox_w     = winsorize(svb_euc_prox_raw),
    svb_euc_prox       = standardize_z(svb_euc_prox_w),
    mtm_x_ui_x_eucprox = mtm_total * uninsured_lev * svb_euc_prox,
    euc_prox_x_mtm     = svb_euc_prox * mtm_total,
    euc_prox_x_ui      = svb_euc_prox * uninsured_lev
  )
}

df_anyfed_s <- add_svb_euclidean(df_anyfed_s)
df_btfp_s   <- add_svb_euclidean(df_btfp_s)
df_dw_s     <- add_svb_euclidean(df_dw_s)
df_fhlb_s   <- add_svb_euclidean(df_fhlb_s)

setFixest_dict(c(
  svb_euc_prox       = "SVB Proximity (Eucl., z)",
  euc_prox_x_mtm     = "SVB Prox (E) $\\times$ MTM",
  euc_prox_x_ui      = "SVB Prox (E) $\\times$ Uninsured",
  mtm_x_ui_x_eucprox = "MTM $\\times$ UI $\\times$ SVB Prox (E)"
))

EXPL_SVB_EUC <- paste0(
  "mtm_total + uninsured_lev + mtm_x_uninsured + ",
  "svb_euc_prox + euc_prox_x_mtm + euc_prox_x_ui + ",
  "mtm_x_ui_x_eucprox")

mod_euc_any  <- safe_run(df_anyfed_s, "any_fed",     EXPL_SVB_EUC)
mod_euc_btfp <- safe_run(df_btfp_s,   "btfp_crisis", EXPL_SVB_EUC)
mod_euc_dw   <- safe_run(df_dw_s,     "dw_crisis",   EXPL_SVB_EUC)
mod_euc_fhlb <- safe_run(df_fhlb_s,   "fhlb_user",   EXPL_SVB_EUC)

models_euc <- list("Any Fed" = mod_euc_any, "BTFP" = mod_euc_btfp,
                    "DW" = mod_euc_dw, "FHLB" = mod_euc_fhlb)

save_etable(models_euc, "SVB_euclidean_continuous",
  title_text = "SVB Proximity (Euclidean): Robustness (Crisis Period)",
  notes_text = paste0(
    "LPM. Euclidean distance on z-standardized ($\\beta^U$, securities/TA, cash/TA). ",
    "Simpler alternative to Mahalanobis. FHLB: falsification. Robust SEs. z-standardized."),
  extra_lines = list(c("Metric", "Euclidean", "Euclidean", "Euclidean", "Euclidean")))

etable(models_euc[!sapply(models_euc, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                          Any Fed        BTFP         DW
## Dependent Var.:                          any_fed btfp_crisis  dw_crisis
##                                                                        
## Constant                               0.2038***   0.1387***  0.1268***
##                                       (0.0065)    (0.0059)   (0.0058)  
## MTM Loss (z)                           0.0281***   0.0221***  0.0157*  
##                                       (0.0072)    (0.0064)   (0.0063)  
## Uninsured Leverage (z)                 0.0166*     0.0208**   0.0076   
##                                       (0.0083)    (0.0075)   (0.0073)  
## MTM $\times$ Uninsured                 0.0181**    0.0149*    0.0183** 
##                                       (0.0068)    (0.0064)   (0.0060)  
## SVB Proximity (Eucl., z)               0.0131      0.0173    -0.0037   
##                                       (0.0120)    (0.0110)   (0.0101)  
## SVB Prox (E) $\times$ MTM              0.0086      0.0099     0.0003   
##                                       (0.0059)    (0.0052)   (0.0052)  
## SVB Prox (E) $\times$ Uninsured        0.0102      0.0128*    0.0023   
##                                       (0.0066)    (0.0062)   (0.0058)  
## MTM $\times$ UI $\times$ SVB Prox (E)  0.0107*     0.0079     0.0079   
##                                       (0.0053)    (0.0048)   (0.0047)  
## Log(Assets)                            0.1086***   0.0730***  0.0941***
##                                       (0.0083)    (0.0078)   (0.0078)  
## Cash Ratio                            -0.0180     -0.0196*   -0.0072   
##                                       (0.0110)    (0.0094)   (0.0093)  
## Loan-to-Deposit                        0.0074      0.0034    -0.0036   
##                                       (0.0113)    (0.0099)   (0.0096)  
## Book Equity Ratio                     -0.0146*    -0.0135**  -0.0004   
##                                       (0.0060)    (0.0051)   (0.0048)  
## Wholesale Funding                      0.0286***   0.0253***  0.0206** 
##                                       (0.0070)    (0.0067)   (0.0064)  
## ROA                                   -0.0044     -0.0084    -0.0037   
##                                       (0.0060)    (0.0052)   (0.0052)  
## _____________________________________ __________ ___________ __________
## S.E. type                             Hete.-rob. Heter.-rob. Hete.-rob.
## Observations                               3,991       3,665      3,599
## R2                                       0.12127     0.09804    0.10332
## 
##                                             FHLB
## Dependent Var.:                        fhlb_user
##                                                 
## Constant                               0.0912***
##                                       (0.0054)  
## MTM Loss (z)                           0.0042   
##                                       (0.0057)  
## Uninsured Leverage (z)                 0.0039   
##                                       (0.0059)  
## MTM $\times$ Uninsured                -0.0077   
##                                       (0.0054)  
## SVB Proximity (Eucl., z)              -0.0108   
##                                       (0.0092)  
## SVB Prox (E) $\times$ MTM             -0.0018   
##                                       (0.0044)  
## SVB Prox (E) $\times$ Uninsured        0.0073   
##                                       (0.0048)  
## MTM $\times$ UI $\times$ SVB Prox (E)  0.0040   
##                                       (0.0040)  
## Log(Assets)                            0.0281***
##                                       (0.0066)  
## Cash Ratio                            -0.0289***
##                                       (0.0080)  
## Loan-to-Deposit                        0.0158   
##                                       (0.0081)  
## Book Equity Ratio                      0.0090*  
##                                       (0.0045)  
## Wholesale Funding                      0.0036   
##                                       (0.0052)  
## ROA                                   -0.0104*  
##                                       (0.0045)  
## _____________________________________ __________
## S.E. type                             Hete.-rob.
## Observations                               3,468
## R2                                       0.04199
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

21.6 Summary: All SVB Approaches Compared

# ==============================================================================
# COMBINED SUMMARY: Original vs. v2 Indicator vs. Mahalanobis vs. Euclidean
# All objects now exist from chunks above.
# ==============================================================================

cat("=== SUMMARY: ALL SVB-LIKE APPROACHES (BTFP) ===\n\n")
## === SUMMARY: ALL SVB-LIKE APPROACHES (BTFP) ===
models_svb_summary <- list(
  "Orig (Like)"   = mod_svb_btfp_like,
  "Orig (Unlike)"  = mod_svb_btfp_unlike,
  "v2 (Like)"     = mod_svbv2_btfp_like,
  "v2 (Unlike)"   = mod_svbv2_btfp_unlike,
  "Mahalanobis"   = mod_prox_btfp,
  "Euclidean"     = mod_euc_btfp)

save_etable(models_svb_summary, "SVB_all_approaches_BTFP",
  title_text = "SVB-Like Approaches Compared: BTFP (Crisis Period)",
  notes_text = paste0(
    "LPM. Cols 1--2: original (above-median $\\beta^U$ $\\cap$ above-median uninsured share). ",
    "Cols 3--4: v2 (above-median $\\beta^U$ $\\cap$ above-median securities/TA $\\cap$ below-median cash/TA). ",
    "Cols 5--6: continuous proximity on full sample. v2 and continuous approaches preserve ",
    "uninsured leverage variation, fixing the restriction-of-range problem. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Approach", "Orig", "Orig", "v2", "v2", "Mahal", "Euclid"),
    c("SVB-Like", "Yes", "No", "Yes", "No", "Full", "Full")))

etable(models_svb_summary[!sapply(models_svb_summary, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                       Orig (Like) Orig (Unl..   v2 (Like)
## Dependent Var.:                       btfp_crisis btfp_crisis btfp_crisis
##                                                                          
## Constant                                0.1594***   0.1382***   0.0165   
##                                        (0.0195)    (0.0071)    (0.0838)  
## MTM Loss (z)                            0.0266      0.0212**    0.0233   
##                                        (0.0197)    (0.0073)    (0.0229)  
## Uninsured Leverage (z)                  0.0086      0.0211**    0.0209   
##                                        (0.0219)    (0.0081)    (0.0241)  
## MTM $\times$ Uninsured                  0.0181      0.0152*     0.0371   
##                                        (0.0191)    (0.0063)    (0.0211)  
## Log(Assets)                             0.0774***   0.0694***   0.1036***
##                                        (0.0169)    (0.0087)    (0.0252)  
## Cash Ratio                             -0.0337*    -0.0278***  -0.2676*  
##                                        (0.0156)    (0.0052)    (0.1221)  
## Loan-to-Deposit                        -0.0175     -0.0068      0.0557   
##                                        (0.0170)    (0.0065)    (0.0312)  
## Book Equity Ratio                      -0.0174     -0.0126*    -0.0366*  
##                                        (0.0157)    (0.0053)    (0.0184)  
## Wholesale Funding                       0.0668***   0.0126      0.0404*  
##                                        (0.0165)    (0.0066)    (0.0166)  
## ROA                                    -0.0038     -0.0071     -0.0319   
##                                        (0.0129)    (0.0056)    (0.0234)  
## SVB Proximity (z)                                                        
##                                                                          
## SVB Prox $\times$ MTM                                                    
##                                                                          
## SVB Prox $\times$ Uninsured                                              
##                                                                          
## MTM $\times$ UI $\times$ SVB Prox                                        
##                                                                          
## SVB Proximity (Eucl., z)                                                 
##                                                                          
## SVB Prox (E) $\times$ MTM                                                
##                                                                          
## SVB Prox (E) $\times$ Uninsured                                          
##                                                                          
## MTM $\times$ UI $\times$ SVB Prox (E)                                    
##                                                                          
## _____________________________________ ___________ ___________ ___________
## S.E. type                             Heter.-rob. Heter.-rob. Heter.-rob.
## Observations                                  862       2,803         448
## R2                                        0.10453     0.08357     0.13177
## 
##                                       v2 (Unlike) Mahalanobis   Euclidean
## Dependent Var.:                       btfp_crisis btfp_crisis btfp_crisis
##                                                                          
## Constant                                0.1366***   0.1372***   0.1387***
##                                        (0.0061)    (0.0058)    (0.0059)  
## MTM Loss (z)                            0.0250***   0.0226***   0.0221***
##                                        (0.0064)    (0.0063)    (0.0064)  
## Uninsured Leverage (z)                  0.0226**    0.0212**    0.0208** 
##                                        (0.0075)    (0.0073)    (0.0075)  
## MTM $\times$ Uninsured                  0.0157**    0.0167**    0.0149*  
##                                        (0.0057)    (0.0062)    (0.0064)  
## Log(Assets)                             0.0658***   0.0725***   0.0730***
##                                        (0.0081)    (0.0078)    (0.0078)  
## Cash Ratio                             -0.0273***  -0.0178*    -0.0196*  
##                                        (0.0051)    (0.0075)    (0.0094)  
## Loan-to-Deposit                        -0.0102      0.0076      0.0034   
##                                        (0.0063)    (0.0087)    (0.0099)  
## Book Equity Ratio                      -0.0098     -0.0130*    -0.0135** 
##                                        (0.0052)    (0.0051)    (0.0051)  
## Wholesale Funding                       0.0219**    0.0247***   0.0253***
##                                        (0.0070)    (0.0066)    (0.0067)  
## ROA                                    -0.0046     -0.0084     -0.0084   
##                                        (0.0052)    (0.0052)    (0.0052)  
## SVB Proximity (z)                                   0.0240**             
##                                                    (0.0090)              
## SVB Prox $\times$ MTM                               0.0143**             
##                                                    (0.0048)              
## SVB Prox $\times$ Uninsured                         0.0112               
##                                                    (0.0060)              
## MTM $\times$ UI $\times$ SVB Prox                   0.0084*              
##                                                    (0.0043)              
## SVB Proximity (Eucl., z)                                        0.0173   
##                                                                (0.0110)  
## SVB Prox (E) $\times$ MTM                                       0.0099   
##                                                                (0.0052)  
## SVB Prox (E) $\times$ Uninsured                                 0.0128*  
##                                                                (0.0062)  
## MTM $\times$ UI $\times$ SVB Prox (E)                           0.0079   
##                                                                (0.0048)  
## _____________________________________ ___________ ___________ ___________
## S.E. type                             Heter.-rob. Heter.-rob. Heter.-rob.
## Observations                                3,217       3,665       3,665
## R2                                        0.08769     0.09876     0.09804
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

21.7 SVB Visualizations

# ==============================================================================
# SVB VISUALIZATIONS — 4-panel figure
# ==============================================================================

# --- Build borrower ID set for coloring ---
fed_borrower_ids <- df_crisis %>% filter(any_fed == 1) %>% pull(idrssd)

# --- Panel A: SVB in MTM × Uninsured scatter ---
svb_pt <- data.frame(
  mtm_total_raw     = svb_ref$mtm_total_rat,
  uninsured_lev_raw = svb_ref$uninsured_lev
)

df_plot_a <- df_2022q4 %>%
  mutate(group = ifelse(idrssd %in% fed_borrower_ids, "Emergency Borrower", "Non-Borrower"))

p_a <- ggplot(df_plot_a, aes(x = mtm_total_raw, y = uninsured_lev_raw)) +
  geom_point(aes(color = group, alpha = group), size = 1.2) +
  geom_point(data = svb_pt, size = 5, shape = 18, color = "red") +
  annotate("text", x = svb_pt$mtm_total_raw + 0.3, y = svb_pt$uninsured_lev_raw + 2,
    label = "SVB", color = "red", fontface = "bold", size = 4) +
  scale_color_manual(values = c("Emergency Borrower" = "#003049", "Non-Borrower" = "grey70")) +
  scale_alpha_manual(values = c("Emergency Borrower" = 0.5, "Non-Borrower" = 0.2)) +
  labs(title = "A. SVB in MTM × Uninsured Space",
    subtitle = "SVB sits at the extreme of both risk dimensions",
    x = "MTM Loss (% of TA)", y = "Uninsured Leverage (% of TA)", color = NULL) +
  theme_paper + guides(alpha = "none")

# --- Panel B: β^U distribution with SVB highlighted ---
df_beta_dist <- df_2022q4 %>% filter(!is.na(uninsured_beta_raw))

p_b <- ggplot(df_beta_dist, aes(x = uninsured_beta_raw)) +
  geom_histogram(bins = 50, fill = "steelblue", alpha = 0.6, color = "white") +
  geom_vline(xintercept = svb_ref$beta_u, color = "red", linewidth = 1.2) +
  geom_vline(xintercept = median(df_beta_dist$uninsured_beta_raw, na.rm = TRUE),
    color = "grey40", linewidth = 0.8, linetype = "dashed") +
  annotate("text", x = svb_ref$beta_u + 0.02, y = Inf,
    label = sprintf("SVB β^U = %.3f", svb_ref$beta_u),
    hjust = 0, vjust = 2, color = "red", fontface = "bold", size = 3.5) +
  annotate("text", x = median(df_beta_dist$uninsured_beta_raw, na.rm = TRUE) - 0.02,
    y = Inf, label = "Median", hjust = 1, vjust = 4,
    color = "grey40", fontface = "italic", size = 3) +
  labs(title = "B. Distribution of Uninsured Deposit Beta (β^U)",
    subtitle = sprintf("SVB at %.0fth percentile",
      100 * mean(df_beta_dist$uninsured_beta_raw <= svb_ref$beta_u, na.rm = TRUE)),
    x = "Uninsured Deposit Beta (β^U)", y = "Count") +
  theme_paper

# --- Panel C: SVB-Like v2 — UI leverage overlap ---
df_ui_v2 <- df_crisis %>%
  filter(!is.na(svb_like_v2)) %>%
  mutate(SVB_Group = ifelse(svb_like_v2 == 1, "SVB-Like (v2)", "SVB-Unlike (v2)"))

p_c <- ggplot(df_ui_v2, aes(x = uninsured_lev_raw, fill = SVB_Group)) +
  geom_density(alpha = 0.4, linewidth = 0.7) +
  scale_fill_manual(values = c("SVB-Like (v2)" = "#D62828", "SVB-Unlike (v2)" = "#2A9D8F")) +
  labs(title = "C. Uninsured Leverage: SVB-Like v2 vs. Unlike",
    subtitle = "v2 definition preserves full overlap in uninsured leverage (no restriction of range)",
    x = "Uninsured Leverage (% of TA)", y = "Density", fill = NULL) +
  theme_paper

# --- Panel D: SVB Proximity (Mahalanobis) by borrower status ---
df_prox_plot <- df_anyfed_s %>%
  filter(!is.na(svb_prox)) %>%
  mutate(Borrower = ifelse(any_fed == 1, "Fed Borrower", "Non-Borrower"))

p_d <- ggplot(df_prox_plot, aes(x = svb_prox, fill = Borrower)) +
  geom_density(alpha = 0.4, linewidth = 0.7) +
  scale_fill_manual(values = c("Fed Borrower" = "#003049", "Non-Borrower" = "grey70")) +
  geom_vline(xintercept = 0, linetype = "dashed", color = "grey40") +
  labs(title = "D. SVB Proximity (Mahalanobis) by Borrower Status",
    subtitle = "Borrowers are closer to SVB's profile (higher proximity)",
    x = "SVB Proximity (z-standardized; higher = more SVB-like)", y = "Density", fill = NULL) +
  theme_paper

# --- Combine ---
p_combined <- (p_a + p_b) / (p_c + p_d) +
  plot_annotation(
    title = "SVB Case Study: Position in Cross-Section and Improved Definitions",
    theme = theme(plot.title = element_text(face = "bold", size = 14, hjust = 0))
  )

print(p_combined)

save_figure(p_combined, "Fig_SVB_CaseStudy_4Panel", width = 14, height = 12)

# --- Also save individual panels ---
save_figure(p_a, "Fig_SVB_MTM_Uninsured_Scatter", width = 10, height = 7)
save_figure(p_b, "Fig_SVB_BetaU_Distribution", width = 10, height = 6)
save_figure(p_c, "Fig_SVB_v2_UILeverage_Overlap", width = 10, height = 6)
save_figure(p_d, "Fig_SVB_Proximity_Borrower", width = 10, height = 6)
# ==============================================================================
# DIAGNOSTIC: Why the original split fails (restriction of range)
# Side-by-side density of uninsured leverage for original vs. v2 definitions
# ==============================================================================

df_ror <- df_crisis %>%
  filter(!is.na(svb_like) & !is.na(svb_like_v2)) %>%
  select(uninsured_lev_raw, svb_like, svb_like_v2) %>%
  pivot_longer(cols = c(svb_like, svb_like_v2),
    names_to = "Definition", values_to = "SVB_Like") %>%
  mutate(
    Definition = factor(ifelse(Definition == "svb_like",
      "Original (β^U × UI Share)", "v2 (β^U × Securities × Cash)"),
      levels = c("Original (β^U × UI Share)", "v2 (β^U × Securities × Cash)")),
    Group = ifelse(SVB_Like == 1, "SVB-Like", "SVB-Unlike")
  )

p_ror <- ggplot(df_ror, aes(x = uninsured_lev_raw, fill = Group)) +
  geom_density(alpha = 0.4, linewidth = 0.7) +
  facet_wrap(~ Definition) +
  scale_fill_manual(values = c("SVB-Like" = "#D62828", "SVB-Unlike" = "#2A9D8F")) +
  labs(
    title = "Restriction of Range: Original vs. Improved SVB-Like Definition",
    subtitle = paste0(
      "Left: original definition splits on uninsured share → groups barely overlap on UI leverage.\n",
      "Right: v2 definition uses orthogonal variables → full overlap preserved."),
    x = "Uninsured Leverage (% of TA)", y = "Density", fill = NULL
  ) + theme_paper

print(p_ror)

save_figure(p_ror, "Fig_SVB_RestrictionOfRange_Diagnostic", width = 12, height = 6)

22 INTENSIVE MARGIN: What Determines Borrowing Amounts?

# ==============================================================================
# INTENSIVE MARGIN ANALYSIS
#
# The extensive margin asks WHO borrows; the intensive margin asks HOW MUCH.
# Conditional on borrowing, what bank characteristics determine the size of
# emergency lending? We estimate:
#
#   Borrow_Amount_i / TA_i = α + β₁·MTM + β₂·UI + β₃·MTM×UI + γ·X + ε
#
# DV: borrowing amount as % of total assets (btfp_pct, dw_pct).
# Sample: borrowers only (conditional on extensive margin = 1).
#
# --- Four model specifications, building progressively ---
#
# M1. RUN PRESSURE (baseline):
#       MTM + Uninsured + MTM×Uninsured + Controls
#       Banks facing more severe run pressure need more emergency liquidity.
#       Controls include anticipated liquidity need proxies:
#         - Cash ratio (liquid buffer)
#         - Loan-to-deposit (illiquidity)
#         - Wholesale funding (rollover risk)
#
# M2. + DEPOSIT BETA CHANNEL:
#       Full triple interaction (MTM × UI × β^U)
#       Banks with flightier (higher β^U) uninsured deposits face faster,
#       larger runs → need more emergency liquidity.
#
# M3. + COLLATERAL / PAR SUPPLY CONSTRAINT:
#       Par benefit + Collateral capacity (BTFP-specific: par_benefit)
#       BTFP lends at par on OMO-eligible securities, so banks with larger
#       unrealized losses on eligible collateral have a bigger par subsidy
#       → incentive to borrow more. DW has no par feature.
#       Collateral capacity constrains maximum borrowing for both facilities.
#
# M4. FULL SPECIFICATION:
#       All channels combined: run pressure + deposit beta + collateral.
#
# Robustness: log(dollar amount) as alternative DV (right-skewed amounts).
# ==============================================================================

cat("=== INTENSIVE MARGIN: BORROWING AMOUNTS (CRISIS) ===\n\n")
## === INTENSIVE MARGIN: BORROWING AMOUNTS (CRISIS) ===
# --- Samples: borrowers only ---
df_btfp_intensive <- df_crisis %>% filter(btfp_crisis == 1, !is.na(btfp_pct), btfp_pct > 0)
df_dw_intensive   <- df_crisis %>% filter(dw_crisis == 1, !is.na(dw_pct), dw_pct > 0)

# Log-transformed DVs (add small constant not needed — already > 0)
df_btfp_intensive <- df_btfp_intensive %>%
  mutate(log_btfp_amt = log(btfp_crisis_amt),
         log_btfp_pct = log(btfp_pct))
df_dw_intensive <- df_dw_intensive %>%
  mutate(log_dw_amt = log(dw_crisis_amt),
         log_dw_pct = log(dw_pct))

cat(sprintf("  BTFP borrowers: %d banks\n", nrow(df_btfp_intensive)))
##   BTFP borrowers: 501 banks
cat(sprintf("    Mean amount: $%.1fM  |  Median: $%.1fM\n",
  mean(df_btfp_intensive$btfp_crisis_amt, na.rm = TRUE) / 1e6,
  median(df_btfp_intensive$btfp_crisis_amt, na.rm = TRUE) / 1e6))
##     Mean amount: $260.9M  |  Median: $22.5M
cat(sprintf("    Mean %%TA: %.2f%%  |  Median: %.2f%%\n",
  mean(df_btfp_intensive$btfp_pct, na.rm = TRUE),
  median(df_btfp_intensive$btfp_pct, na.rm = TRUE)))
##     Mean %TA: 6.62%  |  Median: 3.86%
cat(sprintf("    SD %%TA: %.2f%%  |  Skewness: %.2f\n",
  sd(df_btfp_intensive$btfp_pct, na.rm = TRUE),
  (mean((df_btfp_intensive$btfp_pct - mean(df_btfp_intensive$btfp_pct))^3, na.rm=T)) /
    sd(df_btfp_intensive$btfp_pct, na.rm=T)^3))
##     SD %TA: 10.07%  |  Skewness: 7.67
cat(sprintf("\n  DW borrowers: %d banks\n", nrow(df_dw_intensive)))
## 
##   DW borrowers: 433 banks
cat(sprintf("    Mean amount: $%.1fM  |  Median: $%.1fM\n",
  mean(df_dw_intensive$dw_crisis_amt, na.rm = TRUE) / 1e6,
  median(df_dw_intensive$dw_crisis_amt, na.rm = TRUE) / 1e6))
##     Mean amount: $1240.9M  |  Median: $0.1M
cat(sprintf("    Mean %%TA: %.2f%%  |  Median: %.2f%%\n",
  mean(df_dw_intensive$dw_pct, na.rm = TRUE),
  median(df_dw_intensive$dw_pct, na.rm = TRUE)))
##     Mean %TA: 8.23%  |  Median: 0.01%
cat(sprintf("    SD %%TA: %.2f%%\n",
  sd(df_dw_intensive$dw_pct, na.rm = TRUE)))
##     SD %TA: 34.78%
# --- Explanatory variable sets ---
# M1: Run Pressure
INTENS_M1 <- EXPL_BASE  # "mtm_total + uninsured_lev + mtm_x_uninsured"

# M2: + Deposit Beta (full triple)
INTENS_M2 <- EXPL_BETA_FULL

# M3: + Collateral/Par (BTFP gets par_benefit; DW does not)
INTENS_M3_BTFP <- paste0(EXPL_BASE, " + par_benefit + collateral_capacity")
INTENS_M3_DW   <- paste0(EXPL_BASE, " + collateral_capacity")

# M4: Full
INTENS_M4_BTFP <- paste0(EXPL_BETA_FULL, " + par_benefit + collateral_capacity")
INTENS_M4_DW   <- paste0(EXPL_BETA_FULL, " + collateral_capacity")

# Register additional labels for intensive-margin context
setFixest_dict(c(
  btfp_pct     = "BTFP / TA (\\%)",
  dw_pct       = "DW / TA (\\%)",
  log_btfp_pct = "log(BTFP / TA)",
  log_dw_pct   = "log(DW / TA)",
  log_btfp_amt = "log(BTFP \\$)",
  log_dw_amt   = "log(DW \\$)"
))

22.1 BTFP Intensive Margin

cat("=== BTFP INTENSIVE MARGIN ===\n\n")
## === BTFP INTENSIVE MARGIN ===
# --- Levels: btfp_pct (% of TA) ---
mod_int_btfp_m1 <- safe_run(df_btfp_intensive, "btfp_pct", INTENS_M1, min_n = 20, min_dv1 = 0)
mod_int_btfp_m2 <- safe_run(df_btfp_intensive %>% filter(!is.na(uninsured_beta_w)),
                             "btfp_pct", INTENS_M2, min_n = 20, min_dv1 = 0)
mod_int_btfp_m3 <- safe_run(df_btfp_intensive, "btfp_pct", INTENS_M3_BTFP, min_n = 20, min_dv1 = 0)
mod_int_btfp_m4 <- safe_run(df_btfp_intensive %>% filter(!is.na(uninsured_beta_w)),
                             "btfp_pct", INTENS_M4_BTFP, min_n = 20, min_dv1 = 0)

# --- Log: log(amount in $) ---
mod_int_btfp_log_m1 <- safe_run(df_btfp_intensive, "log_btfp_amt", INTENS_M1, min_n = 20, min_dv1 = 0)
mod_int_btfp_log_m4 <- safe_run(df_btfp_intensive %>% filter(!is.na(uninsured_beta_w)),
                                 "log_btfp_amt", INTENS_M4_BTFP, min_n = 20, min_dv1 = 0)

models_int_btfp <- list(
  "M1: Run" = mod_int_btfp_m1, "M2: +Beta" = mod_int_btfp_m2,
  "M3: +Collat" = mod_int_btfp_m3, "M4: Full" = mod_int_btfp_m4,
  "M1 log($)" = mod_int_btfp_log_m1, "M4 log($)" = mod_int_btfp_log_m4)

save_etable(models_int_btfp, "Intensive_BTFP_crisis",
  title_text = "Intensive Margin: BTFP Borrowing Amount (Crisis Period)",
  notes_text = paste0(
    "OLS. DV cols 1--4: BTFP amount / TA ($\\times 100$). DV cols 5--6: log(BTFP \\$). ",
    "Sample: BTFP borrowers only (conditional on extensive margin). ",
    "M1: Run pressure (MTM $\\times$ Uninsured). ",
    "M2: + Deposit beta channel ($\\beta^U$ triple). ",
    "M3: + Collateral/par supply (par benefit + OMO capacity). ",
    "M4: Full specification. ",
    "Controls: log(assets), cash ratio, loan-to-deposit, book equity, wholesale, ROA. ",
    "Robust SEs. z-standardized explanatory variables."),
  extra_lines = list(
    c("DV", "\\%TA", "\\%TA", "\\%TA", "\\%TA", "log(\\$)", "log(\\$)"),
    c("$\\beta^U$ channel", "No", "Yes", "No", "Yes", "No", "Yes"),
    c("Par/Collateral", "No", "No", "Yes", "Yes", "No", "Yes")))

etable(models_int_btfp[!sapply(models_int_btfp, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                                  M1: Run      M2: +Beta
## Dependent Var.:                           BTFP / TA (\%) BTFP / TA (\%)
##                                                                        
## Constant                                        7.791***       6.896***
##                                                (1.113)        (0.7387) 
## MTM Loss (z)                                   -1.199         -0.3225  
##                                                (1.026)        (0.5904) 
## Uninsured Leverage (z)                         -1.622          0.0880  
##                                                (1.477)        (0.6376) 
## MTM $\times$ Uninsured                          1.392          0.4027  
##                                                (0.9568)       (0.5987) 
## Log(Assets)                                     1.742          0.4455  
##                                                (1.287)        (0.6155) 
## Cash Ratio                                      2.072          1.092   
##                                                (1.626)        (1.314)  
## Loan-to-Deposit                                -2.639         -2.829*  
##                                                (1.565)        (1.273)  
## Book Equity Ratio                               0.8910         0.6620  
##                                                (0.8683)       (0.7616) 
## Wholesale Funding                               0.6748         0.6836* 
##                                                (0.3504)       (0.3222) 
## ROA                                            -0.1763        -1.009*  
##                                                (0.8310)       (0.5060) 
## Uninsured $\beta$ (z)                                          2.398** 
##                                                               (0.9241) 
## MTM $\times$ Unins. $\beta$                                   -2.547*  
##                                                               (1.106)  
## Uninsured $\times$ Unins. $\beta$                             -1.140*  
##                                                               (0.5610) 
## MTM $\times$ Uninsured $\times$ $\beta^U$                      2.025*  
##                                                               (0.9979) 
## Par Benefit (z)                                                        
##                                                                        
## OMO Collateral (z)                                                     
##                                                                        
## ________________________________________  ______________ ______________
## S.E. type                                 Heterosk.-rob. Heterosk.-rob.
## Observations                                         501            496
## R2                                               0.11747        0.26411
## 
##                                              M3: +Collat       M4: Full
## Dependent Var.:                           BTFP / TA (\%) BTFP / TA (\%)
##                                                                        
## Constant                                        7.618***       6.852***
##                                                (0.9117)       (0.6817) 
## MTM Loss (z)                                   -0.2800         0.4714  
##                                                (0.6812)       (0.4961) 
## Uninsured Leverage (z)                         -1.816         -0.2002  
##                                                (1.388)        (0.6654) 
## MTM $\times$ Uninsured                          1.565          0.6966  
##                                                (0.8867)       (0.5609) 
## Log(Assets)                                     1.806          0.4780  
##                                                (1.216)        (0.6356) 
## Cash Ratio                                      1.815          1.076   
##                                                (1.335)        (1.182)  
## Loan-to-Deposit                                -1.189         -1.441   
##                                                (1.110)        (1.014)  
## Book Equity Ratio                               0.5872         0.4828  
##                                                (0.7001)       (0.6809) 
## Wholesale Funding                               0.5540         0.5188  
##                                                (0.3433)       (0.3196) 
## ROA                                            -0.0109        -0.6455  
##                                                (0.7475)       (0.4922) 
## Uninsured $\beta$ (z)                                          2.340** 
##                                                               (0.7875) 
## MTM $\times$ Unins. $\beta$                                   -2.236*  
##                                                               (0.9118) 
## Uninsured $\times$ Unins. $\beta$                             -0.8717  
##                                                               (0.4451) 
## MTM $\times$ Uninsured $\times$ $\beta^U$                      1.844*  
##                                                               (0.8260) 
## Par Benefit (z)                                -3.621*        -2.594*  
##                                                (1.840)        (1.147)  
## OMO Collateral (z)                              1.956**        2.087***
##                                                (0.6647)       (0.5810) 
## ________________________________________  ______________ ______________
## S.E. type                                 Heterosk.-rob. Heterosk.-rob.
## Observations                                         501            496
## R2                                               0.20082        0.31816
## 
##                                              M1 log($)    M4 log($)
## Dependent Var.:                           log(BTFP \$) log(BTFP \$)
##                                                                    
## Constant                                    15.79***      15.76*** 
##                                             (0.2105)      (0.1928) 
## MTM Loss (z)                                 0.0653        0.2778  
##                                             (0.1738)      (0.1792) 
## Uninsured Leverage (z)                      -0.1417       -0.0363  
##                                             (0.2021)      (0.1897) 
## MTM $\times$ Uninsured                       0.1489        0.1718  
##                                             (0.1790)      (0.1667) 
## Log(Assets)                                  0.7499***     0.6611**
##                                             (0.2124)      (0.2182) 
## Cash Ratio                                  -0.6273       -0.6373  
##                                             (0.3778)      (0.3448) 
## Loan-to-Deposit                              0.0708        0.2220  
##                                             (0.2001)      (0.2321) 
## Book Equity Ratio                           -0.2564       -0.2842  
##                                             (0.2280)      (0.2258) 
## Wholesale Funding                            0.2280**      0.1990* 
##                                             (0.0864)      (0.0894) 
## ROA                                         -0.1980       -0.1971  
##                                             (0.1837)      (0.1724) 
## Uninsured $\beta$ (z)                                      0.2324  
##                                                           (0.1338) 
## MTM $\times$ Unins. $\beta$                                0.0325  
##                                                           (0.1498) 
## Uninsured $\times$ Unins. $\beta$                         -0.0891  
##                                                           (0.1192) 
## MTM $\times$ Uninsured $\times$ $\beta^U$                  0.0747  
##                                                           (0.1280) 
## Par Benefit (z)                                           -0.4150* 
##                                                           (0.1753) 
## OMO Collateral (z)                                         0.3781* 
##                                                           (0.1763) 
## ________________________________________  ____________ ____________
## S.E. type                                 Hetero.-rob. Hetero.-rob.
## Observations                                       501          496
## R2                                             0.11225      0.13684
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

22.2 DW Intensive Margin

cat("=== DW INTENSIVE MARGIN ===\n\n")
## === DW INTENSIVE MARGIN ===
# --- Levels: dw_pct (% of TA) ---
mod_int_dw_m1 <- safe_run(df_dw_intensive, "dw_pct", INTENS_M1, min_n = 20, min_dv1 = 0)
mod_int_dw_m2 <- safe_run(df_dw_intensive %>% filter(!is.na(uninsured_beta_w)),
                           "dw_pct", INTENS_M2, min_n = 20, min_dv1 = 0)
mod_int_dw_m3 <- safe_run(df_dw_intensive, "dw_pct", INTENS_M3_DW, min_n = 20, min_dv1 = 0)
mod_int_dw_m4 <- safe_run(df_dw_intensive %>% filter(!is.na(uninsured_beta_w)),
                           "dw_pct", INTENS_M4_DW, min_n = 20, min_dv1 = 0)

# --- Log: log(amount in $) ---
mod_int_dw_log_m1 <- safe_run(df_dw_intensive, "log_dw_amt", INTENS_M1, min_n = 20, min_dv1 = 0)
mod_int_dw_log_m4 <- safe_run(df_dw_intensive %>% filter(!is.na(uninsured_beta_w)),
                               "log_dw_amt", INTENS_M4_DW, min_n = 20, min_dv1 = 0)

models_int_dw <- list(
  "M1: Run" = mod_int_dw_m1, "M2: +Beta" = mod_int_dw_m2,
  "M3: +Collat" = mod_int_dw_m3, "M4: Full" = mod_int_dw_m4,
  "M1 log($)" = mod_int_dw_log_m1, "M4 log($)" = mod_int_dw_log_m4)

save_etable(models_int_dw, "Intensive_DW_crisis",
  title_text = "Intensive Margin: DW Borrowing Amount (Crisis Period)",
  notes_text = paste0(
    "OLS. DV cols 1--4: DW amount / TA ($\\times 100$). DV cols 5--6: log(DW \\$). ",
    "Sample: DW borrowers only (conditional on extensive margin). ",
    "No par benefit for DW (lends at market value, not par). ",
    "M1: Run pressure. M2: + Deposit beta. M3: + Collateral capacity. M4: Full. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("DV", "\\%TA", "\\%TA", "\\%TA", "\\%TA", "log(\\$)", "log(\\$)"),
    c("$\\beta^U$ channel", "No", "Yes", "No", "Yes", "No", "Yes"),
    c("Collateral", "No", "No", "Yes", "Yes", "No", "Yes")))

etable(models_int_dw[!sapply(models_int_dw, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                                M1: Run    M2: +Beta
## Dependent Var.:                           DW / TA (\%) DW / TA (\%)
##                                                                    
## Constant                                       3.943**      4.492**
##                                               (1.512)      (1.464) 
## MTM Loss (z)                                   0.6626       1.395  
##                                               (1.993)      (2.174) 
## Uninsured Leverage (z)                         2.280        2.742  
##                                               (2.036)      (2.033) 
## MTM $\times$ Uninsured                         1.861        2.590  
##                                               (1.444)      (1.780) 
## Log(Assets)                                    3.102        2.753  
##                                               (1.844)      (1.725) 
## Cash Ratio                                    -2.279       -2.108  
##                                               (1.457)      (1.569) 
## Loan-to-Deposit                               -0.6124      -1.277  
##                                               (2.508)      (2.629) 
## Book Equity Ratio                             -0.2767       0.1705 
##                                               (2.008)      (2.026) 
## Wholesale Funding                              2.524*       2.517* 
##                                               (1.265)      (1.208) 
## ROA                                           -0.0455      -0.0425 
##                                               (1.059)      (1.094) 
## Uninsured $\beta$ (z)                                       1.155  
##                                                            (2.152) 
## MTM $\times$ Unins. $\beta$                                -0.6384 
##                                                            (2.316) 
## Uninsured $\times$ Unins. $\beta$                           2.582  
##                                                            (2.341) 
## MTM $\times$ Uninsured $\times$ $\beta^U$                   2.067  
##                                                            (1.724) 
## OMO Collateral (z)                                                 
##                                                                    
## ________________________________________  ____________ ____________
## S.E. type                                 Hetero.-rob. Hetero.-rob.
## Observations                                       433          430
## R2                                             0.03726      0.05058
## 
##                                            M3: +Collat     M4: Full  M1 log($)
## Dependent Var.:                           DW / TA (\%) DW / TA (\%) log(DW \$)
##                                                                               
## Constant                                       3.940**      4.493** 11.04***  
##                                               (1.520)      (1.469)  (0.2545)  
## MTM Loss (z)                                   0.5858       1.427   -0.2730   
##                                               (1.857)      (1.949)  (0.2769)  
## Uninsured Leverage (z)                         2.259        2.753    1.016*** 
##                                               (2.040)      (2.024)  (0.2632)  
## MTM $\times$ Uninsured                         1.875        2.589    0.2793   
##                                               (1.426)      (1.776)  (0.2195)  
## Log(Assets)                                    3.137        2.735    0.3568   
##                                               (1.880)      (1.702)  (0.2734)  
## Cash Ratio                                    -2.357       -2.079   -1.634*** 
##                                               (1.505)      (1.654)  (0.3015)  
## Loan-to-Deposit                               -0.9054      -1.187   -0.2425   
##                                               (2.996)      (3.142)  (0.3378)  
## Book Equity Ratio                             -0.2470       0.1642  -0.2963   
##                                               (1.990)      (2.024)  (0.3486)  
## Wholesale Funding                              2.569        2.504*   0.8106***
##                                               (1.322)      (1.265)  (0.1881)  
## ROA                                           -0.1133      -0.0185   0.3510   
##                                               (0.9888)     (0.9956) (0.2671)  
## Uninsured $\beta$ (z)                                       1.188             
##                                                            (2.057)            
## MTM $\times$ Unins. $\beta$                                -0.6352            
##                                                            (2.333)            
## Uninsured $\times$ Unins. $\beta$                           2.582             
##                                                            (2.343)            
## MTM $\times$ Uninsured $\times$ $\beta^U$                   2.068             
##                                                            (1.726)            
## OMO Collateral (z)                            -0.4756       0.1595            
##                                               (2.310)      (2.249)            
## ________________________________________  ____________ ____________ __________
## S.E. type                                 Hetero.-rob. Hetero.-rob. Hete.-rob.
## Observations                                       433          430        433
## R2                                             0.03737      0.05060    0.19081
## 
##                                            M4 log($)
## Dependent Var.:                           log(DW \$)
##                                                     
## Constant                                  11.01***  
##                                           (0.2612)  
## MTM Loss (z)                              -0.1442   
##                                           (0.2858)  
## Uninsured Leverage (z)                     1.192*** 
##                                           (0.2735)  
## MTM $\times$ Uninsured                     0.2169   
##                                           (0.2337)  
## Log(Assets)                                0.2075   
##                                           (0.2820)  
## Cash Ratio                                -1.604*** 
##                                           (0.3140)  
## Loan-to-Deposit                           -0.4419   
##                                           (0.3834)  
## Book Equity Ratio                         -0.2663   
##                                           (0.3504)  
## Wholesale Funding                          0.8595***
##                                           (0.1894)  
## ROA                                        0.3635   
##                                           (0.2705)  
## Uninsured $\beta$ (z)                      0.6080*  
##                                           (0.2557)  
## MTM $\times$ Unins. $\beta$               -0.1233   
##                                           (0.2314)  
## Uninsured $\times$ Unins. $\beta$         -0.2956   
##                                           (0.2037)  
## MTM $\times$ Uninsured $\times$ $\beta^U$  0.0297   
##                                           (0.1746)  
## OMO Collateral (z)                        -0.0450   
##                                           (0.3121)  
## ________________________________________  __________
## S.E. type                                 Hete.-rob.
## Observations                                     430
## R2                                           0.20170
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

22.3 Combined BTFP vs. DW Comparison

# ==============================================================================
# Side-by-side BTFP vs. DW using the full specification:
# Key question: Do the same factors drive both, or do the facilities serve
# different intensive-margin purposes?
#
# Prediction:
#   - MTM × Uninsured: positive for both (run pressure → more borrowing)
#   - Par benefit: positive for BTFP, irrelevant for DW
#   - β^U triple: positive for BTFP (demand-side), may differ for DW
#     (DW carries stigma → banks minimize DW amounts regardless of need)
#   - Collateral: positive constraint for both
# ==============================================================================

cat("=== BTFP vs. DW INTENSIVE MARGIN COMPARISON ===\n\n")
## === BTFP vs. DW INTENSIVE MARGIN COMPARISON ===
models_int_combined <- list(
  "BTFP: M1" = mod_int_btfp_m1, "DW: M1" = mod_int_dw_m1,
  "BTFP: M4" = mod_int_btfp_m4, "DW: M4" = mod_int_dw_m4)

save_etable(models_int_combined, "Intensive_BTFP_vs_DW",
  title_text = "Intensive Margin Comparison: BTFP vs. DW (Crisis Period)",
  notes_text = paste0(
    "OLS. DV: borrowing amount / TA ($\\times 100$). Sample: borrowers only. ",
    "M1: Run pressure baseline. M4: Full (+ $\\beta^U$ triple + collateral/par). ",
    "BTFP lends at par on OMO-eligible $\\Rightarrow$ par benefit matters. ",
    "DW has stigma $\\Rightarrow$ banks may minimize DW amounts unconditionally. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(
    c("Facility", "BTFP", "DW", "BTFP", "DW"),
    c("Specification", "M1", "M1", "M4", "M4"),
    c("N borrowers",
      nrow(df_btfp_intensive), nrow(df_dw_intensive),
      sum(!is.na(df_btfp_intensive$uninsured_beta_w)),
      sum(!is.na(df_dw_intensive$uninsured_beta_w)))))

etable(models_int_combined[!sapply(models_int_combined, is.null)], fitstat = ~ n + r2, se.below = TRUE)
##                                                 BTFP: M1       DW: M1
## Dependent Var.:                           BTFP / TA (\%) DW / TA (\%)
##                                                                      
## Constant                                        7.791***      3.943**
##                                                (1.113)       (1.512) 
## MTM Loss (z)                                   -1.199         0.6626 
##                                                (1.026)       (1.993) 
## Uninsured Leverage (z)                         -1.622         2.280  
##                                                (1.477)       (2.036) 
## MTM $\times$ Uninsured                          1.392         1.861  
##                                                (0.9568)      (1.444) 
## Log(Assets)                                     1.742         3.102  
##                                                (1.287)       (1.844) 
## Cash Ratio                                      2.072        -2.279  
##                                                (1.626)       (1.457) 
## Loan-to-Deposit                                -2.639        -0.6124 
##                                                (1.565)       (2.508) 
## Book Equity Ratio                               0.8910       -0.2767 
##                                                (0.8683)      (2.008) 
## Wholesale Funding                               0.6748        2.524* 
##                                                (0.3504)      (1.265) 
## ROA                                            -0.1763       -0.0455 
##                                                (0.8310)      (1.059) 
## Uninsured $\beta$ (z)                                                
##                                                                      
## MTM $\times$ Unins. $\beta$                                          
##                                                                      
## Uninsured $\times$ Unins. $\beta$                                    
##                                                                      
## MTM $\times$ Uninsured $\times$ $\beta^U$                            
##                                                                      
## Par Benefit (z)                                                      
##                                                                      
## OMO Collateral (z)                                                   
##                                                                      
## ________________________________________  ______________ ____________
## S.E. type                                 Heterosk.-rob. Hetero.-rob.
## Observations                                         501          433
## R2                                               0.11747      0.03726
## 
##                                                 BTFP: M4       DW: M4
## Dependent Var.:                           BTFP / TA (\%) DW / TA (\%)
##                                                                      
## Constant                                        6.852***      4.493**
##                                                (0.6817)      (1.469) 
## MTM Loss (z)                                    0.4714        1.427  
##                                                (0.4961)      (1.949) 
## Uninsured Leverage (z)                         -0.2002        2.753  
##                                                (0.6654)      (2.024) 
## MTM $\times$ Uninsured                          0.6966        2.589  
##                                                (0.5609)      (1.776) 
## Log(Assets)                                     0.4780        2.735  
##                                                (0.6356)      (1.702) 
## Cash Ratio                                      1.076        -2.079  
##                                                (1.182)       (1.654) 
## Loan-to-Deposit                                -1.441        -1.187  
##                                                (1.014)       (3.142) 
## Book Equity Ratio                               0.4828        0.1642 
##                                                (0.6809)      (2.024) 
## Wholesale Funding                               0.5188        2.504* 
##                                                (0.3196)      (1.265) 
## ROA                                            -0.6455       -0.0185 
##                                                (0.4922)      (0.9956)
## Uninsured $\beta$ (z)                           2.340**       1.188  
##                                                (0.7875)      (2.057) 
## MTM $\times$ Unins. $\beta$                    -2.236*       -0.6352 
##                                                (0.9118)      (2.333) 
## Uninsured $\times$ Unins. $\beta$              -0.8717        2.582  
##                                                (0.4451)      (2.343) 
## MTM $\times$ Uninsured $\times$ $\beta^U$       1.844*        2.068  
##                                                (0.8260)      (1.726) 
## Par Benefit (z)                                -2.594*               
##                                                (1.147)               
## OMO Collateral (z)                              2.087***      0.1595 
##                                                (0.5810)      (2.249) 
## ________________________________________  ______________ ____________
## S.E. type                                 Heterosk.-rob. Hetero.-rob.
## Observations                                         496          430
## R2                                               0.31816      0.05060
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

22.4 Intensive Margin Descriptives

cat("=== INTENSIVE MARGIN DESCRIPTIVE STATISTICS ===\n\n")
## === INTENSIVE MARGIN DESCRIPTIVE STATISTICS ===
# --- Distribution of borrowing amounts ---
cat("--- BTFP Borrowing Distribution ---\n")
## --- BTFP Borrowing Distribution ---
cat(sprintf("  N:      %d\n", nrow(df_btfp_intensive)))
##   N:      501
cat(sprintf("  Mean:   $%.1fM (%.2f%% TA)\n",
  mean(df_btfp_intensive$btfp_crisis_amt) / 1e6, mean(df_btfp_intensive$btfp_pct)))
##   Mean:   $260.9M (6.62% TA)
cat(sprintf("  Median: $%.1fM (%.2f%% TA)\n",
  median(df_btfp_intensive$btfp_crisis_amt) / 1e6, median(df_btfp_intensive$btfp_pct)))
##   Median: $22.5M (3.86% TA)
cat(sprintf("  P10:    $%.1fM (%.2f%% TA)\n",
  quantile(df_btfp_intensive$btfp_crisis_amt, .10) / 1e6,
  quantile(df_btfp_intensive$btfp_pct, .10)))
##   P10:    $1.0M (0.06% TA)
cat(sprintf("  P90:    $%.1fM (%.2f%% TA)\n",
  quantile(df_btfp_intensive$btfp_crisis_amt, .90) / 1e6,
  quantile(df_btfp_intensive$btfp_pct, .90)))
##   P90:    $350.0M (14.79% TA)
cat("\n--- DW Borrowing Distribution ---\n")
## 
## --- DW Borrowing Distribution ---
cat(sprintf("  N:      %d\n", nrow(df_dw_intensive)))
##   N:      433
cat(sprintf("  Mean:   $%.1fM (%.2f%% TA)\n",
  mean(df_dw_intensive$dw_crisis_amt) / 1e6, mean(df_dw_intensive$dw_pct)))
##   Mean:   $1240.9M (8.23% TA)
cat(sprintf("  Median: $%.1fM (%.2f%% TA)\n",
  median(df_dw_intensive$dw_crisis_amt) / 1e6, median(df_dw_intensive$dw_pct)))
##   Median: $0.1M (0.01% TA)
cat(sprintf("  P10:    $%.1fM (%.2f%% TA)\n",
  quantile(df_dw_intensive$dw_crisis_amt, .10) / 1e6,
  quantile(df_dw_intensive$dw_pct, .10)))
##   P10:    $0.0M (0.00% TA)
cat(sprintf("  P90:    $%.1fM (%.2f%% TA)\n",
  quantile(df_dw_intensive$dw_crisis_amt, .90) / 1e6,
  quantile(df_dw_intensive$dw_pct, .90)))
##   P90:    $226.2M (12.67% TA)
# --- Correlation of borrowing with key risk variables ---
cat("\n--- Correlations: Borrowing Intensity vs. Risk Variables ---\n")
## 
## --- Correlations: Borrowing Intensity vs. Risk Variables ---
cor_btfp <- df_btfp_intensive %>%
  select(btfp_pct, mtm_total_raw, uninsured_lev_raw, uninsured_beta_raw,
         cash_ratio_raw, collateral_capacity_raw, par_benefit_raw,
         ln_assets_raw, wholesale_raw) %>%
  drop_na()
if (nrow(cor_btfp) > 10) {
  cat("  BTFP (N=", nrow(cor_btfp), "):\n")
  r <- cor(cor_btfp)[1, -1]
  for (i in seq_along(r)) cat(sprintf("    %-28s r = %+.3f\n", names(r)[i], r[i]))
}
##   BTFP (N= 496 ):
##     mtm_total_raw                r = -0.082
##     uninsured_lev_raw            r = -0.026
##     uninsured_beta_raw           r = +0.236
##     cash_ratio_raw               r = +0.177
##     collateral_capacity_raw      r = +0.314
##     par_benefit_raw              r = -0.256
##     ln_assets_raw                r = +0.035
##     wholesale_raw                r = +0.111
cor_dw <- df_dw_intensive %>%
  select(dw_pct, mtm_total_raw, uninsured_lev_raw, uninsured_beta_raw,
         cash_ratio_raw, collateral_capacity_raw, ln_assets_raw, wholesale_raw) %>%
  drop_na()
if (nrow(cor_dw) > 10) {
  cat("\n  DW (N=", nrow(cor_dw), "):\n")
  r <- cor(cor_dw)[1, -1]
  for (i in seq_along(r)) cat(sprintf("    %-28s r = %+.3f\n", names(r)[i], r[i]))
}
## 
##   DW (N= 430 ):
##     mtm_total_raw                r = +0.047
##     uninsured_lev_raw            r = +0.107
##     uninsured_beta_raw           r = +0.037
##     cash_ratio_raw               r = -0.090
##     collateral_capacity_raw      r = +0.016
##     ln_assets_raw                r = +0.150
##     wholesale_raw                r = +0.053
# --- Distribution plots ---
p_int_dist <- bind_rows(
  df_btfp_intensive %>% transmute(Facility = "BTFP", pct = btfp_pct),
  df_dw_intensive   %>% transmute(Facility = "DW",   pct = dw_pct)
) %>%
  ggplot(aes(x = pct, fill = Facility)) +
  geom_histogram(bins = 40, alpha = 0.6, position = "identity", color = "white") +
  facet_wrap(~Facility, scales = "free") +
  scale_fill_manual(values = c("BTFP" = "#2A9D8F", "DW" = "#D62828")) +
  labs(
    title = "Distribution of Borrowing Intensity: BTFP vs. DW (Crisis)",
    subtitle = "Borrowing amount as % of total assets, conditional on borrowing",
    x = "Borrowing Amount / Total Assets (%)", y = "Count"
  ) + theme_paper + theme(legend.position = "none")

p_int_dist

save_figure(p_int_dist, "Fig_Intensive_Margin_Distribution", width = 12, height = 6)

# --- Scatter: MTM loss vs. borrowing intensity ---
p_int_scatter <- bind_rows(
  df_btfp_intensive %>% transmute(Facility = "BTFP", mtm = mtm_total_raw, pct = btfp_pct),
  df_dw_intensive   %>% transmute(Facility = "DW",   mtm = mtm_total_raw, pct = dw_pct)
) %>%
  ggplot(aes(x = mtm, y = pct, color = Facility)) +
  geom_point(alpha = 0.5, size = 2) +
  geom_smooth(method = "lm", se = TRUE, linewidth = 1) +
  facet_wrap(~Facility, scales = "free_y") +
  scale_color_manual(values = c("BTFP" = "#2A9D8F", "DW" = "#D62828")) +
  labs(
    title = "MTM Loss vs. Borrowing Intensity (Crisis Borrowers)",
    subtitle = "Do banks with larger unrealized losses borrow more?",
    x = "MTM Loss (% of Total Assets)", y = "Borrowing Amount / TA (%)"
  ) + theme_paper + theme(legend.position = "none")

p_int_scatter

save_figure(p_int_scatter, "Fig_Intensive_MTM_vs_Amount", width = 12, height = 6)

23 BTFP PAR RECAPITALIZATION & DW COMPLEMENTARITY

BTFP lent at par (face) value of collateral, while DW lent at market value. For banks with unrealized losses on OMO-eligible securities, this par-value lending provides implicit recapitalization: \[\text{Par Recap}_i = \frac{\text{Face Value}_i - \text{Market Value}_i}{\text{TA}_i} = \frac{\text{MTM Loss on OMO-eligible}_i}{\text{TA}_i}\]

If BTFP complements DW, we should see: 1. Par recapitalization increases DW probability (not decreases) 2. BTFP borrowers with larger par wedge are more likely to also use DW 3. Joint (both) facility usage rises with par recapitalization

23.1 Par Recap → DW (Complementarity)

cat("=== BTFP PAR RECAPITALIZATION → DW COMPLEMENTARITY ===\n\n")
## === BTFP PAR RECAPITALIZATION → DW COMPLEMENTARITY ===
# --- Panel A: Full sample — does par recap increase DW probability? ---
# If BTFP substitutes for DW, par_recap should be NEGATIVE (banks use BTFP instead)
# If BTFP complements DW, par_recap should be POSITIVE (recapitalization enables more DW)

EXPL_RECAP_BASE  <- paste0(EXPL_BASE, " + par_recap")
EXPL_RECAP_INT   <- paste0(EXPL_BASE, " + par_recap + par_recap_x_unins")
EXPL_RECAP_FULL  <- paste0(EXPL_BASE, " + par_recap + par_recap_x_unins + collateral_capacity")

mod_recap_dw_m1 <- run_model(df_dw_s, "dw_crisis", EXPL_BASE)
mod_recap_dw_m2 <- run_model(df_dw_s, "dw_crisis", EXPL_RECAP_BASE)
mod_recap_dw_m3 <- run_model(df_dw_s, "dw_crisis", EXPL_RECAP_INT)
mod_recap_dw_m4 <- run_model(df_dw_s, "dw_crisis", EXPL_RECAP_FULL)

models_recap_dw <- list(
  "DW (Base)"      = mod_recap_dw_m1,
  "DW + Recap"     = mod_recap_dw_m2,
  "DW + Recap×UI"  = mod_recap_dw_m3,
  "DW Full"        = mod_recap_dw_m4)

save_etable(models_recap_dw, "ParRecap_DW_complementarity",
  title_text = "BTFP Par Recapitalization → DW Borrowing (Complementarity Test)",
  notes_text = paste0(
    "LPM. DV = dw\\_crisis. Sample: DW borrowers + non-users (Crisis). ",
    "Par Recap = MTM loss on OMO-eligible / TA (z). ",
    "Positive par recap coefficient = BTFP complements DW. Robust SEs."))

etable(models_recap_dw, fitstat = ~ n + r2, se.below = TRUE)
##                               DW (Base) DW + Recap DW + Rec..    DW Full
## Dependent Var.:               dw_crisis  dw_crisis  dw_crisis  dw_crisis
##                                                                         
## Constant                      0.1272***  0.1273***  0.1271***  0.1271***
##                              (0.0054)   (0.0054)   (0.0054)   (0.0054)  
## MTM Loss (z)                  0.0158**   0.0149*    0.0146*    0.0133*  
##                              (0.0061)   (0.0062)   (0.0062)   (0.0067)  
## Uninsured Leverage (z)        0.0126     0.0129     0.0128     0.0127   
##                              (0.0067)   (0.0067)   (0.0067)   (0.0067)  
## MTM $\times$ Uninsured        0.0170***  0.0169***  0.0159**   0.0158** 
##                              (0.0051)   (0.0051)   (0.0053)   (0.0053)  
## Log(Assets)                   0.0920***  0.0907***  0.0905***  0.0902***
##                              (0.0077)   (0.0077)   (0.0077)   (0.0077)  
## Cash Ratio                   -0.0043    -0.0034    -0.0035    -0.0039   
##                              (0.0053)   (0.0053)   (0.0053)   (0.0054)  
## Loan-to-Deposit              -0.0007     0.0022     0.0021     0.0007   
##                              (0.0057)   (0.0061)   (0.0061)   (0.0065)  
## Book Equity Ratio            -0.0006    -0.0004    -0.0004    -2.82e-5  
##                              (0.0044)   (0.0044)   (0.0044)   (0.0045)  
## Wholesale Funding             0.0204**   0.0199**   0.0198**   0.0199** 
##                              (0.0063)   (0.0063)   (0.0063)   (0.0063)  
## ROA                          -0.0029    -0.0021    -0.0021    -0.0024   
##                              (0.0048)   (0.0049)   (0.0049)   (0.0049)  
## Par Recap (z)                            0.0068     0.0069     0.0100   
##                                         (0.0060)   (0.0061)   (0.0076)  
## Par Recap $\times$ Uninsured                        0.0031     0.0031   
##                                                    (0.0054)   (0.0054)  
## OMO Collateral (z)                                            -0.0045   
##                                                               (0.0066)  
## ____________________________ __________ __________ __________ __________
## S.E. type                    Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                      3,649      3,649      3,649      3,649
## R2                              0.10314    0.10347    0.10356    0.10363
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("\n--- Interpretation ---\n")
## 
## --- Interpretation ---
cat("Par Recap > 0 → BTFP recapitalization INCREASES DW probability (complement)\n")
## Par Recap > 0 → BTFP recapitalization INCREASES DW probability (complement)
cat("Par Recap < 0 → BTFP recapitalization DECREASES DW probability (substitute)\n")
## Par Recap < 0 → BTFP recapitalization DECREASES DW probability (substitute)
cat("Par Recap × Uninsured > 0 → recapitalization amplifies coordination channel\n")
## Par Recap × Uninsured > 0 → recapitalization amplifies coordination channel

23.2 BTFP Borrowers → Also DW?

cat("=== AMONG BTFP BORROWERS: PAR RECAP → ALSO DW? ===\n\n")
## === AMONG BTFP BORROWERS: PAR RECAP → ALSO DW? ===
# Among banks that already accessed BTFP (got par recapitalization),
# does the SIZE of that recapitalization predict also using DW?
df_btfp_comp <- df_crisis %>%
  filter(btfp_crisis == 1) %>%
  mutate(also_dw = as.integer(dw_crisis == 1))

cat("BTFP borrowers:", nrow(df_btfp_comp), "| Also DW:", sum(df_btfp_comp$also_dw),
    sprintf("(%.1f%%)\n", 100 * mean(df_btfp_comp$also_dw)))
## BTFP borrowers: 501 | Also DW: 106 (21.2%)
mod_btfp2dw_m1 <- safe_run(df_btfp_comp, "also_dw", EXPL_BASE, min_n = 20, min_dv1 = 5)
mod_btfp2dw_m2 <- safe_run(df_btfp_comp, "also_dw", EXPL_RECAP_BASE, min_n = 20, min_dv1 = 5)
mod_btfp2dw_m3 <- safe_run(df_btfp_comp, "also_dw",
  paste0(EXPL_BASE, " + par_recap + collateral_capacity"), min_n = 20, min_dv1 = 5)
mod_btfp2dw_m4 <- safe_run(df_btfp_comp, "also_dw",
  paste0(EXPL_BASE, " + par_recap + par_recap_x_unins + collateral_capacity"),
  min_n = 20, min_dv1 = 5)

models_btfp2dw <- list(
  "Base"              = mod_btfp2dw_m1,
  "+ Recap"           = mod_btfp2dw_m2,
  "+ Recap + Coll"    = mod_btfp2dw_m3,
  "+ Recap×UI + Coll" = mod_btfp2dw_m4)

save_etable(models_btfp2dw, "ParRecap_BTFP_to_DW",
  title_text = "Among BTFP Borrowers: Par Recapitalization → Also DW?",
  notes_text = paste0(
    "LPM. DV = 1 if BTFP borrower also used DW. Sample: BTFP borrowers (Crisis). ",
    "Positive par recap → larger recapitalization predicts joint facility use. Robust SEs."),
  extra_lines = list(
    c("BTFP Borrowers", rep(nrow(df_btfp_comp), 4)),
    c("Also DW", rep(sum(df_btfp_comp$also_dw), 4))))

etable(models_btfp2dw[!sapply(models_btfp2dw, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                    Base    + Recap + Recap .. + Recap×..
## Dependent Var.:                 Also DW    Also DW    Also DW    Also DW
##                                                                         
## Constant                      0.1466***  0.1459***  0.1480***  0.1479***
##                              (0.0226)   (0.0226)   (0.0225)   (0.0225)  
## MTM Loss (z)                 -0.0283    -0.0273    -0.0357    -0.0356   
##                              (0.0234)   (0.0235)   (0.0255)   (0.0256)  
## Uninsured Leverage (z)        0.0356     0.0357     0.0344     0.0346   
##                              (0.0220)   (0.0221)   (0.0220)   (0.0220)  
## MTM $\times$ Uninsured        0.0198     0.0194     0.0189     0.0200   
##                              (0.0192)   (0.0192)   (0.0193)   (0.0217)  
## Log(Assets)                   0.1121***  0.1158***  0.1152***  0.1158***
##                              (0.0224)   (0.0228)   (0.0225)   (0.0232)  
## Cash Ratio                    0.0177     0.0137     0.0138     0.0139   
##                              (0.0357)   (0.0360)   (0.0356)   (0.0357)  
## Loan-to-Deposit              -0.0060    -0.0126    -0.0216    -0.0214   
##                              (0.0282)   (0.0291)   (0.0312)   (0.0312)  
## Book Equity Ratio            -0.0184    -0.0199    -0.0175    -0.0171   
##                              (0.0228)   (0.0231)   (0.0234)   (0.0236)  
## Wholesale Funding             0.0145     0.0159     0.0165     0.0164   
##                              (0.0143)   (0.0143)   (0.0143)   (0.0143)  
## ROA                          -0.0357    -0.0381    -0.0392    -0.0393   
##                              (0.0241)   (0.0245)   (0.0245)   (0.0245)  
## Par Recap (z)                           -0.0136     0.0035     0.0046   
##                                         (0.0179)   (0.0251)   (0.0253)  
## OMO Collateral (z)                                 -0.0261    -0.0261   
##                                                    (0.0288)   (0.0288)  
## Par Recap $\times$ Uninsured                                  -0.0027   
##                                                               (0.0194)  
## ____________________________ __________ __________ __________ __________
## S.E. type                    Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                        501        501        501        501
## R2                              0.10284    0.10384    0.10497    0.10502
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

23.3 Joint Usage (Both Fed)

cat("=== PAR RECAPITALIZATION → JOINT BTFP + DW USAGE ===\n\n")
## === PAR RECAPITALIZATION → JOINT BTFP + DW USAGE ===
# Direct test: does par recapitalization predict using BOTH facilities?
# DV = both_fed (1 if used both BTFP and DW during crisis)
# Sample: full crisis (all banks)

df_both_s <- df_crisis %>%
  filter(both_fed == 1 | (btfp_crisis == 0 & dw_crisis == 0 & fhlb_user == 0))

cat("Both-Fed sample:", nrow(df_both_s),
    "| Both users:", sum(df_both_s$both_fed),
    "| Non-users:", sum(df_both_s$both_fed == 0), "\n")
## Both-Fed sample: 3332 | Both users: 106 | Non-users: 3226
mod_both_m1 <- safe_run(df_both_s, "both_fed", EXPL_BASE, min_n = 20, min_dv1 = 5)
mod_both_m2 <- safe_run(df_both_s, "both_fed", EXPL_RECAP_BASE, min_n = 20, min_dv1 = 5)
mod_both_m3 <- safe_run(df_both_s, "both_fed", EXPL_RECAP_FULL, min_n = 20, min_dv1 = 5)

# Also run on the full anyfed sample (both_fed vs single-facility vs none)
mod_both_full_m1 <- safe_run(df_anyfed_s, "both_fed", EXPL_BASE, min_n = 20, min_dv1 = 5)
mod_both_full_m2 <- safe_run(df_anyfed_s, "both_fed", EXPL_RECAP_FULL, min_n = 20, min_dv1 = 5)

models_both <- list(
  "Both (clean)"     = mod_both_m1,
  "+ Recap"          = mod_both_m2,
  "+ Recap Full"     = mod_both_m3,
  "AnyFed Base"      = mod_both_full_m1,
  "AnyFed + Recap"   = mod_both_full_m2)

save_etable(models_both, "ParRecap_BothFed",
  title_text = "Par Recapitalization → Joint BTFP + DW Usage",
  notes_text = paste0(
    "LPM. DV = both\\_fed (1 if used BTFP and DW). ",
    "Cols 1-3: Both users vs. pure non-users. Cols 4-5: Both users vs. AnyFed sample. ",
    "Par Recap measures BTFP's implicit capital injection. Robust SEs."))

etable(models_both[!sapply(models_both, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                              Both (cl..    + Recap + Recap .. AnyFed B..
## Dependent Var.:                both_fed   both_fed   both_fed   both_fed
##                                                                         
## Constant                      0.0394***  0.0395***  0.0391***  0.0273***
##                              (0.0036)   (0.0036)   (0.0036)   (0.0026)  
## MTM Loss (z)                  0.0048     0.0042     0.0040     0.0019   
##                              (0.0036)   (0.0037)   (0.0040)   (0.0029)  
## Uninsured Leverage (z)        0.0119**   0.0121**   0.0120**   0.0086*  
##                              (0.0045)   (0.0045)   (0.0045)   (0.0036)  
## MTM $\times$ Uninsured        0.0118***  0.0118***  0.0096**   0.0076** 
##                              (0.0034)   (0.0034)   (0.0036)   (0.0027)  
## Log(Assets)                   0.0390***  0.0381***  0.0378***  0.0268***
##                              (0.0055)   (0.0055)   (0.0054)   (0.0042)  
## Cash Ratio                   -0.0054*   -0.0047    -0.0048    -0.0039   
##                              (0.0026)   (0.0026)   (0.0026)   (0.0023)  
## Loan-to-Deposit              -0.0069*   -0.0049    -0.0048    -0.0049   
##                              (0.0032)   (0.0033)   (0.0036)   (0.0027)  
## Book Equity Ratio             0.0011     0.0013     0.0011     2.86e-5  
##                              (0.0021)   (0.0021)   (0.0022)   (0.0018)  
## Wholesale Funding             0.0118**   0.0115**   0.0112**   0.0078*  
##                              (0.0041)   (0.0040)   (0.0040)   (0.0031)  
## ROA                          -0.0061*   -0.0056*   -0.0055*   -0.0048*  
##                              (0.0027)   (0.0027)   (0.0027)   (0.0023)  
## Par Recap (z)                            0.0048     0.0044              
##                                         (0.0038)   (0.0045)             
## Par Recap $\times$ Uninsured                        0.0069              
##                                                    (0.0044)             
## OMO Collateral (z)                                  0.0012              
##                                                    (0.0035)             
## ____________________________ __________ __________ __________ __________
## S.E. type                    Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                      3,322      3,322      3,322      4,044
## R2                              0.06807    0.06862    0.07015    0.04246
## 
##                              AnyFed +..
## Dependent Var.:                both_fed
##                                        
## Constant                      0.0270***
##                              (0.0026)  
## MTM Loss (z)                  0.0015   
##                              (0.0033)  
## Uninsured Leverage (z)        0.0087*  
##                              (0.0037)  
## MTM $\times$ Uninsured        0.0063*  
##                              (0.0029)  
## Log(Assets)                   0.0260***
##                              (0.0042)  
## Cash Ratio                   -0.0036   
##                              (0.0023)  
## Loan-to-Deposit              -0.0037   
##                              (0.0031)  
## Book Equity Ratio            -4.46e-5  
##                              (0.0019)  
## Wholesale Funding             0.0075*  
##                              (0.0030)  
## ROA                          -0.0044   
##                              (0.0023)  
## Par Recap (z)                 0.0018   
##                              (0.0036)  
## Par Recap $\times$ Uninsured  0.0040   
##                              (0.0036)  
## OMO Collateral (z)            0.0011   
##                              (0.0031)  
## ____________________________ __________
## S.E. type                    Hete.-rob.
## Observations                      4,044
## R2                              0.04329
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

23.4 Intensive: Total Fed Borrowing

cat("=== PAR RECAPITALIZATION → TOTAL FED BORROWING INTENSITY ===\n\n")
## === PAR RECAPITALIZATION → TOTAL FED BORROWING INTENSITY ===
# Among banks using ANY fed facility: total borrowing = BTFP + DW amount
df_total_int <- df_crisis %>%
  filter(any_fed == 1) %>%
  mutate(
    btfp_amt_safe = replace_na(btfp_crisis_amt, 0),
    dw_amt_safe   = replace_na(dw_crisis_amt, 0),
    total_fed_amt = btfp_amt_safe + dw_amt_safe,
    total_fed_pct = 100 * total_fed_amt / (total_asset * 1000),
    log_total_fed = log(pmax(total_fed_amt, 1))
  )

cat(sprintf("Any-Fed borrowers: %d\n", nrow(df_total_int)))
## Any-Fed borrowers: 828
cat(sprintf("  Mean total fed / TA: %.2f%%\n", mean(df_total_int$total_fed_pct, na.rm=T)))
##   Mean total fed / TA: 8.31%
cat(sprintf("  Median total fed / TA: %.2f%%\n", median(df_total_int$total_fed_pct, na.rm=T)))
##   Median total fed / TA: 2.27%
cat(sprintf("  Mean total fed ($M): %.1f\n", mean(df_total_int$total_fed_amt, na.rm=T) / 1e6))
##   Mean total fed ($M): 806.8
INTENS_RECAP_M1 <- EXPL_BASE
INTENS_RECAP_M2 <- paste0(EXPL_BASE, " + par_recap + collateral_capacity")
INTENS_RECAP_M3 <- paste0(EXPL_BASE, " + par_recap + par_recap_x_unins + collateral_capacity")

mod_total_m1 <- safe_run(df_total_int, "total_fed_pct", INTENS_RECAP_M1, min_n = 20, min_dv1 = 0)
mod_total_m2 <- safe_run(df_total_int, "total_fed_pct", INTENS_RECAP_M2, min_n = 20, min_dv1 = 0)
mod_total_m3 <- safe_run(df_total_int, "total_fed_pct", INTENS_RECAP_M3, min_n = 20, min_dv1 = 0)

mod_total_log_m1 <- safe_run(df_total_int, "log_total_fed", INTENS_RECAP_M1, min_n = 20, min_dv1 = 0)
mod_total_log_m2 <- safe_run(df_total_int, "log_total_fed", INTENS_RECAP_M3, min_n = 20, min_dv1 = 0)

models_total <- list(
  "%TA Base"       = mod_total_m1,
  "%TA + Recap"    = mod_total_m2,
  "%TA + Recap×UI" = mod_total_m3,
  "log($) Base"    = mod_total_log_m1,
  "log($) Full"    = mod_total_log_m2)

save_etable(models_total, "ParRecap_TotalFed_Intensive",
  title_text = "Par Recapitalization → Total Fed Borrowing (Intensive Margin)",
  notes_text = paste0(
    "OLS. DV: total fed borrowing (BTFP + DW) / TA (\\%) or log(\\$). ",
    "Sample: AnyFed borrowers (Crisis). ",
    "Par Recap > 0 → larger BTFP recapitalization increases total borrowing. Robust SEs."),
  extra_lines = list(
    c("Borrowers", rep(nrow(df_total_int), 5)),
    c("Mean DV", round(mean(df_total_int$total_fed_pct, na.rm=T), 2),
      round(mean(df_total_int$total_fed_pct, na.rm=T), 2),
      round(mean(df_total_int$total_fed_pct, na.rm=T), 2),
      round(mean(df_total_int$log_total_fed, na.rm=T), 2),
      round(mean(df_total_int$log_total_fed, na.rm=T), 2))))

etable(models_total[!sapply(models_total, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                   %TA Base   %TA + Recap %TA + Recap..
## Dependent Var.:              total_fed_pct total_fed_pct total_fed_pct
##                                                                       
## Constant                          6.124***      6.064***      5.965***
##                                  (0.8546)      (0.8201)      (0.8493) 
## MTM Loss (z)                     -0.4515        0.6457        0.7256  
##                                  (1.269)       (1.171)       (1.193)  
## Uninsured Leverage (z)            0.6744        0.8902        0.9699  
##                                  (1.477)       (1.404)       (1.435)  
## MTM $\times$ Uninsured            1.961         2.041*        2.761*  
##                                  (1.022)       (1.015)       (1.190)  
## Log(Assets)                       3.304*        3.579*        3.941** 
##                                  (1.391)       (1.425)       (1.501)  
## Cash Ratio                       -0.9301       -0.9716       -0.7937  
##                                  (1.153)       (1.131)       (1.136)  
## Loan-to-Deposit                  -2.145        -1.363        -1.137   
##                                  (1.739)       (1.830)       (1.899)  
## Book Equity Ratio                 0.5655        0.3649        0.4575  
##                                  (1.140)       (1.117)       (1.100)  
## Wholesale Funding                 1.919**       1.922*        1.950** 
##                                  (0.7066)      (0.7459)      (0.7538) 
## ROA                              -0.3661       -0.2762       -0.2426  
##                                  (0.7737)      (0.7403)      (0.7606) 
## Par Recap (z)                                  -2.978        -2.386   
##                                                (2.173)       (2.075)  
## OMO Collateral (z)                              3.560         3.530   
##                                                (2.635)       (2.634)  
## Par Recap $\times$ Uninsured                                 -1.671   
##                                                              (1.244)  
## ____________________________ _____________ _____________ _____________
## S.E. type                    Heteros.-rob. Heteros.-rob. Heteros.-rob.
## Observations                           828           828           828
## R2                                 0.03451       0.03930       0.04316
## 
##                                log($) Base   log($) Full
## Dependent Var.:              log_total_fed log_total_fed
##                                                         
## Constant                        13.69***      13.67***  
##                                 (0.1889)      (0.1860)  
## MTM Loss (z)                    -0.0680        0.1589   
##                                 (0.1968)      (0.2121)  
## Uninsured Leverage (z)           0.5303**      0.5798** 
##                                 (0.1959)      (0.1857)  
## MTM $\times$ Uninsured           0.0724        0.1204   
##                                 (0.1656)      (0.1766)  
## Log(Assets)                      0.3988        0.4523*  
##                                 (0.2035)      (0.2070)  
## Cash Ratio                      -1.685***     -1.665*** 
##                                 (0.2814)      (0.2757)  
## Loan-to-Deposit                 -0.3381       -0.1143   
##                                 (0.2375)      (0.2539)  
## Book Equity Ratio               -0.3250       -0.3609   
##                                 (0.2243)      (0.2249)  
## Wholesale Funding                0.4740***     0.4659***
##                                 (0.1126)      (0.1149)  
## ROA                              0.0003        0.0343   
##                                 (0.1797)      (0.1818)  
## Par Recap (z)                                 -0.5129   
##                                               (0.2857)  
## OMO Collateral (z)                             0.7574*  
##                                               (0.3260)  
## Par Recap $\times$ Uninsured                  -0.0764   
##                                               (0.1551)  
## ____________________________ _____________ _____________
## S.E. type                    Heteros.-rob. Heteros.-rob.
## Observations                           828           828
## R2                                 0.12827       0.13569
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

23.5 Descriptive Evidence

cat("=== DESCRIPTIVE: PAR RECAPITALIZATION BY FACILITY CHOICE ===\n\n")
## === DESCRIPTIVE: PAR RECAPITALIZATION BY FACILITY CHOICE ===
# --- Compare par recap across facility choice groups ---
df_choice_desc <- df_crisis %>%
  filter(any_fed == 1 | (btfp_crisis == 0 & dw_crisis == 0)) %>%
  mutate(group = factor(case_when(
    both_fed == 1    ~ "Both BTFP+DW",
    btfp_crisis == 1 ~ "BTFP Only",
    dw_crisis == 1   ~ "DW Only",
    TRUE             ~ "Neither"),
    levels = c("Neither", "DW Only", "BTFP Only", "Both BTFP+DW")))

desc_recap <- df_choice_desc %>%
  group_by(group) %>%
  summarise(
    N = n(),
    pct = sprintf("%.1f%%", 100 * n() / nrow(df_choice_desc)),
    mtm_total_mean     = round(mean(mtm_total_raw, na.rm=T), 3),
    mtm_omo_mean       = round(mean(mtm_btfp_raw, na.rm=T), 3),
    uninsured_lev_mean = round(mean(uninsured_lev_raw, na.rm=T), 3),
    collateral_mean    = round(mean(collateral_capacity_raw, na.rm=T), 3),
    par_benefit_mean   = round(mean(par_benefit_raw, na.rm=T), 3),
    book_equity_mean   = round(mean(book_equity_ratio_raw, na.rm=T), 3),
    ln_assets_mean     = round(mean(ln_assets_raw, na.rm=T), 2),
    .groups = "drop")

cat("--- Mean Characteristics by Facility Choice (Par Recap Focus) ---\n")
## --- Mean Characteristics by Facility Choice (Par Recap Focus) ---
print(desc_recap, width = Inf)
## # A tibble: 4 × 10
##   group            N pct   mtm_total_mean mtm_omo_mean uninsured_lev_mean
##   <fct>        <int> <chr>          <dbl>        <dbl>              <dbl>
## 1 Neither       3464 80.7%           5.35        0.647               22.8
## 2 DW Only        327 7.6%            5.72        0.728               26.8
## 3 BTFP Only      395 9.2%            6.18        0.875               26.2
## 4 Both BTFP+DW   106 2.5%            5.83        0.924               32.0
##   collateral_mean par_benefit_mean book_equity_mean ln_assets_mean
##             <dbl>            <dbl>            <dbl>          <dbl>
## 1           0.011            0.909            10.6            12.7
## 2           0.009            0.962             9.10           13.8
## 3           0.012            0.933             8.19           13.5
## 4           0.011            0.978             8.14           14.6
# --- T-tests: Both vs. Single-facility users ---
cat("\n--- T-Tests: Joint (Both) vs. BTFP-Only Users ---\n")
## 
## --- T-Tests: Joint (Both) vs. BTFP-Only Users ---
both_users <- df_choice_desc %>% filter(group == "Both BTFP+DW")
btfp_only_d <- df_choice_desc %>% filter(group == "BTFP Only")
dw_only_d   <- df_choice_desc %>% filter(group == "DW Only")

recap_vars <- c("mtm_btfp_raw", "mtm_total_raw", "uninsured_lev_raw",
                "collateral_capacity_raw", "par_benefit_raw",
                "book_equity_ratio_raw", "ln_assets_raw")

for (v in recap_vars) {
  tt <- tryCatch(t.test(both_users[[v]], btfp_only_d[[v]]), error = function(e) NULL)
  if (!is.null(tt)) {
    stars <- case_when(tt$p.value < 0.01 ~ "***", tt$p.value < 0.05 ~ "**",
                       tt$p.value < 0.10 ~ "*", TRUE ~ "")
    cat(sprintf("  %-28s Both=%.3f  BTFPonly=%.3f  diff=%.3f  t=%.2f %s\n", v,
      mean(both_users[[v]], na.rm=T), mean(btfp_only_d[[v]], na.rm=T),
      mean(both_users[[v]], na.rm=T) - mean(btfp_only_d[[v]], na.rm=T),
      tt$statistic, stars))
  }
}
##   mtm_btfp_raw                 Both=0.924  BTFPonly=0.875  diff=0.049  t=0.46 
##   mtm_total_raw                Both=5.832  BTFPonly=6.175  diff=-0.344  t=-1.65 
##   uninsured_lev_raw            Both=32.010  BTFPonly=26.154  diff=5.856  t=4.03 ***
##   collateral_capacity_raw      Both=0.011  BTFPonly=0.012  diff=-0.000  t=-0.36 
##   par_benefit_raw              Both=0.978  BTFPonly=0.933  diff=0.045  t=4.09 ***
##   book_equity_ratio_raw        Both=8.138  BTFPonly=8.188  diff=-0.050  t=-0.16 
##   ln_assets_raw                Both=14.577  BTFPonly=13.486  diff=1.091  t=5.82 ***
cat("\n--- T-Tests: Joint (Both) vs. DW-Only Users ---\n")
## 
## --- T-Tests: Joint (Both) vs. DW-Only Users ---
for (v in recap_vars) {
  tt <- tryCatch(t.test(both_users[[v]], dw_only_d[[v]]), error = function(e) NULL)
  if (!is.null(tt)) {
    stars <- case_when(tt$p.value < 0.01 ~ "***", tt$p.value < 0.05 ~ "**",
                       tt$p.value < 0.10 ~ "*", TRUE ~ "")
    cat(sprintf("  %-28s Both=%.3f  DWonly=%.3f  diff=%.3f  t=%.2f %s\n", v,
      mean(both_users[[v]], na.rm=T), mean(dw_only_d[[v]], na.rm=T),
      mean(both_users[[v]], na.rm=T) - mean(dw_only_d[[v]], na.rm=T),
      tt$statistic, stars))
  }
}
##   mtm_btfp_raw                 Both=0.924  DWonly=0.728  diff=0.196  t=1.90 *
##   mtm_total_raw                Both=5.832  DWonly=5.718  diff=0.114  t=0.53 
##   uninsured_lev_raw            Both=32.010  DWonly=26.774  diff=5.236  t=3.53 ***
##   collateral_capacity_raw      Both=0.011  DWonly=0.009  diff=0.002  t=1.84 *
##   par_benefit_raw              Both=0.978  DWonly=0.962  diff=0.016  t=1.70 *
##   book_equity_ratio_raw        Both=8.138  DWonly=9.097  diff=-0.959  t=-2.99 ***
##   ln_assets_raw                Both=14.577  DWonly=13.833  diff=0.744  t=3.89 ***
# --- Figure: Par Recap Distribution by Facility Choice ---
p_recap_box <- df_choice_desc %>%
  filter(group != "Neither") %>%
  ggplot(aes(x = group, y = mtm_btfp_raw, fill = group)) +
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.3) +
  scale_fill_manual(values = c("DW Only" = "#D62828",
    "BTFP Only" = "#2A9D8F", "Both BTFP+DW" = "#6A0572")) +
  labs(
    title = "Par Recapitalization by Facility Choice",
    subtitle = "MTM loss on OMO-eligible / TA (the par wedge banks capture from BTFP)",
    x = NULL, y = "MTM Loss on OMO-Eligible (% of TA)"
  ) + theme_paper + theme(legend.position = "none")

p_recap_box

save_figure(p_recap_box, "Fig_ParRecap_by_FacilityChoice", width = 10, height = 7)

# --- Figure: Par Recap vs. DW probability (scatterplot with loess) ---
p_recap_dw <- df_crisis %>%
  mutate(dw_label = ifelse(dw_crisis == 1, "DW Borrower", "Non-DW")) %>%
  ggplot(aes(x = mtm_btfp_raw, y = dw_crisis)) +
  geom_jitter(aes(color = dw_label), alpha = 0.3, height = 0.05, width = 0, size = 1.5) +
  geom_smooth(method = "loess", se = TRUE, color = "black", linewidth = 1.2) +
  scale_color_manual(values = c("Non-DW" = "grey60", "DW Borrower" = "#D62828")) +
  labs(
    title = "BTFP Par Recapitalization vs. DW Borrowing Probability",
    subtitle = "Does larger par wedge increase DW usage? (loess fit)",
    x = "Par Recapitalization (MTM Loss on OMO-Eligible / TA, %)",
    y = "P(DW Borrowing)"
  ) + theme_paper

p_recap_dw

save_figure(p_recap_dw, "Fig_ParRecap_vs_DW_probability", width = 10, height = 7)

# --- Summary statistics ---
cat("\n--- Key Complementarity Statistics ---\n")
## 
## --- Key Complementarity Statistics ---
n_both <- sum(df_crisis$both_fed, na.rm = TRUE)
n_btfp <- sum(df_crisis$btfp_crisis, na.rm = TRUE)
n_dw   <- sum(df_crisis$dw_crisis, na.rm = TRUE)
cat(sprintf("  BTFP borrowers: %d\n", n_btfp))
##   BTFP borrowers: 501
cat(sprintf("  DW borrowers: %d\n", n_dw))
##   DW borrowers: 433
cat(sprintf("  Both: %d (%.1f%% of BTFP users, %.1f%% of DW users)\n",
    n_both, 100 * n_both / n_btfp, 100 * n_both / n_dw))
##   Both: 106 (21.2% of BTFP users, 24.5% of DW users)
cat(sprintf("  If independent: expected Both = %.1f\n",
    n_btfp * n_dw / nrow(df_crisis)))
##   If independent: expected Both = 50.5
cat(sprintf("  Observed / Expected ratio: %.2f\n",
    n_both / (n_btfp * n_dw / nrow(df_crisis))))
##   Observed / Expected ratio: 2.10
cat("  Ratio > 1 → positive association → complementarity\n")
##   Ratio > 1 → positive association → complementarity

24 COLLATERAL UTILIZATION & LIQUIDITY HIERARCHY

BTFP accepts only OMO-eligible securities (Treasury, Agency MBS/CMO/Debt) at par. DW accepts everything — securities, loans (CRE, C&I, consumer, residential) — at market value with haircuts.

This creates a natural collateral pecking order under run pressure: 1. Pledge OMO-eligible securities at BTFP (best terms, par value, no stigma) 2. If OMO capacity is exhausted, pledge remaining assets at DW (stigma, haircuts) 3. Banks pledging a larger fraction of their OMO portfolio → more severe liquidity need

Key variables from loan-level data: - BTFP utilization = Total BTFP collateral pledged / Bank’s OMO-eligible portfolio - DW collateral composition = Share of OMO-eligible vs. loan-based vs. other at DW - Advance rate = Loan amount / Collateral pledged (BTFP ≈ 1 at par; DW < 1 with haircuts) - Loan count = Number of trips to each facility (repeat borrowing intensity)

24.1 Collateral Aggregation

cat("=== LOAN-LEVEL COLLATERAL AGGREGATION ===\n\n")
## === LOAN-LEVEL COLLATERAL AGGREGATION ===
# --- BTFP: Aggregate to bank level (crisis period) ---
# Each BTFP loan encumbers specific securities (1-year term); summing is appropriate
btfp_coll_crisis <- btfp_loans %>%
  filter(btfp_loan_date >= CRISIS_START & btfp_loan_date <= CRISIS_END) %>%
  group_by(rssd_id) %>%
  summarise(
    btfp_n_loans       = n(),
    btfp_total_coll    = sum(btfp_total_collateral, na.rm = TRUE),
    btfp_coll_treasury = sum(btfp_treasury_sec, na.rm = TRUE),
    btfp_coll_mbs      = sum(btfp_agency_mbs, na.rm = TRUE),
    btfp_coll_cmo      = sum(btfp_agency_cmo, na.rm = TRUE),
    btfp_coll_agdebt   = sum(btfp_agency_debt, na.rm = TRUE),
    btfp_total_lent    = sum(btfp_loan_amount, na.rm = TRUE),
    btfp_avg_rate      = weighted.mean(btfp_interest_rate, btfp_loan_amount, na.rm = TRUE),
    btfp_first_date    = min(btfp_loan_date),
    btfp_last_date     = max(btfp_loan_date),
    .groups = "drop"
  ) %>%
  mutate(
    btfp_advance_rate   = btfp_total_lent / btfp_total_coll,
    btfp_share_treasury = btfp_coll_treasury / btfp_total_coll,
    btfp_share_mbs      = btfp_coll_mbs / btfp_total_coll,
    btfp_share_cmo      = btfp_coll_cmo / btfp_total_coll,
    btfp_share_agdebt   = btfp_coll_agdebt / btfp_total_coll
  ) %>%
  rename(idrssd = rssd_id)

cat(sprintf("BTFP crisis loans: %d from %d banks\n",
    sum(btfp_coll_crisis$btfp_n_loans), nrow(btfp_coll_crisis)))
## BTFP crisis loans: 1303 from 526 banks
cat(sprintf("  Mean loans/bank: %.1f | Max: %d\n",
    mean(btfp_coll_crisis$btfp_n_loans), max(btfp_coll_crisis$btfp_n_loans)))
##   Mean loans/bank: 2.5 | Max: 33
cat(sprintf("  Advance rate: mean=%.3f, median=%.3f (1.0 = full par)\n",
    mean(btfp_coll_crisis$btfp_advance_rate, na.rm=T),
    median(btfp_coll_crisis$btfp_advance_rate, na.rm=T)))
##   Advance rate: mean=0.579, median=0.580 (1.0 = full par)
# --- DW: Aggregate to bank level (crisis period) ---
# DW collateral is a maintained pool; max across loans = pool size
# Sum loan amounts = total liquidity drawn (may include rollovers)
dw_coll_crisis <- dw_loans %>%
  filter(dw_loan_date >= CRISIS_START &
         dw_loan_date <= min(CRISIS_END, DW_DATA_END)) %>%
  group_by(rssd_id) %>%
  summarise(
    dw_n_loans          = n(),
    dw_max_coll         = max(dw_total_collateral, na.rm = TRUE),
    dw_max_omo          = max(dw_omo_eligible, na.rm = TRUE),
    dw_max_nonomo       = max(dw_non_omo_eligible, na.rm = TRUE),
    dw_max_comm         = max(dw_comm_loans, na.rm = TRUE),
    dw_max_resmort      = max(dw_res_mortgages, na.rm = TRUE),
    dw_max_cre          = max(dw_cre_loans, na.rm = TRUE),
    dw_max_consumer     = max(dw_consumer_loans, na.rm = TRUE),
    dw_max_treas_agency = max(dw_treasury_agency, na.rm = TRUE),
    dw_max_mbs_agency   = max(dw_mbs_agency, na.rm = TRUE),
    dw_max_municipal    = max(dw_municipal_sec, na.rm = TRUE),
    dw_max_corporate    = max(dw_corporate_instruments, na.rm = TRUE),
    dw_total_lent       = sum(dw_loan_amount, na.rm = TRUE),
    dw_max_single_loan  = max(dw_loan_amount, na.rm = TRUE),
    dw_first_date       = min(dw_loan_date),
    dw_last_date        = max(dw_loan_date),
    .groups = "drop"
  ) %>%
  mutate(
    dw_advance_rate  = dw_max_single_loan / dw_max_coll,
    dw_share_omo     = dw_max_omo / dw_max_coll,
    dw_share_loans   = (dw_max_comm + dw_max_resmort + dw_max_cre + dw_max_consumer) / dw_max_coll,
    dw_share_treas   = dw_max_treas_agency / dw_max_coll,
    dw_share_mbs     = dw_max_mbs_agency / dw_max_coll
  ) %>%
  rename(idrssd = rssd_id)

cat(sprintf("\nDW crisis loans: %d from %d banks\n",
    sum(dw_coll_crisis$dw_n_loans), nrow(dw_coll_crisis)))
## 
## DW crisis loans: 1842 from 459 banks
cat(sprintf("  Mean loans/bank: %.1f | Max: %d\n",
    mean(dw_coll_crisis$dw_n_loans), max(dw_coll_crisis$dw_n_loans)))
##   Mean loans/bank: 4.0 | Max: 42
cat(sprintf("  Advance rate (max loan/max coll): mean=%.3f, median=%.3f\n",
    mean(dw_coll_crisis$dw_advance_rate, na.rm=T),
    median(dw_coll_crisis$dw_advance_rate, na.rm=T)))
##   Advance rate (max loan/max coll): mean=0.173, median=0.014
cat(sprintf("  Share OMO-eligible at DW: mean=%.3f, median=%.3f\n",
    mean(dw_coll_crisis$dw_share_omo, na.rm=T),
    median(dw_coll_crisis$dw_share_omo, na.rm=T)))
##   Share OMO-eligible at DW: mean=0.332, median=0.000
# --- Merge with crisis dataset ---
df_coll <- df_crisis %>%
  left_join(btfp_coll_crisis, by = "idrssd") %>%
  left_join(dw_coll_crisis, by = "idrssd") %>%
  mutate(
    # BTFP Utilization = collateral pledged / available OMO portfolio
    # omo_eligible in call report is in thousands; btfp_total_coll in dollars
    btfp_utilization_raw = ifelse(btfp_crisis == 1 & !is.na(omo_eligible) & omo_eligible > 0,
      btfp_total_coll / (omo_eligible * 1000), NA_real_),
    # Cap at reasonable max (>1 possible if bank pledged more than Q4 holdings)
    btfp_utilization_raw = pmin(btfp_utilization_raw, 2.0),

    # DW utilization = max collateral pool / total assets (in dollars)
    dw_utilization_raw = ifelse(dw_crisis == 1 & !is.na(total_asset) & total_asset > 0,
      dw_max_coll / (total_asset * 1000), NA_real_),

    # Number of trips
    btfp_n_loans = replace_na(btfp_n_loans, 0L),
    dw_n_loans   = replace_na(dw_n_loans, 0L),
    total_n_loans = btfp_n_loans + dw_n_loans,

    # Z-standardize for regressions (within borrowers)
    btfp_util     = standardize_z(btfp_utilization_raw),
    dw_util       = standardize_z(dw_utilization_raw),
    dw_share_omo_z = standardize_z(dw_share_omo),
    dw_share_loans_z = standardize_z(dw_share_loans)
  )

cat(sprintf("\n--- BTFP Utilization (collateral / OMO portfolio) ---\n"))
## 
## --- BTFP Utilization (collateral / OMO portfolio) ---
cat(sprintf("  Mean: %.3f | Median: %.3f | P25: %.3f | P75: %.3f\n",
    mean(df_coll$btfp_utilization_raw, na.rm=T),
    median(df_coll$btfp_utilization_raw, na.rm=T),
    quantile(df_coll$btfp_utilization_raw, .25, na.rm=T),
    quantile(df_coll$btfp_utilization_raw, .75, na.rm=T)))
##   Mean: 1.081 | Median: 0.961 | P25: 0.368 | P75: 2.000
cat(sprintf("  Banks with utilization > 0.80: %d (%.1f%% of BTFP borrowers)\n",
    sum(df_coll$btfp_utilization_raw > 0.80, na.rm=T),
    100 * mean(df_coll$btfp_utilization_raw > 0.80, na.rm=T)))
##   Banks with utilization > 0.80: 270 (53.9% of BTFP borrowers)

24.2 Utilization as Run Severity

cat("=== COLLATERAL UTILIZATION = REVEALED RUN SEVERITY ===\n\n")
## === COLLATERAL UTILIZATION = REVEALED RUN SEVERITY ===
# Among BTFP borrowers: what predicts pledging a larger fraction of OMO portfolio?
# Higher utilization = more desperate for liquidity = more severe run pressure
df_btfp_util <- df_coll %>% filter(btfp_crisis == 1 & !is.na(btfp_util))

cat(sprintf("BTFP borrowers with utilization data: %d\n", nrow(df_btfp_util)))
## BTFP borrowers with utilization data: 501
# DV: btfp_utilization_raw (continuous 0-2)
UTIL_M1 <- EXPL_BASE
UTIL_M2 <- paste0(EXPL_BASE, " + collateral_capacity")
UTIL_M3 <- paste0(EXPL_BASE, " + collateral_capacity + uninsured_beta")
UTIL_M4 <- paste0(EXPL_BASE, " + collateral_capacity + uninsured_beta + mtm_x_unins_x_beta")

mod_util_m1 <- safe_run(df_btfp_util, "btfp_utilization_raw", UTIL_M1, min_n = 20, min_dv1 = 0)
mod_util_m2 <- safe_run(df_btfp_util, "btfp_utilization_raw", UTIL_M2, min_n = 20, min_dv1 = 0)
mod_util_m3 <- safe_run(df_btfp_util, "btfp_utilization_raw", UTIL_M3, min_n = 20, min_dv1 = 0)
mod_util_m4 <- safe_run(df_btfp_util, "btfp_utilization_raw", UTIL_M4, min_n = 20, min_dv1 = 0)

# Also: log(loan count) as alternative DV
df_btfp_util <- df_btfp_util %>%
  mutate(log_n_loans = log(btfp_n_loans))

mod_nloans_m1 <- safe_run(df_btfp_util, "log_n_loans", UTIL_M1, min_n = 20, min_dv1 = 0)
mod_nloans_m2 <- safe_run(df_btfp_util, "log_n_loans", UTIL_M4, min_n = 20, min_dv1 = 0)

models_util <- list(
  "Util M1"       = mod_util_m1,
  "Util M2"       = mod_util_m2,
  "Util M3"       = mod_util_m3,
  "Util Full"     = mod_util_m4,
  "log(Trips) M1" = mod_nloans_m1,
  "log(Trips) Full" = mod_nloans_m2)

save_etable(models_util, "Collateral_Utilization_RunSeverity",
  title_text = "Collateral Utilization as Revealed Run Severity (BTFP Borrowers)",
  notes_text = paste0(
    "OLS. Cols 1-4: DV = BTFP collateral pledged / OMO-eligible portfolio (0--2). ",
    "Cols 5-6: DV = log(number of BTFP loans). ",
    "Sample: BTFP crisis borrowers with call-report match. ",
    "Higher utilization = bank pledged more of its capacity = more severe liquidity need. ",
    "Robust SEs. z-standardized regressors."),
  extra_lines = list(
    c("Borrowers", rep(nrow(df_btfp_util), 6)),
    c("Mean Util", rep(round(mean(df_btfp_util$btfp_utilization_raw, na.rm=T), 3), 4),
      round(mean(df_btfp_util$log_n_loans, na.rm=T), 3),
      round(mean(df_btfp_util$log_n_loans, na.rm=T), 3))))

etable(models_util[!sapply(models_util, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                                        Util M1
## Dependent Var.:                           btfp_utilization_raw
##                                                               
## Constant                                             1.069*** 
##                                                     (0.0486)  
## MTM Loss (z)                                         0.1357** 
##                                                     (0.0454)  
## Uninsured Leverage (z)                               0.0206   
##                                                     (0.0438)  
## MTM $\times$ Uninsured                               0.0139   
##                                                     (0.0372)  
## Log(Assets)                                         -0.0476   
##                                                     (0.0442)  
## Cash Ratio                                           0.0622   
##                                                     (0.0718)  
## Loan-to-Deposit                                      0.1913***
##                                                     (0.0540)  
## Book Equity Ratio                                   -0.0006   
##                                                     (0.0583)  
## Wholesale Funding                                    0.0053   
##                                                     (0.0265)  
## ROA                                                  0.0332   
##                                                     (0.0423)  
## OMO Collateral (z)                                            
##                                                               
## Uninsured $\beta$ (z)                                         
##                                                               
## MTM $\times$ Uninsured $\times$ $\beta^U$                     
##                                                               
## ________________________________________  ____________________
## S.E. type                                 Heteroskedasti.-rob.
## Observations                                               501
## R2                                                     0.04363
## 
##                                                        Util M2
## Dependent Var.:                           btfp_utilization_raw
##                                                               
## Constant                                             1.083*** 
##                                                     (0.0492)  
## MTM Loss (z)                                         0.0442   
##                                                     (0.0433)  
## Uninsured Leverage (z)                               0.0058   
##                                                     (0.0460)  
## MTM $\times$ Uninsured                               0.0006   
##                                                     (0.0388)  
## Log(Assets)                                          0.0045   
##                                                     (0.0448)  
## Cash Ratio                                          -0.0016   
##                                                     (0.0759)  
## Loan-to-Deposit                                     -0.0308   
##                                                     (0.0569)  
## Book Equity Ratio                                    0.0049   
##                                                     (0.0549)  
## Wholesale Funding                                    0.0350   
##                                                     (0.0246)  
## ROA                                                 -0.0204   
##                                                     (0.0410)  
## OMO Collateral (z)                                  -0.3351***
##                                                     (0.0357)  
## Uninsured $\beta$ (z)                                         
##                                                               
## MTM $\times$ Uninsured $\times$ $\beta^U$                     
##                                                               
## ________________________________________  ____________________
## S.E. type                                 Heteroskedasti.-rob.
## Observations                                               501
## R2                                                     0.17489
## 
##                                                        Util M3
## Dependent Var.:                           btfp_utilization_raw
##                                                               
## Constant                                             1.076*** 
##                                                     (0.0479)  
## MTM Loss (z)                                         0.0575   
##                                                     (0.0429)  
## Uninsured Leverage (z)                               0.0242   
##                                                     (0.0436)  
## MTM $\times$ Uninsured                               0.0023   
##                                                     (0.0379)  
## Log(Assets)                                         -0.0136   
##                                                     (0.0429)  
## Cash Ratio                                          -0.0146   
##                                                     (0.0734)  
## Loan-to-Deposit                                     -0.0561   
##                                                     (0.0588)  
## Book Equity Ratio                                    0.0025   
##                                                     (0.0543)  
## Wholesale Funding                                    0.0317   
##                                                     (0.0248)  
## ROA                                                 -0.0212   
##                                                     (0.0404)  
## OMO Collateral (z)                                  -0.3258***
##                                                     (0.0370)  
## Uninsured $\beta$ (z)                                0.0648   
##                                                     (0.0330)  
## MTM $\times$ Uninsured $\times$ $\beta^U$                     
##                                                               
## ________________________________________  ____________________
## S.E. type                                 Heteroskedasti.-rob.
## Observations                                               496
## R2                                                     0.18056
## 
##                                                      Util Full log(Trip..1
## Dependent Var.:                           btfp_utilization_raw log_n_loans
##                                                                           
## Constant                                             1.076***    0.5751***
##                                                     (0.0479)    (0.0424)  
## MTM Loss (z)                                         0.0559      0.0157   
##                                                     (0.0425)    (0.0396)  
## Uninsured Leverage (z)                               0.0221     -0.0345   
##                                                     (0.0410)    (0.0339)  
## MTM $\times$ Uninsured                               0.0029      0.0536   
##                                                     (0.0373)    (0.0351)  
## Log(Assets)                                         -0.0131      0.1175***
##                                                     (0.0426)    (0.0346)  
## Cash Ratio                                          -0.0144     -0.0634   
##                                                     (0.0736)    (0.0645)  
## Loan-to-Deposit                                     -0.0563     -0.0812   
##                                                     (0.0587)    (0.0490)  
## Book Equity Ratio                                    0.0019      0.0764   
##                                                     (0.0549)    (0.0510)  
## Wholesale Funding                                    0.0316      0.0532*  
##                                                     (0.0247)    (0.0261)  
## ROA                                                 -0.0201     -0.0593   
##                                                     (0.0396)    (0.0383)  
## OMO Collateral (z)                                  -0.3256***            
##                                                     (0.0369)              
## Uninsured $\beta$ (z)                                0.0643               
##                                                     (0.0339)              
## MTM $\times$ Uninsured $\times$ $\beta^U$           -0.0058               
##                                                     (0.0287)              
## ________________________________________  ____________________ ___________
## S.E. type                                 Heteroskedasti.-rob. Heter.-rob.
## Observations                                               496         501
## R2                                                     0.18065     0.05749
## 
##                                           log(Trips..
## Dependent Var.:                           log_n_loans
##                                                      
## Constant                                    0.5691***
##                                            (0.0423)  
## MTM Loss (z)                                0.0311   
##                                            (0.0418)  
## Uninsured Leverage (z)                     -0.0262   
##                                            (0.0358)  
## MTM $\times$ Uninsured                      0.0531   
##                                            (0.0352)  
## Log(Assets)                                 0.1138** 
##                                            (0.0356)  
## Cash Ratio                                 -0.0607   
##                                            (0.0663)  
## Loan-to-Deposit                            -0.0699   
##                                            (0.0608)  
## Book Equity Ratio                           0.0705   
##                                            (0.0513)  
## Wholesale Funding                           0.0511   
##                                            (0.0265)  
## ROA                                        -0.0558   
##                                            (0.0379)  
## OMO Collateral (z)                          0.0220   
##                                            (0.0385)  
## Uninsured $\beta$ (z)                      -0.0041   
##                                            (0.0313)  
## MTM $\times$ Uninsured $\times$ $\beta^U$   0.0054   
##                                            (0.0198)  
## ________________________________________  ___________
## S.E. type                                 Heter.-rob.
## Observations                                      496
## R2                                            0.06044
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

24.3 BTFP Exhaustion → DW

cat("=== BTFP COLLATERAL EXHAUSTION → DW COMPLEMENTARITY ===\n\n")
## === BTFP COLLATERAL EXHAUSTION → DW COMPLEMENTARITY ===
# KEY TEST: Among BTFP borrowers, does HIGH utilization predict also using DW?
# If yes → banks exhaust BTFP capacity, then turn to DW for additional liquidity
# This is the collateral-based complementarity mechanism

df_btfp_exh <- df_coll %>%
  filter(btfp_crisis == 1 & !is.na(btfp_utilization_raw)) %>%
  mutate(
    also_dw = as.integer(dw_crisis == 1),
    btfp_exhausted = as.integer(btfp_utilization_raw > 0.80),
    btfp_high_util = as.integer(btfp_utilization_raw > median(btfp_utilization_raw, na.rm=T))
  )

cat(sprintf("BTFP borrowers: %d\n", nrow(df_btfp_exh)))
## BTFP borrowers: 501
cat(sprintf("  Also DW: %d (%.1f%%)\n",
    sum(df_btfp_exh$also_dw), 100 * mean(df_btfp_exh$also_dw)))
##   Also DW: 106 (21.2%)
cat(sprintf("  BTFP Exhausted (>80%%): %d (%.1f%%)\n",
    sum(df_btfp_exh$btfp_exhausted), 100 * mean(df_btfp_exh$btfp_exhausted)))
##   BTFP Exhausted (>80%): 270 (53.9%)
cat(sprintf("  DW rate among exhausted: %.1f%%\n",
    100 * mean(df_btfp_exh$also_dw[df_btfp_exh$btfp_exhausted == 1])))
##   DW rate among exhausted: 20.0%
cat(sprintf("  DW rate among non-exhausted: %.1f%%\n",
    100 * mean(df_btfp_exh$also_dw[df_btfp_exh$btfp_exhausted == 0])))
##   DW rate among non-exhausted: 22.5%
# Regressions: does utilization predict also_dw?
EXH_M1 <- "btfp_util"
EXH_M2 <- paste0("btfp_util + ", EXPL_BASE)
EXH_M3 <- paste0("btfp_util + btfp_exhausted + ", EXPL_BASE)
EXH_M4 <- paste0("btfp_util + ", EXPL_BASE, " + collateral_capacity + uninsured_beta")

mod_exh_m1 <- safe_run(df_btfp_exh, "also_dw", EXH_M1, min_n = 20, min_dv1 = 5)
mod_exh_m2 <- safe_run(df_btfp_exh, "also_dw", EXH_M2, min_n = 20, min_dv1 = 5)
mod_exh_m3 <- safe_run(df_btfp_exh, "also_dw", EXH_M3, min_n = 20, min_dv1 = 5)
mod_exh_m4 <- safe_run(df_btfp_exh, "also_dw", EXH_M4, min_n = 20, min_dv1 = 5)

models_exh <- list(
  "Util Only"    = mod_exh_m1,
  "+ Run Vars"   = mod_exh_m2,
  "+ Exhausted"  = mod_exh_m3,
  "Full"         = mod_exh_m4)

# Add btfp_util and btfp_exhausted labels to fixest dict temporarily
save_etable(models_exh, "Collateral_BTFP_Exhaustion_to_DW",
  title_text = "BTFP Collateral Exhaustion → DW Borrowing (Complementarity)",
  notes_text = paste0(
    "LPM. DV = also\\_dw (1 if BTFP borrower also used DW). ",
    "Sample: BTFP crisis borrowers. ",
    "BTFP Util = collateral pledged / OMO portfolio (z). ",
    "Exhausted = 1 if utilization > 80\\%. ",
    "Positive coefficient = banks that used more BTFP capacity also went to DW. Robust SEs."),
  extra_lines = list(
    c("BTFP Borrowers", rep(nrow(df_btfp_exh), 4)),
    c("Also DW", rep(sum(df_btfp_exh$also_dw), 4)),
    c("Mean DV", rep(round(mean(df_btfp_exh$also_dw), 3), 4))))

etable(models_exh[!sapply(models_exh, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                         Util Only + Run Vars + Exhaus..       Full
## Dependent Var.:           Also DW    Also DW    Also DW    Also DW
##                                                                   
## Constant                0.1458***  0.1466***  0.1793***  0.1425***
##                        (0.0215)   (0.0226)   (0.0460)   (0.0230)  
## BTFP Utilization (z)   -0.0040    -0.0021     0.0253    -0.0072   
##                        (0.0181)   (0.0186)   (0.0376)   (0.0210)  
## Log(Assets)             0.1294***  0.1120***  0.1115***  0.1118***
##                        (0.0204)   (0.0224)   (0.0224)   (0.0231)  
## Cash Ratio              0.0379     0.0179     0.0172     0.0065   
##                        (0.0328)   (0.0359)   (0.0360)   (0.0359)  
## Loan-to-Deposit        -0.0066    -0.0055    -0.0048    -0.0193   
##                        (0.0262)   (0.0286)   (0.0286)   (0.0317)  
## Book Equity Ratio      -0.0210    -0.0184    -0.0187    -0.0147   
##                        (0.0232)   (0.0229)   (0.0229)   (0.0229)  
## Wholesale Funding       0.0132     0.0146     0.0152     0.0173   
##                        (0.0143)   (0.0143)   (0.0143)   (0.0144)  
## ROA                    -0.0207    -0.0356    -0.0347    -0.0355   
##                        (0.0227)   (0.0242)   (0.0241)   (0.0246)  
## MTM Loss (z)                      -0.0279    -0.0282    -0.0342   
##                                   (0.0241)   (0.0240)   (0.0247)  
## Uninsured Leverage (z)             0.0356     0.0361     0.0355   
##                                   (0.0221)   (0.0221)   (0.0225)  
## MTM $\times$ Uninsured             0.0198     0.0195     0.0161   
##                                   (0.0192)   (0.0192)   (0.0192)  
## BTFP Exhausted (>80\%)                       -0.0616              
##                                              (0.0733)             
## OMO Collateral (z)                                      -0.0187   
##                                                         (0.0233)  
## Uninsured $\beta$ (z)                                    0.0136   
##                                                         (0.0193)  
## ______________________ __________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                  501        501        501        496
## R2                        0.09104    0.10286    0.10399    0.10672
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

24.4 DW Collateral Composition

cat("=== DW COLLATERAL COMPOSITION: WHAT DID BANKS PLEDGE? ===\n\n")
## === DW COLLATERAL COMPOSITION: WHAT DID BANKS PLEDGE? ===
# Among DW borrowers: what fraction of collateral is OMO-eligible vs. loans?
# Banks that also used BTFP may have less OMO left → more loan-based DW collateral
df_dw_coll <- df_coll %>%
  filter(dw_crisis == 1 & !is.na(dw_share_omo)) %>%
  mutate(
    also_btfp = as.integer(btfp_crisis == 1),
    dw_loan_collateral = as.integer(dw_share_loans > 0.5),  # majority loan-based
    dw_pure_loan_coll  = as.integer(dw_share_omo < 0.01)    # almost no OMO at DW
  )

cat(sprintf("DW borrowers with collateral data: %d\n", nrow(df_dw_coll)))
## DW borrowers with collateral data: 433
cat(sprintf("  Also BTFP: %d (%.1f%%)\n",
    sum(df_dw_coll$also_btfp), 100 * mean(df_dw_coll$also_btfp)))
##   Also BTFP: 106 (24.5%)
cat("\n--- DW Collateral Composition by Also-BTFP Status ---\n")
## 
## --- DW Collateral Composition by Also-BTFP Status ---
df_dw_coll %>%
  group_by(also_btfp) %>%
  summarise(
    N = n(),
    share_omo       = round(mean(dw_share_omo, na.rm=T), 3),
    share_loans     = round(mean(dw_share_loans, na.rm=T), 3),
    share_treas     = round(mean(dw_share_treas, na.rm=T), 3),
    share_mbs       = round(mean(dw_share_mbs, na.rm=T), 3),
    advance_rate    = round(mean(dw_advance_rate, na.rm=T), 3),
    dw_max_coll_M   = round(mean(dw_max_coll, na.rm=T) / 1e6, 1),
    .groups = "drop"
  ) %>% print()
## # A tibble: 2 × 8
##   also_btfp     N share_omo share_loans share_treas share_mbs advance_rate
##       <int> <int>     <dbl>       <dbl>       <dbl>     <dbl>        <dbl>
## 1         0   327     0.354       0.418       0.193     0.16         0.153
## 2         1   106     0.309       0.501       0.149     0.161        0.227
## # ℹ 1 more variable: dw_max_coll_M <dbl>
# T-test: do joint users pledge less OMO at DW?
tt_omo <- t.test(dw_share_omo ~ also_btfp, data = df_dw_coll)
cat(sprintf("\nT-test (OMO share at DW): DW-only=%.3f, Joint=%.3f, diff=%.3f, p=%.4f\n",
    mean(df_dw_coll$dw_share_omo[df_dw_coll$also_btfp == 0], na.rm=T),
    mean(df_dw_coll$dw_share_omo[df_dw_coll$also_btfp == 1], na.rm=T),
    tt_omo$estimate[2] - tt_omo$estimate[1], tt_omo$p.value))
## 
## T-test (OMO share at DW): DW-only=0.354, Joint=0.309, diff=-0.045, p=0.3635
tt_loans <- t.test(dw_share_loans ~ also_btfp, data = df_dw_coll)
cat(sprintf("T-test (Loan share at DW): DW-only=%.3f, Joint=%.3f, diff=%.3f, p=%.4f\n",
    mean(df_dw_coll$dw_share_loans[df_dw_coll$also_btfp == 0], na.rm=T),
    mean(df_dw_coll$dw_share_loans[df_dw_coll$also_btfp == 1], na.rm=T),
    tt_loans$estimate[2] - tt_loans$estimate[1], tt_loans$p.value))
## T-test (Loan share at DW): DW-only=0.418, Joint=0.501, diff=0.083, p=0.1235
# Regressions: what predicts OMO share at DW?
DW_COMP_M1 <- "also_btfp"
DW_COMP_M2 <- paste0("also_btfp + ", EXPL_BASE)
DW_COMP_M3 <- paste0("also_btfp + ", EXPL_BASE, " + collateral_capacity + uninsured_beta")

mod_dwcomp_m1 <- safe_run(df_dw_coll, "dw_share_omo", DW_COMP_M1, min_n = 20, min_dv1 = 0)
mod_dwcomp_m2 <- safe_run(df_dw_coll, "dw_share_omo", DW_COMP_M2, min_n = 20, min_dv1 = 0)
mod_dwcomp_m3 <- safe_run(df_dw_coll, "dw_share_omo", DW_COMP_M3, min_n = 20, min_dv1 = 0)

# Also: what predicts using MORE loan-based collateral at DW?
mod_dwloan_m1 <- safe_run(df_dw_coll, "dw_share_loans", DW_COMP_M1, min_n = 20, min_dv1 = 0)
mod_dwloan_m2 <- safe_run(df_dw_coll, "dw_share_loans", DW_COMP_M3, min_n = 20, min_dv1 = 0)

models_dwcomp <- list(
  "OMO Share M1"   = mod_dwcomp_m1,
  "OMO Share M2"   = mod_dwcomp_m2,
  "OMO Share Full"  = mod_dwcomp_m3,
  "Loan Share M1"  = mod_dwloan_m1,
  "Loan Share Full" = mod_dwloan_m2)

save_etable(models_dwcomp, "Collateral_DW_Composition",
  title_text = "DW Collateral Composition: OMO-Eligible vs. Loan-Based",
  notes_text = paste0(
    "OLS. Cols 1-3: DV = share of DW collateral that is OMO-eligible (0--1). ",
    "Cols 4-5: DV = share of DW collateral that is loan-based (0--1). ",
    "Sample: DW crisis borrowers. Also\\_BTFP = 1 if bank also used BTFP. ",
    "Negative Also\\_BTFP on OMO share = joint users lack OMO for DW → collateral exhaustion. ",
    "Robust SEs."),
  extra_lines = list(
    c("DW Borrowers", rep(nrow(df_dw_coll), 5)),
    c("Also BTFP", rep(sum(df_dw_coll$also_btfp), 5))))

etable(models_dwcomp[!sapply(models_dwcomp, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                        OMO Share M1 OMO Share M2 OMO Share ..  Loan Share M1
## Dependent Var.:        dw_share_omo dw_share_omo dw_share_omo dw_share_loans
##                                                                             
## Constant                  0.4326***    0.4284***    0.4272***      0.3165***
##                          (0.0300)     (0.0297)     (0.0288)       (0.0268)  
## Also BTFP                -0.0372      -0.0199      -0.0350         0.0767   
##                          (0.0464)     (0.0466)     (0.0475)       (0.0494)  
## Log(Assets)              -0.0638**    -0.0286      -0.0332         0.1246***
##                          (0.0209)     (0.0228)     (0.0228)       (0.0213)  
## Cash Ratio               -0.0352       0.0024       0.0213         0.0997***
##                          (0.0285)     (0.0305)     (0.0295)       (0.0268)  
## Loan-to-Deposit          -0.1190***   -0.1101***   -0.0309         0.1596***
##                          (0.0290)     (0.0294)     (0.0344)       (0.0268)  
## Book Equity Ratio         0.0052       0.0058       0.0003         0.0370   
##                          (0.0333)     (0.0328)     (0.0333)       (0.0289)  
## Wholesale Funding        -0.0169      -0.0170      -0.0285        -0.0033   
##                          (0.0169)     (0.0169)     (0.0163)       (0.0174)  
## ROA                      -0.0690**    -0.0566*     -0.0388         0.0282   
##                          (0.0241)     (0.0237)     (0.0234)       (0.0249)  
## MTM Loss (z)                           0.0397       0.0554*                 
##                                       (0.0279)     (0.0273)                 
## Uninsured Leverage (z)                -0.0667**    -0.0647**                
##                                       (0.0215)     (0.0215)                 
## MTM $\times$ Uninsured                 0.0115       0.0044                  
##                                       (0.0197)     (0.0193)                 
## OMO Collateral (z)                                  0.1199***               
##                                                    (0.0289)                 
## Uninsured $\beta$ (z)                              -0.0061                  
##                                                    (0.0192)                 
## ______________________ ____________ ____________ ____________ ______________
## S.E. type              Hetero.-rob. Hetero.-rob. Hetero.-rob. Heterosk.-rob.
## Observations                    433          433          430            433
## R2                          0.12424      0.14813      0.18269        0.22628
## 
##                        Loan Share F..
## Dependent Var.:        dw_share_loans
##                                      
## Constant                    0.3302***
##                            (0.0271)  
## Also BTFP                   0.0445   
##                            (0.0506)  
## Log(Assets)                 0.0794** 
##                            (0.0246)  
## Cash Ratio                  0.0703*  
##                            (0.0293)  
## Loan-to-Deposit             0.1631***
##                            (0.0331)  
## Book Equity Ratio           0.0398   
##                            (0.0280)  
## Wholesale Funding          -0.0040   
##                            (0.0170)  
## ROA                         0.0167   
##                            (0.0254)  
## MTM Loss (z)               -0.0423   
##                            (0.0282)  
## Uninsured Leverage (z)      0.0786***
##                            (0.0227)  
## MTM $\times$ Uninsured      0.0142   
##                            (0.0198)  
## OMO Collateral (z)          0.0364   
##                            (0.0261)  
## Uninsured $\beta$ (z)       0.0288   
##                            (0.0207)  
## ______________________ ______________
## S.E. type              Heterosk.-rob.
## Observations                      430
## R2                            0.25379
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

24.5 Advance Rate & Recapitalization Gap

cat("=== ADVANCE RATE: BTFP (PAR) vs. DW (MARKET + HAIRCUT) ===\n\n")
## === ADVANCE RATE: BTFP (PAR) vs. DW (MARKET + HAIRCUT) ===
# BTFP advance rate ≈ 1 (par lending) vs. DW < 1 (haircuts)
# The gap = implicit recapitalization per dollar of collateral
cat("--- BTFP Advance Rate Distribution ---\n")
## --- BTFP Advance Rate Distribution ---
cat(sprintf("  N: %d | Mean: %.3f | Median: %.3f | P10: %.3f | P90: %.3f\n",
    sum(!is.na(df_coll$btfp_advance_rate) & df_coll$btfp_crisis == 1),
    mean(df_coll$btfp_advance_rate[df_coll$btfp_crisis == 1], na.rm=T),
    median(df_coll$btfp_advance_rate[df_coll$btfp_crisis == 1], na.rm=T),
    quantile(df_coll$btfp_advance_rate[df_coll$btfp_crisis == 1], .10, na.rm=T),
    quantile(df_coll$btfp_advance_rate[df_coll$btfp_crisis == 1], .90, na.rm=T)))
##   N: 501 | Mean: 0.571 | Median: 0.564 | P10: 0.095 | P90: 1.000
cat("\n--- DW Advance Rate Distribution ---\n")
## 
## --- DW Advance Rate Distribution ---
cat(sprintf("  N: %d | Mean: %.3f | Median: %.3f | P10: %.3f | P90: %.3f\n",
    sum(!is.na(df_coll$dw_advance_rate) & df_coll$dw_crisis == 1),
    mean(df_coll$dw_advance_rate[df_coll$dw_crisis == 1], na.rm=T),
    median(df_coll$dw_advance_rate[df_coll$dw_crisis == 1], na.rm=T),
    quantile(df_coll$dw_advance_rate[df_coll$dw_crisis == 1], .10, na.rm=T),
    quantile(df_coll$dw_advance_rate[df_coll$dw_crisis == 1], .90, na.rm=T)))
##   N: 433 | Mean: 0.171 | Median: 0.012 | P10: 0.000 | P90: 0.628
# For BOTH-facility users: compare advance rates at each
df_both_users <- df_coll %>%
  filter(both_fed == 1 & !is.na(btfp_advance_rate) & !is.na(dw_advance_rate))

if (nrow(df_both_users) > 10) {
  cat(sprintf("\n--- Joint Users (Both BTFP + DW): %d banks ---\n", nrow(df_both_users)))
  cat(sprintf("  BTFP advance rate: mean=%.3f, median=%.3f\n",
      mean(df_both_users$btfp_advance_rate, na.rm=T),
      median(df_both_users$btfp_advance_rate, na.rm=T)))
  cat(sprintf("  DW advance rate:   mean=%.3f, median=%.3f\n",
      mean(df_both_users$dw_advance_rate, na.rm=T),
      median(df_both_users$dw_advance_rate, na.rm=T)))
  cat(sprintf("  Gap (BTFP - DW):   mean=%.3f = %.1f%% recapitalization per dollar of collateral\n",
      mean(df_both_users$btfp_advance_rate - df_both_users$dw_advance_rate, na.rm=T),
      100 * mean(df_both_users$btfp_advance_rate - df_both_users$dw_advance_rate, na.rm=T)))

  tt_adv <- t.test(df_both_users$btfp_advance_rate, df_both_users$dw_advance_rate, paired = TRUE)
  cat(sprintf("  Paired t-test: t=%.2f, p=%.4f\n", tt_adv$statistic, tt_adv$p.value))
}
## 
## --- Joint Users (Both BTFP + DW): 106 banks ---
##   BTFP advance rate: mean=0.490, median=0.476
##   DW advance rate:   mean=0.227, median=0.078
##   Gap (BTFP - DW):   mean=0.264 = 26.4% recapitalization per dollar of collateral
##   Paired t-test: t=6.85, p=0.0000
# Regression: does the advance rate gap predict total borrowing?
df_adv <- df_coll %>%
  filter(any_fed == 1 & !is.na(btfp_advance_rate)) %>%
  mutate(
    adv_rate_z = standardize_z(btfp_advance_rate),
    total_fed_pct = 100 * (replace_na(btfp_total_lent, 0) + replace_na(dw_total_lent, 0)) /
                    (total_asset * 1000)
  )

if (nrow(df_adv) > 30) {
  mod_adv_m1 <- safe_run(df_adv, "total_fed_pct",
    paste0("adv_rate_z + ", EXPL_BASE), min_n = 20, min_dv1 = 0)
  mod_adv_m2 <- safe_run(df_adv, "total_fed_pct",
    paste0("adv_rate_z + ", EXPL_BASE, " + collateral_capacity"), min_n = 20, min_dv1 = 0)

  models_adv <- list("+ Advance Rate" = mod_adv_m1, "Full" = mod_adv_m2)

  save_etable(models_adv, "Collateral_AdvanceRate",
    title_text = "BTFP Advance Rate and Total Fed Borrowing",
    notes_text = paste0(
      "OLS. DV = total fed borrowing (BTFP + DW) / TA (\\%). ",
      "Sample: BTFP borrowers (crisis). ",
      "Advance Rate = loan amount / collateral (higher = closer to par). Robust SEs."))

  etable(models_adv[!sapply(models_adv, is.null)], fitstat = ~ n + r2, se.below = TRUE)
}
##                        + Advance R..          Full
## Dependent Var.:        total_fed_pct total_fed_pct
##                                                   
## Constant                    7.737***      7.713***
##                            (1.317)       (1.289)  
## Advance Rate (z)            3.081*        3.080*  
##                            (1.258)       (1.259)  
## MTM Loss (z)               -1.184        -1.032   
##                            (1.450)       (1.386)  
## Uninsured Leverage (z)      0.4067        0.4311  
##                            (2.166)       (2.145)  
## MTM $\times$ Uninsured      2.885*        2.907*  
##                            (1.297)       (1.293)  
## Log(Assets)                 5.856*        5.770*  
##                            (2.271)       (2.317)  
## Cash Ratio                  2.334         2.440   
##                            (1.809)       (1.794)  
## Loan-to-Deposit            -1.560        -1.193   
##                            (2.202)       (1.867)  
## Book Equity Ratio           0.7734        0.7642  
##                            (1.253)       (1.244)  
## Wholesale Funding           2.049*        2.000*  
##                            (0.8665)      (0.9115) 
## ROA                        -0.6370       -0.5486  
##                            (1.161)       (1.151)  
## OMO Collateral (z)                        0.5536  
##                                          (1.166)  
## ______________________ _____________ _____________
## S.E. type              Heteros.-rob. Heteros.-rob.
## Observations                     501           501
## R2                           0.07249       0.07276
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

24.6 Repeat Borrowing & Escalation

cat("=== REPEAT BORROWING: ESCALATION DYNAMICS ===\n\n")
## === REPEAT BORROWING: ESCALATION DYNAMICS ===
# Banks with multiple loans → escalating run pressure?
# Compare first-loan vs last-loan characteristics within BTFP borrowers
df_btfp_first_last <- btfp_loans %>%
  filter(btfp_loan_date >= CRISIS_START & btfp_loan_date <= CRISIS_END) %>%
  group_by(rssd_id) %>%
  filter(n() > 1) %>%
  arrange(btfp_loan_date) %>%
  summarise(
    n_loans       = n(),
    first_amount  = first(btfp_loan_amount),
    last_amount   = last(btfp_loan_amount),
    first_coll    = first(btfp_total_collateral),
    last_coll     = last(btfp_total_collateral),
    first_date    = first(btfp_loan_date),
    last_date     = last(btfp_loan_date),
    total_amount  = sum(btfp_loan_amount),
    .groups = "drop"
  ) %>%
  mutate(
    escalation_ratio = last_amount / first_amount,
    coll_escalation  = last_coll / first_coll,
    days_span        = as.numeric(last_date - first_date)
  )

cat(sprintf("BTFP banks with multiple crisis loans: %d\n", nrow(df_btfp_first_last)))
## BTFP banks with multiple crisis loans: 292
cat(sprintf("  Mean escalation ratio (last/first amount): %.2f\n",
    mean(df_btfp_first_last$escalation_ratio, na.rm=T)))
##   Mean escalation ratio (last/first amount): 90.44
cat(sprintf("  Median: %.2f | Share with escalation > 1: %.1f%%\n",
    median(df_btfp_first_last$escalation_ratio, na.rm=T),
    100 * mean(df_btfp_first_last$escalation_ratio > 1, na.rm=T)))
##   Median: 1.00 | Share with escalation > 1: 36.0%
# DW repeat borrowers
df_dw_first_last <- dw_loans %>%
  filter(dw_loan_date >= CRISIS_START &
         dw_loan_date <= min(CRISIS_END, DW_DATA_END)) %>%
  group_by(rssd_id) %>%
  filter(n() > 1) %>%
  arrange(dw_loan_date) %>%
  summarise(
    n_loans       = n(),
    first_amount  = first(dw_loan_amount),
    last_amount   = last(dw_loan_amount),
    first_coll    = first(dw_total_collateral),
    last_coll     = last(dw_total_collateral),
    first_date    = first(dw_loan_date),
    last_date     = last(dw_loan_date),
    total_amount  = sum(dw_loan_amount),
    .groups = "drop"
  ) %>%
  mutate(
    escalation_ratio = last_amount / first_amount,
    days_span = as.numeric(last_date - first_date)
  )

cat(sprintf("\nDW banks with multiple crisis loans: %d\n", nrow(df_dw_first_last)))
## 
## DW banks with multiple crisis loans: 130
cat(sprintf("  Mean escalation ratio (last/first amount): %.2f\n",
    mean(df_dw_first_last$escalation_ratio, na.rm=T)))
##   Mean escalation ratio (last/first amount): 43.22
# Regression: number of trips ~ run pressure
cat("\n--- Loan Count Regressions (All Borrowers) ---\n")
## 
## --- Loan Count Regressions (All Borrowers) ---
df_trips <- df_coll %>%
  filter(any_fed == 1) %>%
  mutate(log_total_trips = log(pmax(total_n_loans, 1)))

mod_trips_m1 <- safe_run(df_trips, "log_total_trips", EXPL_BASE, min_n = 20, min_dv1 = 0)
mod_trips_m2 <- safe_run(df_trips, "log_total_trips",
  paste0(EXPL_BASE, " + collateral_capacity + uninsured_beta"),
  min_n = 20, min_dv1 = 0)

models_trips <- list("Base" = mod_trips_m1, "Full" = mod_trips_m2)

save_etable(models_trips, "Collateral_RepeatBorrowing",
  title_text = "Repeat Borrowing: Number of Trips to Fed Facilities",
  notes_text = paste0(
    "OLS. DV = log(total number of BTFP + DW loans during crisis). ",
    "Sample: any-fed borrowers (crisis). ",
    "More trips = sustained/escalating liquidity demand. Robust SEs."),
  extra_lines = list(
    c("Borrowers", rep(nrow(df_trips), 2)),
    c("Mean Trips", rep(round(mean(df_trips$total_n_loans), 1), 2))))

etable(models_trips[!sapply(models_trips, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                   Base            Full
## Dependent Var.:        log_total_trips log_total_trips
##                                                       
## Constant                     0.5596***       0.5535***
##                             (0.0354)        (0.0352)  
## MTM Loss (z)                -0.0071          0.0061   
##                             (0.0408)        (0.0414)  
## Uninsured Leverage (z)       0.0466          0.0547   
##                             (0.0335)        (0.0339)  
## MTM $\times$ Uninsured       0.0493          0.0476   
##                             (0.0332)        (0.0334)  
## Log(Assets)                  0.0986**        0.0892*  
##                             (0.0354)        (0.0357)  
## Cash Ratio                  -0.1703***      -0.1683***
##                             (0.0459)        (0.0461)  
## Loan-to-Deposit             -0.0854         -0.0773   
##                             (0.0488)        (0.0554)  
## Book Equity Ratio            0.0207          0.0212   
##                             (0.0485)        (0.0483)  
## Wholesale Funding            0.1134***       0.1121***
##                             (0.0288)        (0.0294)  
## ROA                         -0.0538         -0.0463   
##                             (0.0351)        (0.0344)  
## OMO Collateral (z)                           0.0259   
##                                             (0.0424)  
## Uninsured $\beta$ (z)                        0.0272   
##                                             (0.0321)  
## ______________________ _______________ _______________
## S.E. type              Heteroske.-rob. Heteroske.-rob.
## Observations                       828             822
## R2                             0.07261         0.07376
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

24.7 Collateral Figures

cat("=== COLLATERAL UTILIZATION FIGURES ===\n\n")
## === COLLATERAL UTILIZATION FIGURES ===
# --- Figure 1: BTFP Utilization Distribution ---
p_util_hist <- df_coll %>%
  filter(btfp_crisis == 1 & !is.na(btfp_utilization_raw)) %>%
  mutate(also_dw_label = ifelse(dw_crisis == 1, "Also DW", "BTFP Only")) %>%
  ggplot(aes(x = btfp_utilization_raw, fill = also_dw_label)) +
  geom_histogram(bins = 40, alpha = 0.7, position = "identity") +
  geom_vline(xintercept = 0.80, linetype = "dashed", color = "red", linewidth = 1) +
  scale_fill_manual(values = c("BTFP Only" = "#2A9D8F", "Also DW" = "#D62828")) +
  annotate("text", x = 0.82, y = Inf, label = "80% exhaustion",
           hjust = 0, vjust = 2, color = "red", size = 3.5) +
  labs(
    title = "BTFP Collateral Utilization (Collateral Pledged / OMO Portfolio)",
    subtitle = "Red = banks that also used DW; dashed line = 80% exhaustion threshold",
    x = "BTFP Utilization Rate", y = "Count", fill = NULL
  ) + theme_paper

p_util_hist

save_figure(p_util_hist, "Fig_BTFP_Utilization_Distribution", width = 12, height = 7)

# --- Figure 2: DW Collateral Composition by Also-BTFP ---
df_dw_comp_plot <- df_coll %>%
  filter(dw_crisis == 1 & !is.na(dw_share_omo)) %>%
  mutate(group = ifelse(btfp_crisis == 1, "Joint (BTFP+DW)", "DW Only")) %>%
  select(group, dw_share_omo, dw_share_loans) %>%
  pivot_longer(-group, names_to = "Collateral Type", values_to = "Share") %>%
  mutate(`Collateral Type` = recode(`Collateral Type`,
    "dw_share_omo" = "OMO-Eligible (Securities)",
    "dw_share_loans" = "Loan-Based (C&I, CRE, etc.)"))

p_dw_comp <- df_dw_comp_plot %>%
  ggplot(aes(x = group, y = Share, fill = `Collateral Type`)) +
  geom_boxplot(alpha = 0.7) +
  scale_fill_manual(values = c("OMO-Eligible (Securities)" = "#2A9D8F",
    "Loan-Based (C&I, CRE, etc.)" = "#E76F51")) +
  labs(
    title = "DW Collateral Composition: Joint BTFP+DW vs. DW-Only Banks",
    subtitle = "Do joint users have less OMO-eligible collateral left for DW?",
    x = NULL, y = "Share of DW Collateral", fill = NULL
  ) + theme_paper

p_dw_comp

save_figure(p_dw_comp, "Fig_DW_CollateralComposition", width = 12, height = 7)

# --- Figure 3: BTFP Utilization vs. Run Pressure (hex scatter) ---
p_util_scatter <- df_coll %>%
  filter(btfp_crisis == 1 & !is.na(btfp_utilization_raw)) %>%
  ggplot(aes(x = mtm_total_raw, y = btfp_utilization_raw)) +
  geom_point(aes(color = uninsured_lev_raw), alpha = 0.6, size = 2.5) +
  geom_smooth(method = "lm", se = TRUE, color = "black", linewidth = 1.2) +
  scale_color_viridis_c(option = "plasma", name = "Uninsured\nLeverage (%)") +
  labs(
    title = "MTM Loss vs. BTFP Collateral Utilization",
    subtitle = "Color = uninsured deposit leverage; Higher utilization = more severe liquidity need",
    x = "MTM Loss (% of Total Assets)", y = "BTFP Utilization (Collateral / OMO Portfolio)"
  ) + theme_paper

p_util_scatter

save_figure(p_util_scatter, "Fig_BTFP_Util_vs_MTM", width = 12, height = 8)

# --- Figure 4: Advance Rate Comparison ---
df_adv_plot <- bind_rows(
  df_coll %>% filter(btfp_crisis == 1 & !is.na(btfp_advance_rate)) %>%
    transmute(Facility = "BTFP (Par)", advance_rate = btfp_advance_rate),
  df_coll %>% filter(dw_crisis == 1 & !is.na(dw_advance_rate)) %>%
    transmute(Facility = "DW (Market)", advance_rate = dw_advance_rate)
)

p_adv_rate <- df_adv_plot %>%
  ggplot(aes(x = Facility, y = advance_rate, fill = Facility)) +
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.2) +
  geom_hline(yintercept = 1.0, linetype = "dashed", color = "grey50") +
  scale_fill_manual(values = c("BTFP (Par)" = "#2A9D8F", "DW (Market)" = "#D62828")) +
  labs(
    title = "Advance Rate: BTFP (Par Valuation) vs. DW (Market + Haircuts)",
    subtitle = "Advance rate = loan received / collateral pledged; gap = recapitalization benefit",
    x = NULL, y = "Advance Rate (Loan / Collateral)"
  ) + theme_paper + theme(legend.position = "none")

p_adv_rate

save_figure(p_adv_rate, "Fig_AdvanceRate_BTFP_vs_DW", width = 10, height = 7)

# --- Figure 5: BTFP collateral composition (treemap-style bar) ---
btfp_agg_type <- df_coll %>%
  filter(btfp_crisis == 1) %>%
  summarise(
    Treasury = sum(btfp_coll_treasury, na.rm=T),
    `Agency MBS` = sum(btfp_coll_mbs, na.rm=T),
    `Agency CMO` = sum(btfp_coll_cmo, na.rm=T),
    `Agency Debt` = sum(btfp_coll_agdebt, na.rm=T)
  ) %>%
  pivot_longer(everything(), names_to = "Type", values_to = "Amount") %>%
  mutate(Share = Amount / sum(Amount))

dw_agg_type <- df_coll %>%
  filter(dw_crisis == 1) %>%
  summarise(
    `Commercial` = sum(dw_max_comm, na.rm=T),
    `Residential` = sum(dw_max_resmort, na.rm=T),
    `CRE` = sum(dw_max_cre, na.rm=T),
    `Consumer` = sum(dw_max_consumer, na.rm=T),
    `Treasury/Agency` = sum(dw_max_treas_agency, na.rm=T),
    `Agency MBS` = sum(dw_max_mbs_agency, na.rm=T),
    `Municipal` = sum(dw_max_municipal, na.rm=T),
    `Corporate` = sum(dw_max_corporate, na.rm=T)
  ) %>%
  pivot_longer(everything(), names_to = "Type", values_to = "Amount") %>%
  mutate(Share = Amount / sum(Amount)) %>%
  filter(Share > 0.01)

p_coll_type <- bind_rows(
  btfp_agg_type %>% mutate(Facility = "BTFP"),
  dw_agg_type %>% mutate(Facility = "DW")
) %>%
  ggplot(aes(x = reorder(Type, Share), y = Share, fill = Facility)) +
  geom_col(alpha = 0.8, position = "dodge") +
  scale_fill_manual(values = c("BTFP" = "#2A9D8F", "DW" = "#D62828")) +
  scale_y_continuous(labels = percent_format()) +
  coord_flip() +
  labs(
    title = "Collateral Composition: BTFP vs. DW",
    subtitle = "BTFP: all OMO-eligible securities | DW: dominated by loans",
    x = NULL, y = "Share of Total Collateral", fill = NULL
  ) + theme_paper

p_coll_type

save_figure(p_coll_type, "Fig_CollateralComposition_BTFP_vs_DW", width = 12, height = 8)

24.8 Summary Statistics

cat("=== COLLATERAL UTILIZATION: KEY STATISTICS ===\n\n")
## === COLLATERAL UTILIZATION: KEY STATISTICS ===
# Comprehensive summary table
cat("--- By Facility Choice Group ---\n")
## --- By Facility Choice Group ---
df_coll %>%
  filter(any_fed == 1 | (btfp_crisis == 0 & dw_crisis == 0 & fhlb_user == 0)) %>%
  mutate(group = case_when(
    both_fed == 1    ~ "Both",
    btfp_crisis == 1 ~ "BTFP Only",
    dw_crisis == 1   ~ "DW Only",
    TRUE             ~ "Neither"
  )) %>%
  filter(group != "Neither") %>%
  group_by(group) %>%
  summarise(
    N = n(),
    btfp_util_mean = round(mean(btfp_utilization_raw, na.rm=T), 3),
    btfp_util_med  = round(median(btfp_utilization_raw, na.rm=T), 3),
    dw_util_mean   = round(mean(dw_utilization_raw, na.rm=T), 3),
    btfp_n_loans   = round(mean(btfp_n_loans[btfp_n_loans > 0], na.rm=T), 1),
    dw_n_loans     = round(mean(dw_n_loans[dw_n_loans > 0], na.rm=T), 1),
    btfp_adv_rate  = round(mean(btfp_advance_rate, na.rm=T), 3),
    dw_adv_rate    = round(mean(dw_advance_rate, na.rm=T), 3),
    dw_share_omo   = round(mean(dw_share_omo, na.rm=T), 3),
    dw_share_loans = round(mean(dw_share_loans, na.rm=T), 3),
    .groups = "drop"
  ) %>%
  print(width = Inf)
## # A tibble: 3 × 11
##   group         N btfp_util_mean btfp_util_med dw_util_mean btfp_n_loans
##   <chr>     <int>          <dbl>         <dbl>        <dbl>        <dbl>
## 1 BTFP Only   395           1.09         0.967      NaN              2.4
## 2 Both        106           1.05         0.836        0.067          2.9
## 3 DW Only     327         NaN           NA            0.063        NaN  
##   dw_n_loans btfp_adv_rate dw_adv_rate dw_share_omo dw_share_loans
##        <dbl>         <dbl>       <dbl>        <dbl>          <dbl>
## 1      NaN           0.593     NaN          NaN            NaN    
## 2        5           0.49        0.227        0.309          0.501
## 3        3.8       NaN           0.153        0.354          0.418
cat("\n--- Collateral Exhaustion & DW Transition ---\n")
## 
## --- Collateral Exhaustion & DW Transition ---
btfp_b <- df_coll %>% filter(btfp_crisis == 1 & !is.na(btfp_utilization_raw))
n_exhausted <- sum(btfp_b$btfp_utilization_raw > 0.80, na.rm=T)
n_exhausted_also_dw <- sum(btfp_b$btfp_utilization_raw > 0.80 & btfp_b$dw_crisis == 1, na.rm=T)
n_nonexhausted_also_dw <- sum(btfp_b$btfp_utilization_raw <= 0.80 & btfp_b$dw_crisis == 1, na.rm=T)

cat(sprintf("  BTFP borrowers: %d\n", nrow(btfp_b)))
##   BTFP borrowers: 501
cat(sprintf("  Exhausted (util > 80%%): %d (%.1f%%)\n",
    n_exhausted, 100 * n_exhausted / nrow(btfp_b)))
##   Exhausted (util > 80%): 270 (53.9%)
cat(sprintf("  Exhausted → Also DW: %d (%.1f%% of exhausted)\n",
    n_exhausted_also_dw,
    100 * n_exhausted_also_dw / max(n_exhausted, 1)))
##   Exhausted → Also DW: 54 (20.0% of exhausted)
cat(sprintf("  Non-exhausted → Also DW: %d (%.1f%% of non-exhausted)\n",
    n_nonexhausted_also_dw,
    100 * n_nonexhausted_also_dw / max(nrow(btfp_b) - n_exhausted, 1)))
##   Non-exhausted → Also DW: 52 (22.5% of non-exhausted)
if (n_exhausted > 5 & n_exhausted < nrow(btfp_b)) {
  ft <- fisher.test(table(btfp_b$btfp_utilization_raw > 0.80, btfp_b$dw_crisis == 1))
  cat(sprintf("  Fisher exact test (exhaustion → DW): OR=%.2f, p=%.4f\n",
      ft$estimate, ft$p.value))
}
##   Fisher exact test (exhaustion → DW): OR=0.86, p=0.5117
cat("\n--- Advance Rate Gap (Recapitalization) ---\n")
## 
## --- Advance Rate Gap (Recapitalization) ---
btfp_ar <- mean(df_coll$btfp_advance_rate[df_coll$btfp_crisis == 1], na.rm=T)
dw_ar   <- mean(df_coll$dw_advance_rate[df_coll$dw_crisis == 1], na.rm=T)
cat(sprintf("  BTFP mean advance rate: %.3f (close to 1 = par)\n", btfp_ar))
##   BTFP mean advance rate: 0.571 (close to 1 = par)
cat(sprintf("  DW mean advance rate:   %.3f (< 1 = haircut)\n", dw_ar))
##   DW mean advance rate:   0.171 (< 1 = haircut)
cat(sprintf("  Gap: %.3f = %.1f%% recapitalization per $ of collateral\n",
    btfp_ar - dw_ar, 100 * (btfp_ar - dw_ar)))
##   Gap: 0.400 = 40.0% recapitalization per $ of collateral

25 DSSW TABLE A.10 ANALOG: Deposit Fragility (Cols 1–5)

# ==============================================================================
# DSSW TABLE A.10 — EXACT REPLICATION OF COLUMNS 1–5
#
# DSSW regress SVB beta on deposit fragility measures for 171 public banks.
# We replicate their 5-column structure but with DV = emergency borrowing
# and our full sample. "Uninsured share" in DSSW ≡ our uninsured_lev
# (uninsured deposits / total assets).
#
# Col 1: Uninsured leverage only
# Col 2: Uninsured leverage + β^U + (β^U × Uninsured leverage)
# Col 3: (1 − β^U) × Uninsured leverage  [Proposition 4 product]
# Col 4: Uninsured deposit franchise / TA = (1 − β^U) × Uninsured_D / TA
# Col 5: Col 4 + Insured deposit franchise / TA = (1 − β^I) × Insured_D / TA
# ==============================================================================

cat("=== DSSW TABLE A.10 ANALOG (COLS 1–5) ===\n\n")
## === DSSW TABLE A.10 ANALOG (COLS 1–5) ===
# --- Construct DSSW-specific variables ---
add_dssw_a10_vars <- function(df) {
  df %>% mutate(
    # Col 3: (1 − β^U) × Uninsured leverage (raw → winsorize → z)
    one_minus_betaU_x_unins_raw = (1 - uninsured_beta_raw) * uninsured_lev_raw,
    one_minus_betaU_x_unins_w   = winsorize(one_minus_betaU_x_unins_raw),
    one_minus_betaU_x_unins     = standardize_z(one_minus_betaU_x_unins_w),

    # Col 4: Uninsured deposit franchise / TA = (1 − β^U) × Uninsured_D / TA
    # Same economic quantity as Col 3 given our leverage definition;
    # constructed identically for transparency
    unins_franchise_raw = (1 - uninsured_beta_raw) * uninsured_lev_raw,
    unins_franchise_w   = winsorize(unins_franchise_raw),
    unins_franchise     = standardize_z(unins_franchise_w),

    # Col 5: Insured deposit franchise / TA = (1 − β^I) × Insured_D / TA
    ins_franchise_raw = (1 - beta_insured) * insured_lev_raw,
    ins_franchise_w   = winsorize(ins_franchise_raw),
    ins_franchise     = standardize_z(ins_franchise_w)
  )
}

df_anyfed_s <- add_dssw_a10_vars(df_anyfed_s)
df_btfp_s   <- add_dssw_a10_vars(df_btfp_s)
df_dw_s     <- add_dssw_a10_vars(df_dw_s)
df_fhlb_s   <- add_dssw_a10_vars(df_fhlb_s)

# Register labels for new variables
setFixest_dict(c(
  one_minus_betaU_x_unins = "$(1 - \\beta^U) \\times$ Uninsured",
  unins_franchise         = "Uninsured Deposit Franchise",
  ins_franchise           = "Insured Deposit Franchise"
))

# --- Filter to banks with beta coverage ---
df_a10_any  <- df_anyfed_s %>% filter(!is.na(uninsured_beta_w) & !is.na(beta_insured))
df_a10_btfp <- df_btfp_s   %>% filter(!is.na(uninsured_beta_w) & !is.na(beta_insured))
df_a10_dw   <- df_dw_s     %>% filter(!is.na(uninsured_beta_w) & !is.na(beta_insured))
df_a10_fhlb <- df_fhlb_s   %>% filter(!is.na(uninsured_beta_w) & !is.na(beta_insured))

cat(sprintf("  Beta coverage: Any=%d, BTFP=%d, DW=%d, FHLB=%d\n\n",
    nrow(df_a10_any), nrow(df_a10_btfp), nrow(df_a10_dw), nrow(df_a10_fhlb)))
##   Beta coverage: Any=3991, BTFP=3665, DW=3599, FHLB=3468
# --- Specifications matching DSSW Cols 1–5 ---
EXPL_C1 <- "uninsured_lev"
EXPL_C2 <- "uninsured_lev + uninsured_beta + unins_x_unins_beta"
EXPL_C3 <- "one_minus_betaU_x_unins"
EXPL_C4 <- "unins_franchise"
EXPL_C5 <- "unins_franchise + ins_franchise"

# =========================================================================
# Panel A: Any Fed (Cols 1–5)
# =========================================================================
cat("=== Panel A: Any Fed ===\n")
## === Panel A: Any Fed ===
mod_any_c1 <- safe_run(df_a10_any, "any_fed", EXPL_C1)
mod_any_c2 <- safe_run(df_a10_any, "any_fed", EXPL_C2)
mod_any_c3 <- safe_run(df_a10_any, "any_fed", EXPL_C3)
mod_any_c4 <- safe_run(df_a10_any, "any_fed", EXPL_C4)
mod_any_c5 <- safe_run(df_a10_any, "any_fed", EXPL_C5)

models_any_a10 <- list(
  "(1)" = mod_any_c1, "(2)" = mod_any_c2, "(3)" = mod_any_c3,
  "(4)" = mod_any_c4, "(5)" = mod_any_c5)

save_etable(models_any_a10, "DSSW_A10_AnyFed",
  title_text = "DSSW Table A.10 Analog — Any Fed Borrowing (Crisis Period)",
  notes_text = paste0(
    "LPM. DV = 1 if borrowed from any Fed facility, 0 if non-borrower. ",
    "Col~1: uninsured leverage. Col~2: + $\\beta^U$ + $\\beta^U \\times$ uninsured. ",
    "Col~3: $(1-\\beta^U) \\times$ uninsured (Prop.~4). ",
    "Col~4: uninsured deposit franchise$/TA$. Col~5: + insured deposit franchise$/TA$. ",
    "Robust SEs. z-standardized. Controls: log(assets), cash, LTD, book equity, wholesale, ROA."),
  extra_lines = list(
    c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_any_a10[!sapply(models_any_a10, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                      any_fed    any_fed    any_fed    any_fed
##                                                                              
## Constant                           0.2044***  0.2042***  0.2045***  0.2045***
##                                   (0.0060)   (0.0060)   (0.0060)   (0.0060)  
## Uninsured Leverage (z)             0.0114     0.0118                         
##                                   (0.0073)   (0.0073)                        
## Log(Assets)                        0.1106***  0.1102***  0.1124***  0.1124***
##                                   (0.0082)   (0.0083)   (0.0079)   (0.0079)  
## Cash Ratio                        -0.0367*** -0.0370*** -0.0363*** -0.0363***
##                                   (0.0058)   (0.0059)   (0.0059)   (0.0059)  
## Loan-to-Deposit                   -0.0098    -0.0099    -0.0093    -0.0093   
##                                   (0.0070)   (0.0072)   (0.0071)   (0.0071)  
## Book Equity Ratio                 -0.0209*** -0.0209*** -0.0213*** -0.0213***
##                                   (0.0058)   (0.0058)   (0.0058)   (0.0058)  
## Wholesale Funding                  0.0293***  0.0294***  0.0291***  0.0291***
##                                   (0.0070)   (0.0070)   (0.0070)   (0.0070)  
## ROA                               -0.0052    -0.0055    -0.0051    -0.0051   
##                                   (0.0060)   (0.0060)   (0.0060)   (0.0060)  
## Uninsured $\beta$ (z)                         0.0020                         
##                                              (0.0069)                        
## Uninsured $\times$ Unins. $\beta$            -0.0052                         
##                                              (0.0058)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0092              
##                                                         (0.0070)             
## Uninsured Deposit Franchise                                         0.0092   
##                                                                    (0.0070)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,991      3,991      3,991      3,991
## R2                                   0.11479    0.11500    0.11462    0.11462
## 
##                                          (5)
## Dependent Var.:                      any_fed
##                                             
## Constant                           0.2043***
##                                   (0.0060)  
## Uninsured Leverage (z)                      
##                                             
## Log(Assets)                        0.1068***
##                                   (0.0084)  
## Cash Ratio                        -0.0373***
##                                   (0.0059)  
## Loan-to-Deposit                   -0.0135   
##                                   (0.0071)  
## Book Equity Ratio                 -0.0269***
##                                   (0.0067)  
## Wholesale Funding                  0.0270***
##                                   (0.0070)  
## ROA                               -0.0051   
##                                   (0.0060)  
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise       -0.0001   
##                                   (0.0084)  
## Insured Deposit Franchise         -0.0191*  
##                                   (0.0091)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,991
## R2                                   0.11565
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# Panel B: BTFP (Cols 1–5)
# =========================================================================
cat("\n=== Panel B: BTFP ===\n")
## 
## === Panel B: BTFP ===
mod_btfp_c1 <- safe_run(df_a10_btfp, "btfp_crisis", EXPL_C1)
mod_btfp_c2 <- safe_run(df_a10_btfp, "btfp_crisis", EXPL_C2)
mod_btfp_c3 <- safe_run(df_a10_btfp, "btfp_crisis", EXPL_C3)
mod_btfp_c4 <- safe_run(df_a10_btfp, "btfp_crisis", EXPL_C4)
mod_btfp_c5 <- safe_run(df_a10_btfp, "btfp_crisis", EXPL_C5)

models_btfp_a10 <- list(
  "(1)" = mod_btfp_c1, "(2)" = mod_btfp_c2, "(3)" = mod_btfp_c3,
  "(4)" = mod_btfp_c4, "(5)" = mod_btfp_c5)

save_etable(models_btfp_a10, "DSSW_A10_BTFP",
  title_text = "DSSW Table A.10 Analog — BTFP Borrowing (Crisis Period)",
  notes_text = paste0(
    "LPM. DV = 1 if BTFP borrower, 0 if non-borrower. ",
    "Columns match DSSW Table A.10 Cols 1--5. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_btfp_a10[!sapply(models_btfp_a10, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                           (1)         (2)         (3)
## Dependent Var.:                   btfp_crisis btfp_crisis btfp_crisis
##                                                                      
## Constant                            0.1395***   0.1393***   0.1395***
##                                    (0.0055)    (0.0055)    (0.0055)  
## Uninsured Leverage (z)              0.0141*     0.0149*              
##                                    (0.0066)    (0.0066)              
## Log(Assets)                         0.0747***   0.0735***   0.0770***
##                                    (0.0077)    (0.0078)    (0.0075)  
## Cash Ratio                         -0.0384***  -0.0388***  -0.0379***
##                                    (0.0047)    (0.0047)    (0.0047)  
## Loan-to-Deposit                    -0.0154*    -0.0167**   -0.0148*  
##                                    (0.0061)    (0.0062)    (0.0062)  
## Book Equity Ratio                  -0.0186***  -0.0187***  -0.0191***
##                                    (0.0050)    (0.0050)    (0.0050)  
## Wholesale Funding                   0.0262***   0.0264***   0.0260***
##                                    (0.0066)    (0.0066)    (0.0066)  
## ROA                                -0.0087     -0.0089     -0.0085   
##                                    (0.0052)    (0.0052)    (0.0052)  
## Uninsured $\beta$ (z)                           0.0060               
##                                                (0.0062)              
## Uninsured $\times$ Unins. $\beta$              -0.0045               
##                                                (0.0054)              
## $(1 - \beta^U) \times$ Uninsured                            0.0111   
##                                                            (0.0064)  
## Uninsured Deposit Franchise                                          
##                                                                      
## Insured Deposit Franchise                                            
##                                                                      
## _________________________________ ___________ ___________ ___________
## S.E. type                         Heter.-rob. Heter.-rob. Heter.-rob.
## Observations                            3,665       3,665       3,665
## R2                                    0.09062     0.09101     0.09021
## 
##                                           (4)         (5)
## Dependent Var.:                   btfp_crisis btfp_crisis
##                                                          
## Constant                            0.1395***   0.1385***
##                                    (0.0055)    (0.0055)  
## Uninsured Leverage (z)                                   
##                                                          
## Log(Assets)                         0.0770***   0.0686***
##                                    (0.0075)    (0.0078)  
## Cash Ratio                         -0.0379***  -0.0392***
##                                    (0.0047)    (0.0047)  
## Loan-to-Deposit                    -0.0148*    -0.0207***
##                                    (0.0062)    (0.0062)  
## Book Equity Ratio                  -0.0191***  -0.0275***
##                                    (0.0050)    (0.0059)  
## Wholesale Funding                   0.0260***   0.0230***
##                                    (0.0066)    (0.0066)  
## ROA                                -0.0085     -0.0085   
##                                    (0.0052)    (0.0052)  
## Uninsured $\beta$ (z)                                    
##                                                          
## Uninsured $\times$ Unins. $\beta$                        
##                                                          
## $(1 - \beta^U) \times$ Uninsured                         
##                                                          
## Uninsured Deposit Franchise         0.0111     -0.0027   
##                                    (0.0064)    (0.0077)  
## Insured Deposit Franchise                      -0.0277***
##                                                (0.0082)  
## _________________________________ ___________ ___________
## S.E. type                         Heter.-rob. Heter.-rob.
## Observations                            3,665       3,665
## R2                                    0.09021     0.09323
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# Panel C: DW (Cols 1–5)
# =========================================================================
cat("\n=== Panel C: DW ===\n")
## 
## === Panel C: DW ===
mod_dw_c1 <- safe_run(df_a10_dw, "dw_crisis", EXPL_C1)
mod_dw_c2 <- safe_run(df_a10_dw, "dw_crisis", EXPL_C2)
mod_dw_c3 <- safe_run(df_a10_dw, "dw_crisis", EXPL_C3)
mod_dw_c4 <- safe_run(df_a10_dw, "dw_crisis", EXPL_C4)
mod_dw_c5 <- safe_run(df_a10_dw, "dw_crisis", EXPL_C5)

models_dw_a10 <- list(
  "(1)" = mod_dw_c1, "(2)" = mod_dw_c2, "(3)" = mod_dw_c3,
  "(4)" = mod_dw_c4, "(5)" = mod_dw_c5)

save_etable(models_dw_a10, "DSSW_A10_DW",
  title_text = "DSSW Table A.10 Analog — DW Borrowing (Crisis Period)",
  notes_text = paste0(
    "LPM. DV = 1 if DW borrower, 0 if non-borrower. ",
    "Columns match DSSW Table A.10 Cols 1--5. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_dw_a10[!sapply(models_dw_a10, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                    dw_crisis  dw_crisis  dw_crisis  dw_crisis
##                                                                              
## Constant                           0.1241***  0.1241***  0.1240***  0.1240***
##                                   (0.0053)   (0.0053)   (0.0053)   (0.0053)  
## Uninsured Leverage (z)             0.0058     0.0056                         
##                                   (0.0063)   (0.0063)                        
## Log(Assets)                        0.0945***  0.0949***  0.0958***  0.0958***
##                                   (0.0077)   (0.0078)   (0.0076)   (0.0076)  
## Cash Ratio                        -0.0098*   -0.0098    -0.0095    -0.0095   
##                                   (0.0050)   (0.0050)   (0.0050)   (0.0050)  
## Loan-to-Deposit                   -0.0042    -0.0038    -0.0042    -0.0042   
##                                   (0.0060)   (0.0061)   (0.0061)   (0.0061)  
## Book Equity Ratio                 -0.0050    -0.0050    -0.0053    -0.0053   
##                                   (0.0047)   (0.0047)   (0.0047)   (0.0047)  
## Wholesale Funding                  0.0204**   0.0204**   0.0203**   0.0203** 
##                                   (0.0064)   (0.0064)   (0.0064)   (0.0064)  
## ROA                               -0.0034    -0.0034    -0.0033    -0.0033   
##                                   (0.0051)   (0.0051)   (0.0051)   (0.0051)  
## Uninsured $\beta$ (z)                        -0.0017                         
##                                              (0.0060)                        
## Uninsured $\times$ Unins. $\beta$             0.0007                         
##                                              (0.0052)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0038              
##                                                         (0.0061)             
## Uninsured Deposit Franchise                                         0.0038   
##                                                                    (0.0061)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,599      3,599      3,599      3,599
## R2                                   0.09909    0.09912    0.09897    0.09897
## 
##                                          (5)
## Dependent Var.:                    dw_crisis
##                                             
## Constant                           0.1239***
##                                   (0.0053)  
## Uninsured Leverage (z)                      
##                                             
## Log(Assets)                        0.0942***
##                                   (0.0079)  
## Cash Ratio                        -0.0097   
##                                   (0.0050)  
## Loan-to-Deposit                   -0.0054   
##                                   (0.0061)  
## Book Equity Ratio                 -0.0070   
##                                   (0.0056)  
## Wholesale Funding                  0.0197** 
##                                   (0.0064)  
## ROA                               -0.0033   
##                                   (0.0051)  
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise        0.0010   
##                                   (0.0076)  
## Insured Deposit Franchise         -0.0056   
##                                   (0.0081)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,599
## R2                                   0.09911
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# Panel D: FHLB — Falsification (Cols 1–5)
# =========================================================================
cat("\n=== Panel D: FHLB (Falsification) ===\n")
## 
## === Panel D: FHLB (Falsification) ===
mod_fhlb_c1 <- safe_run(df_a10_fhlb, "fhlb_user", EXPL_C1)
mod_fhlb_c2 <- safe_run(df_a10_fhlb, "fhlb_user", EXPL_C2)
mod_fhlb_c3 <- safe_run(df_a10_fhlb, "fhlb_user", EXPL_C3)
mod_fhlb_c4 <- safe_run(df_a10_fhlb, "fhlb_user", EXPL_C4)
mod_fhlb_c5 <- safe_run(df_a10_fhlb, "fhlb_user", EXPL_C5)

models_fhlb_a10 <- list(
  "(1)" = mod_fhlb_c1, "(2)" = mod_fhlb_c2, "(3)" = mod_fhlb_c3,
  "(4)" = mod_fhlb_c4, "(5)" = mod_fhlb_c5)

save_etable(models_fhlb_a10, "DSSW_A10_FHLB",
  title_text = "DSSW Table A.10 Analog — FHLB Falsification (Crisis Period)",
  notes_text = paste0(
    "LPM. DV = 1 if abnormal FHLB borrower, 0 if non-borrower. Falsification test. ",
    "Columns match DSSW Table A.10 Cols 1--5. Robust SEs. z-standardized."),
  extra_lines = list(
    c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_fhlb_a10[!sapply(models_fhlb_a10, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                    fhlb_user  fhlb_user  fhlb_user  fhlb_user
##                                                                              
## Constant                           0.0906***  0.0907***  0.0905***  0.0905***
##                                   (0.0049)   (0.0049)   (0.0049)   (0.0049)  
## Uninsured Leverage (z)             0.0068     0.0082                         
##                                   (0.0050)   (0.0050)                        
## Log(Assets)                        0.0285***  0.0255***  0.0318***  0.0318***
##                                   (0.0065)   (0.0066)   (0.0065)   (0.0065)  
## Cash Ratio                        -0.0226*** -0.0222*** -0.0216*** -0.0216***
##                                   (0.0034)   (0.0034)   (0.0034)   (0.0034)  
## Loan-to-Deposit                    0.0249***  0.0209***  0.0242***  0.0242***
##                                   (0.0052)   (0.0052)   (0.0052)   (0.0052)  
## Book Equity Ratio                  0.0083     0.0081     0.0073     0.0073   
##                                   (0.0045)   (0.0044)   (0.0045)   (0.0045)  
## Wholesale Funding                  0.0019     0.0025     0.0014     0.0014   
##                                   (0.0051)   (0.0051)   (0.0052)   (0.0052)  
## ROA                               -0.0115*   -0.0107*   -0.0108*   -0.0108*  
##                                   (0.0045)   (0.0045)   (0.0045)   (0.0045)  
## Uninsured $\beta$ (z)                         0.0132*                        
##                                              (0.0056)                        
## Uninsured $\times$ Unins. $\beta$             0.0043                         
##                                              (0.0044)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0002              
##                                                         (0.0047)             
## Uninsured Deposit Franchise                                         0.0002   
##                                                                    (0.0047)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,468      3,468      3,468      3,468
## R2                                   0.04024    0.04259    0.03983    0.03983
## 
##                                          (5)
## Dependent Var.:                    fhlb_user
##                                             
## Constant                           0.0902***
##                                   (0.0049)  
## Uninsured Leverage (z)                      
##                                             
## Log(Assets)                        0.0283***
##                                   (0.0067)  
## Cash Ratio                        -0.0221***
##                                   (0.0034)  
## Loan-to-Deposit                    0.0216***
##                                   (0.0052)  
## Book Equity Ratio                  0.0037   
##                                   (0.0054)  
## Wholesale Funding                  0.0003   
##                                   (0.0053)  
## ROA                               -0.0107*  
##                                   (0.0045)  
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise       -0.0057   
##                                   (0.0061)  
## Insured Deposit Franchise         -0.0118   
##                                   (0.0069)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,468
## R2                                   0.04066
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# COMPACT TABLE: Col 2 across all facilities (key specification)
# =========================================================================
cat("\n=== Compact: Col 2 (Key Spec) Across Facilities ===\n")
## 
## === Compact: Col 2 (Key Spec) Across Facilities ===
models_c2_compact <- list(
  "Any Fed" = mod_any_c2, "BTFP" = mod_btfp_c2,
  "DW" = mod_dw_c2, "FHLB" = mod_fhlb_c2)

save_etable(models_c2_compact, "DSSW_A10_Col2_compact",
  title_text = "DSSW Col 2 Analog: $\\beta^U \\times$ Uninsured Across Facilities",
  notes_text = paste0(
    "LPM. Specification: Uninsured + $\\beta^U$ + ($\\beta^U \\times$ Uninsured) + Controls. ",
    "FHLB: falsification. Robust SEs. z-standardized."))

etable(models_c2_compact[!sapply(models_c2_compact, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                      Any Fed        BTFP         DW       FHLB
## Dependent Var.:                      any_fed btfp_crisis  dw_crisis  fhlb_user
##                                                                               
## Constant                           0.2042***   0.1393***  0.1241***  0.0907***
##                                   (0.0060)    (0.0055)   (0.0053)   (0.0049)  
## Uninsured Leverage (z)             0.0118      0.0149*    0.0056     0.0082   
##                                   (0.0073)    (0.0066)   (0.0063)   (0.0050)  
## Uninsured $\beta$ (z)              0.0020      0.0060    -0.0017     0.0132*  
##                                   (0.0069)    (0.0062)   (0.0060)   (0.0056)  
## Uninsured $\times$ Unins. $\beta$ -0.0052     -0.0045     0.0007     0.0043   
##                                   (0.0058)    (0.0054)   (0.0052)   (0.0044)  
## Log(Assets)                        0.1102***   0.0735***  0.0949***  0.0255***
##                                   (0.0083)    (0.0078)   (0.0078)   (0.0066)  
## Cash Ratio                        -0.0370***  -0.0388*** -0.0098    -0.0222***
##                                   (0.0059)    (0.0047)   (0.0050)   (0.0034)  
## Loan-to-Deposit                   -0.0099     -0.0167**  -0.0038     0.0209***
##                                   (0.0072)    (0.0062)   (0.0061)   (0.0052)  
## Book Equity Ratio                 -0.0209***  -0.0187*** -0.0050     0.0081   
##                                   (0.0058)    (0.0050)   (0.0047)   (0.0044)  
## Wholesale Funding                  0.0294***   0.0264***  0.0204**   0.0025   
##                                   (0.0070)    (0.0066)   (0.0064)   (0.0051)  
## ROA                               -0.0055     -0.0089    -0.0034    -0.0107*  
##                                   (0.0060)    (0.0052)   (0.0051)   (0.0045)  
## _________________________________ __________ ___________ __________ __________
## S.E. type                         Hete.-rob. Heter.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,991       3,665      3,599      3,468
## R2                                   0.11500     0.09101    0.09912    0.04259
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

25.1 DSSW A.10 — No Controls

# ==============================================================================
# DSSW TABLE A.10 — NO CONTROLS
# DSSW Table A.10 does not include bank-level controls.
# This chunk replicates Cols 1–5 without controls for direct comparison.
# ==============================================================================

cat("=== DSSW TABLE A.10 — NO CONTROLS ===\n\n")
## === DSSW TABLE A.10 — NO CONTROLS ===
NO_CTRL <- "1"  # intercept only (no additional controls)

# --- Specifications (same RHS, no controls) ---
run_nc <- function(data, dv, expl) {
  ff <- as.formula(paste(dv, "~", expl))
  feols(ff, data = data, vcov = "hetero")
}

safe_run_nc <- function(data, dv, expl, min_n = 30, min_dv1 = 5) {
  n_obs <- sum(!is.na(data[[dv]]))
  n_dv1 <- sum(data[[dv]] == 1, na.rm = TRUE)
  if (n_obs < min_n || n_dv1 < min_dv1) {
    message("  Skip: N=", n_obs, " DV=1:", n_dv1, " for ", dv)
    return(NULL)
  }
  tryCatch(run_nc(data, dv, expl),
    error = function(e) { message("  Error: ", e$message); NULL })
}

# --- Any Fed (Cols 1–5, no controls) ---
cat("=== Panel A: Any Fed (No Controls) ===\n")
## === Panel A: Any Fed (No Controls) ===
nc_any_c1 <- safe_run_nc(df_a10_any, "any_fed", "uninsured_lev")
nc_any_c2 <- safe_run_nc(df_a10_any, "any_fed", "uninsured_lev + uninsured_beta + unins_x_unins_beta")
nc_any_c3 <- safe_run_nc(df_a10_any, "any_fed", "one_minus_betaU_x_unins")
nc_any_c4 <- safe_run_nc(df_a10_any, "any_fed", "unins_franchise")
nc_any_c5 <- safe_run_nc(df_a10_any, "any_fed", "unins_franchise + ins_franchise")

models_nc_any <- list(
  "(1)" = nc_any_c1, "(2)" = nc_any_c2, "(3)" = nc_any_c3,
  "(4)" = nc_any_c4, "(5)" = nc_any_c5)

save_etable(models_nc_any, "DSSW_A10_AnyFed_nocontrols",
  title_text = "DSSW Table A.10 Analog — Any Fed, No Controls",
  notes_text = paste0(
    "LPM. No controls (exact DSSW specification). ",
    "Col~1: uninsured leverage. Col~2: + $\\beta^U$ + $\\beta^U \\times$ uninsured. ",
    "Col~3: $(1-\\beta^U) \\times$ uninsured. ",
    "Col~4: uninsured franchise$/TA$. Col~5: + insured franchise$/TA$. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_nc_any[!sapply(models_nc_any, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                      any_fed    any_fed    any_fed    any_fed
##                                                                              
## Constant                           0.2052***  0.2055***  0.2060***  0.2060***
##                                   (0.0063)   (0.0063)   (0.0064)   (0.0064)  
## Uninsured Leverage (z)             0.0595***  0.0612***                      
##                                   (0.0064)   (0.0064)                        
## Uninsured $\beta$ (z)                         0.0299***                      
##                                              (0.0067)                        
## Uninsured $\times$ Unins. $\beta$            -0.0052                         
##                                              (0.0059)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0467***           
##                                                         (0.0065)             
## Uninsured Deposit Franchise                                         0.0467***
##                                                                    (0.0065)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,991      3,991      3,991      3,991
## R2                                   0.02143    0.02654    0.01333    0.01333
## 
##                                          (5)
## Dependent Var.:                      any_fed
##                                             
## Constant                           0.2060***
##                                   (0.0063)  
## Uninsured Leverage (z)                      
##                                             
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise        0.0179*  
##                                   (0.0076)  
## Insured Deposit Franchise         -0.0565***
##                                   (0.0077)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,991
## R2                                   0.02778
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# --- BTFP (Cols 1–5, no controls) ---
cat("\n=== Panel B: BTFP (No Controls) ===\n")
## 
## === Panel B: BTFP (No Controls) ===
nc_btfp_c1 <- safe_run_nc(df_a10_btfp, "btfp_crisis", "uninsured_lev")
nc_btfp_c2 <- safe_run_nc(df_a10_btfp, "btfp_crisis", "uninsured_lev + uninsured_beta + unins_x_unins_beta")
nc_btfp_c3 <- safe_run_nc(df_a10_btfp, "btfp_crisis", "one_minus_betaU_x_unins")
nc_btfp_c4 <- safe_run_nc(df_a10_btfp, "btfp_crisis", "unins_franchise")
nc_btfp_c5 <- safe_run_nc(df_a10_btfp, "btfp_crisis", "unins_franchise + ins_franchise")

models_nc_btfp <- list(
  "(1)" = nc_btfp_c1, "(2)" = nc_btfp_c2, "(3)" = nc_btfp_c3,
  "(4)" = nc_btfp_c4, "(5)" = nc_btfp_c5)

save_etable(models_nc_btfp, "DSSW_A10_BTFP_nocontrols",
  title_text = "DSSW Table A.10 Analog — BTFP, No Controls",
  notes_text = "LPM. No controls. Cols 1--5 match DSSW Table A.10. Robust SEs. z-standardized.",
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_nc_btfp[!sapply(models_nc_btfp, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                           (1)         (2)         (3)
## Dependent Var.:                   btfp_crisis btfp_crisis btfp_crisis
##                                                                      
## Constant                            0.1358***   0.1363***   0.1353***
##                                    (0.0056)    (0.0056)    (0.0056)  
## Uninsured Leverage (z)              0.0447***   0.0460***            
##                                    (0.0058)    (0.0058)              
## Uninsured $\beta$ (z)                           0.0227***            
##                                                (0.0061)              
## Uninsured $\times$ Unins. $\beta$              -0.0035               
##                                                (0.0055)              
## $(1 - \beta^U) \times$ Uninsured                            0.0356***
##                                                            (0.0058)  
## Uninsured Deposit Franchise                                          
##                                                                      
## Insured Deposit Franchise                                            
##                                                                      
## _________________________________ ___________ ___________ ___________
## S.E. type                         Heter.-rob. Heter.-rob. Heter.-rob.
## Observations                            3,665       3,665       3,665
## R2                                    0.01685     0.02094     0.01081
## 
##                                           (4)         (5)
## Dependent Var.:                   btfp_crisis btfp_crisis
##                                                          
## Constant                            0.1353***   0.1353***
##                                    (0.0056)    (0.0056)  
## Uninsured Leverage (z)                                   
##                                                          
## Uninsured $\beta$ (z)                                    
##                                                          
## Uninsured $\times$ Unins. $\beta$                        
##                                                          
## $(1 - \beta^U) \times$ Uninsured                         
##                                                          
## Uninsured Deposit Franchise         0.0356***   0.0140*  
##                                    (0.0058)    (0.0068)  
## Insured Deposit Franchise                      -0.0423***
##                                                (0.0069)  
## _________________________________ ___________ ___________
## S.E. type                         Heter.-rob. Heter.-rob.
## Observations                            3,665       3,665
## R2                                    0.01081     0.02210
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# --- DW (Cols 1–5, no controls) ---
cat("\n=== Panel C: DW (No Controls) ===\n")
## 
## === Panel C: DW (No Controls) ===
nc_dw_c1 <- safe_run_nc(df_a10_dw, "dw_crisis", "uninsured_lev")
nc_dw_c2 <- safe_run_nc(df_a10_dw, "dw_crisis", "uninsured_lev + uninsured_beta + unins_x_unins_beta")
nc_dw_c3 <- safe_run_nc(df_a10_dw, "dw_crisis", "one_minus_betaU_x_unins")
nc_dw_c4 <- safe_run_nc(df_a10_dw, "dw_crisis", "unins_franchise")
nc_dw_c5 <- safe_run_nc(df_a10_dw, "dw_crisis", "unins_franchise + ins_franchise")

models_nc_dw <- list(
  "(1)" = nc_dw_c1, "(2)" = nc_dw_c2, "(3)" = nc_dw_c3,
  "(4)" = nc_dw_c4, "(5)" = nc_dw_c5)

save_etable(models_nc_dw, "DSSW_A10_DW_nocontrols",
  title_text = "DSSW Table A.10 Analog — DW, No Controls",
  notes_text = "LPM. No controls. Cols 1--5 match DSSW Table A.10. Robust SEs. z-standardized.",
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_nc_dw[!sapply(models_nc_dw, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                    dw_crisis  dw_crisis  dw_crisis  dw_crisis
##                                                                              
## Constant                           0.1199***  0.1206***  0.1195***  0.1195***
##                                   (0.0054)   (0.0054)   (0.0054)   (0.0054)  
## Uninsured Leverage (z)             0.0459***  0.0470***                      
##                                   (0.0057)   (0.0057)                        
## Uninsured $\beta$ (z)                         0.0219***                      
##                                              (0.0058)                        
## Uninsured $\times$ Unins. $\beta$             0.0014                         
##                                              (0.0054)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0349***           
##                                                         (0.0057)             
## Uninsured Deposit Franchise                                         0.0349***
##                                                                    (0.0057)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,599      3,599      3,599      3,599
## R2                                   0.01998    0.02463    0.01159    0.01159
## 
##                                          (5)
## Dependent Var.:                    dw_crisis
##                                             
## Constant                           0.1195***
##                                   (0.0053)  
## Uninsured Leverage (z)                      
##                                             
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise        0.0120   
##                                   (0.0066)  
## Insured Deposit Franchise         -0.0449***
##                                   (0.0068)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,599
## R2                                   0.02577
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# --- FHLB Falsification (Cols 1–5, no controls) ---
cat("\n=== Panel D: FHLB Falsification (No Controls) ===\n")
## 
## === Panel D: FHLB Falsification (No Controls) ===
nc_fhlb_c1 <- safe_run_nc(df_a10_fhlb, "fhlb_user", "uninsured_lev")
nc_fhlb_c2 <- safe_run_nc(df_a10_fhlb, "fhlb_user", "uninsured_lev + uninsured_beta + unins_x_unins_beta")
nc_fhlb_c3 <- safe_run_nc(df_a10_fhlb, "fhlb_user", "one_minus_betaU_x_unins")
nc_fhlb_c4 <- safe_run_nc(df_a10_fhlb, "fhlb_user", "unins_franchise")
nc_fhlb_c5 <- safe_run_nc(df_a10_fhlb, "fhlb_user", "unins_franchise + ins_franchise")

models_nc_fhlb <- list(
  "(1)" = nc_fhlb_c1, "(2)" = nc_fhlb_c2, "(3)" = nc_fhlb_c3,
  "(4)" = nc_fhlb_c4, "(5)" = nc_fhlb_c5)

save_etable(models_nc_fhlb, "DSSW_A10_FHLB_nocontrols",
  title_text = "DSSW Table A.10 Analog — FHLB Falsification, No Controls",
  notes_text = "LPM. No controls. Falsification test. Cols 1--5 match DSSW Table A.10. Robust SEs. z-standardized.",
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

etable(models_nc_fhlb[!sapply(models_nc_fhlb, is.null)],
       fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                    fhlb_user  fhlb_user  fhlb_user  fhlb_user
##                                                                              
## Constant                           0.0868***  0.0877***  0.0862***  0.0862***
##                                   (0.0048)   (0.0048)   (0.0048)   (0.0048)  
## Uninsured Leverage (z)             0.0130**   0.0142**                       
##                                   (0.0048)   (0.0048)                        
## Uninsured $\beta$ (z)                         0.0300***                      
##                                              (0.0053)                        
## Uninsured $\times$ Unins. $\beta$             0.0069                         
##                                              (0.0045)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0016              
##                                                         (0.0044)             
## Uninsured Deposit Franchise                                         0.0016   
##                                                                    (0.0044)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,468      3,468      3,468      3,468
## R2                                   0.00206    0.01506    3.08e-5    3.08e-5
## 
##                                          (5)
## Dependent Var.:                    fhlb_user
##                                             
## Constant                           0.0862***
##                                   (0.0047)  
## Uninsured Leverage (z)                      
##                                             
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise       -0.0172** 
##                                   (0.0053)  
## Insured Deposit Franchise         -0.0368***
##                                   (0.0057)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,468
## R2                                   0.01275
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

25.2 DSSW A.10 — Exact DV: SVB Beta (Stock Return, Mar 6–13, 2023)

# ==============================================================================
# DSSW TABLE A.10 — EXACT REPLICATION WITH SVB BETA AS DV
#
# DSSW's DV is "SVB beta" = a bank's cumulative stock return during the
# SVB crisis window (March 6 to March 13, 2023). This is only available
# for publicly traded banks.
#
# We load daily CRSP returns, compute SVB beta as the cumulative return
# over this window, merge into our cross-section, and run Cols 1–5
# with NO controls (exact DSSW specification).
#
# Panel A: Public banks (have stock returns)
# Panel B: Non-public banks → cannot compute SVB beta (no stock data)
#          Instead, we use our borrowing DV for non-public banks as a
#          comparison to show the deposit fragility channel operates
#          even without equity market signaling.
# ==============================================================================

cat("=== DSSW TABLE A.10 — SVB BETA AS DV ===\n\n")
## === DSSW TABLE A.10 — SVB BETA AS DV ===
# --- Load daily stock returns ---
df_stock <- read_csv(file.path(DATA_PROC, "df_public_bank.csv"), show_col_types = FALSE) %>%
  mutate(idrssd = as.character(rssd_bank),
         DlyCalDt = as.Date(DlyCalDt),
         ret = as.numeric(ret))

# --- Compute SVB beta = cumulative return (product of 1+r) from Mar 6–13, 2023 ---
svb_window <- df_stock %>%
  filter(DlyCalDt >= as.Date("2023-03-06") & DlyCalDt <= as.Date("2023-03-13")) %>%
  group_by(idrssd) %>%
  summarise(
    n_days = n(),
    svb_beta_raw = prod(1 + ret, na.rm = TRUE) - 1,
    .groups = "drop"
  ) %>%
  filter(n_days >= 4)  # require at least 4 of 6 trading days

cat(sprintf("  SVB beta computed for %d public banks\n", nrow(svb_window)))
##   SVB beta computed for 1235 public banks
cat(sprintf("  Mean SVB beta: %.4f (%.2f%%)\n", mean(svb_window$svb_beta_raw), mean(svb_window$svb_beta_raw) * 100))
##   Mean SVB beta: -0.1781 (-17.81%)
cat(sprintf("  SD: %.4f | Min: %.4f | Max: %.4f\n",
    sd(svb_window$svb_beta_raw), min(svb_window$svb_beta_raw), max(svb_window$svb_beta_raw)))
##   SD: 0.1081 | Min: -0.8616 | Max: -0.0122
# --- Merge SVB beta into crisis cross-section ---
df_crisis_svb <- df_crisis %>%
  inner_join(svb_window %>% select(idrssd, svb_beta_raw), by = "idrssd") %>%
  filter(!is.na(uninsured_beta_w) & !is.na(beta_insured))

# Add DSSW A.10 variables (already added to df_*_s but df_crisis may not have them)
df_crisis_svb <- df_crisis_svb %>% mutate(
  one_minus_betaU_x_unins_raw = (1 - uninsured_beta_raw) * uninsured_lev_raw,
  one_minus_betaU_x_unins_w   = winsorize(one_minus_betaU_x_unins_raw),
  one_minus_betaU_x_unins     = standardize_z(one_minus_betaU_x_unins_w),
  unins_franchise_raw = (1 - uninsured_beta_raw) * uninsured_lev_raw,
  unins_franchise_w   = winsorize(unins_franchise_raw),
  unins_franchise     = standardize_z(unins_franchise_w),
  ins_franchise_raw   = (1 - beta_insured) * insured_lev_raw,
  ins_franchise_w     = winsorize(ins_franchise_raw),
  ins_franchise       = standardize_z(ins_franchise_w)
)

cat(sprintf("  Merged sample: %d public banks with SVB beta + deposit betas\n", nrow(df_crisis_svb)))
##   Merged sample: 265 public banks with SVB beta + deposit betas
# =========================================================================
# Panel A: SVB Beta as DV — Public Banks (Exact DSSW Replication)
# =========================================================================
cat("\n=== Panel A: SVB Beta (Public Banks, No Controls) ===\n")
## 
## === Panel A: SVB Beta (Public Banks, No Controls) ===
# SVB beta is continuous — use run_nc directly (safe_run_nc checks DV==1 count)
svb_c1 <- tryCatch(run_nc(df_crisis_svb, "svb_beta_raw", "uninsured_lev"), error = function(e) NULL)
svb_c2 <- tryCatch(run_nc(df_crisis_svb, "svb_beta_raw", "uninsured_lev + uninsured_beta + unins_x_unins_beta"), error = function(e) NULL)
svb_c3 <- tryCatch(run_nc(df_crisis_svb, "svb_beta_raw", "one_minus_betaU_x_unins"), error = function(e) NULL)
svb_c4 <- tryCatch(run_nc(df_crisis_svb, "svb_beta_raw", "unins_franchise"), error = function(e) NULL)
svb_c5 <- tryCatch(run_nc(df_crisis_svb, "svb_beta_raw", "unins_franchise + ins_franchise"), error = function(e) NULL)

models_svb_beta <- list(
  "(1)" = svb_c1, "(2)" = svb_c2, "(3)" = svb_c3,
  "(4)" = svb_c4, "(5)" = svb_c5)

save_etable(models_svb_beta, "DSSW_A10_SVBbeta_public",
  title_text = "DSSW Table A.10 Replication: SVB Beta as DV (Public Banks, No Controls)",
  notes_text = paste0(
    "OLS. DV = SVB beta (cumulative stock return, March 6--13, 2023). ",
    "Public banks only. No controls (exact DSSW specification). ",
    "Col~1: uninsured leverage. Col~2: + $\\beta^U$ + $\\beta^U \\times$ uninsured. ",
    "Col~3: $(1-\\beta^U) \\times$ uninsured. ",
    "Col~4: uninsured franchise$/TA$. Col~5: + insured franchise$/TA$. ",
    "Robust SEs. z-standardized."),
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

models_svb_beta_ok <- models_svb_beta[!sapply(models_svb_beta, is.null)]
if (length(models_svb_beta_ok) > 0) etable(models_svb_beta_ok, fitstat = ~ n + r2, se.below = TRUE)
##                                            (1)          (2)          (3)
## Dependent Var.:                   svb_beta_raw svb_beta_raw svb_beta_raw
##                                                                         
## Constant                            -0.1394***   -0.1285***   -0.1644***
##                                     (0.0054)     (0.0057)     (0.0051)  
## Uninsured Leverage (z)              -0.0314***   -0.0364***             
##                                     (0.0067)     (0.0071)               
## Uninsured $\beta$ (z)                            -0.0233***             
##                                                  (0.0046)               
## Uninsured $\times$ Unins. $\beta$                 0.0075                
##                                                  (0.0041)               
## $(1 - \beta^U) \times$ Uninsured                              -0.0175** 
##                                                               (0.0066)  
## Uninsured Deposit Franchise                                             
##                                                                         
## Insured Deposit Franchise                                               
##                                                                         
## _________________________________ ____________ ____________ ____________
## S.E. type                         Hetero.-rob. Hetero.-rob. Hetero.-rob.
## Observations                               265          265          265
## R2                                     0.11414      0.18345      0.04370
## 
##                                            (4)          (5)
## Dependent Var.:                   svb_beta_raw svb_beta_raw
##                                                            
## Constant                            -0.1644***   -0.1644***
##                                     (0.0051)     (0.0045)  
## Uninsured Leverage (z)                                     
##                                                            
## Uninsured $\beta$ (z)                                      
##                                                            
## Uninsured $\times$ Unins. $\beta$                          
##                                                            
## $(1 - \beta^U) \times$ Uninsured                           
##                                                            
## Uninsured Deposit Franchise         -0.0175**    -0.0067   
##                                     (0.0066)     (0.0059)  
## Insured Deposit Franchise                         0.0379***
##                                                  (0.0062)  
## _________________________________ ____________ ____________
## S.E. type                         Hetero.-rob. Hetero.-rob.
## Observations                               265          265
## R2                                     0.04370      0.23105
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# Panel A.v2: SVB Beta as DV — Deduplicated to 1 Bank per BHC
#
# Panel A assigns the SAME stock return (SVB beta) to every subsidiary
# under a BHC (rssd_top). E.g., Wintrust (WTFC) has 15 subs sharing
# identical SVB beta. This inflates N and biases inference.
#
# Fix: keep only the LARGEST subsidiary (by total_asset) per BHC.
# This gives one independent stock return per publicly traded entity.
# =========================================================================
cat("\n=== Panel A.v2: SVB Beta — Deduplicated (1 Bank per BHC) ===\n")
## 
## === Panel A.v2: SVB Beta — Deduplicated (1 Bank per BHC) ===
# Bring rssd_top into the merged data from the stock file
rssd_top_map <- df_stock %>%
  distinct(idrssd, rssd_top = as.character(rssd_top))

df_crisis_svb_dedup <- df_crisis_svb %>%
  left_join(rssd_top_map, by = "idrssd") %>%
  group_by(rssd_top) %>%
  slice_max(order_by = total_asset, n = 1, with_ties = FALSE) %>%
  ungroup()

cat(sprintf("  Before dedup: %d banks (%d unique BHCs)\n",
    nrow(df_crisis_svb), n_distinct(df_crisis_svb %>% left_join(rssd_top_map, by = "idrssd") %>% pull(rssd_top))))
##   Before dedup: 265 banks (234 unique BHCs)
cat(sprintf("  After dedup:  %d banks (1 per BHC)\n", nrow(df_crisis_svb_dedup)))
##   After dedup:  234 banks (1 per BHC)
svb2_c1 <- tryCatch(run_nc(df_crisis_svb_dedup, "svb_beta_raw", "uninsured_lev"), error = function(e) NULL)
svb2_c2 <- tryCatch(run_nc(df_crisis_svb_dedup, "svb_beta_raw", "uninsured_lev + uninsured_beta + unins_x_unins_beta"), error = function(e) NULL)
svb2_c3 <- tryCatch(run_nc(df_crisis_svb_dedup, "svb_beta_raw", "one_minus_betaU_x_unins"), error = function(e) NULL)
svb2_c4 <- tryCatch(run_nc(df_crisis_svb_dedup, "svb_beta_raw", "unins_franchise"), error = function(e) NULL)
svb2_c5 <- tryCatch(run_nc(df_crisis_svb_dedup, "svb_beta_raw", "unins_franchise + ins_franchise"), error = function(e) NULL)

models_svb_dedup <- list(
  "(1)" = svb2_c1, "(2)" = svb2_c2, "(3)" = svb2_c3,
  "(4)" = svb2_c4, "(5)" = svb2_c5)

save_etable(models_svb_dedup, "DSSW_A10_SVBbeta_public_dedup",
  title_text = "DSSW Table A.10 Replication: SVB Beta — Deduplicated (1 Bank per BHC)",
  notes_text = paste0(
    "OLS. DV = SVB beta (cumulative stock return, March 6--13, 2023). ",
    "Public banks only, largest subsidiary per BHC (rssd\\_top). ",
    "Eliminates duplicate stock returns from multi-charter BHCs. ",
    "No controls (exact DSSW specification). Robust SEs. z-standardized."),
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

models_svb_dedup_ok <- models_svb_dedup[!sapply(models_svb_dedup, is.null)]
if (length(models_svb_dedup_ok) > 0) etable(models_svb_dedup_ok, fitstat = ~ n + r2, se.below = TRUE)
##                                            (1)          (2)          (3)
## Dependent Var.:                   svb_beta_raw svb_beta_raw svb_beta_raw
##                                                                         
## Constant                            -0.1318***   -0.1213***   -0.1616***
##                                     (0.0062)     (0.0061)     (0.0055)  
## Uninsured Leverage (z)              -0.0369***   -0.0423***             
##                                     (0.0077)     (0.0077)               
## Uninsured $\beta$ (z)                            -0.0237***             
##                                                  (0.0050)               
## Uninsured $\times$ Unins. $\beta$                 0.0091*               
##                                                  (0.0044)               
## $(1 - \beta^U) \times$ Uninsured                              -0.0211** 
##                                                               (0.0075)  
## Uninsured Deposit Franchise                                             
##                                                                         
## Insured Deposit Franchise                                               
##                                                                         
## _________________________________ ____________ ____________ ____________
## S.E. type                         Hetero.-rob. Hetero.-rob. Hetero.-rob.
## Observations                               234          234          234
## R2                                     0.13742      0.20097      0.05631
## 
##                                            (4)          (5)
## Dependent Var.:                   svb_beta_raw svb_beta_raw
##                                                            
## Constant                            -0.1616***   -0.1626***
##                                     (0.0055)     (0.0050)  
## Uninsured Leverage (z)                                     
##                                                            
## Uninsured $\beta$ (z)                                      
##                                                            
## Uninsured $\times$ Unins. $\beta$                          
##                                                            
## $(1 - \beta^U) \times$ Uninsured                           
##                                                            
## Uninsured Deposit Franchise         -0.0211**    -0.0096   
##                                     (0.0075)     (0.0065)  
## Insured Deposit Franchise                         0.0404***
##                                                  (0.0069)  
## _________________________________ ____________ ____________
## S.E. type                         Hetero.-rob. Hetero.-rob.
## Observations                               234          234
## R2                                     0.05631      0.25443
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# Panel B: Borrowing DV — Public Banks Only (No Controls)
# For comparison: same public-bank sample but with borrowing as DV
# =========================================================================
cat("\n=== Panel B: Borrowing DV — Public Banks Only (No Controls) ===\n")
## 
## === Panel B: Borrowing DV — Public Banks Only (No Controls) ===
pub_c1 <- safe_run_nc(df_crisis_svb, "any_fed", "uninsured_lev")
pub_c2 <- safe_run_nc(df_crisis_svb, "any_fed", "uninsured_lev + uninsured_beta + unins_x_unins_beta")
pub_c3 <- safe_run_nc(df_crisis_svb, "any_fed", "one_minus_betaU_x_unins")
pub_c4 <- safe_run_nc(df_crisis_svb, "any_fed", "unins_franchise")
pub_c5 <- safe_run_nc(df_crisis_svb, "any_fed", "unins_franchise + ins_franchise")

models_pub_borrow <- list(
  "(1)" = pub_c1, "(2)" = pub_c2, "(3)" = pub_c3,
  "(4)" = pub_c4, "(5)" = pub_c5)

save_etable(models_pub_borrow, "DSSW_A10_borrow_public",
  title_text = "DSSW A.10 Analog: Borrowing DV — Public Banks Only (No Controls)",
  notes_text = paste0(
    "LPM. DV = 1 if borrowed from any Fed facility. Public banks with SVB beta coverage only. ",
    "Same sample as SVB beta panel for direct comparison. No controls. Robust SEs. z-standardized."),
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

models_pub_borrow_ok <- models_pub_borrow[!sapply(models_pub_borrow, is.null)]
if (length(models_pub_borrow_ok) > 0) etable(models_pub_borrow_ok, fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                      any_fed    any_fed    any_fed    any_fed
##                                                                              
## Constant                           0.2652***  0.2556***  0.3623***  0.3623***
##                                   (0.0343)   (0.0358)   (0.0290)   (0.0290)  
## Uninsured Leverage (z)             0.1219***  0.1348***                      
##                                   (0.0304)   (0.0315)                        
## Uninsured $\beta$ (z)                         0.0145                         
##                                              (0.0275)                        
## Uninsured $\times$ Unins. $\beta$            -0.0230                         
##                                              (0.0220)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0955**            
##                                                         (0.0291)             
## Uninsured Deposit Franchise                                         0.0955** 
##                                                                    (0.0291)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                             265        265        265        265
## R2                                   0.05228    0.05550    0.03934    0.03934
## 
##                                          (5)
## Dependent Var.:                      any_fed
##                                             
## Constant                           0.3623***
##                                   (0.0291)  
## Uninsured Leverage (z)                      
##                                             
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise        0.0886** 
##                                   (0.0308)  
## Insured Deposit Franchise         -0.0242   
##                                   (0.0304)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                             265
## R2                                   0.04166
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# =========================================================================
# Panel C: Borrowing DV — Non-Public Banks Only (No Controls)
# Non-public banks have no stock returns, so SVB beta is unavailable.
# We show the deposit fragility channel operates without equity signaling.
# =========================================================================
cat("\n=== Panel C: Borrowing DV — Non-Public Banks Only (No Controls) ===\n")
## 
## === Panel C: Borrowing DV — Non-Public Banks Only (No Controls) ===
df_nonpub <- df_a10_any %>% filter(is_public == 0)
cat(sprintf("  Non-public banks with beta coverage: %d\n", nrow(df_nonpub)))
##   Non-public banks with beta coverage: 3709
np_c1 <- safe_run_nc(df_nonpub, "any_fed", "uninsured_lev")
np_c2 <- safe_run_nc(df_nonpub, "any_fed", "uninsured_lev + uninsured_beta + unins_x_unins_beta")
np_c3 <- safe_run_nc(df_nonpub, "any_fed", "one_minus_betaU_x_unins")
np_c4 <- safe_run_nc(df_nonpub, "any_fed", "unins_franchise")
np_c5 <- safe_run_nc(df_nonpub, "any_fed", "unins_franchise + ins_franchise")

models_np_borrow <- list(
  "(1)" = np_c1, "(2)" = np_c2, "(3)" = np_c3,
  "(4)" = np_c4, "(5)" = np_c5)

save_etable(models_np_borrow, "DSSW_A10_borrow_nonpublic",
  title_text = "DSSW A.10 Analog: Borrowing DV — Non-Public Banks (No Controls)",
  notes_text = paste0(
    "LPM. DV = 1 if borrowed from any Fed facility. Non-public banks only (no stock return data). ",
    "Tests whether deposit fragility channel operates without equity market signaling. ",
    "No controls. Robust SEs. z-standardized."),
  extra_lines = list(c("Spec", "C1", "C2", "C3", "C4", "C5")))

models_np_borrow_ok <- models_np_borrow[!sapply(models_np_borrow, is.null)]
if (length(models_np_borrow_ok) > 0) etable(models_np_borrow_ok, fitstat = ~ n + r2, se.below = TRUE)
##                                          (1)        (2)        (3)        (4)
## Dependent Var.:                      any_fed    any_fed    any_fed    any_fed
##                                                                              
## Constant                           0.1949***  0.1960***  0.1944***  0.1944***
##                                   (0.0065)   (0.0065)   (0.0065)   (0.0065)  
## Uninsured Leverage (z)             0.0464***  0.0485***                      
##                                   (0.0066)   (0.0066)                        
## Uninsured $\beta$ (z)                         0.0290***                      
##                                              (0.0070)                        
## Uninsured $\times$ Unins. $\beta$            -0.0059                         
##                                              (0.0062)                        
## $(1 - \beta^U) \times$ Uninsured                         0.0353***           
##                                                         (0.0065)             
## Uninsured Deposit Franchise                                         0.0353***
##                                                                    (0.0065)  
## Insured Deposit Franchise                                                    
##                                                                              
## _________________________________ __________ __________ __________ __________
## S.E. type                         Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                           3,709      3,709      3,709      3,709
## R2                                   0.01319    0.01809    0.00781    0.00781
## 
##                                          (5)
## Dependent Var.:                      any_fed
##                                             
## Constant                           0.1969***
##                                   (0.0065)  
## Uninsured Leverage (z)                      
##                                             
## Uninsured $\beta$ (z)                       
##                                             
## Uninsured $\times$ Unins. $\beta$           
##                                             
## $(1 - \beta^U) \times$ Uninsured            
##                                             
## Uninsured Deposit Franchise        0.0101   
##                                   (0.0078)  
## Insured Deposit Franchise         -0.0507***
##                                   (0.0080)  
## _________________________________ __________
## S.E. type                         Hete.-rob.
## Observations                           3,709
## R2                                   0.01939
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# --- Summary ---
cat("\n=== DSSW A.10 SVB BETA SUMMARY ===\n")
## 
## === DSSW A.10 SVB BETA SUMMARY ===
cat("  Panel A: SVB beta (stock return) as DV — public banks — EXACT DSSW replication\n")
##   Panel A: SVB beta (stock return) as DV — public banks — EXACT DSSW replication
cat("  Panel B: Borrowing as DV — SAME public bank sample — for comparison\n")
##   Panel B: Borrowing as DV — SAME public bank sample — for comparison
cat("  Panel C: Borrowing as DV — non-public banks — equity signal not required\n")
##   Panel C: Borrowing as DV — non-public banks — equity signal not required

26 SUMMARY

cat("======================================================================\n")
## ======================================================================
cat("  COMPREHENSIVE ANALYSIS — COMPLETE\n")
##   COMPREHENSIVE ANALYSIS — COMPLETE
cat("======================================================================\n\n")
## ======================================================================
cat("MAIN RESULTS (Crisis, Extensive Margin):\n")
## MAIN RESULTS (Crisis, Extensive Margin):
cat("  A. Full Sample:             4 regressions (AnyFed, BTFP, DW, FHLB)\n")
##   A. Full Sample:             4 regressions (AnyFed, BTFP, DW, FHLB)
cat("  B. Jiang MTM Sol/Ins:       8 regressions (4 × 2)\n")
##   B. Jiang MTM Sol/Ins:       8 regressions (4 × 2)
cat("  C. IDCR-100% Sol/Ins:       8 regressions (4 × 2)\n")
##   C. IDCR-100% Sol/Ins:       8 regressions (4 × 2)
cat("  D. DSSW Diagnostic:         0 insolvent → supports coordination story\n\n")
##   D. DSSW Diagnostic:         0 insolvent → supports coordination story
cat("TEMPORAL ROBUSTNESS:\n")
## TEMPORAL ROBUSTNESS:
cat("  Full sample:                4 regressions (BTFP/DW × Crisis/Arb)\n")
##   Full sample:                4 regressions (BTFP/DW × Crisis/Arb)
cat("  Jiang MTM Sol/Ins:          8 regressions (BTFP/DW × Crisis/Arb × Sol/Ins)\n")
##   Jiang MTM Sol/Ins:          8 regressions (BTFP/DW × Crisis/Arb × Sol/Ins)
cat("  IDCR-100% Sol/Ins:          8 regressions (BTFP/DW × Crisis/Arb × Sol/Ins)\n")
##   IDCR-100% Sol/Ins:          8 regressions (BTFP/DW × Crisis/Arb × Sol/Ins)
cat("  → Solvency × Period DID: interaction only among solvent banks in crisis\n\n")
##   → Solvency × Period DID: interaction only among solvent banks in crisis
cat("DEPOSIT BETA CHANNEL:\n")
## DEPOSIT BETA CHANNEL:
cat("  Full sample:                7 regressions (nested/full × 3 facilities + FHLB)\n")
##   Full sample:                7 regressions (nested/full × 3 facilities + FHLB)
cat("  Jiang MTM Sol/Ins:          6 regressions (3 facilities × Sol/Ins)\n")
##   Jiang MTM Sol/Ins:          6 regressions (3 facilities × Sol/Ins)
cat("  IDCR-100% Sol/Ins:          6 regressions (3 facilities × Sol/Ins)\n")
##   IDCR-100% Sol/Ins:          6 regressions (3 facilities × Sol/Ins)
cat("  → β^U triple should work only among solvent (panic-region) banks\n\n")
##   → β^U triple should work only among solvent (panic-region) banks
cat("FACILITY COMPLEMENTARITY:\n")
## FACILITY COMPLEMENTARITY:
cat("  4a. Multinomial: facility choice {BTFP, DW, Both}\n")
##   4a. Multinomial: facility choice {BTFP, DW, Both}
cat("  4b. Complementarity: DW borrowers → also BTFP?\n")
##   4b. Complementarity: DW borrowers → also BTFP?
cat("  4c. Substitution: BTFP-only vs DW-only\n")
##   4c. Substitution: BTFP-only vs DW-only
cat("  4d. Descriptive t-tests\n\n")
##   4d. Descriptive t-tests
cat("BTFP PAR RECAPITALIZATION & DW COMPLEMENTARITY:\n")
## BTFP PAR RECAPITALIZATION & DW COMPLEMENTARITY:
cat("  Par Recap → DW:             4 regressions (Base, +Recap, +Recap×UI, Full)\n")
##   Par Recap → DW:             4 regressions (Base, +Recap, +Recap×UI, Full)
cat("  BTFP Borrowers → Also DW:   4 regressions (within-BTFP complementarity)\n")
##   BTFP Borrowers → Also DW:   4 regressions (within-BTFP complementarity)
cat("  Joint Usage (Both Fed):     5 regressions (clean sample + AnyFed sample)\n")
##   Joint Usage (Both Fed):     5 regressions (clean sample + AnyFed sample)
cat("  Intensive (Total Fed):      5 regressions (%TA + log($) × 3 specs)\n")
##   Intensive (Total Fed):      5 regressions (%TA + log($) × 3 specs)
cat("  Descriptive + figures:      Boxplots, loess curves, t-tests\n")
##   Descriptive + figures:      Boxplots, loess curves, t-tests
cat("  → BTFP par valuation = implicit recapitalization; does it crowd IN DW usage?\n\n")
##   → BTFP par valuation = implicit recapitalization; does it crowd IN DW usage?
cat("COLLATERAL UTILIZATION & LIQUIDITY HIERARCHY:\n")
## COLLATERAL UTILIZATION & LIQUIDITY HIERARCHY:
cat("  Run Severity:               6 regressions (Util %TA × 4 specs + log(trips) × 2)\n")
##   Run Severity:               6 regressions (Util %TA × 4 specs + log(trips) × 2)
cat("  BTFP Exhaustion → DW:       4 regressions (complementarity via collateral channel)\n")
##   BTFP Exhaustion → DW:       4 regressions (complementarity via collateral channel)
cat("  DW Collateral Composition:  5 regressions (OMO share × 3 + Loan share × 2)\n")
##   DW Collateral Composition:  5 regressions (OMO share × 3 + Loan share × 2)
cat("  Advance Rate Gap:           2 regressions + paired t-test (par vs. market)\n")
##   Advance Rate Gap:           2 regressions + paired t-test (par vs. market)
cat("  Repeat Borrowing:           2 regressions (log trips ~ run pressure)\n")
##   Repeat Borrowing:           2 regressions (log trips ~ run pressure)
cat("  Figures: Utilization dist, DW composition boxplot, MTM scatter, advance rate,\n")
##   Figures: Utilization dist, DW composition boxplot, MTM scatter, advance rate,
cat("           collateral type composition (BTFP vs DW)\n")
##            collateral type composition (BTFP vs DW)
cat("  → Collateral pecking order: BTFP (par, OMO) → exhaustion → DW (loans, haircuts)\n\n")
##   → Collateral pecking order: BTFP (par, OMO) → exhaustion → DW (loans, haircuts)
cat("SIZE-SPLIT REGRESSIONS:\n")
## SIZE-SPLIT REGRESSIONS:
cat("  Small (≤$10B):              4 regressions (AnyFed, BTFP, DW, FHLB)\n")
##   Small (≤$10B):              4 regressions (AnyFed, BTFP, DW, FHLB)
cat("  Large (>$10B):              4 regressions (AnyFed, BTFP, DW, FHLB)\n")
##   Large (>$10B):              4 regressions (AnyFed, BTFP, DW, FHLB)
cat("  → Test whether MTM × Uninsured effect differs by bank size\n\n")
##   → Test whether MTM × Uninsured effect differs by bank size
cat("THRESHOLD GRADIENT (UNINSURED TERCILES):\n")
## THRESHOLD GRADIENT (UNINSURED TERCILES):
cat("  Any Fed:                    3 regressions (Low, Medium, High UI)\n")
##   Any Fed:                    3 regressions (Low, Medium, High UI)
cat("  BTFP:                       3 regressions (Low, Medium, High UI)\n")
##   BTFP:                       3 regressions (Low, Medium, High UI)
cat("  DW:                         3 regressions (Low, Medium, High UI)\n")
##   DW:                         3 regressions (Low, Medium, High UI)
cat("  → Prediction: β^(H) >> β^(M) > β^(L) — MTM matters most for high-UI banks\n\n")
##   → Prediction: β^(H) >> β^(M) > β^(L) — MTM matters most for high-UI banks
cat("LOW β^U INTERACTION:\n")
## LOW β^U INTERACTION:
cat("  Full sample:                4 regressions (AnyFed, BTFP, DW, FHLB)\n")
##   Full sample:                4 regressions (AnyFed, BTFP, DW, FHLB)
cat("  Small (≤$10B):              4 regressions\n")
##   Small (≤$10B):              4 regressions
cat("  Large (>$10B):              4 regressions\n")
##   Large (>$10B):              4 regressions
cat("  → Tests whether sticky-deposit (low β^U) banks show stronger panic borrowing\n\n")
##   → Tests whether sticky-deposit (low β^U) banks show stronger panic borrowing
cat("PUBLIC vs. NON-PUBLIC BANKS:\n")
## PUBLIC vs. NON-PUBLIC BANKS:
cat("  Public banks:               4 regressions (AnyFed, BTFP, DW, FHLB)\n")
##   Public banks:               4 regressions (AnyFed, BTFP, DW, FHLB)
cat("  Non-public banks:           4 regressions (AnyFed, BTFP, DW, FHLB)\n")
##   Non-public banks:           4 regressions (AnyFed, BTFP, DW, FHLB)
cat("  Combined table:             8 columns (Pub/NP × 4 facilities)\n")
##   Combined table:             8 columns (Pub/NP × 4 facilities)
cat("  Descriptive comparison & borrowing rate differences\n")
##   Descriptive comparison & borrowing rate differences
cat("  → If MTM × Uninsured significant among non-public: coordination ≠ equity signal\n\n")
##   → If MTM × Uninsured significant among non-public: coordination ≠ equity signal
cat("SVB CASE STUDY:\n")
## SVB CASE STUDY:
cat("  Percentile profile:         12 variables ranked vs. cross-section\n")
##   Percentile profile:         12 variables ranked vs. cross-section
cat("  Solvency classification:    Jiang / IDCR-100% / DSSW\n")
##   Solvency classification:    Jiang / IDCR-100% / DSSW
cat("  Beta decomposition:         β_overall = s_U × β^U + (1-s_U) × β^I\n")
##   Beta decomposition:         β_overall = s_U × β^U + (1-s_U) × β^I
cat("  MTM × Uninsured scatter + β^U distribution (with SVB highlighted)\n")
##   MTM × Uninsured scatter + β^U distribution (with SVB highlighted)
cat("  SVB-like regressions:       8 regressions (Like/Unlike × 4 facilities)\n")
##   SVB-like regressions:       8 regressions (Like/Unlike × 4 facilities)
cat("  → SVB-like = above-median β^U AND above-median uninsured share\n")
##   → SVB-like = above-median β^U AND above-median uninsured share
cat("  → If MTM × UI significant among SVB-unlike: coordination failure is pervasive\n\n")
##   → If MTM × UI significant among SVB-unlike: coordination failure is pervasive
cat("INTENSIVE MARGIN (BORROWING AMOUNTS):\n")
## INTENSIVE MARGIN (BORROWING AMOUNTS):
cat("  BTFP:                       6 models (4 specs × %TA + 2 log($) robustness)\n")
##   BTFP:                       6 models (4 specs × %TA + 2 log($) robustness)
cat("  DW:                         6 models (4 specs × %TA + 2 log($) robustness)\n")
##   DW:                         6 models (4 specs × %TA + 2 log($) robustness)
cat("  Combined BTFP vs DW:        4 models (M1/M4 side-by-side)\n")
##   Combined BTFP vs DW:        4 models (M1/M4 side-by-side)
cat("  Model progression:\n")
##   Model progression:
cat("    M1: Run pressure (MTM × Uninsured)\n")
##     M1: Run pressure (MTM × Uninsured)
cat("    M2: + Deposit beta channel (β^U triple interaction)\n")
##     M2: + Deposit beta channel (β^U triple interaction)
cat("    M3: + Collateral/par supply (par benefit for BTFP; capacity for both)\n")
##     M3: + Collateral/par supply (par benefit for BTFP; capacity for both)
cat("    M4: Full specification (all channels)\n")
##     M4: Full specification (all channels)
cat("  Descriptive distributions + correlations + scatter plots\n")
##   Descriptive distributions + correlations + scatter plots
cat("  → Tests what determines HOW MUCH a bank borrows, conditional on borrowing\n\n")
##   → Tests what determines HOW MUCH a bank borrows, conditional on borrowing
cat("KEY INSIGHT FROM DSSW:\n")
## KEY INSIGHT FROM DSSW:
cat("  Every bank is DSSW-solvent. DFV ≈ 68%/TA >> MTM ≈ 5.5%/TA.\n")
##   Every bank is DSSW-solvent. DFV ≈ 68%/TA >> MTM ≈ 5.5%/TA.
cat("  But franchise exists ONLY if depositors stay.\n")
##   But franchise exists ONLY if depositors stay.
cat("  828 banks borrowed despite being DSSW-solvent\n")
##   828 banks borrowed despite being DSSW-solvent
cat("  → Coordination failure, not insolvency, drove borrowing.\n")
##   → Coordination failure, not insolvency, drove borrowing.
cat("  → The triple interaction (β^U) directly tests the DSSW mechanism.\n\n")
##   → The triple interaction (β^U) directly tests the DSSW mechanism.
cat("Tables:", TABLE_PATH, "\n")
## Tables: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/Comprehensive_Analysis/tables
cat("Figures:", FIG_PATH, "\n")
## Figures: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/Comprehensive_Analysis/figures
cat("======================================================================\n")
## ======================================================================

27 SOLVENCY-BASED PARTICIPATION: Borrowing Rates & Descriptive Statistics

27.1 Panel A: Jiang MTM Solvency — Borrowing by Facility & Period

# ==============================================================================
# PARTICIPATION PUZZLE BY SOLVENCY STATUS
#
# Key question: Among banks classified as solvent (insolvent) as of 2022Q4,
# what percentage borrowed from each facility during the crisis and
# arbitrage periods?
#
# Solvency classified at BASELINE (2022Q4) for crisis, (2023Q3) for arb.
# ==============================================================================

cat("================================================================\n")
## ================================================================
cat("  PANEL A: JIANG MTM SOLVENCY — BORROWING BY FACILITY & PERIOD\n")
##   PANEL A: JIANG MTM SOLVENCY — BORROWING BY FACILITY & PERIOD
cat("================================================================\n\n")
## ================================================================
# --- Crisis Period ---
cat("--- CRISIS PERIOD (Mar 8 – May 4, 2023) ---\n")
## --- CRISIS PERIOD (Mar 8 – May 4, 2023) ---
cat("Solvency measured at 2022Q4 baseline\n\n")
## Solvency measured at 2022Q4 baseline
crisis_mtm <- df_crisis %>%
  mutate(Solvency = ifelse(mtm_solvent == 1, "Solvent", "Insolvent")) %>%
  group_by(Solvency) %>%
  summarise(
    N = n(),
    AnyFed_N   = sum(any_fed, na.rm = TRUE),
    AnyFed_pct = round(100 * mean(any_fed, na.rm = TRUE), 2),
    BTFP_N     = sum(btfp_crisis, na.rm = TRUE),
    BTFP_pct   = round(100 * mean(btfp_crisis, na.rm = TRUE), 2),
    DW_N       = sum(dw_crisis, na.rm = TRUE),
    DW_pct     = round(100 * mean(dw_crisis, na.rm = TRUE), 2),
    FHLB_N     = sum(fhlb_user, na.rm = TRUE),
    FHLB_pct   = round(100 * mean(fhlb_user, na.rm = TRUE), 2),
    .groups = "drop"
  )

print(crisis_mtm, width = Inf)
## # A tibble: 3 × 10
##   Solvency      N AnyFed_N AnyFed_pct BTFP_N BTFP_pct  DW_N DW_pct FHLB_N
##   <chr>     <int>    <int>      <dbl>  <int>    <dbl> <int>  <dbl>  <int>
## 1 Insolvent   825      205       24.8    144     17.4    85   10.3     45
## 2 Solvent    3457      623       18.0    357     10.3   348   10.1    257
## 3 <NA>         10        0        0        0      0       0    0        0
##   FHLB_pct
##      <dbl>
## 1     5.45
## 2     7.43
## 3     0
# Nicely formatted
cat("\nCrisis Borrowing Rates (Jiang MTM):\n")
## 
## Crisis Borrowing Rates (Jiang MTM):
for (i in 1:nrow(crisis_mtm)) {
  cat(sprintf("  %s (N=%d):\n", crisis_mtm$Solvency[i], crisis_mtm$N[i]))
  cat(sprintf("    Any Fed: %d (%.2f%%)\n", crisis_mtm$AnyFed_N[i], crisis_mtm$AnyFed_pct[i]))
  cat(sprintf("    BTFP:    %d (%.2f%%)\n", crisis_mtm$BTFP_N[i], crisis_mtm$BTFP_pct[i]))
  cat(sprintf("    DW:      %d (%.2f%%)\n", crisis_mtm$DW_N[i], crisis_mtm$DW_pct[i]))
  cat(sprintf("    FHLB:    %d (%.2f%%)\n", crisis_mtm$FHLB_N[i], crisis_mtm$FHLB_pct[i]))
}
##   Insolvent (N=825):
##     Any Fed: 205 (24.85%)
##     BTFP:    144 (17.45%)
##     DW:      85 (10.30%)
##     FHLB:    45 (5.45%)
##   Solvent (N=3457):
##     Any Fed: 623 (18.02%)
##     BTFP:    357 (10.33%)
##     DW:      348 (10.07%)
##     FHLB:    257 (7.43%)
##   NA (N=10):
##     Any Fed: 0 (0.00%)
##     BTFP:    0 (0.00%)
##     DW:      0 (0.00%)
##     FHLB:    0 (0.00%)
# Chi-squared tests for participation differences
cat("\n--- Chi-squared Tests: Solvent vs. Insolvent (Crisis) ---\n")
## 
## --- Chi-squared Tests: Solvent vs. Insolvent (Crisis) ---
for (fac in c("any_fed", "btfp_crisis", "dw_crisis", "fhlb_user")) {
  tbl <- table(df_crisis$mtm_solvent, df_crisis[[fac]])
  chi <- tryCatch(chisq.test(tbl, correct = FALSE), error = function(e) NULL)
  if (!is.null(chi)) {
    stars <- case_when(chi$p.value < 0.01 ~ "***", chi$p.value < 0.05 ~ "**",
                       chi$p.value < 0.10 ~ "*", TRUE ~ "")
    cat(sprintf("  %-15s χ²=%.2f p=%.4f %s\n", fac, chi$statistic, chi$p.value, stars))
  }
}
##   any_fed         χ²=19.90 p=0.0000 ***
##   btfp_crisis     χ²=32.75 p=0.0000 ***
##   dw_crisis       χ²=0.04 p=0.8396 
##   fhlb_user       χ²=3.98 p=0.0460 **
# --- Arbitrage Period ---
cat("\n\n--- ARBITRAGE PERIOD (Nov 15, 2023 – Jan 24, 2024) ---\n")
## 
## 
## --- ARBITRAGE PERIOD (Nov 15, 2023 – Jan 24, 2024) ---
cat("Solvency measured at 2023Q3 baseline\n\n")
## Solvency measured at 2023Q3 baseline
arb_mtm <- df_arb %>%
  mutate(Solvency = ifelse(mtm_solvent == 1, "Solvent", "Insolvent")) %>%
  group_by(Solvency) %>%
  summarise(
    N = n(),
    AnyFed_N   = sum(any_fed, na.rm = TRUE),
    AnyFed_pct = round(100 * mean(any_fed, na.rm = TRUE), 2),
    BTFP_N     = sum(btfp_arb, na.rm = TRUE),
    BTFP_pct   = round(100 * mean(btfp_arb, na.rm = TRUE), 2),
    DW_N       = sum(dw_arb, na.rm = TRUE),
    DW_pct     = round(100 * mean(dw_arb, na.rm = TRUE), 2),
    FHLB_N     = sum(fhlb_user, na.rm = TRUE),
    FHLB_pct   = round(100 * mean(fhlb_user, na.rm = TRUE), 2),
    .groups = "drop"
  )

print(arb_mtm, width = Inf)
## # A tibble: 3 × 10
##   Solvency      N AnyFed_N AnyFed_pct BTFP_N BTFP_pct  DW_N DW_pct FHLB_N
##   <chr>     <int>    <int>      <dbl>  <int>    <dbl> <int>  <dbl>  <int>
## 1 Insolvent   801      244       30.5    208     26.0    70   8.74     31
## 2 Solvent    3396      757       22.3    541     15.9   292   8.6     165
## 3 <NA>         17        0        0        0      0       0   0         0
##   FHLB_pct
##      <dbl>
## 1     3.87
## 2     4.86
## 3     0
cat("\nArbitrage Borrowing Rates (Jiang MTM):\n")
## 
## Arbitrage Borrowing Rates (Jiang MTM):
for (i in 1:nrow(arb_mtm)) {
  cat(sprintf("  %s (N=%d):\n", arb_mtm$Solvency[i], arb_mtm$N[i]))
  cat(sprintf("    Any Fed: %d (%.2f%%)\n", arb_mtm$AnyFed_N[i], arb_mtm$AnyFed_pct[i]))
  cat(sprintf("    BTFP:    %d (%.2f%%)\n", arb_mtm$BTFP_N[i], arb_mtm$BTFP_pct[i]))
  cat(sprintf("    DW:      %d (%.2f%%)\n", arb_mtm$DW_N[i], arb_mtm$DW_pct[i]))
  cat(sprintf("    FHLB:    %d (%.2f%%)\n", arb_mtm$FHLB_N[i], arb_mtm$FHLB_pct[i]))
}
##   Insolvent (N=801):
##     Any Fed: 244 (30.46%)
##     BTFP:    208 (25.97%)
##     DW:      70 (8.74%)
##     FHLB:    31 (3.87%)
##   Solvent (N=3396):
##     Any Fed: 757 (22.29%)
##     BTFP:    541 (15.93%)
##     DW:      292 (8.60%)
##     FHLB:    165 (4.86%)
##   NA (N=17):
##     Any Fed: 0 (0.00%)
##     BTFP:    0 (0.00%)
##     DW:      0 (0.00%)
##     FHLB:    0 (0.00%)
# Combined table for LaTeX
crisis_mtm_long <- crisis_mtm %>% mutate(Period = "Crisis")
arb_mtm_long    <- arb_mtm %>% mutate(Period = "Arbitrage")
combined_mtm    <- bind_rows(crisis_mtm_long, arb_mtm_long)

cat("\n--- Combined Borrowing Table (Jiang MTM) ---\n")
## 
## --- Combined Borrowing Table (Jiang MTM) ---
print(combined_mtm, width = Inf)
## # A tibble: 6 × 11
##   Solvency      N AnyFed_N AnyFed_pct BTFP_N BTFP_pct  DW_N DW_pct FHLB_N
##   <chr>     <int>    <int>      <dbl>  <int>    <dbl> <int>  <dbl>  <int>
## 1 Insolvent   825      205       24.8    144     17.4    85  10.3      45
## 2 Solvent    3457      623       18.0    357     10.3   348  10.1     257
## 3 <NA>         10        0        0        0      0       0   0         0
## 4 Insolvent   801      244       30.5    208     26.0    70   8.74     31
## 5 Solvent    3396      757       22.3    541     15.9   292   8.6     165
## 6 <NA>         17        0        0        0      0       0   0         0
##   FHLB_pct Period   
##      <dbl> <chr>    
## 1     5.45 Crisis   
## 2     7.43 Crisis   
## 3     0    Crisis   
## 4     3.87 Arbitrage
## 5     4.86 Arbitrage
## 6     0    Arbitrage
# --- Display table ---
disp_mtm <- combined_mtm %>%
  mutate(
    `Any Fed` = sprintf("%d (%.1f%%)", AnyFed_N, AnyFed_pct),
    BTFP      = sprintf("%d (%.1f%%)", BTFP_N, BTFP_pct),
    DW        = sprintf("%d (%.1f%%)", DW_N, DW_pct),
    FHLB      = sprintf("%d (%.1f%%)", FHLB_N, FHLB_pct)
  ) %>%
  select(Period, Solvency, N, `Any Fed`, BTFP, DW, FHLB)

kbl(disp_mtm, format = "html", escape = FALSE,
    caption = "Borrowing Rates by Jiang MTM Solvency Status and Period") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE, position = "left") %>%
  collapse_rows(columns = 1, valign = "middle")
Borrowing Rates by Jiang MTM Solvency Status and Period
Period Solvency N Any Fed BTFP DW FHLB
Crisis Insolvent 825 205 (24.9%) 144 (17.4%) 85 (10.3%) 45 (5.4%)
Solvent 3457 623 (18.0%) 357 (10.3%) 348 (10.1%) 257 (7.4%)
NA 10 0 (0.0%) 0 (0.0%) 0 (0.0%) 0 (0.0%)
Arbitrage Insolvent 801 244 (30.5%) 208 (26.0%) 70 (8.7%) 31 (3.9%)
Solvent 3396 757 (22.3%) 541 (15.9%) 292 (8.6%) 165 (4.9%)
NA 17 0 (0.0%) 0 (0.0%) 0 (0.0%) 0 (0.0%)
# --- Save LaTeX version ---
tex_mtm <- combined_mtm %>%
  mutate(
    AnyFed = sprintf("%d (%.1f\\%%)", AnyFed_N, AnyFed_pct),
    BTFP   = sprintf("%d (%.1f\\%%)", BTFP_N, BTFP_pct),
    DW     = sprintf("%d (%.1f\\%%)", DW_N, DW_pct),
    FHLB   = sprintf("%d (%.1f\\%%)", FHLB_N, FHLB_pct)
  ) %>%
  select(Period, Solvency, N, AnyFed, BTFP, DW, FHLB)

kbl_mtm_tex <- kbl(tex_mtm, format = "latex", booktabs = TRUE, escape = FALSE,
  caption = "Borrowing Rates by Jiang MTM Solvency Status and Period") %>%
  kable_styling(latex_options = c("hold_position")) %>%
  collapse_rows(columns = 1, valign = "middle")

tex_file_mtm <- file.path(TABLE_PATH, "Table_Participation_ByFacility_MTM.tex")
writeLines(kbl_mtm_tex, tex_file_mtm)
cat(sprintf("Saved: %s\n", tex_file_mtm))
## Saved: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/Comprehensive_Analysis/tables/Table_Participation_ByFacility_MTM.tex

27.2 Panel B: IDCR-100% Solvency — Borrowing by Facility & Period

cat("================================================================\n")
## ================================================================
cat("  PANEL B: IDCR-100%% SOLVENCY — BORROWING BY FACILITY & PERIOD\n")
##   PANEL B: IDCR-100%% SOLVENCY — BORROWING BY FACILITY & PERIOD
cat("================================================================\n\n")
## ================================================================
# --- Crisis Period ---
cat("--- CRISIS PERIOD (Mar 8 – May 4, 2023) ---\n")
## --- CRISIS PERIOD (Mar 8 – May 4, 2023) ---
cat("Solvency: IDCR = (MV Assets - Uninsured - Insured) / Insured\n\n")
## Solvency: IDCR = (MV Assets - Uninsured - Insured) / Insured
crisis_idcr <- df_crisis %>%
  mutate(Solvency = ifelse(solvent_idcr_100 == 1, "Solvent", "Insolvent")) %>%
  group_by(Solvency) %>%
  summarise(
    N = n(),
    AnyFed_N   = sum(any_fed, na.rm = TRUE),
    AnyFed_pct = round(100 * mean(any_fed, na.rm = TRUE), 2),
    BTFP_N     = sum(btfp_crisis, na.rm = TRUE),
    BTFP_pct   = round(100 * mean(btfp_crisis, na.rm = TRUE), 2),
    DW_N       = sum(dw_crisis, na.rm = TRUE),
    DW_pct     = round(100 * mean(dw_crisis, na.rm = TRUE), 2),
    FHLB_N     = sum(fhlb_user, na.rm = TRUE),
    FHLB_pct   = round(100 * mean(fhlb_user, na.rm = TRUE), 2),
    .groups = "drop"
  )

print(crisis_idcr, width = Inf)
## # A tibble: 3 × 10
##   Solvency      N AnyFed_N AnyFed_pct BTFP_N BTFP_pct  DW_N DW_pct FHLB_N
##   <chr>     <int>    <int>      <dbl>  <int>    <dbl> <int>  <dbl>  <int>
## 1 Insolvent   364       78       21.4     57     15.7    30   8.24     13
## 2 Solvent    3887      750       19.3    444     11.4   403  10.4     289
## 3 <NA>         41        0        0        0      0       0   0         0
##   FHLB_pct
##      <dbl>
## 1     3.57
## 2     7.44
## 3     0
cat("\nCrisis Borrowing Rates (IDCR-100%):\n")
## 
## Crisis Borrowing Rates (IDCR-100%):
for (i in 1:nrow(crisis_idcr)) {
  cat(sprintf("  %s (N=%d):\n", crisis_idcr$Solvency[i], crisis_idcr$N[i]))
  cat(sprintf("    Any Fed: %d (%.2f%%)\n", crisis_idcr$AnyFed_N[i], crisis_idcr$AnyFed_pct[i]))
  cat(sprintf("    BTFP:    %d (%.2f%%)\n", crisis_idcr$BTFP_N[i], crisis_idcr$BTFP_pct[i]))
  cat(sprintf("    DW:      %d (%.2f%%)\n", crisis_idcr$DW_N[i], crisis_idcr$DW_pct[i]))
  cat(sprintf("    FHLB:    %d (%.2f%%)\n", crisis_idcr$FHLB_N[i], crisis_idcr$FHLB_pct[i]))
}
##   Insolvent (N=364):
##     Any Fed: 78 (21.43%)
##     BTFP:    57 (15.66%)
##     DW:      30 (8.24%)
##     FHLB:    13 (3.57%)
##   Solvent (N=3887):
##     Any Fed: 750 (19.30%)
##     BTFP:    444 (11.42%)
##     DW:      403 (10.37%)
##     FHLB:    289 (7.44%)
##   NA (N=41):
##     Any Fed: 0 (0.00%)
##     BTFP:    0 (0.00%)
##     DW:      0 (0.00%)
##     FHLB:    0 (0.00%)
# Chi-squared tests
cat("\n--- Chi-squared Tests: Solvent vs. Insolvent (Crisis, IDCR) ---\n")
## 
## --- Chi-squared Tests: Solvent vs. Insolvent (Crisis, IDCR) ---
for (fac in c("any_fed", "btfp_crisis", "dw_crisis", "fhlb_user")) {
  tbl <- table(df_crisis$solvent_idcr_100, df_crisis[[fac]])
  chi <- tryCatch(chisq.test(tbl, correct = FALSE), error = function(e) NULL)
  if (!is.null(chi)) {
    stars <- case_when(chi$p.value < 0.01 ~ "***", chi$p.value < 0.05 ~ "**",
                       chi$p.value < 0.10 ~ "*", TRUE ~ "")
    cat(sprintf("  %-15s χ²=%.2f p=%.4f %s\n", fac, chi$statistic, chi$p.value, stars))
  }
}
##   any_fed         χ²=0.97 p=0.3257 
##   btfp_crisis     χ²=5.75 p=0.0165 **
##   dw_crisis       χ²=1.64 p=0.1997 
##   fhlb_user       χ²=7.53 p=0.0061 ***
# --- Arbitrage Period ---
cat("\n\n--- ARBITRAGE PERIOD (Nov 15, 2023 – Jan 24, 2024) ---\n\n")
## 
## 
## --- ARBITRAGE PERIOD (Nov 15, 2023 – Jan 24, 2024) ---
arb_idcr <- df_arb %>%
  mutate(Solvency = ifelse(solvent_idcr_100 == 1, "Solvent", "Insolvent")) %>%
  group_by(Solvency) %>%
  summarise(
    N = n(),
    AnyFed_N   = sum(any_fed, na.rm = TRUE),
    AnyFed_pct = round(100 * mean(any_fed, na.rm = TRUE), 2),
    BTFP_N     = sum(btfp_arb, na.rm = TRUE),
    BTFP_pct   = round(100 * mean(btfp_arb, na.rm = TRUE), 2),
    DW_N       = sum(dw_arb, na.rm = TRUE),
    DW_pct     = round(100 * mean(dw_arb, na.rm = TRUE), 2),
    FHLB_N     = sum(fhlb_user, na.rm = TRUE),
    FHLB_pct   = round(100 * mean(fhlb_user, na.rm = TRUE), 2),
    .groups = "drop"
  )

print(arb_idcr, width = Inf)
## # A tibble: 3 × 10
##   Solvency      N AnyFed_N AnyFed_pct BTFP_N BTFP_pct  DW_N DW_pct FHLB_N
##   <chr>     <int>    <int>      <dbl>  <int>    <dbl> <int>  <dbl>  <int>
## 1 Insolvent   268       50       18.7     40     14.9    15    5.6      7
## 2 Solvent    3900      951       24.4    709     18.2   347    8.9    189
## 3 <NA>         46        0        0        0      0       0    0        0
##   FHLB_pct
##      <dbl>
## 1     2.61
## 2     4.85
## 3     0
cat("\nArbitrage Borrowing Rates (IDCR-100%):\n")
## 
## Arbitrage Borrowing Rates (IDCR-100%):
for (i in 1:nrow(arb_idcr)) {
  cat(sprintf("  %s (N=%d):\n", arb_idcr$Solvency[i], arb_idcr$N[i]))
  cat(sprintf("    Any Fed: %d (%.2f%%)\n", arb_idcr$AnyFed_N[i], arb_idcr$AnyFed_pct[i]))
  cat(sprintf("    BTFP:    %d (%.2f%%)\n", arb_idcr$BTFP_N[i], arb_idcr$BTFP_pct[i]))
  cat(sprintf("    DW:      %d (%.2f%%)\n", arb_idcr$DW_N[i], arb_idcr$DW_pct[i]))
  cat(sprintf("    FHLB:    %d (%.2f%%)\n", arb_idcr$FHLB_N[i], arb_idcr$FHLB_pct[i]))
}
##   Insolvent (N=268):
##     Any Fed: 50 (18.66%)
##     BTFP:    40 (14.93%)
##     DW:      15 (5.60%)
##     FHLB:    7 (2.61%)
##   Solvent (N=3900):
##     Any Fed: 951 (24.38%)
##     BTFP:    709 (18.18%)
##     DW:      347 (8.90%)
##     FHLB:    189 (4.85%)
##   NA (N=46):
##     Any Fed: 0 (0.00%)
##     BTFP:    0 (0.00%)
##     DW:      0 (0.00%)
##     FHLB:    0 (0.00%)
# Combined + LaTeX
crisis_idcr_long <- crisis_idcr %>% mutate(Period = "Crisis")
arb_idcr_long    <- arb_idcr %>% mutate(Period = "Arbitrage")
combined_idcr    <- bind_rows(crisis_idcr_long, arb_idcr_long)

cat("\n--- Combined Borrowing Table (IDCR-100%) ---\n")
## 
## --- Combined Borrowing Table (IDCR-100%) ---
print(combined_idcr, width = Inf)
## # A tibble: 6 × 11
##   Solvency      N AnyFed_N AnyFed_pct BTFP_N BTFP_pct  DW_N DW_pct FHLB_N
##   <chr>     <int>    <int>      <dbl>  <int>    <dbl> <int>  <dbl>  <int>
## 1 Insolvent   364       78       21.4     57     15.7    30   8.24     13
## 2 Solvent    3887      750       19.3    444     11.4   403  10.4     289
## 3 <NA>         41        0        0        0      0       0   0         0
## 4 Insolvent   268       50       18.7     40     14.9    15   5.6       7
## 5 Solvent    3900      951       24.4    709     18.2   347   8.9     189
## 6 <NA>         46        0        0        0      0       0   0         0
##   FHLB_pct Period   
##      <dbl> <chr>    
## 1     3.57 Crisis   
## 2     7.44 Crisis   
## 3     0    Crisis   
## 4     2.61 Arbitrage
## 5     4.85 Arbitrage
## 6     0    Arbitrage
tex_idcr <- combined_idcr %>%
  mutate(
    AnyFed = sprintf("%d (%.1f\\%%)", AnyFed_N, AnyFed_pct),
    BTFP   = sprintf("%d (%.1f\\%%)", BTFP_N, BTFP_pct),
    DW     = sprintf("%d (%.1f\\%%)", DW_N, DW_pct),
    FHLB   = sprintf("%d (%.1f\\%%)", FHLB_N, FHLB_pct)
  ) %>%
  select(Period, Solvency, N, AnyFed, BTFP, DW, FHLB)

# --- Display table ---
disp_idcr <- combined_idcr %>%
  mutate(
    `Any Fed` = sprintf("%d (%.1f%%)", AnyFed_N, AnyFed_pct),
    BTFP      = sprintf("%d (%.1f%%)", BTFP_N, BTFP_pct),
    DW        = sprintf("%d (%.1f%%)", DW_N, DW_pct),
    FHLB      = sprintf("%d (%.1f%%)", FHLB_N, FHLB_pct)
  ) %>%
  select(Period, Solvency, N, `Any Fed`, BTFP, DW, FHLB)

kbl(disp_idcr, format = "html", escape = FALSE,
    caption = "Borrowing Rates by IDCR-100% Solvency Status and Period") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE, position = "left") %>%
  collapse_rows(columns = 1, valign = "middle")
Borrowing Rates by IDCR-100% Solvency Status and Period
Period Solvency N Any Fed BTFP DW FHLB
Crisis Insolvent 364 78 (21.4%) 57 (15.7%) 30 (8.2%) 13 (3.6%)
Solvent 3887 750 (19.3%) 444 (11.4%) 403 (10.4%) 289 (7.4%)
NA 41 0 (0.0%) 0 (0.0%) 0 (0.0%) 0 (0.0%)
Arbitrage Insolvent 268 50 (18.7%) 40 (14.9%) 15 (5.6%) 7 (2.6%)
Solvent 3900 951 (24.4%) 709 (18.2%) 347 (8.9%) 189 (4.8%)
NA 46 0 (0.0%) 0 (0.0%) 0 (0.0%) 0 (0.0%)
# --- Save LaTeX version ---
tex_idcr <- combined_idcr %>%
  mutate(
    AnyFed = sprintf("%d (%.1f\\%%)", AnyFed_N, AnyFed_pct),
    BTFP   = sprintf("%d (%.1f\\%%)", BTFP_N, BTFP_pct),
    DW     = sprintf("%d (%.1f\\%%)", DW_N, DW_pct),
    FHLB   = sprintf("%d (%.1f\\%%)", FHLB_N, FHLB_pct)
  ) %>%
  select(Period, Solvency, N, AnyFed, BTFP, DW, FHLB)

kbl_idcr_tex <- kbl(tex_idcr, format = "latex", booktabs = TRUE, escape = FALSE,
  caption = "Borrowing Rates by IDCR-100\\% Solvency Status and Period") %>%
  kable_styling(latex_options = c("hold_position")) %>%
  collapse_rows(columns = 1, valign = "middle")

tex_file_idcr <- file.path(TABLE_PATH, "Table_Participation_ByFacility_IDCR.tex")
writeLines(kbl_idcr_tex, tex_file_idcr)
cat(sprintf("Saved: %s\n", tex_file_idcr))
## Saved: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/Comprehensive_Analysis/tables/Table_Participation_ByFacility_IDCR.tex

27.3 Panel C: Descriptive Statistics — Jiang MTM Solvent vs. Insolvent

cat("================================================================\n")
## ================================================================
cat("  PANEL C: DESCRIPTIVE STATISTICS BY JIANG MTM SOLVENCY (2022Q4)\n")
##   PANEL C: DESCRIPTIVE STATISTICS BY JIANG MTM SOLVENCY (2022Q4)
cat("================================================================\n\n")
## ================================================================
# Variables to summarize
desc_vars <- c("ln_assets_raw", "cash_ratio_raw", "securities_ratio_raw",
  "loan_ratio_raw", "book_equity_ratio_raw", "roa_raw", "fhlb_ratio_raw",
  "loan_to_deposit_raw", "wholesale_raw", "mtm_total_raw", "uninsured_lev_raw",
  "adjusted_equity_raw", "idcr_100")

desc_labels <- c("Log(Assets)", "Cash / TA", "Securities / TA",
  "Loans / TA", "Book Equity / TA", "ROA", "FHLB / TA",
  "Loan-to-Deposit", "Wholesale Funding", "MTM Loss / TA",
  "Uninsured Dep. / TA", "Adj. Equity (MTM)", "IDCR-100%")

# --- Solvent (MTM) ---
df_sol_mtm <- df_2022q4 %>% filter(mtm_solvent == 1)
df_ins_mtm <- df_2022q4 %>% filter(mtm_insolvent == 1)

cat(sprintf("MTM Solvent: N = %d (%.1f%%)\n", nrow(df_sol_mtm),
    100 * nrow(df_sol_mtm) / nrow(df_2022q4)))
## MTM Solvent: N = 3457 (80.5%)
cat(sprintf("MTM Insolvent: N = %d (%.1f%%)\n\n", nrow(df_ins_mtm),
    100 * nrow(df_ins_mtm) / nrow(df_2022q4)))
## MTM Insolvent: N = 825 (19.2%)
# Build summary table
build_desc_table <- function(df_a, df_b, label_a, label_b, vars, labels) {
  results <- data.frame(
    Variable = labels,
    stringsAsFactors = FALSE
  )
  results[[paste0("Mean_", label_a)]]   <- sapply(vars, function(v) round(mean(df_a[[v]], na.rm = TRUE), 3))
  results[[paste0("SD_", label_a)]]     <- sapply(vars, function(v) round(sd(df_a[[v]], na.rm = TRUE), 3))
  results[[paste0("Median_", label_a)]] <- sapply(vars, function(v) round(median(df_a[[v]], na.rm = TRUE), 3))
  results[[paste0("Mean_", label_b)]]   <- sapply(vars, function(v) round(mean(df_b[[v]], na.rm = TRUE), 3))
  results[[paste0("SD_", label_b)]]     <- sapply(vars, function(v) round(sd(df_b[[v]], na.rm = TRUE), 3))
  results[[paste0("Median_", label_b)]] <- sapply(vars, function(v) round(median(df_b[[v]], na.rm = TRUE), 3))
  
  # T-test for difference in means
  results$Diff <- results[[paste0("Mean_", label_a)]] - results[[paste0("Mean_", label_b)]]
  results$t_stat <- sapply(vars, function(v) {
    tt <- tryCatch(t.test(df_a[[v]], df_b[[v]]), error = function(e) NULL)
    if (!is.null(tt)) round(tt$statistic, 2) else NA_real_
  })
  results$p_val <- sapply(vars, function(v) {
    tt <- tryCatch(t.test(df_a[[v]], df_b[[v]]), error = function(e) NULL)
    if (!is.null(tt)) round(tt$p.value, 4) else NA_real_
  })
  results$Stars <- sapply(results$p_val, function(p) {
    if (is.na(p)) "" else if (p < 0.01) "***" else if (p < 0.05) "**" else if (p < 0.10) "*" else ""
  })
  return(results)
}

desc_mtm <- build_desc_table(df_sol_mtm, df_ins_mtm, "Solvent", "Insolvent",
                              desc_vars, desc_labels)

# --- Display table (HTML for RPubs) ---
desc_mtm_disp <- desc_mtm %>%
  mutate(
    `Solvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
    `Insolvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
    Difference = sprintf("%.3f%s", Diff, Stars),
    `t-stat` = round(t_stat, 2)
  ) %>%
  select(Variable, `Solvent Mean (SD)`, `Insolvent Mean (SD)`, Difference, `t-stat`)

kbl(desc_mtm_disp, format = "html", escape = FALSE,
    caption = sprintf("Descriptive Statistics: Jiang MTM Solvent (N=%d) vs. Insolvent (N=%d)",
                      nrow(df_sol_mtm), nrow(df_ins_mtm))) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE, position = "left") %>%
  footnote(general = "Solvency: Adj. Equity = Book Equity/TA - MTM Loss/TA. Solvent: AE >= 0. Stars: *** p<0.01, ** p<0.05, * p<0.10.",
           general_title = "")
Descriptive Statistics: Jiang MTM Solvent (N=3457) vs. Insolvent (N=825)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 12.906 (1.540) 12.804 (1.204) 0.102** 2.07
Cash / TA 8.790 (9.798) 5.274 (4.629) 3.516*** 15.17
Securities / TA 22.914 (14.581) 37.185 (15.293) -14.271*** -24.30
Loans / TA 61.965 (17.386) 52.103 (16.108) 9.862*** 15.56
Book Equity / TA 11.254 (9.192) 5.468 (1.871) 5.786*** 34.16
ROA 1.244 (2.818) 0.901 (0.485) 0.343*** 6.76
FHLB / TA 2.657 (4.274) 2.631 (3.979) 0.026 0.17
Loan-to-Deposit 73.649 (24.475) 58.367 (19.636) 15.282*** 19.09
Wholesale Funding 0.967 (3.221) 1.101 (2.581) -0.134 -1.27
MTM Loss / TA 4.905 (1.991) 7.822 (1.472) -2.917*** -47.50
Uninsured Dep. / TA 23.432 (12.375) 24.307 (11.126) -0.875** -1.99
Adj. Equity (MTM) 6.348 (9.697) -2.354 (1.945) 8.702*** 48.82
IDCR-100% 1.067 (19.228) 0.038 (0.303) 1.029*** 3.13
Solvency: Adj. Equity = Book Equity/TA - MTM Loss/TA. Solvent: AE >= 0. Stars: *** p<0.01, ** p<0.05, * p<0.10.
# --- Save LaTeX version ---
desc_mtm_tex <- desc_mtm %>%
  mutate(
    Solvent_col   = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
    Insolvent_col = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
    Diff_col      = sprintf("%.3f%s", Diff, Stars)
  ) %>%
  select(Variable, Solvent_col, Insolvent_col, Diff_col, t_stat)

names(desc_mtm_tex) <- c("Variable", "Solvent Mean (SD)", "Insolvent Mean (SD)",
                           "Difference", "t-stat")

kbl_desc_mtm_tex <- kbl(desc_mtm_tex, format = "latex", booktabs = TRUE, escape = FALSE,
  caption = sprintf("Descriptive Statistics: Jiang MTM Solvent (N=%d) vs. Insolvent (N=%d)",
                    nrow(df_sol_mtm), nrow(df_ins_mtm))) %>%
  kable_styling(latex_options = c("hold_position", "scale_down")) %>%
  footnote(general = "Solvency: Adj. Equity = Book Equity/TA $-$ MTM Loss/TA. Solvent: AE $\\\\geq$ 0. Stars: *** p<0.01, ** p<0.05, * p<0.10.",
           escape = FALSE, general_title = "")

tex_desc_mtm <- file.path(TABLE_PATH, "Table_DescStats_MTM_Solvency.tex")
writeLines(kbl_desc_mtm_tex, tex_desc_mtm)
cat(sprintf("Saved: %s\n", tex_desc_mtm))
## Saved: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/Comprehensive_Analysis/tables/Table_DescStats_MTM_Solvency.tex
# Also include uninsured beta if available
if ("uninsured_beta_raw" %in% names(df_2022q4)) {
  cat("\n--- Deposit Beta by MTM Solvency ---\n")
  cat(sprintf("  Solvent:   β^U mean = %.4f, median = %.4f (N=%d)\n",
    mean(df_sol_mtm$uninsured_beta_raw, na.rm = TRUE),
    median(df_sol_mtm$uninsured_beta_raw, na.rm = TRUE),
    sum(!is.na(df_sol_mtm$uninsured_beta_raw))))
  cat(sprintf("  Insolvent: β^U mean = %.4f, median = %.4f (N=%d)\n",
    mean(df_ins_mtm$uninsured_beta_raw, na.rm = TRUE),
    median(df_ins_mtm$uninsured_beta_raw, na.rm = TRUE),
    sum(!is.na(df_ins_mtm$uninsured_beta_raw))))
}
## 
## --- Deposit Beta by MTM Solvency ---
##   Solvent:   β^U mean = 0.3367, median = 0.3139 (N=3413)
##   Insolvent: β^U mean = 0.3087, median = 0.2961 (N=813)

27.4 Panel D: Descriptive Statistics — IDCR-100% Solvent vs. Insolvent

cat("================================================================\n")
## ================================================================
cat("  PANEL D: DESCRIPTIVE STATISTICS BY IDCR-100%% SOLVENCY (2022Q4)\n")
##   PANEL D: DESCRIPTIVE STATISTICS BY IDCR-100%% SOLVENCY (2022Q4)
cat("================================================================\n\n")
## ================================================================
df_sol_idcr <- df_2022q4 %>% filter(solvent_idcr_100 == 1)
df_ins_idcr <- df_2022q4 %>% filter(insolvent_idcr_100 == 1)

cat(sprintf("IDCR-100%% Solvent: N = %d (%.1f%%)\n", nrow(df_sol_idcr),
    100 * nrow(df_sol_idcr) / nrow(df_2022q4)))
## IDCR-100% Solvent: N = 3887 (90.6%)
cat(sprintf("IDCR-100%% Insolvent: N = %d (%.1f%%)\n\n", nrow(df_ins_idcr),
    100 * nrow(df_ins_idcr) / nrow(df_2022q4)))
## IDCR-100% Insolvent: N = 364 (8.5%)
desc_idcr <- build_desc_table(df_sol_idcr, df_ins_idcr, "Solvent", "Insolvent",
                               desc_vars, desc_labels)

# --- Display table (HTML for RPubs) ---
desc_idcr_disp <- desc_idcr %>%
  mutate(
    `Solvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
    `Insolvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
    Difference = sprintf("%.3f%s", Diff, Stars),
    `t-stat` = round(t_stat, 2)
  ) %>%
  select(Variable, `Solvent Mean (SD)`, `Insolvent Mean (SD)`, Difference, `t-stat`)

kbl(desc_idcr_disp, format = "html", escape = FALSE,
    caption = sprintf("Descriptive Statistics: IDCR-100%% Solvent (N=%d) vs. Insolvent (N=%d)",
                      nrow(df_sol_idcr), nrow(df_ins_idcr))) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE, position = "left") %>%
  footnote(general = "Solvency: IDCR = (MV Assets - Uninsured - Insured) / Insured. Solvent: IDCR >= 0. Stars: *** p<0.01, ** p<0.05, * p<0.10.",
           general_title = "")
Descriptive Statistics: IDCR-100% Solvent (N=3887) vs. Insolvent (N=364)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 12.934 (1.477) 12.594 (1.283) 0.340*** 4.76
Cash / TA 8.098 (8.896) 6.571 (5.535) 1.527*** 4.72
Securities / TA 24.100 (14.620) 40.405 (16.126) -16.305*** -18.59
Loans / TA 61.723 (16.379) 47.473 (16.636) 14.250*** 15.65
Book Equity / TA 10.040 (5.739) 4.881 (1.949) 5.159*** 37.52
ROA 1.077 (1.811) 0.936 (0.493) 0.141*** 3.63
FHLB / TA 2.879 (4.348) 0.456 (1.217) 2.423*** 25.63
Loan-to-Deposit 73.135 (23.228) 50.775 (18.511) 22.360*** 21.51
Wholesale Funding 1.076 (3.246) 0.193 (0.589) 0.883*** 14.58
MTM Loss / TA 5.280 (2.125) 7.809 (1.490) -2.529*** -29.67
Uninsured Dep. / TA 23.574 (12.003) 25.891 (12.052) -2.317*** -3.51
Adj. Equity (MTM) 4.760 (6.381) -2.928 (2.287) 7.688*** 48.78
IDCR-100% 0.953 (18.055) -0.048 (0.183) 1.001*** 3.45
Solvency: IDCR = (MV Assets - Uninsured - Insured) / Insured. Solvent: IDCR >= 0. Stars: *** p<0.01, ** p<0.05, * p<0.10.
# --- Save LaTeX version ---
desc_idcr_tex <- desc_idcr %>%
  mutate(
    Solvent_col   = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
    Insolvent_col = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
    Diff_col      = sprintf("%.3f%s", Diff, Stars)
  ) %>%
  select(Variable, Solvent_col, Insolvent_col, Diff_col, t_stat)

names(desc_idcr_tex) <- c("Variable", "Solvent Mean (SD)", "Insolvent Mean (SD)",
                            "Difference", "t-stat")

kbl_desc_idcr_tex <- kbl(desc_idcr_tex, format = "latex", booktabs = TRUE, escape = FALSE,
  caption = sprintf("Descriptive Statistics: IDCR-100\\%% Solvent (N=%d) vs. Insolvent (N=%d)",
                    nrow(df_sol_idcr), nrow(df_ins_idcr))) %>%
  kable_styling(latex_options = c("hold_position", "scale_down")) %>%
  footnote(general = "Solvency: IDCR = (MV Assets $-$ Uninsured $-$ Insured) / Insured. Solvent: IDCR $\\\\geq$ 0. Stars: *** p<0.01, ** p<0.05, * p<0.10.",
           escape = FALSE, general_title = "")

tex_desc_idcr <- file.path(TABLE_PATH, "Table_DescStats_IDCR_Solvency.tex")
writeLines(kbl_desc_idcr_tex, tex_desc_idcr)
cat(sprintf("Saved: %s\n", tex_desc_idcr))
## Saved: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/Comprehensive_Analysis/tables/Table_DescStats_IDCR_Solvency.tex
# Beta comparison
if ("uninsured_beta_raw" %in% names(df_2022q4)) {
  cat("\n--- Deposit Beta by IDCR-100% Solvency ---\n")
  cat(sprintf("  Solvent:   β^U mean = %.4f, median = %.4f (N=%d)\n",
    mean(df_sol_idcr$uninsured_beta_raw, na.rm = TRUE),
    median(df_sol_idcr$uninsured_beta_raw, na.rm = TRUE),
    sum(!is.na(df_sol_idcr$uninsured_beta_raw))))
  cat(sprintf("  Insolvent: β^U mean = %.4f, median = %.4f (N=%d)\n",
    mean(df_ins_idcr$uninsured_beta_raw, na.rm = TRUE),
    median(df_ins_idcr$uninsured_beta_raw, na.rm = TRUE),
    sum(!is.na(df_ins_idcr$uninsured_beta_raw))))
}
## 
## --- Deposit Beta by IDCR-100% Solvency ---
##   Solvent:   β^U mean = 0.3343, median = 0.3132 (N=3871)
##   Insolvent: β^U mean = 0.2978, median = 0.2866 (N=355)

27.5 Panel F: Borrower Descriptive Stats — Solvent vs. Insolvent by Facility (MTM)

cat("================================================================\n")

================================================================

cat("  PANEL F: BORROWER DESCRIPTIVE STATS — MTM SOLVENCY (CRISIS)\n")

PANEL F: BORROWER DESCRIPTIVE STATS — MTM SOLVENCY (CRISIS)

cat("================================================================\n\n")

================================================================

# For each facility: compare solvent borrowers vs insolvent borrowers
facility_list <- list(
  list(name = "Any Fed", var = "any_fed"),
  list(name = "BTFP",    var = "btfp_crisis"),
  list(name = "DW",      var = "dw_crisis")
)

for (fac in facility_list) {
  df_sol_b <- df_crisis %>% filter(mtm_solvent == 1, !!sym(fac$var) == 1)
  df_ins_b <- df_crisis %>% filter(mtm_insolvent == 1, !!sym(fac$var) == 1)
  
  cat(sprintf("\n--- %s Borrowers: MTM Solvent (N=%d) vs. Insolvent (N=%d) ---\n",
              fac$name, nrow(df_sol_b), nrow(df_ins_b)))
  
  if (nrow(df_sol_b) < 2 || nrow(df_ins_b) < 2) {
    cat("  Insufficient observations for comparison.\n")
    next
  }
  
  desc_fac <- build_desc_table(df_sol_b, df_ins_b, "Solvent", "Insolvent",
                                desc_vars, desc_labels)
  
  # HTML display
  desc_fac_disp <- desc_fac %>%
    mutate(
      `Solvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
      `Insolvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
      Difference = sprintf("%.3f%s", Diff, Stars),
      `t-stat` = round(t_stat, 2)
    ) %>%
    select(Variable, `Solvent Mean (SD)`, `Insolvent Mean (SD)`, Difference, `t-stat`)
  
  tbl_html <- kbl(desc_fac_disp, format = "html", escape = FALSE,
      caption = sprintf("%s Borrowers (Crisis): MTM Solvent (N=%d) vs. Insolvent (N=%d)",
                        fac$name, nrow(df_sol_b), nrow(df_ins_b))) %>%
    kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                  full_width = FALSE, position = "left") %>%
    footnote(general = "Sample: borrowers only (DV=1). MTM Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.",
             general_title = "")
  cat(tbl_html)
  cat("\n\n")
  
  # LaTeX save
  desc_fac_tex <- desc_fac %>%
    mutate(
      Solvent_col   = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
      Insolvent_col = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
      Diff_col      = sprintf("%.3f%s", Diff, Stars)
    ) %>%
    select(Variable, Solvent_col, Insolvent_col, Diff_col, t_stat)
  names(desc_fac_tex) <- c("Variable", "Solvent Mean (SD)", "Insolvent Mean (SD)",
                             "Difference", "t-stat")
  
  kbl_tex <- kbl(desc_fac_tex, format = "latex", booktabs = TRUE, escape = FALSE,
    caption = sprintf("%s Borrowers (Crisis): MTM Solvent (N=%d) vs. Insolvent (N=%d)",
                      fac$name, nrow(df_sol_b), nrow(df_ins_b))) %>%
    kable_styling(latex_options = c("hold_position", "scale_down"))
  
  fname <- paste0("Table_DescStats_Borrowers_MTM_", gsub(" ", "", fac$name), ".tex")
  writeLines(kbl_tex, file.path(TABLE_PATH, fname))
  cat(sprintf("Saved: %s\n", fname))
}
— Any Fed Borrowers: MTM Solvent (N=623) vs. Insolvent (N=205) —
Any Fed Borrowers (Crisis): MTM Solvent (N=623) vs. Insolvent (N=205)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 13.892 (1.580) 13.369 (1.266) 0.523*** 4.82
Cash / TA 5.647 (5.966) 4.068 (3.576) 1.579*** 4.57
Securities / TA 22.806 (12.329) 37.614 (13.995) -14.808*** -13.52
Loans / TA 65.556 (13.319) 53.092 (15.019) 12.464*** 10.59
Book Equity / TA 9.637 (2.690) 5.207 (1.878) 4.430*** 26.09
ROA 1.146 (0.633) 0.928 (0.360) 0.218*** 6.11
FHLB / TA 3.794 (4.937) 3.109 (3.774) 0.685** 2.08
Loan-to-Deposit 78.508 (18.232) 60.140 (18.884) 18.368*** 12.18
Wholesale Funding 1.495 (3.487) 1.635 (3.435) -0.140 -0.50
MTM Loss / TA 5.321 (1.746) 7.863 (1.334) -2.542*** -21.81
Uninsured Dep. / TA 27.504 (12.461) 26.068 (10.602) 1.436 1.61
Adj. Equity (MTM) 4.316 (3.207) -2.656 (1.959) 6.972*** 37.15
IDCR-100% 0.203 (0.196) 0.049 (0.101) 0.154*** 14.59
Sample: borrowers only (DV=1). MTM Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.

Saved: Table_DescStats_Borrowers_MTM_AnyFed.tex

— BTFP Borrowers: MTM Solvent (N=357) vs. Insolvent (N=144) —
BTFP Borrowers (Crisis): MTM Solvent (N=357) vs. Insolvent (N=144)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 13.899 (1.668) 13.265 (1.155) 0.634*** 4.86
Cash / TA 4.956 (5.045) 3.965 (3.407) 0.991** 2.54
Securities / TA 24.349 (11.952) 38.178 (14.138) -13.829*** -10.34
Loans / TA 64.747 (12.692) 52.760 (14.737) 11.987*** 8.56
Book Equity / TA 9.420 (2.551) 5.095 (1.919) 4.325*** 20.67
ROA 1.126 (0.593) 0.917 (0.327) 0.209*** 5.04
FHLB / TA 4.144 (5.182) 3.206 (3.947) 0.938** 2.19
Loan-to-Deposit 77.619 (17.122) 59.746 (18.903) 17.873*** 9.83
Wholesale Funding 1.572 (3.393) 1.490 (2.769) 0.082 0.28
MTM Loss / TA 5.393 (1.692) 7.863 (1.340) -2.470*** -17.26
Uninsured Dep. / TA 28.047 (12.837) 25.771 (10.429) 2.276** 2.06
Adj. Equity (MTM) 4.027 (2.993) -2.768 (2.049) 6.795*** 29.17
IDCR-100% 0.209 (0.194) 0.045 (0.102) 0.164*** 12.29
Sample: borrowers only (DV=1). MTM Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.

Saved: Table_DescStats_Borrowers_MTM_BTFP.tex

— DW Borrowers: MTM Solvent (N=348) vs. Insolvent (N=85) —
DW Borrowers (Crisis): MTM Solvent (N=348) vs. Insolvent (N=85)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 14.111 (1.612) 13.622 (1.372) 0.489*** 2.84
Cash / TA 6.193 (6.650) 4.064 (3.675) 2.129*** 3.98
Securities / TA 21.563 (12.495) 37.407 (14.938) -15.844*** -9.04
Loans / TA 66.229 (13.699) 53.070 (16.754) 13.159*** 6.71
Book Equity / TA 9.749 (2.672) 5.231 (1.960) 4.518*** 17.62
ROA 1.170 (0.654) 0.928 (0.422) 0.242*** 4.20
FHLB / TA 3.520 (4.994) 3.087 (3.664) 0.433 0.90
Loan-to-Deposit 79.292 (18.776) 60.545 (21.266) 18.747*** 7.45
Wholesale Funding 1.486 (3.452) 1.859 (4.204) -0.373 -0.76
MTM Loss / TA 5.217 (1.742) 7.908 (1.351) -2.691*** -15.49
Uninsured Dep. / TA 28.312 (12.834) 27.009 (10.766) 1.303 0.96
Adj. Equity (MTM) 4.532 (3.262) -2.677 (2.039) 7.209*** 25.56
IDCR-100% 0.211 (0.216) 0.057 (0.112) 0.154*** 9.16
Sample: borrowers only (DV=1). MTM Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.

Saved: Table_DescStats_Borrowers_MTM_DW.tex

27.6 Panel G: Borrower Descriptive Stats — Solvent vs. Insolvent by Facility (IDCR-100%)

cat("================================================================\n")

================================================================

cat("  PANEL G: BORROWER DESCRIPTIVE STATS — IDCR SOLVENCY (CRISIS)\n")

PANEL G: BORROWER DESCRIPTIVE STATS — IDCR SOLVENCY (CRISIS)

cat("================================================================\n\n")

================================================================

for (fac in facility_list) {
  df_sol_b <- df_crisis %>% filter(solvent_idcr_100 == 1, !!sym(fac$var) == 1)
  df_ins_b <- df_crisis %>% filter(insolvent_idcr_100 == 1, !!sym(fac$var) == 1)
  
  cat(sprintf("\n--- %s Borrowers: IDCR Solvent (N=%d) vs. Insolvent (N=%d) ---\n",
              fac$name, nrow(df_sol_b), nrow(df_ins_b)))
  
  if (nrow(df_sol_b) < 2 || nrow(df_ins_b) < 2) {
    cat("  Insufficient observations for comparison.\n")
    next
  }
  
  desc_fac <- build_desc_table(df_sol_b, df_ins_b, "Solvent", "Insolvent",
                                desc_vars, desc_labels)
  
  # HTML display
  desc_fac_disp <- desc_fac %>%
    mutate(
      `Solvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
      `Insolvent Mean (SD)` = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
      Difference = sprintf("%.3f%s", Diff, Stars),
      `t-stat` = round(t_stat, 2)
    ) %>%
    select(Variable, `Solvent Mean (SD)`, `Insolvent Mean (SD)`, Difference, `t-stat`)
  
  tbl_html <- kbl(desc_fac_disp, format = "html", escape = FALSE,
      caption = sprintf("%s Borrowers (Crisis): IDCR Solvent (N=%d) vs. Insolvent (N=%d)",
                        fac$name, nrow(df_sol_b), nrow(df_ins_b))) %>%
    kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                  full_width = FALSE, position = "left") %>%
    footnote(general = "Sample: borrowers only (DV=1). IDCR-100% Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.",
             general_title = "")
  cat(tbl_html)
  cat("\n\n")
  
  # LaTeX save
  desc_fac_tex <- desc_fac %>%
    mutate(
      Solvent_col   = sprintf("%.3f (%.3f)", Mean_Solvent, SD_Solvent),
      Insolvent_col = sprintf("%.3f (%.3f)", Mean_Insolvent, SD_Insolvent),
      Diff_col      = sprintf("%.3f%s", Diff, Stars)
    ) %>%
    select(Variable, Solvent_col, Insolvent_col, Diff_col, t_stat)
  names(desc_fac_tex) <- c("Variable", "Solvent Mean (SD)", "Insolvent Mean (SD)",
                             "Difference", "t-stat")
  
  kbl_tex <- kbl(desc_fac_tex, format = "latex", booktabs = TRUE, escape = FALSE,
    caption = sprintf("%s Borrowers (Crisis): IDCR Solvent (N=%d) vs. Insolvent (N=%d)",
                      fac$name, nrow(df_sol_b), nrow(df_ins_b))) %>%
    kable_styling(latex_options = c("hold_position", "scale_down"))
  
  fname <- paste0("Table_DescStats_Borrowers_IDCR_", gsub(" ", "", fac$name), ".tex")
  writeLines(kbl_tex, file.path(TABLE_PATH, fname))
  cat(sprintf("Saved: %s\n", fname))
}
— Any Fed Borrowers: IDCR Solvent (N=750) vs. Insolvent (N=78) —
Any Fed Borrowers (Crisis): IDCR Solvent (N=750) vs. Insolvent (N=78)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 13.812 (1.512) 13.290 (1.568) 0.522*** 2.81
Cash / TA 5.266 (5.635) 5.159 (4.191) 0.107 0.21
Securities / TA 24.865 (13.031) 41.929 (16.345) -17.064*** -8.93
Loans / TA 64.000 (13.578) 47.754 (17.501) 16.246*** 7.95
Book Equity / TA 8.933 (2.984) 4.769 (2.152) 4.164*** 15.60
ROA 1.103 (0.598) 0.985 (0.420) 0.118** 2.26
FHLB / TA 3.928 (4.785) 0.699 (1.813) 3.229*** 11.98
Loan-to-Deposit 76.295 (18.501) 51.512 (20.308) 24.783*** 10.34
Wholesale Funding 1.665 (3.615) 0.233 (0.716) 1.432*** 9.24
MTM Loss / TA 5.736 (1.907) 8.018 (1.466) -2.282*** -12.68
Uninsured Dep. / TA 27.051 (12.143) 28.087 (10.992) -1.036 -0.78
Adj. Equity (MTM) 3.197 (3.873) -3.250 (2.567) 6.447*** 19.94
IDCR-100% 0.187 (0.184) -0.050 (0.061) 0.237*** 24.52
Sample: borrowers only (DV=1). IDCR-100% Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.

Saved: Table_DescStats_Borrowers_IDCR_AnyFed.tex

— BTFP Borrowers: IDCR Solvent (N=444) vs. Insolvent (N=57) —
BTFP Borrowers (Crisis): IDCR Solvent (N=444) vs. Insolvent (N=57)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 13.821 (1.585) 12.908 (1.097) 0.913*** 5.58
Cash / TA 4.634 (4.739) 4.968 (3.936) -0.334 -0.59
Securities / TA 26.362 (12.429) 43.607 (16.699) -17.245*** -7.53
Loans / TA 63.196 (12.853) 46.543 (16.879) 16.653*** 7.19
Book Equity / TA 8.652 (2.860) 4.475 (2.147) 4.177*** 13.26
ROA 1.079 (0.559) 0.962 (0.328) 0.117** 2.30
FHLB / TA 4.300 (4.994) 0.561 (1.489) 3.739*** 12.12
Loan-to-Deposit 75.386 (17.391) 49.863 (19.522) 25.523*** 9.40
Wholesale Funding 1.714 (3.378) 0.257 (0.777) 1.457*** 7.65
MTM Loss / TA 5.848 (1.854) 8.087 (1.497) -2.239*** -10.32
Uninsured Dep. / TA 27.318 (12.490) 27.973 (10.022) -0.655 -0.45
Adj. Equity (MTM) 2.804 (3.703) -3.612 (2.584) 6.416*** 16.68
IDCR-100% 0.189 (0.181) -0.049 (0.057) 0.238*** 20.84
Sample: borrowers only (DV=1). IDCR-100% Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.

Saved: Table_DescStats_Borrowers_IDCR_BTFP.tex

— DW Borrowers: IDCR Solvent (N=403) vs. Insolvent (N=30) —
DW Borrowers (Crisis): IDCR Solvent (N=403) vs. Insolvent (N=30)
Variable Solvent Mean (SD) Insolvent Mean (SD) Difference t-stat
Log(Assets) 14.017 (1.554) 13.986 (1.906) 0.031 0.09
Cash / TA 5.801 (6.351) 5.432 (4.426) 0.369 0.43
Securities / TA 23.423 (13.452) 41.481 (16.833) -18.058*** -5.74
Loans / TA 64.860 (14.161) 47.339 (19.771) 17.521*** 4.76
Book Equity / TA 9.163 (2.953) 4.818 (2.362) 4.345*** 9.54
ROA 1.129 (0.627) 1.024 (0.563) 0.105 0.98
FHLB / TA 3.630 (4.847) 0.816 (2.120) 2.814*** 6.17
Loan-to-Deposit 77.412 (19.350) 51.434 (22.720) 25.978*** 6.10
Wholesale Funding 1.660 (3.719) 0.209 (0.621) 1.451*** 6.68
MTM Loss / TA 5.573 (1.910) 8.059 (1.446) -2.486*** -8.86
Uninsured Dep. / TA 27.907 (12.495) 30.064 (11.905) -2.157 -0.95
Adj. Equity (MTM) 3.590 (3.886) -3.241 (2.741) 6.831*** 12.73
IDCR-100% 0.198 (0.205) -0.056 (0.066) 0.254*** 16.07
Sample: borrowers only (DV=1). IDCR-100% Solvency at 2022Q4 baseline. *** p<0.01, ** p<0.05, * p<0.10.

Saved: Table_DescStats_Borrowers_IDCR_DW.tex

27.7 Panel E: Cross-Tab Summary — Both Definitions

cat("================================================================\n")
## ================================================================
cat("  PANEL E: CROSS-TABULATION — MTM vs IDCR SOLVENCY & BORROWING\n")
##   PANEL E: CROSS-TABULATION — MTM vs IDCR SOLVENCY & BORROWING
cat("================================================================\n\n")
## ================================================================
# Cross-tab: MTM × IDCR solvency × borrowing
cat("--- Cross-Tab: MTM × IDCR Solvency Classification ---\n")
## --- Cross-Tab: MTM × IDCR Solvency Classification ---
xtab_solv <- df_crisis %>%
  count(
    MTM  = ifelse(mtm_solvent == 1, "MTM-Sol", "MTM-Ins"),
    IDCR = ifelse(solvent_idcr_100 == 1, "IDCR-Sol", "IDCR-Ins")
  ) %>%
  arrange(MTM, IDCR)
print(xtab_solv)
## # A tibble: 6 × 3
##   MTM     IDCR         n
##   <chr>   <chr>    <int>
## 1 MTM-Ins IDCR-Ins   355
## 2 MTM-Ins IDCR-Sol   470
## 3 MTM-Sol IDCR-Ins     9
## 4 MTM-Sol IDCR-Sol  3417
## 5 MTM-Sol <NA>        31
## 6 <NA>    <NA>        10
# Borrowing rates within each cross-cell
cat("\n--- Borrowing Rates by Joint Solvency Status (Crisis) ---\n")
## 
## --- Borrowing Rates by Joint Solvency Status (Crisis) ---
joint_borrow <- df_crisis %>%
  mutate(
    Joint = case_when(
      mtm_solvent == 1 & solvent_idcr_100 == 1 ~ "Both Solvent",
      mtm_solvent == 1 & insolvent_idcr_100 == 1 ~ "MTM-Sol / IDCR-Ins",
      mtm_insolvent == 1 & solvent_idcr_100 == 1 ~ "MTM-Ins / IDCR-Sol",
      mtm_insolvent == 1 & insolvent_idcr_100 == 1 ~ "Both Insolvent"
    )
  ) %>%
  group_by(Joint) %>%
  summarise(
    N = n(),
    AnyFed_pct = round(100 * mean(any_fed, na.rm = TRUE), 2),
    BTFP_pct   = round(100 * mean(btfp_crisis, na.rm = TRUE), 2),
    DW_pct     = round(100 * mean(dw_crisis, na.rm = TRUE), 2),
    FHLB_pct   = round(100 * mean(fhlb_user, na.rm = TRUE), 2),
    .groups = "drop"
  )

print(joint_borrow, width = Inf)
## # A tibble: 5 × 6
##   Joint                  N AnyFed_pct BTFP_pct DW_pct FHLB_pct
##   <chr>              <int>      <dbl>    <dbl>  <dbl>    <dbl>
## 1 Both Insolvent       355       21.1     15.8   7.89     3.66
## 2 Both Solvent        3417       18.1     10.4  10.1      7.52
## 3 MTM-Ins / IDCR-Sol   470       27.7     18.7  12.1      6.81
## 4 MTM-Sol / IDCR-Ins     9       33.3     11.1  22.2      0   
## 5 <NA>                  41        0        0     0        0
cat("\n--- Key Insight ---\n")
## 
## --- Key Insight ---
n_sol_borrowers <- df_crisis %>%
  filter(mtm_solvent == 1, any_fed == 1) %>% nrow()
n_sol_total <- df_crisis %>% filter(mtm_solvent == 1) %>% nrow()
cat(sprintf("  %d out of %d MTM-solvent banks (%.1f%%) borrowed from Fed facilities\n",
    n_sol_borrowers, n_sol_total, 100 * n_sol_borrowers / n_sol_total))
##   623 out of 3457 MTM-solvent banks (18.0%) borrowed from Fed facilities
n_sol_idcr_borrowers <- df_crisis %>%
  filter(solvent_idcr_100 == 1, any_fed == 1) %>% nrow()
n_sol_idcr_total <- df_crisis %>% filter(solvent_idcr_100 == 1) %>% nrow()
cat(sprintf("  %d out of %d IDCR-solvent banks (%.1f%%) borrowed from Fed facilities\n",
    n_sol_idcr_borrowers, n_sol_idcr_total,
    100 * n_sol_idcr_borrowers / n_sol_idcr_total))
##   750 out of 3887 IDCR-solvent banks (19.3%) borrowed from Fed facilities
cat("  → Solvent banks borrowing = participation puzzle (coordination failure, not insolvency)\n")
##   → Solvent banks borrowing = participation puzzle (coordination failure, not insolvency)