Depositor Runs = f(Fundamentals, Liquidity Fragility)

Public / common shock (helps coordination in panic) = Mark-to-Market (MTM) losses on securities

Larger MTM losses → worse perceived solvency / collateral value → higher run probability especially in an acute panic window

Liquidity fragility / mismatch (amplifies run incentives) = Uninsured deposit leverage

Higher uninsured deposits (relative to liquid resources/equity) → greater rollover risk and weaker ability to meet withdrawals → higher run probability

Key interaction (panic mechanism)

MTM × Uninsured leverage: Runs rise with (i) public bad news about solvency (MTM) and (ii) rollover fragility (uninsured leverage), and the effect of MTM is strongest when uninsured leverage is high.

Identification Strategy:

  1. Baseline — Who Borrowed? \(\text{BTFP}_i = \alpha + \beta_1 \cdot \text{MTM Loss}_i + \beta_2 \cdot \text{UninsuredLev}_i + \gamma \mathbf{X}_i + \varepsilon_i\) Expect \(\beta_1 > 0\) (worse fundamentals → borrow), \(\beta_2 > 0\) (fragile banks borrowed).

  2. Interaction Model \(\text{BTFP}_i = \alpha + \beta_1 \cdot \text{MTM}_i + \beta_2 \cdot \text{UninsuredLev}_i + \beta_3 (\text{MTM}_i \times \text{UninsuredLev}_i) + \gamma \mathbf{X}_i + \varepsilon_i\) \(\beta_3 > 0\) → threshold varies with fragility (Goldstein-Pauzner).

  3. Solvent (AdjEquity > 0) vs Insolvent (AdjEquity < 0) splits.

  4. Intensive Margin — Borrowing amount conditional on borrowing.

  5. OMO Losses Only — Exploits collateral eligibility channel.

  6. Par Benefit — Treatment intensity from BTFP design.

  7. Temporal Evolution — Falsification: crisis drivers should fade post-crisis.

  8. Pre-BTFP Discount Window — Before par-value subsidy existed.

Table Map:

Paper Table Analysis Sample Method
Table 1 Extensive Margin — Baseline + Interaction (Acute) BTFP: All, Solvent, Insolvent 6 models, LPM
Table 1-DW Extensive Margin — DW (Acute) DW: All, Solvent, Insolvent 6 models, LPM
Table 1-FHLB Extensive Margin — FHLB (Acute) FHLB: All, Solvent, Insolvent 6 models, LPM
Table 2 Robustness: Acute vs Arb BTFP All 4 models, LPM
Table 3 Robustness: OMO Losses Only (Acute) BTFP All 2 models, LPM
Table 4 Robustness: Intensive Margin (Acute) BTFP Borrowers 2 models, LPM
Table 5 Robustness: Par Benefit (Acute) BTFP All 2 models, LPM
Table 6 Temporal Evolution (BTFP, DW, FHLB) All 2 per period, LPM
Table 7 Pre-BTFP DW (March 10 & March 10–13) DW All 4+ models, LPM

Sections:

  • Section 1: Main Analysis (All Banks, LPM)
  • Section 2: Solvent Bank Only (repeat Tables 2–6)
  • Section 3: Insolvent Bank Only (repeat Tables 2–6)
  • Section 4: Logit Robustness (repeat Section 1 with logit)

Controls: ln_assets, cash_ratio, loan_to_deposit, book_equity_ratio, wholesale, roa

(Note: book_equity_ratio omitted from to avoid collinearity.)


1 SETUP AND DATA PREPARATION

1.1 Packages

rm(list = ls())

# Core
library(data.table)
library(dplyr)
library(tidyr)
library(stringr)
library(lubridate)
library(purrr)
library(tibble)

# Econometrics
library(fixest)
library(marginaleffects)
library(nnet)
library(broom)

# Tables
library(modelsummary)
library(knitr)
library(kableExtra)

# Statistics
library(DescTools)

# Visualization
library(ggplot2)
library(gridExtra)
library(scales)
library(patchwork)

# I/O
library(readr)
library(readxl)

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

1.2 Helper Functions

# ==============================================================================
# CORE HELPERS
# ==============================================================================

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 ~ "")
}

# ==============================================================================
# SUMMARY STATISTICS
# ==============================================================================

summary_stats_function <- function(df, column_list, group_by = NULL) {
  summary_stat_df <- df %>% select(all_of(column_list)) %>% data.table()
  calc_stats <- function(data) {
    data %>%
      summarise(across(everything(), list(
        N    = ~ sum(!is.na(.)),
        Mean = ~ round(mean(., na.rm = TRUE), 3),
        SD   = ~ round(sd(., na.rm = TRUE), 3),
        P10  = ~ round(quantile(., 0.10, na.rm = TRUE), 3),
        P25  = ~ round(quantile(., 0.25, na.rm = TRUE), 3),
        P50  = ~ round(quantile(., 0.50, na.rm = TRUE), 3),
        P75  = ~ round(quantile(., 0.75, na.rm = TRUE), 3),
        P90  = ~ round(quantile(., 0.90, na.rm = TRUE), 3)
      ), .names = "{col}__{fn}")) %>%
      pivot_longer(cols = everything(),
                   names_to = c("Variable", ".value"), names_sep = "__")
  }
  if (!is.null(group_by)) {
    summary_stat_df %>% group_by(across(all_of(group_by))) %>% calc_stats()
  } else {
    calc_stats(summary_stat_df)
  }
}

# ==============================================================================
# FILE I/O (OneDrive resilient)
# ==============================================================================

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_table <- function(tbl, filename, caption_text = "") {
  latex_file <- file.path(TABLE_PATH, paste0(filename, ".tex"))
  latex_content <- knitr::kable(tbl, format = "latex", caption = caption_text, booktabs = TRUE)
  safe_writeLines(as.character(latex_content), latex_file)
  message("Saved: ", filename, ".tex")
}

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

1.3 Paths and Key Dates

# ==============================================================================
# PATHS — EDIT THIS BLOCK ONLY
# ==============================================================================
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/analysis_all_specification")
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)
}

# ==============================================================================
# KEY DATES AND PERIODS
# ==============================================================================
BASELINE_MAIN <- "2022Q4"
BASELINE_ARB  <- "2023Q3"
BASELINE_WIND <- "2023Q4"

DATE_MAR01 <- as.Date("2023-03-01")
DATE_MAR09 <- as.Date("2023-03-09")
DATE_MAR10 <- as.Date("2023-03-10")
DATE_MAR12 <- as.Date("2023-03-12")
DATE_MAR13 <- as.Date("2023-03-13")
DATE_MAR14 <- as.Date("2023-03-14")

ACUTE_START     <- as.Date("2023-03-13")
ACUTE_END       <- as.Date("2023-05-01")
POST_ACUTE_END  <- as.Date("2023-10-31")
ARB_START       <- as.Date("2023-11-01")
ARB_END         <- as.Date("2024-01-24")
WIND_START      <- as.Date("2024-01-25")
WIND_END        <- as.Date("2024-03-11")
DW_DATA_END     <- as.Date("2023-12-31")
OVERALL_START   <- as.Date("2023-03-01")
OVERALL_END     <- as.Date("2024-03-11")

1.4 Load Data

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

btfp_loans_raw <- read_csv(file.path(DATA_PROC, "btfp_loan_bank_only.csv"), show_col_types = FALSE) %>%
  mutate(rssd_id = as.character(rssd_id), btfp_loan_date = mdy(btfp_loan_date))

dw_loans_raw <- read_csv(file.path(DATA_PROC, "dw_loan_bank_2023.csv"), show_col_types = FALSE) %>%
  mutate(rssd_id = as.character(rssd_id), dw_loan_date = ymd(dw_loan_date))

cat("=== 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), "| DW Loans:", nrow(dw_loans_raw), "\n")
## BTFP Loans: 6734 | DW Loans: 10008

1.5 Exclude Failed Banks and G-SIBs

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

cat("Excluded banks (failed + G-SIBs):", length(excluded_banks), "\n")
## Excluded banks (failed + G-SIBs): 41
btfp_loans <- btfp_loans_raw %>% filter(!rssd_id %in% excluded_banks)
dw_loans   <- dw_loans_raw   %>% filter(!rssd_id %in% excluded_banks)

1.6 Borrower Indicator Factory

# ==============================================================================
# Creates period-specific borrower indicators from loan-level data
# ==============================================================================

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 indicators ---
btfp_mar10    <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", DATE_MAR10, DATE_MAR10, "btfp_mar10")
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `btfp_mar10_first = min(btfp_loan_date)`.
## Caused by warning in `min.default()`:
## ! no non-missing arguments to min; returning Inf
btfp_mar10_13 <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", DATE_MAR10, DATE_MAR13, "btfp_mar10_13")
btfp_acute    <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", ACUTE_START, ACUTE_END, "btfp_acute")
btfp_post     <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", ACUTE_END + 1, POST_ACUTE_END, "btfp_post")
btfp_arb      <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", ARB_START, ARB_END, "btfp_arb")
btfp_wind     <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", WIND_START, WIND_END, "btfp_wind")
btfp_overall  <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount", OVERALL_START, OVERALL_END, "btfp_overall")

# --- DW indicators ---
dw_prebtfp  <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", DATE_MAR01, DATE_MAR12, "dw_prebtfp")
dw_mar10    <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", DATE_MAR10, DATE_MAR10, "dw_mar10")
dw_mar10_13 <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", DATE_MAR10, DATE_MAR13, "dw_mar10_13")
dw_acute    <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", ACUTE_START, min(ACUTE_END, DW_DATA_END), "dw_acute")
dw_post     <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", ACUTE_END + 1, min(POST_ACUTE_END, DW_DATA_END), "dw_post")
dw_overall  <- create_borrower_indicator(dw_loans, "dw_loan_date", "rssd_id", "dw_loan_amount", OVERALL_START, DW_DATA_END, "dw_overall")

cat("\n=== BORROWER COUNTS ===\n")
## 
## === BORROWER COUNTS ===
cat("BTFP: Mar10=", nrow(btfp_mar10), " Acute=", nrow(btfp_acute),
    " Post=", nrow(btfp_post), " Arb=", nrow(btfp_arb), " Wind=", nrow(btfp_wind), "\n")
## BTFP: Mar10= 0  Acute= 485  Post= 811  Arb= 797  Wind= 237
cat("DW: Pre=", nrow(dw_prebtfp), " Acute=", nrow(dw_acute), " Post=", nrow(dw_post), "\n")
## DW: Pre= 106  Acute= 417  Post= 954

1.7 Variable Construction

# ==============================================================================
# UNIFIED VARIABLE CONSTRUCTION
# Builds BOTH the AE and MTM variables in a single pass
# ==============================================================================

construct_analysis_vars <- function(baseline_data) {
  baseline_data %>%
    mutate(
      # =======================================================================
      # RAW VARIABLES (for descriptive tables — original scale)
      # =======================================================================
      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,
      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,
      tier1_ratio_raw       = tier1cap_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,
      
      # Deposit outflows (forward-looking)
      uninsured_outflow_raw = change_uninsured_fwd_q,
      insured_outflow_raw   = change_insured_deposit_fwd_q,
      total_outflow_raw     = change_total_deposit_fwd_q,
      
      # =======================================================================
      # ADJUSTED EQUITY (the primary solvency measure)
      # AE = Book Equity - MTM Losses, as % of assets
      # This is theta in Goldstein-Pauzner: the bank's TRUE economic position
      # =======================================================================
      adjusted_equity_raw = book_equity_to_total_asset - mtm_loss_to_total_asset,
      
      # =======================================================================
      # JIANG ET AL. INSOLVENCY MEASURES
      # =======================================================================
      mv_assets = total_asset * (1 - mtm_loss_to_total_asset / 100),
      
      idcr_1 = safe_div(
        mv_assets - 0.5 * uninsured_deposit - insured_deposit,
        insured_deposit, NA_real_),
      idcr_2 = safe_div(
        mv_assets - uninsured_deposit - insured_deposit,
        insured_deposit, NA_real_),
      
      mtm_insolvent     = as.integer(adjusted_equity_raw < 0),
      mtm_solvent       = as.integer(adjusted_equity_raw >= 0),
      insolvent_idcr_s50  = as.integer(idcr_1 < 0),
      insolvent_idcr_s100 = as.integer(idcr_2 < 0),
      
      # =======================================================================
      # WINSORIZED VARIABLES (2.5% / 97.5%)
      # =======================================================================
      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),
      adjusted_equity_w = winsorize(adjusted_equity_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),
      uninsured_outflow_w = winsorize(uninsured_outflow_raw),
      insured_outflow_w   = winsorize(insured_outflow_raw),
      total_outflow_w     = winsorize(total_outflow_raw),
      
      # =======================================================================
      # Z-SCORE STANDARDIZED (for regression — interpret as 1-SD change)
      # =======================================================================
      # --- Primary: Adjusted Equity framework ---
      adjusted_equity   = standardize_z(adjusted_equity_w),
      uninsured_lev     = standardize_z(uninsured_lev_w),
      ae_x_uninsured    = adjusted_equity * uninsured_lev,
      
      # --- Robustness: MTM framework ---
      mtm_total         = standardize_z(mtm_total_w),
      mtm_btfp          = standardize_z(mtm_btfp_w),
      mtm_other         = standardize_z(mtm_other_w),
      mtm_x_uninsured   = mtm_total * uninsured_lev,
      mtm_omo_x_uninsured    = mtm_btfp * uninsured_lev,
      mtm_nonomo_x_uninsured = mtm_other * uninsured_lev,
      
      # --- Controls ---
      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),
      
      # --- Deposit outflows (standardized) ---
      uninsured_outflow = standardize_z(uninsured_outflow_w),
      insured_outflow   = standardize_z(insured_outflow_w),
      total_outflow     = standardize_z(total_outflow_w),
      
      # --- Par Benefit and Collateral Capacity ---
      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 category
      size_cat = factor(create_size_category_3(total_asset), levels = size_levels_3),
      
      # Clustering variables
      state        = if ("state" %in% names(.)) state else NA_character_,
      fed_district = if ("fed_district" %in% names(.)) fed_district else NA_character_
    ) %>%
    # --- Par Benefit: winsorize and standardize (needs prior columns) ---
    mutate(
      par_benefit_w     = winsorize(par_benefit_raw),
      par_benefit       = standardize_z(par_benefit_w),
      par_x_uninsured   = par_benefit * uninsured_lev
    )
}

# ==============================================================================
# QUARTILE DUMMIES AND RISK CATEGORIES
# ==============================================================================

add_run_risk_dummies <- function(data) {
  
  # Median splits for 2x2 risk categories
  medians <- data %>%
    summarise(median_mtm = median(mtm_total_w, na.rm = TRUE),
              median_uninsured = median(uninsured_lev_w, na.rm = TRUE))
  
  # Quartile breakpoints
  quartiles <- data %>%
    summarise(
      adj_eq_q1    = quantile(adjusted_equity_w, 0.25, na.rm = TRUE),
      adj_eq_q2    = quantile(adjusted_equity_w, 0.50, na.rm = TRUE),
      adj_eq_q3    = quantile(adjusted_equity_w, 0.75, na.rm = TRUE),
      unins_lev_q1 = quantile(uninsured_lev_w, 0.25, na.rm = TRUE),
      unins_lev_q2 = quantile(uninsured_lev_w, 0.50, na.rm = TRUE),
      unins_lev_q3 = quantile(uninsured_lev_w, 0.75, na.rm = TRUE),
      mtm_q1       = quantile(mtm_total_w, 0.25, na.rm = TRUE),
      mtm_q2       = quantile(mtm_total_w, 0.50, na.rm = TRUE),
      mtm_q3       = quantile(mtm_total_w, 0.75, na.rm = TRUE)
    )
  
  data %>%
    mutate(
      # --- 2x2 Median-split Risk Dummies (MTM-based, reference = Risk 1) ---
      run_risk_1 = replace_na(as.integer(mtm_total_w <  medians$median_mtm & uninsured_lev_w <  medians$median_uninsured), 0L),
      run_risk_2 = replace_na(as.integer(mtm_total_w <  medians$median_mtm & uninsured_lev_w >= medians$median_uninsured), 0L),
      run_risk_3 = replace_na(as.integer(mtm_total_w >= medians$median_mtm & uninsured_lev_w <  medians$median_uninsured), 0L),
      run_risk_4 = replace_na(as.integer(mtm_total_w >= medians$median_mtm & uninsured_lev_w >= medians$median_uninsured), 0L),
      
      # --- Adjusted Equity Quartiles (ref = Q4 = strongest solvency) ---
      adj_equity_q1 = replace_na(as.integer(adjusted_equity_w <= quartiles$adj_eq_q1), 0L),
      adj_equity_q2 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q1 & adjusted_equity_w <= quartiles$adj_eq_q2), 0L),
      adj_equity_q3 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q2 & adjusted_equity_w <= quartiles$adj_eq_q3), 0L),
      
      # --- Uninsured Leverage Quartiles (ref = Q1 = lowest fragility) ---
      unins_lev_q2 = replace_na(as.integer(uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      unins_lev_q3 = replace_na(as.integer(uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      unins_lev_q4 = replace_na(as.integer(uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      # Uninsured Leverage tercile (for threshold gradient figure)
      unins_lev_tercile = cut(uninsured_lev_w,
                              breaks = quantile(uninsured_lev_w, c(0, 1/3, 2/3, 1), na.rm = TRUE),
                              labels = c("Low", "Med", "High"), include.lowest = TRUE),
      
      # --- MTM Quartiles (ref = Q1 = lowest loss) ---
      mtm_q2 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q1 & mtm_total_w <= quartiles$mtm_q2), 0L),
      mtm_q3 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q2 & mtm_total_w <= quartiles$mtm_q3), 0L),
      mtm_q4 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q3), 0L),
      
      # =======================================================================
      # 16-CELL AE x UNINSURED LEVERAGE (ref = aeq4_ulq1: safest cell)
      # =======================================================================
      aeq1_ulq1 = replace_na(as.integer(adjusted_equity_w <= quartiles$adj_eq_q1 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),
      aeq1_ulq2 = replace_na(as.integer(adjusted_equity_w <= quartiles$adj_eq_q1 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      aeq1_ulq3 = replace_na(as.integer(adjusted_equity_w <= quartiles$adj_eq_q1 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      aeq1_ulq4 = replace_na(as.integer(adjusted_equity_w <= quartiles$adj_eq_q1 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      aeq2_ulq1 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q1 & adjusted_equity_w <= quartiles$adj_eq_q2 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),
      aeq2_ulq2 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q1 & adjusted_equity_w <= quartiles$adj_eq_q2 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      aeq2_ulq3 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q1 & adjusted_equity_w <= quartiles$adj_eq_q2 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      aeq2_ulq4 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q1 & adjusted_equity_w <= quartiles$adj_eq_q2 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      aeq3_ulq1 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q2 & adjusted_equity_w <= quartiles$adj_eq_q3 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),
      aeq3_ulq2 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q2 & adjusted_equity_w <= quartiles$adj_eq_q3 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      aeq3_ulq3 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q2 & adjusted_equity_w <= quartiles$adj_eq_q3 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      aeq3_ulq4 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q2 & adjusted_equity_w <= quartiles$adj_eq_q3 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      aeq4_ulq1 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q3 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),  # REFERENCE
      aeq4_ulq2 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q3 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      aeq4_ulq3 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q3 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      aeq4_ulq4 = replace_na(as.integer(adjusted_equity_w > quartiles$adj_eq_q3 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      # =======================================================================
      # 16-CELL MTM x UNINSURED LEVERAGE (ref = mtmq1_ulq1)
      # =======================================================================
      mtmq1_ulq1 = replace_na(as.integer(mtm_total_w <= quartiles$mtm_q1 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),  # REFERENCE
      mtmq1_ulq2 = replace_na(as.integer(mtm_total_w <= quartiles$mtm_q1 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      mtmq1_ulq3 = replace_na(as.integer(mtm_total_w <= quartiles$mtm_q1 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      mtmq1_ulq4 = replace_na(as.integer(mtm_total_w <= quartiles$mtm_q1 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      mtmq2_ulq1 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q1 & mtm_total_w <= quartiles$mtm_q2 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),
      mtmq2_ulq2 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q1 & mtm_total_w <= quartiles$mtm_q2 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      mtmq2_ulq3 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q1 & mtm_total_w <= quartiles$mtm_q2 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      mtmq2_ulq4 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q1 & mtm_total_w <= quartiles$mtm_q2 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      mtmq3_ulq1 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q2 & mtm_total_w <= quartiles$mtm_q3 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),
      mtmq3_ulq2 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q2 & mtm_total_w <= quartiles$mtm_q3 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      mtmq3_ulq3 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q2 & mtm_total_w <= quartiles$mtm_q3 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      mtmq3_ulq4 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q2 & mtm_total_w <= quartiles$mtm_q3 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      mtmq4_ulq1 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q3 & uninsured_lev_w <= quartiles$unins_lev_q1), 0L),
      mtmq4_ulq2 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q3 & uninsured_lev_w > quartiles$unins_lev_q1 & uninsured_lev_w <= quartiles$unins_lev_q2), 0L),
      mtmq4_ulq3 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q3 & uninsured_lev_w > quartiles$unins_lev_q2 & uninsured_lev_w <= quartiles$unins_lev_q3), 0L),
      mtmq4_ulq4 = replace_na(as.integer(mtm_total_w > quartiles$mtm_q3 & uninsured_lev_w > quartiles$unins_lev_q3), 0L),
      
      # Store cutoff values for reporting
      median_mtm_used       = medians$median_mtm,
      median_uninsured_used = medians$median_uninsured
    )
}

1.8 Create Baselines and Period Datasets

# ==============================================================================
# BASELINE DATASETS (one per Call Report quarter)
# ==============================================================================
df_2022q4 <- call_q %>%
  filter(period == BASELINE_MAIN, !idrssd %in% excluded_banks,
         !is.na(omo_eligible) & omo_eligible > 0) %>%
  construct_analysis_vars() %>% add_run_risk_dummies()

df_2023q3 <- call_q %>%
  filter(period == BASELINE_ARB, !idrssd %in% excluded_banks,
         !is.na(omo_eligible) & omo_eligible > 0) %>%
  construct_analysis_vars() %>% add_run_risk_dummies()

df_2023q4 <- call_q %>%
  filter(period == BASELINE_WIND, !idrssd %in% excluded_banks,
         !is.na(omo_eligible) & omo_eligible > 0) %>%
  construct_analysis_vars() %>% add_run_risk_dummies()

cat("=== BASELINE DATASETS ===\n")
## === BASELINE DATASETS ===
cat("2022Q4:", nrow(df_2022q4), "| 2023Q3:", nrow(df_2023q3), "| 2023Q4:", nrow(df_2023q4), "\n")
## 2022Q4: 4292 | 2023Q3: 4214 | 2023Q4: 4197
cat("\n=== INSOLVENCY COUNTS (2022Q4) ===\n")
## 
## === INSOLVENCY COUNTS (2022Q4) ===
cat("MTM Insolvent (AE < 0):", sum(df_2022q4$mtm_insolvent, na.rm = TRUE), "\n")
## MTM Insolvent (AE < 0): 825
cat("IDCR 50% Insolvent:", sum(df_2022q4$insolvent_idcr_s50, na.rm = TRUE), "\n")
## IDCR 50% Insolvent: 16
cat("IDCR 100% Insolvent:", sum(df_2022q4$insolvent_idcr_s100, na.rm = TRUE), "\n")
## IDCR 100% Insolvent: 364
# ==============================================================================
# JOIN BORROWER INDICATORS TO BASELINES
# ==============================================================================

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),
      user_group = factor(case_when(
        !!sym(btfp_var) == 1 & !!sym(dw_var) == 1 ~ "Both",
        !!sym(btfp_var) == 1 ~ "BTFP_Only",
        !!sym(dw_var) == 1   ~ "DW_Only",
        TRUE                 ~ "Neither"
      ), levels = c("Neither", "BTFP_Only", "DW_Only", "Both")),
      any_fed  = as.integer(!!sym(btfp_var) == 1 | !!sym(dw_var) == 1),
      non_user = as.integer(!!sym(btfp_var) == 0 & !!sym(dw_var) == 0 & fhlb_user == 0)
    )
}

# --- Acute Period ---
df_acute <- join_all_borrowers(df_2022q4, btfp_acute, dw_acute, "btfp_acute", "dw_acute") %>%
  mutate(
    btfp_pct     = ifelse(btfp_acute == 1 & btfp_acute_amt > 0,
                          100 * btfp_acute_amt / (total_asset * 1000), NA_real_),
    dw_pct       = ifelse(dw_acute == 1 & dw_acute_amt > 0,
                          100 * dw_acute_amt / (total_asset * 1000), NA_real_),
    log_btfp_amt = ifelse(btfp_acute == 1 & btfp_acute_amt > 0, log(btfp_acute_amt), NA_real_),
    log_dw_amt   = ifelse(dw_acute == 1 & dw_acute_amt > 0, log(dw_acute_amt), NA_real_)
  )

# --- Pre-BTFP (Mar 1 - Mar 12) ---
btfp_prebtfp <- create_borrower_indicator(btfp_loans, "btfp_loan_date", "rssd_id", "btfp_loan_amount",
                                           DATE_MAR01, DATE_MAR12, "btfp_prebtfp")
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `btfp_prebtfp_first = min(btfp_loan_date)`.
## Caused by warning in `min.default()`:
## ! no non-missing arguments to min; returning Inf
df_prebtfp <- join_all_borrowers(df_2022q4, btfp_prebtfp, dw_prebtfp, "btfp_prebtfp", "dw_prebtfp")

# --- Mar 10 only ---
df_mar10 <- join_all_borrowers(df_2022q4, btfp_mar10, dw_mar10, "btfp_mar10", "dw_mar10")

# --- Mar 10-13 ---
df_mar10_13 <- join_all_borrowers(df_2022q4, btfp_mar10_13, dw_mar10_13, "btfp_mar10_13", "dw_mar10_13")

# --- Post-Acute Period ---
df_post <- df_2022q4 %>%
  left_join(btfp_post %>% select(idrssd, btfp_post, btfp_post_amt), by = "idrssd") %>%
  left_join(dw_post %>% select(idrssd, dw_post, dw_post_amt), by = "idrssd") %>%
  mutate(btfp_post = replace_na(btfp_post, 0L), dw_post = replace_na(dw_post, 0L),
         fhlb_user = as.integer(abnormal_fhlb_borrowing_10pct == 1),
         any_fed = as.integer(btfp_post == 1 | dw_post == 1),
         non_user = as.integer(btfp_post == 0 & dw_post == 0 & fhlb_user == 0),
         user_group = factor(case_when(
           btfp_post == 1 & dw_post == 1 ~ "Both", btfp_post == 1 ~ "BTFP_Only",
           dw_post == 1 ~ "DW_Only", TRUE ~ "Neither"),
           levels = c("Neither", "BTFP_Only", "DW_Only", "Both")))

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

# --- Wind-down Period (2023Q4 baseline) ---
df_wind <- df_2023q4 %>%
  left_join(btfp_wind %>% select(idrssd, btfp_wind, btfp_wind_amt), by = "idrssd") %>%
  mutate(btfp_wind = replace_na(btfp_wind, 0L),
         fhlb_user = as.integer(abnormal_fhlb_borrowing_10pct == 1),
         any_fed = btfp_wind,
         non_user = as.integer(btfp_wind == 0 & fhlb_user == 0),
         user_group = factor(ifelse(btfp_wind == 1, "BTFP_Only", "Neither"),
                             levels = c("Neither", "BTFP_Only", "DW_Only", "Both")))

cat("\n=== USER GROUP COUNTS (ACUTE) ===\n")
## 
## === USER GROUP COUNTS (ACUTE) ===
print(table(df_acute$user_group))
## 
##   Neither BTFP_Only   DW_Only      Both 
##      3531       368       299        94
cat("Pure Non-Users:", sum(df_acute$non_user), "\n")
## Pure Non-Users: 3285

1.9 Model Infrastructure

# ==============================================================================
# MODEL INFRASTRUCTURE
#   CONTROLS_MTM — used with raw MTM (includes book_equity_ratio)
# ==============================================================================

# ==============================================================================
# MODEL INFRASTRUCTURE
# ==============================================================================

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

# ==============================================================================
# FIXEST DICTIONARY (labels for etable output)
# ==============================================================================
setFixest_dict(c(
  # Primary: Explanatory
  mtm_total          = "MTM Loss (z)",
  uninsured_lev      = "Uninsured Leverage (z)",
  # (Duplicate mtm_total removed)
  mtm_btfp           = "MTM Loss OMO (z)",
  mtm_other          = "MTM Loss Non-OMO (z)",
  mtm_x_uninsured    = "MTM $\\times$ Uninsured",
  mtm_omo_x_uninsured    = "MTM OMO $\\times$ Uninsured",
  mtm_nonomo_x_uninsured = "MTM Non-OMO $\\times$ Uninsured",
  
  # Par Benefit
  par_benefit        = "Par Benefit (z)",
  par_x_uninsured    = "Par Benefit $\\times$ Uninsured",

  # AE quartile dummies
  adj_equity_q1 = "Adj. Equity Q1 (Lowest)", adj_equity_q2 = "Adj. Equity Q2", adj_equity_q3 = "Adj. Equity Q3",

  # UL quartile dummies
  unins_lev_q2 = "Unins. Lev. Q2", unins_lev_q3 = "Unins. Lev. Q3", unins_lev_q4 = "Unins. Lev. Q4 (Highest)",

  # MTM quartile dummies
  mtm_q2 = "MTM Q2", mtm_q3 = "MTM Q3", mtm_q4 = "MTM Q4 (Highest Loss)",

  # Controls
  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"
))

# ==============================================================================
# EXPLANATORY VARIABLE STRINGS
# ==============================================================================

# --- Primary: Adjusted Equity ---
EXPL_MTM_BASE    <- "mtm_total + uninsured_lev"
EXPL_MTM_INTER   <- "mtm_total + uninsured_lev + mtm_x_uninsured"

# --- Mechanism: OMO Decomposition ---
EXPL_OMO_BASE    <- "mtm_btfp + uninsured_lev"
EXPL_OMO_INTER   <- "mtm_btfp + uninsured_lev + mtm_omo_x_uninsured"
EXPL_OMO_DECOMP  <- "mtm_btfp + mtm_other + uninsured_lev"
EXPL_OMO_HORSE   <- "mtm_btfp + mtm_other + uninsured_lev + mtm_omo_x_uninsured + mtm_nonomo_x_uninsured"

# --- Par Benefit ---
EXPL_PAR_BASE    <- "par_benefit + uninsured_lev"
EXPL_PAR_INTER   <- "par_benefit + uninsured_lev + par_x_uninsured"


# ==============================================================================
# COEFFICIENT DISPLAY ORDER
# ==============================================================================
COEF_ORDER <- c(
  "Constant",
  "MTM Loss", 
  "Uninsured Leverage",
  "MTM.*Uninsured", 
  "MTM Loss OMO", "MTM Loss Non-OMO","Par Benefit",
  "MTM OMO.*Uninsured", "MTM Non-OMO.*Uninsured", "Par Benefit.*Uninsured"
)

# ==============================================================================
# GENERIC MODEL RUNNER
# ==============================================================================
run_one <- function(data, dv, explanatory, family_type = "lpm", controls = CONTROLS_MTM) {
  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")
  }
}

# ==============================================================================
# BATCH MODEL RUNNER: Base + Interaction (Refactored)
# ==============================================================================
run_base_inter <- function(data, dv, framework = "mtm", family_type = "lpm") {
  
  # 1. Define the mapping of frameworks to their formula strings
  framework_map <- list(
    mtm = list(base = EXPL_MTM_BASE, inter = EXPL_MTM_INTER),
    omo = list(base = EXPL_OMO_BASE, inter = EXPL_OMO_INTER),
    par = list(base = EXPL_PAR_BASE, inter = EXPL_PAR_INTER)
  )
  
  # 2. Check to ensure valid framework input
  if (!framework %in% names(framework_map)) {
    stop("Error: Framework '", framework, "' not found. Options: ", 
         paste(names(framework_map), collapse = ", "))
  }
  
  # 3. Retrieve the formulas
  forms <- framework_map[[framework]]
  
  # 4. Run the models
  list(
    base  = run_one(data, dv, forms$base,  family_type, CONTROLS_MTM),
    inter = run_one(data, dv, forms$inter, family_type, CONTROLS_MTM)
  )
}





# ==============================================================================
# ETABLE SAVER (produces .tex files)
# ==============================================================================
save_etable <- function(models, filename, title_text, notes_text,
                        fitstat_use = ~ n + r2, extra_lines = NULL) {
  
  # Export to LaTeX (Force SE below coefficient)
  etable(models, 
         title = title_text, 
         notes = notes_text, 
         fitstat = fitstat_use,
         order = COEF_ORDER, 
         extralines = extra_lines,
         se.below = TRUE,                     # <--- Enforces SE below coefficient
         tex = TRUE, 
         file = file.path(TABLE_PATH, paste0(filename, ".tex")),
         replace = TRUE, 
         style.tex = style.tex("aer")
  )
  message("Saved: ", filename, ".tex")
}

# ==============================================================================
# VISUALIZATION THEME
# ==============================================================================
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)
  )

pal_user <- c("DW" = "#D62828", "BTFP" = "#003049", "FHLB" = "#F77F00",
              "Pure Non-Borrower" = "grey70", "Both" = "#7209B7")

1.10 Regression Samples

# ==============================================================================
# PURE COMPARISON SAMPLES: facility borrowers vs pure non-borrowers
# ==============================================================================

# --- Acute Period ---
df_btfp_s  <- df_acute %>% filter(btfp_acute == 1 | non_user == 1)
df_dw_s    <- df_acute %>% filter(dw_acute == 1   | non_user == 1)
df_fhlb_s  <- df_acute %>% filter(fhlb_user == 1  | non_user == 1)

# --- Solvency subsamples (Acute) ---
df_btfp_sol <- df_btfp_s %>% filter(mtm_solvent == 1)
df_btfp_ins <- df_btfp_s %>% filter(mtm_insolvent == 1)
df_dw_sol   <- df_dw_s   %>% filter(mtm_solvent == 1)
df_dw_ins   <- df_dw_s   %>% filter(mtm_insolvent == 1)
df_fhlb_sol <- df_fhlb_s %>% filter(mtm_solvent == 1)
df_fhlb_ins <- df_fhlb_s %>% filter(mtm_insolvent == 1)

# --- Pre-BTFP DW ---
df_dw_pre_s    <- df_prebtfp %>% filter(dw_prebtfp == 1 | non_user == 1)
df_dw_mar10_s  <- df_mar10   %>% filter(dw_mar10 == 1   | non_user == 1)
df_dw_mar10_13_s <- df_mar10_13 %>% filter(dw_mar10_13 == 1 | non_user == 1)

# --- Post-Acute ---
df_btfp_post_s <- df_post %>% filter(btfp_post == 1 | non_user == 1)
df_dw_post_s   <- df_post %>% filter(dw_post == 1   | non_user == 1)
df_fhlb_post_s <- df_post %>% filter(fhlb_user == 1 | non_user == 1)

# --- Arbitrage ---
df_btfp_arb_s  <- df_arb  %>% filter(btfp_arb == 1  | non_user == 1)
df_fhlb_arb_s  <- df_arb  %>% filter(fhlb_user == 1 | non_user == 1)

# --- Wind-down ---
df_btfp_wind_s <- df_wind %>% filter(btfp_wind == 1 | non_user == 1)
df_fhlb_wind_s <- df_wind %>% filter(fhlb_user == 1 | non_user == 1)

cat("=== REGRESSION SAMPLES (Acute) ===\n")
## === REGRESSION SAMPLES (Acute) ===
cat("BTFP vs Non:", nrow(df_btfp_s), "(BTFP =", sum(df_btfp_s$btfp_acute), ")\n")
## BTFP vs Non: 3747 (BTFP = 462 )
cat("DW vs Non:",   nrow(df_dw_s),   "(DW =",   sum(df_dw_s$dw_acute), ")\n")
## DW vs Non: 3678 (DW = 393 )
cat("FHLB vs Non:", nrow(df_fhlb_s), "(FHLB =", sum(df_fhlb_s$fhlb_user), ")\n")
## FHLB vs Non: 3587 (FHLB = 302 )
cat("Including Non User: BTFP Solvent:", nrow(df_btfp_sol), "| BTFP Insolvent:", nrow(df_btfp_ins), "\n")
## Including Non User: BTFP Solvent: 3003 | BTFP Insolvent: 734

2 SECTION 1: MAIN ANALYSIS (ALL BANKS — LPM)

2.1 Table 1: Extensive Margin — BTFP (Acute Period)

Primary specification. Columns 1–2: All banks. Columns 3–4: Solvent banks (AdjEquity ≥ 0). Columns 5–6: Insolvent banks (AdjEquity < 0). Uses Adjusted Equity framework (LPM).

\[ \Pr(\text{BTFP}_i = 1) = \alpha + \beta_1 \cdot \text{MTM Loss}_i + \beta_2 \cdot \text{UninsLev}_i + \beta_3 (\text{MTM Loss}_i \times \text{UninsLev}_i) + \gamma \mathbf{X}_i + \varepsilon_i \]

Predictions: \(\beta_1 < 0\) (weaker solvency → borrow), \(\beta_2 > 0\) (fragile → borrow), \(\beta_3 < 0\) (interaction: solvency effect stronger among fragile banks).

# ==============================================================================
# TABLE 1: EXTENSIVE MARGIN — BTFP (ACUTE)
# 6 columns: All (base, inter), Solvent (base, inter), Insolvent (base, inter)
# ==============================================================================

models_t1 <- list(
  "(1) All"       = run_one(df_btfp_s,   "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) All"       = run_one(df_btfp_s,   "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Solvent"   = run_one(df_btfp_sol, "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Solvent"   = run_one(df_btfp_sol, "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Insolvent" = run_one(df_btfp_ins, "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Insolvent" = run_one(df_btfp_ins, "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t1_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_s$btfp_acute), sum(df_btfp_s$btfp_acute),
                     sum(df_btfp_sol$btfp_acute), sum(df_btfp_sol$btfp_acute),
                     sum(df_btfp_ins$btfp_acute), sum(df_btfp_ins$btfp_acute)),
  "__Subsample" = c("All", "All", "Solvent", "Solvent", "Insolvent", "Insolvent"),
  "__Framework" = rep("Adjusted Equity", 6)
)

# --- DISPLAY (HTML) ---

etable(models_t1, 
       fitstat = ~ n + r2,
       order = COEF_ORDER, 
       extralines = t1_extra,
       se.below = TRUE,         # <--- Puts standard errors below coefficients
       digits = 4,              # <--- Increases decimal precision
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),
       title = "Table 1: BTFP Extensive Margin — Acute Period (LPM)")
##                                (1) All         (2) All      (3) Solv..
## Dependent Var.:             btfp_acute      btfp_acute      btfp_acute
##                                                                       
## Constant                     0.1293***       0.1316***       0.1263***
##                             (0.0054)        (0.0055)        (0.0064)  
## MTM Loss (z)                 0.0198***       0.0243***       0.0193***
##                             (0.0055)        (0.0059)        (0.0062)  
## Uninsured Leverage (z)       0.0154**        0.0199***       0.0162** 
##                             (0.0063)        (0.0068)        (0.0068)  
## MTM $\times$ Uninsured                       0.0181***                
##                                             (0.0051)                  
## Log(Assets)                  0.0676***       0.0674***       0.0621***
##                             (0.0074)        (0.0074)        (0.0080)  
## Cash Ratio                  -0.0255***      -0.0238***      -0.0236***
##                             (0.0047)        (0.0046)        (0.0047)  
## Loan-to-Deposit             -0.0117**       -0.0083         -0.0111*  
##                             (0.0055)        (0.0055)        (0.0058)  
## Book Equity Ratio           -0.0123***      -0.0109**       -0.0088** 
##                             (0.0044)        (0.0044)        (0.0044)  
## Wholesale Funding            0.0258***       0.0252***       0.0264***
##                             (0.0064)        (0.0064)        (0.0070)  
## ROA                         -0.0028         -0.0048          0.0011   
##                             (0.0047)        (0.0047)        (0.0049)  
## ______________________      __________      __________      __________
## S.E. type                   Hete.-rob.      Hete.-rob.      Hete.-rob.
## Observations                     3,737           3,737           3,003
## R2                             0.08704         0.09017         0.08692
## N(BTFP=1)                          462             462             330
## Subsample                          All             All         Solvent
## Framework              Adjusted Equity Adjusted Equity Adjusted Equity
## 
##                             (4) Solv..      (5) Inso..      (6) Inso..
## Dependent Var.:             btfp_acute      btfp_acute      btfp_acute
##                                                                       
## Constant                     0.1303***       0.0017          0.0168   
##                             (0.0068)        (0.0544)        (0.0541)  
## MTM Loss (z)                 0.0262***       0.0314          0.0289   
##                             (0.0070)        (0.0260)        (0.0259)  
## Uninsured Leverage (z)       0.0255***       0.0233         -0.0213   
##                             (0.0080)        (0.0177)        (0.0262)  
## MTM $\times$ Uninsured       0.0185***                       0.0443*  
##                             (0.0059)                        (0.0226)  
## Log(Assets)                  0.0610***       0.1016***       0.0995***
##                             (0.0080)        (0.0207)        (0.0208)  
## Cash Ratio                  -0.0221***      -0.0599***      -0.0588***
##                             (0.0047)        (0.0203)        (0.0202)  
## Loan-to-Deposit             -0.0091          0.0143          0.0176   
##                             (0.0057)        (0.0196)        (0.0197)  
## Book Equity Ratio           -0.0074*        -0.1332***      -0.1269***
##                             (0.0045)        (0.0404)        (0.0403)  
## Wholesale Funding            0.0257***       0.0185          0.0170   
##                             (0.0070)        (0.0144)        (0.0143)  
## ROA                         -0.0005         -0.0341**       -0.0344** 
##                             (0.0049)        (0.0146)        (0.0145)  
## ______________________      __________      __________      __________
## S.E. type                   Hete.-rob.      Hete.-rob.      Hete.-rob.
## Observations                     3,003             734             734
## R2                             0.08991         0.08892         0.09341
## N(BTFP=1)                          330             132             132
## Subsample                      Solvent       Insolvent       Insolvent
## Framework              Adjusted Equity Adjusted Equity Adjusted Equity
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
# --- SAVE (LaTeX) ---

save_etable(models_t1, "Table_1_BTFP_Extensive",
            title_text = "BTFP Extensive Margin: (Acute Period)",
            notes_text = "LPM with robust SEs. Sample: BTFP borrowers vs. pure non-borrowers. Solvent: AdjEquity $\\geq$ 0. Insolvent: AdjEquity $<$ 0. All regressors z-standardized. Controls: log(assets), cash ratio, loan-to-deposit, wholesale, ROA, Book equity . Baseline: 2022Q4.",
            extra_lines = t1_extra)
## Saved: Table_1_BTFP_Extensive.tex

2.2 Table 1-DW: Extensive Margin — DW (Acute Period)

# ==============================================================================
# TABLE 1-DW: EXTENSIVE MARGIN — DISCOUNT WINDOW (ACUTE)
# ==============================================================================

models_t1_dw <- list(
  "(1) All"       = run_one(df_dw_s,   "dw_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) All"       = run_one(df_dw_s,   "dw_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Solvent"   = run_one(df_dw_sol, "dw_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Solvent"   = run_one(df_dw_sol, "dw_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Insolvent" = run_one(df_dw_ins, "dw_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Insolvent" = run_one(df_dw_ins, "dw_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t1_dw_extra <- list(
  "__N(DW=1)" = c(sum(df_dw_s$dw_acute), sum(df_dw_s$dw_acute),
                   sum(df_dw_sol$dw_acute), sum(df_dw_sol$dw_acute),
                   sum(df_dw_ins$dw_acute), sum(df_dw_ins$dw_acute)),
  "__Subsample" = c("All", "All", "Solvent", "Solvent", "Insolvent", "Insolvent")
)

etable(models_t1_dw, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t1_dw_extra,
       title = "Table 1-DW: DW Extensive Margin — Acute Period (LPM)")
##                                   (1) All            (2) All        (3) Solvent
## Dependent Var.:                  dw_acute           dw_acute           dw_acute
##                                                                                
## Constant               0.1130*** (0.0051) 0.1151*** (0.0052) 0.1169*** (0.0062)
## MTM Loss (z)             0.0122* (0.0054)  0.0161** (0.0059)  0.0177** (0.0063)
## Uninsured Leverage (z)    0.0089 (0.0060)   0.0131* (0.0064)    0.0074 (0.0066)
## MTM $\times$ Uninsured                     0.0160** (0.0049)                   
## Log(Assets)            0.0843*** (0.0074) 0.0842*** (0.0074) 0.0827*** (0.0080)
## Cash Ratio               -0.0040 (0.0051)   -0.0025 (0.0051)   -0.0020 (0.0053)
## Loan-to-Deposit          -0.0041 (0.0054)   -0.0014 (0.0055)   -0.0054 (0.0058)
## Book Equity Ratio        -0.0013 (0.0042)  -3.36e-5 (0.0043)   -0.0034 (0.0046)
## Wholesale Funding      0.0211*** (0.0062) 0.0205*** (0.0062)  0.0213** (0.0069)
## ROA                      -0.0004 (0.0046)   -0.0022 (0.0046)    0.0030 (0.0049)
## ______________________ __________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        3,668              3,668              2,989
## R2                                0.09279            0.09557            0.09698
## N(DW=1)                               393                393                316
## Subsample                             All                All            Solvent
## 
##                               (4) Solvent      (5) Insolvent      (6) Insolvent
## Dependent Var.:                  dw_acute           dw_acute           dw_acute
##                                                                                
## Constant               0.1205*** (0.0065)    0.0243 (0.0479)    0.0360 (0.0476)
## MTM Loss (z)            0.0236** (0.0073)    0.0166 (0.0230)    0.0152 (0.0228)
## Uninsured Leverage (z)   0.0160* (0.0078)    0.0239 (0.0164)   -0.0148 (0.0237)
## MTM $\times$ Uninsured  0.0169** (0.0059)                      0.0392. (0.0200)
## Log(Assets)            0.0818*** (0.0080) 0.0945*** (0.0196) 0.0927*** (0.0198)
## Cash Ratio               -0.0007 (0.0053)  -0.0303. (0.0178)   -0.0286 (0.0177)
## Loan-to-Deposit          -0.0036 (0.0058)    0.0094 (0.0172)    0.0117 (0.0171)
## Book Equity Ratio        -0.0020 (0.0046)  -0.0710* (0.0340)  -0.0661. (0.0340)
## Wholesale Funding       0.0206** (0.0069)    0.0181 (0.0136)    0.0173 (0.0138)
## ROA                       0.0014 (0.0049)  -0.0242. (0.0138)  -0.0244. (0.0136)
## ______________________ __________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        2,989                679                679
## R2                                0.09957            0.09145            0.09678
## N(DW=1)                               316                 77                 77
## Subsample                         Solvent          Insolvent          Insolvent
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t1_dw, "Table_1DW_Extensive",
            title_text = "DW Extensive Margin:   (Acute Period)",
           notes_text = "LPM with robust SEs. Sample: DW borrowers vs. pure non-borrowers. Solvent: AdjEquity $\\geq$ 0. Insolvent: AdjEquity $<$ 0. All regressors z-standardized. Controls: log(assets), cash ratio, loan-to-deposit, wholesale, ROA, Book equity . Baseline: 2022Q4.",
            extra_lines = t1_dw_extra)
## Saved: Table_1DW_Extensive.tex

2.3 Table 1-FHLB: Extensive Margin — FHLB (Acute Period)

# ==============================================================================
# TABLE 1-FHLB: EXTENSIVE MARGIN — FHLB (BENCHMARK)
# ==============================================================================

models_t1_fhlb <- list(
  "(1) All"       = run_one(df_fhlb_s,   "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) All"       = run_one(df_fhlb_s,   "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Solvent"   = run_one(df_fhlb_sol, "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Solvent"   = run_one(df_fhlb_sol, "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Insolvent" = run_one(df_fhlb_ins, "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Insolvent" = run_one(df_fhlb_ins, "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t1_fhlb_extra <- list(
  "__N(FHLB=1)" = c(sum(df_fhlb_s$fhlb_user), sum(df_fhlb_s$fhlb_user),
                     sum(df_fhlb_sol$fhlb_user), sum(df_fhlb_sol$fhlb_user),
                     sum(df_fhlb_ins$fhlb_user), sum(df_fhlb_ins$fhlb_user)),
  "__Subsample" = c("All", "All", "Solvent", "Solvent", "Insolvent", "Insolvent")
)

etable(models_t1_fhlb, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t1_fhlb_extra,
       title = "Table 1-FHLB: FHLB Extensive Margin — Acute Period (LPM)")
##                                    (1) All             (2) All
## Dependent Var.:                  fhlb_user           fhlb_user
##                                                               
## Constant                0.0894*** (0.0048)  0.0887*** (0.0049)
## MTM Loss (z)               0.0047 (0.0053)     0.0034 (0.0055)
## Uninsured Leverage (z)     0.0073 (0.0047)     0.0060 (0.0050)
## MTM $\times$ Uninsured                        -0.0044 (0.0042)
## Log(Assets)             0.0254*** (0.0063)  0.0254*** (0.0063)
## Cash Ratio             -0.0205*** (0.0039) -0.0209*** (0.0039)
## Loan-to-Deposit         0.0248*** (0.0050)  0.0240*** (0.0050)
## Book Equity Ratio         0.0102* (0.0041)    0.0098* (0.0041)
## Wholesale Funding          0.0017 (0.0050)     0.0018 (0.0050)
## ROA                      -0.0093* (0.0042)   -0.0088* (0.0042)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,577               3,577
## R2                                 0.03907             0.03932
## N(FHLB=1)                              302                 302
## Subsample                              All                 All
## 
##                                (3) Solvent         (4) Solvent    (5) Insolvent
## Dependent Var.:                  fhlb_user           fhlb_user        fhlb_user
##                                                                                
## Constant                0.0909*** (0.0057)  0.0896*** (0.0059) 0.0756. (0.0406)
## MTM Loss (z)               0.0029 (0.0061)     0.0007 (0.0066)  0.0298 (0.0184)
## Uninsured Leverage (z)     0.0069 (0.0052)     0.0039 (0.0063)  0.0094 (0.0115)
## MTM $\times$ Uninsured                        -0.0056 (0.0054)                 
## Log(Assets)             0.0273*** (0.0070)  0.0275*** (0.0070)  0.0110 (0.0133)
## Cash Ratio             -0.0221*** (0.0040) -0.0226*** (0.0040) -0.0094 (0.0149)
## Loan-to-Deposit         0.0222*** (0.0055)  0.0216*** (0.0055) 0.0257* (0.0127)
## Book Equity Ratio         0.0084. (0.0045)    0.0079. (0.0044)  0.0266 (0.0297)
## Wholesale Funding          0.0021 (0.0058)     0.0022 (0.0058)  0.0012 (0.0101)
## ROA                      -0.0093* (0.0046)   -0.0088. (0.0046) -0.0085 (0.0108)
## ______________________ ___________________ ___________________ ________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob. Heterosked.-rob.
## Observations                         2,930               2,930              647
## R2                                 0.04103             0.04136          0.03177
## N(FHLB=1)                              257                 257               45
## Subsample                          Solvent             Solvent        Insolvent
## 
##                           (6) Insolvent
## Dependent Var.:               fhlb_user
##                                        
## Constant               0.0762. (0.0408)
## MTM Loss (z)            0.0298 (0.0184)
## Uninsured Leverage (z)  0.0072 (0.0175)
## MTM $\times$ Uninsured  0.0022 (0.0155)
## Log(Assets)             0.0109 (0.0133)
## Cash Ratio             -0.0093 (0.0151)
## Loan-to-Deposit        0.0258* (0.0126)
## Book Equity Ratio       0.0268 (0.0298)
## Wholesale Funding       0.0011 (0.0100)
## ROA                    -0.0085 (0.0107)
## ______________________ ________________
## S.E. type              Heterosked.-rob.
## Observations                        647
## R2                              0.03179
## N(FHLB=1)                            45
## Subsample                     Insolvent
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t1_fhlb, "Table_1FHLB_Extensive",
            title_text = "FHLB Extensive Margin:   (Acute, Benchmark)",
            notes_text = "LPM with robust SEs. FHLB = abnormal borrowing ($>$90th pctile increase). If FHLB is collateral-based, interaction should be weak.",
            extra_lines = t1_fhlb_extra)
## Saved: Table_1FHLB_Extensive.tex

2.4 Table 2: Robustness — Acute vs Arb (BTFP)

Falsification: If AE and UL predict BTFP borrowing during the acute crisis but not during the arbitrage period (profit-driven), then acute-period coefficients reflect genuine crisis dynamics.

# ==============================================================================
# TABLE 2: ACUTE VS ARB — BTFP (All Banks)
# 4 columns: Acute (base, inter), Arb (base, inter)
# ==============================================================================

models_t2 <- list(
  "(1) Acute"     = run_one(df_btfp_s,     "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"     = run_one(df_btfp_s,     "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Arb"       = run_one(df_btfp_arb_s, "btfp_arb",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Arb"       = run_one(df_btfp_arb_s, "btfp_arb",   EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 17 observations removed because of NA values (RHS: 17).
t2_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_s$btfp_acute), sum(df_btfp_s$btfp_acute),
                     sum(df_btfp_arb_s$btfp_arb), sum(df_btfp_arb_s$btfp_arb)),
  "__Period" = c("Acute", "Acute", "Arbitrage", "Arbitrage"),
  "__Baseline" = c("2022Q4", "2022Q4", "2023Q3", "2023Q3")
)

etable(models_t2, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t2_extra,
       title = "Table 2: BTFP — Acute vs Arbitrage (LPM)")
##                                  (1) Acute           (2) Acute
## Dependent Var.:                 btfp_acute          btfp_acute
##                                                               
## Constant                0.1293*** (0.0054)  0.1316*** (0.0055)
## MTM Loss (z)            0.0198*** (0.0055)  0.0243*** (0.0059)
## Uninsured Leverage (z)    0.0154* (0.0063)   0.0199** (0.0068)
## MTM $\times$ Uninsured                      0.0181*** (0.0051)
## Log(Assets)             0.0676*** (0.0074)  0.0674*** (0.0074)
## Cash Ratio             -0.0255*** (0.0047) -0.0238*** (0.0046)
## Loan-to-Deposit          -0.0117* (0.0055)    -0.0083 (0.0055)
## Book Equity Ratio       -0.0123** (0.0044)   -0.0109* (0.0044)
## Wholesale Funding       0.0258*** (0.0064)  0.0252*** (0.0064)
## ROA                       -0.0028 (0.0047)    -0.0048 (0.0047)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,737               3,737
## R2                                 0.08704             0.09017
## N(BTFP=1)                              462                 462
## Period                               Acute               Acute
## Baseline                            2022Q4              2022Q4
## 
##                                    (3) Arb             (4) Arb
## Dependent Var.:                   btfp_arb            btfp_arb
##                                                               
## Constant                0.1898*** (0.0057)  0.1907*** (0.0058)
## MTM Loss (z)             0.0209** (0.0066)   0.0223** (0.0068)
## Uninsured Leverage (z)    0.0120. (0.0064)    0.0135* (0.0066)
## MTM $\times$ Uninsured                         0.0082 (0.0051)
## Log(Assets)             0.0535*** (0.0070)  0.0536*** (0.0070)
## Cash Ratio             -0.0368*** (0.0057) -0.0360*** (0.0057)
## Loan-to-Deposit           -0.0048 (0.0062)    -0.0035 (0.0063)
## Book Equity Ratio         -0.0072 (0.0056)    -0.0065 (0.0056)
## Wholesale Funding       0.1009*** (0.0075)  0.1007*** (0.0075)
## ROA                    -0.0226*** (0.0057) -0.0236*** (0.0057)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         4,038               4,038
## R2                                 0.14195             0.14242
## N(BTFP=1)                              766                 766
## Period                           Arbitrage           Arbitrage
## Baseline                            2023Q3              2023Q3
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t2, "Table_2_Acute_vs_Arb",
            title_text = "BTFP Robustness: Acute vs.\\ Arbitrage Period",
            notes_text = "LPM with robust SEs. Acute: Mar 13--May 1, 2023. Arb: Nov 1, 2023--Jan 24, 2024 (BTFP rate $<$ IORB). If crisis dynamics differ from arbitrage dynamics, AE/UL should be significant only in acute period.",
            extra_lines = t2_extra)
## Saved: Table_2_Acute_vs_Arb.tex

2.5 Table 3: Robustness — OMO Losses Only (Acute)

Does BTFP selection respond to losses on eligible collateral specifically?

# ==============================================================================
# TABLE 3: OMO LOSSES ONLY — BTFP (All Banks)
# 2 columns: OMO base, OMO + interaction
# ==============================================================================

models_t3 <- list(
  "(1) OMO Base"  = run_one(df_btfp_s, "btfp_acute", EXPL_OMO_BASE,  controls = CONTROLS_MTM),
  "(2) OMO Inter" = run_one(df_btfp_s, "btfp_acute", EXPL_OMO_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t3_extra <- list(
  "__N(BTFP=1)" = rep(sum(df_btfp_s$btfp_acute), 2),
  "__Specification" = c("OMO Base", "OMO + Interaction")
)

etable(models_t3, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t3_extra,
       title = "Table 3: OMO Losses Only — Acute Period (LPM)")
##                                   (1) OMO Base       (2) OMO Inter
## Dependent Var.:                     btfp_acute          btfp_acute
##                                                                   
## Constant                    0.1291*** (0.0054)  0.1290*** (0.0053)
## MTM Loss OMO (z)              0.0155* (0.0062)    0.0157* (0.0062)
## Uninsured Leverage (z)        0.0131* (0.0063)    0.0138* (0.0063)
## MTM OMO $\times$ Uninsured                        0.0106* (0.0053)
## Log(Assets)                 0.0666*** (0.0075)  0.0658*** (0.0074)
## Cash Ratio                 -0.0307*** (0.0044) -0.0307*** (0.0044)
## Loan-to-Deposit               -0.0087 (0.0061)    -0.0086 (0.0061)
## Book Equity Ratio          -0.0145*** (0.0044) -0.0144*** (0.0043)
## Wholesale Funding           0.0240*** (0.0064)  0.0237*** (0.0064)
## ROA                           -0.0035 (0.0047)    -0.0039 (0.0047)
## __________________________ ___________________ ___________________
## S.E. type                  Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                             3,737               3,737
## R2                                     0.08613             0.08727
## N(BTFP=1)                                  462                 462
## Specification                         OMO Base   OMO + Interaction
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t3, "Table_3_OMO_Only",
            title_text = "OMO Losses Only: Collateral Channel (Acute Period)",
            notes_text = "LPM with robust SEs. MTM Loss OMO = losses on BTFP-eligible securities only. Controls include book equity ratio.",
            extra_lines = t3_extra)
## Saved: Table_3_OMO_Only.tex

2.6 Table 4: Robustness — Intensive Margin (Acute)

Conditional on borrowing, did fragile banks borrow more?

# ==============================================================================
# TABLE 4: INTENSIVE MARGIN — BTFP Borrowers Only
# DV: btfp_pct (BTFP amount / total assets %)
# 2 columns: AE base, AE + interaction
# ==============================================================================

df_btfp_int <- df_acute %>% filter(btfp_acute == 1, !is.na(btfp_pct))

cat("=== INTENSIVE MARGIN ===\n")
## === INTENSIVE MARGIN ===
cat("BTFP borrowers with amount data:", nrow(df_btfp_int), "\n")
## BTFP borrowers with amount data: 462
cat("Mean BTFP/TA (%):", round(mean(df_btfp_int$btfp_pct, na.rm = TRUE), 3), "\n")
## Mean BTFP/TA (%): 5.994
models_t4 <- list(
  "(1) Base"        = run_one(df_btfp_int, "btfp_pct", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) +Interaction" = run_one(df_btfp_int, "btfp_pct", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

t4_extra <- list(
  "__N (Borrowers)" = rep(nrow(df_btfp_int), 2),
  "__DV" = rep("BTFP/TA (%)", 2)
)

etable(models_t4, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t4_extra,
       title = "Table 4: Intensive Margin — BTFP Borrowing Amount (LPM/OLS)")
##                                 (1) Base (2) +Interaction
## Dependent Var.:                 btfp_pct         btfp_pct
##                                                          
## Constant               6.964*** (0.9615) 7.358*** (1.141)
## MTM Loss (z)              -1.052 (1.029)   -1.185 (1.069)
## Uninsured Leverage (z)    -1.809 (1.480)   -2.040 (1.560)
## MTM $\times$ Uninsured                     1.560 (0.9851)
## Log(Assets)                2.081 (1.442)    2.069 (1.388)
## Cash Ratio                 1.914 (1.587)    2.364 (1.654)
## Loan-to-Deposit          -3.363. (1.992)  -2.823. (1.681)
## Book Equity Ratio         1.042 (0.8556)   1.084 (0.8766)
## Wholesale Funding       0.5755. (0.3354)  0.5103 (0.3443)
## ROA                      0.3286 (0.9277)  0.1701 (0.8330)
## ______________________ _________________ ________________
## S.E. type              Heteroskeda.-rob. Heterosked.-rob.
## Observations                         462              462
## R2                               0.12509          0.14654
## N (Borrowers)                        462              462
## DV                           BTFP/TA (%)      BTFP/TA (%)
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t4, "Table_4_Intensive",
            title_text = "Intensive Margin: BTFP Borrowing Amount (Acute Period)",
            notes_text = "OLS with robust SEs. Sample: BTFP borrowers only. DV = BTFP amount / total assets (\\%).",
            extra_lines = t4_extra)
## Saved: Table_4_Intensive.tex

2.7 Table 5: Robustness — Par Benefit (Acute)

Exploits BTFP design: par valuation benefit varies across banks.

\(\text{ParBenefit}_i = \text{MTM}^{OMO}_i / \text{OMO\_Holdings}_i\)

\(\beta_1 > 0\) → arbitrage motive; \(\beta_3 > 0\) → fragile banks with larger par benefit more likely to borrow.

# ==============================================================================
# TABLE 5: PAR BENEFIT — BTFP (All Banks)
# 2 columns: Par base, Par + interaction
# ==============================================================================

models_t5 <- list(
  "(1) Par Base"  = run_one(df_btfp_s, "btfp_acute", EXPL_PAR_BASE,  controls = CONTROLS_MTM),
  "(2) Par Inter" = run_one(df_btfp_s, "btfp_acute", EXPL_PAR_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t5_extra <- list(
  "__N(BTFP=1)" = rep(sum(df_btfp_s$btfp_acute), 2),
  "__Specification" = c("Par Benefit Base", "Par + Interaction")
)

etable(models_t5, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t5_extra,
       title = "Table 5: Par Benefit — Acute Period (LPM)")
##                                       (1) Par Base       (2) Par Inter
## Dependent Var.:                         btfp_acute          btfp_acute
##                                                                       
## Constant                        0.1292*** (0.0054)  0.1292*** (0.0054)
## Uninsured Leverage (z)            0.0121. (0.0062)    0.0112. (0.0063)
## Par Benefit $\times$ Uninsured                        -0.0061 (0.0046)
## Par Benefit (z)                    0.0013 (0.0040)     0.0008 (0.0042)
## Log(Assets)                     0.0697*** (0.0074)  0.0701*** (0.0074)
## Cash Ratio                     -0.0336*** (0.0043) -0.0341*** (0.0043)
## Loan-to-Deposit                 -0.0158** (0.0056)  -0.0160** (0.0056)
## Book Equity Ratio              -0.0154*** (0.0044) -0.0154*** (0.0044)
## Wholesale Funding               0.0249*** (0.0064)  0.0249*** (0.0064)
## ROA                               -0.0056 (0.0047)    -0.0051 (0.0047)
## ______________________________ ___________________ ___________________
## S.E. type                      Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                                 3,737               3,737
## R2                                         0.08442             0.08486
## N(BTFP=1)                                      462                 462
## Specification                     Par Benefit Base   Par + Interaction
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t5, "Table_5_Par_Benefit",
            title_text = "Par Benefit as Treatment Intensity (Acute Period)",
            notes_text = "LPM with robust SEs. Par Benefit = MTM on OMO-eligible / OMO holdings. Tests whether the par valuation subsidy interacts with funding fragility.",
            extra_lines = t5_extra)
## Saved: Table_5_Par_Benefit.tex

2.8 Table 7: Pre-BTFP Discount Window

Before BTFP existed, DW was the only option. If AE/UL predict DW usage in this narrow window, it confirms run risk drove emergency borrowing before the par-value subsidy was available.

# ==============================================================================
# TABLE 7: PRE-BTFP DW — MARCH 10 & MARCH 10-13
# 4 columns: Mar10 (base, inter), Mar10-13 (base, inter)
# ==============================================================================

models_t7 <- list(
  "(1) Mar10"     = run_one(df_dw_mar10_s,    "dw_mar10",    EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Mar10"     = run_one(df_dw_mar10_s,    "dw_mar10",    EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Mar10-13"  = run_one(df_dw_mar10_13_s, "dw_mar10_13", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Mar10-13"  = run_one(df_dw_mar10_13_s, "dw_mar10_13", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t7_extra <- list(
  "__N(DW=1)" = c(sum(df_dw_mar10_s$dw_mar10), sum(df_dw_mar10_s$dw_mar10),
                   sum(df_dw_mar10_13_s$dw_mar10_13), sum(df_dw_mar10_13_s$dw_mar10_13)),
  "__Window" = c("Mar 10 only", "Mar 10 only", "Mar 10-13", "Mar 10-13")
)

etable(models_t7, fitstat = ~ n + r2,
       order = COEF_ORDER, extralines = t7_extra,
       title = "Table 7: Pre-BTFP Discount Window Usage (LPM)")
##                                 (1) Mar10          (2) Mar10       (3) Mar10-13
## Dependent Var.:                  dw_mar10           dw_mar10        dw_mar10_13
##                                                                                
## Constant               0.0121*** (0.0017) 0.0122*** (0.0018) 0.0231*** (0.0024)
## MTM Loss (z)             -0.0023 (0.0020)   -0.0022 (0.0022)   -0.0031 (0.0026)
## Uninsured Leverage (z)    0.0009 (0.0020)    0.0011 (0.0021)   0.0067* (0.0030)
## MTM $\times$ Uninsured                       0.0007 (0.0018)                   
## Log(Assets)            0.0133*** (0.0030) 0.0133*** (0.0030) 0.0265*** (0.0041)
## Cash Ratio             -0.0041** (0.0013) -0.0041** (0.0013) -0.0058** (0.0020)
## Loan-to-Deposit          -0.0019 (0.0017)   -0.0018 (0.0018)  -0.0045. (0.0026)
## Book Equity Ratio        -0.0004 (0.0014)   -0.0004 (0.0014)    0.0016 (0.0020)
## Wholesale Funding       0.0071** (0.0025)  0.0071** (0.0025)  0.0085** (0.0030)
## ROA                    -0.0036** (0.0013) -0.0037** (0.0013)   -0.0023 (0.0019)
## ______________________ __________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        3,986              3,986              3,988
## R2                                0.02394            0.02398            0.04583
## N(DW=1)                                47                 47                 90
## Window                        Mar 10 only        Mar 10 only          Mar 10-13
## 
##                              (4) Mar10-13
## Dependent Var.:               dw_mar10_13
##                                          
## Constant               0.0236*** (0.0024)
## MTM Loss (z)             -0.0021 (0.0029)
## Uninsured Leverage (z)   0.0078* (0.0033)
## MTM $\times$ Uninsured   0.0046. (0.0026)
## Log(Assets)            0.0265*** (0.0041)
## Cash Ratio             -0.0054** (0.0020)
## Loan-to-Deposit          -0.0037 (0.0027)
## Book Equity Ratio         0.0019 (0.0020)
## Wholesale Funding       0.0083** (0.0031)
## ROA                      -0.0028 (0.0019)
## ______________________ __________________
## S.E. type              Heteroskedas.-rob.
## Observations                        3,988
## R2                                0.04684
## N(DW=1)                                90
## Window                          Mar 10-13
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t7, "Table_7_PreBTFP_DW",
            title_text = "Pre-BTFP Discount Window: Immediate Crisis",
            notes_text = "LPM with robust SEs. March 10 = SVB closure day (before BTFP announcement). March 10--13 includes BTFP announcement on March 12. DW borrowers vs. pure non-users.",
            extra_lines = t7_extra)
## Saved: Table_7_PreBTFP_DW.tex

2.9 Table 6: Temporal Evolution — BTFP, DW, FHLB

Falsification logic: Crisis drivers should predict borrowing during panic periods but not during arbitrage or wind-down phases.

# ==============================================================================
# TABLE 6: TEMPORAL EVOLUTION
# BTFP: 4 periods x 2 specs = 8 columns
# ==============================================================================

models_t6_btfp <- list(
  "(1) Acute"   = run_one(df_btfp_s,      "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"   = run_one(df_btfp_s,      "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Post"    = run_one(df_btfp_post_s, "btfp_post",  EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Post"    = run_one(df_btfp_post_s, "btfp_post",  EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Arb"     = run_one(df_btfp_arb_s,  "btfp_arb",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Arb"     = run_one(df_btfp_arb_s,  "btfp_arb",   EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(7) Wind"    = run_one(df_btfp_wind_s, "btfp_wind",  EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(8) Wind"    = run_one(df_btfp_wind_s, "btfp_wind",  EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 18 observations removed because of NA values (RHS: 18).
## NOTE: 18 observations removed because of NA values (RHS: 18).
t6_btfp_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_s$btfp_acute), sum(df_btfp_s$btfp_acute),
                     sum(df_btfp_post_s$btfp_post), sum(df_btfp_post_s$btfp_post),
                     sum(df_btfp_arb_s$btfp_arb), sum(df_btfp_arb_s$btfp_arb),
                     sum(df_btfp_wind_s$btfp_wind), sum(df_btfp_wind_s$btfp_wind)),
  "__Baseline" = c("2022Q4","2022Q4","2022Q4","2022Q4","2023Q3","2023Q3","2023Q4","2023Q4")
)

# --- DISPLAY (HTML) ---
etable(models_t6_btfp, 
       fitstat = ~ n + r2,
       order = COEF_ORDER, 
       extralines = t6_btfp_extra,
       se.below = TRUE,                                     # <--- SE below coefficient
       digits = 4,                                          # <--- 4 decimal places
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),    # <--- Standard stars
       title = "Table 6A: BTFP Temporal —  ")
##                         (1) Acute  (2) Acute   (3) Post   (4) Post    (5) Arb
## Dependent Var.:        btfp_acute btfp_acute  btfp_post  btfp_post   btfp_arb
##                                                                              
## Constant                0.1293***  0.1316***  0.2342***  0.2363***  0.1898***
##                        (0.0054)   (0.0055)   (0.0071)   (0.0071)   (0.0057)  
## MTM Loss (z)            0.0198***  0.0243***  0.0217***  0.0259***  0.0209***
##                        (0.0055)   (0.0059)   (0.0075)   (0.0079)   (0.0066)  
## Uninsured Leverage (z)  0.0154**   0.0199***  0.0150*    0.0191**   0.0120*  
##                        (0.0063)   (0.0068)   (0.0080)   (0.0085)   (0.0064)  
## MTM $\times$ Uninsured             0.0181***             0.0167***           
##                                   (0.0051)              (0.0062)             
## Log(Assets)             0.0676***  0.0674***  0.0726***  0.0724***  0.0535***
##                        (0.0074)   (0.0074)   (0.0093)   (0.0093)   (0.0070)  
## Cash Ratio             -0.0255*** -0.0238*** -0.0540*** -0.0520*** -0.0368***
##                        (0.0047)   (0.0046)   (0.0066)   (0.0066)   (0.0057)  
## Loan-to-Deposit        -0.0117**  -0.0083    -0.0228*** -0.0197*** -0.0048   
##                        (0.0055)   (0.0055)   (0.0074)   (0.0075)   (0.0062)  
## Book Equity Ratio      -0.0123*** -0.0109**  -0.0213*** -0.0198*** -0.0072   
##                        (0.0044)   (0.0044)   (0.0063)   (0.0063)   (0.0056)  
## Wholesale Funding       0.0258***  0.0252***  0.0165**   0.0158**   0.1009***
##                        (0.0064)   (0.0064)   (0.0076)   (0.0076)   (0.0075)  
## ROA                    -0.0028    -0.0048    -0.0111*   -0.0129**  -0.0226***
##                        (0.0047)   (0.0047)   (0.0064)   (0.0065)   (0.0057)  
## ______________________ __________ __________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                3,737      3,737      3,437      3,437      4,038
## R2                        0.08704    0.09017    0.08307    0.08472    0.14195
## N(BTFP=1)                     462        462        775        775        766
## Baseline                   2022Q4     2022Q4     2022Q4     2022Q4     2023Q3
## 
##                           (6) Arb   (7) Wind   (8) Wind
## Dependent Var.:          btfp_arb  btfp_wind  btfp_wind
##                                                        
## Constant                0.1907***  0.0569***  0.0568***
##                        (0.0058)   (0.0035)   (0.0036)  
## MTM Loss (z)            0.0223***  0.0025     0.0023   
##                        (0.0068)   (0.0041)   (0.0042)  
## Uninsured Leverage (z)  0.0135**   0.0075*    0.0073*  
##                        (0.0066)   (0.0041)   (0.0043)  
## MTM $\times$ Uninsured  0.0082               -0.0010   
##                        (0.0051)              (0.0033)  
## Log(Assets)             0.0536***  4.22e-6   -1.18e-5  
##                        (0.0070)   (0.0042)   (0.0042)  
## Cash Ratio             -0.0360*** -0.0103*** -0.0104***
##                        (0.0057)   (0.0038)   (0.0038)  
## Loan-to-Deposit        -0.0035    -0.0098**  -0.0100** 
##                        (0.0063)   (0.0040)   (0.0041)  
## Book Equity Ratio      -0.0065    -0.0059*   -0.0060*  
##                        (0.0056)   (0.0035)   (0.0035)  
## Wholesale Funding       0.1007***  0.0526***  0.0526***
##                        (0.0075)   (0.0058)   (0.0058)  
## ROA                    -0.0236*** -0.0068*   -0.0067*  
##                        (0.0057)   (0.0038)   (0.0038)  
## ______________________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                4,038      4,043      4,043
## R2                        0.14242    0.06271    0.06273
## N(BTFP=1)                     766        229        229
## Baseline                   2023Q3     2023Q4     2023Q4
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
# --- SAVE (LaTeX) ---
save_etable(models_t6_btfp, "Table_6A_Temporal_BTFP",
            title_text = "BTFP Temporal:   Across Crisis Periods",
            notes_text = "LPM with robust SEs. Acute: Mar 13--May 1. Post: May 2--Oct 31. Arb: Nov 1--Jan 24. Wind: Jan 25--Mar 11.",
            extra_lines = t6_btfp_extra)
## Saved: Table_6A_Temporal_BTFP.tex
# ==============================================================================
# TABLE 6-DW: DW TEMPORAL (DW data through Dec 2023 only)
# ==============================================================================
models_t6_dw <- list(
  "(1) Pre-BTFP" = run_one(df_dw_pre_s,  "dw_prebtfp", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Pre-BTFP" = run_one(df_dw_pre_s,  "dw_prebtfp", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Acute"    = run_one(df_dw_s,      "dw_acute",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Acute"    = run_one(df_dw_s,      "dw_acute",   EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Post"     = run_one(df_dw_post_s, "dw_post",    EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Post"     = run_one(df_dw_post_s, "dw_post",    EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
t6_dw_extra <- list(
  "__N(DW=1)" = c(sum(df_dw_pre_s$dw_prebtfp), sum(df_dw_pre_s$dw_prebtfp),
                  sum(df_dw_s$dw_acute),       sum(df_dw_s$dw_acute),
                  sum(df_dw_post_s$dw_post),   sum(df_dw_post_s$dw_post)),
  "__Period" = c("Pre-BTFP", "Pre-BTFP", "Acute", "Acute", "Post", "Post")
)

# --- DISPLAY (HTML) ---
etable(models_t6_dw, 
       fitstat = ~ n + r2,
       order = COEF_ORDER, 
       extralines = t6_dw_extra,
       se.below = TRUE,
       digits = 4,
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),
       title = "Table 6B: DW Temporal — Pre-BTFP, Acute, and Post-Acute")
##                        (1) Pre-.. (2) Pre-..  (3) Acute  (4) Acute   (5) Post
## Dependent Var.:        dw_prebtfp dw_prebtfp   dw_acute   dw_acute    dw_post
##                                                                              
## Constant                0.0256***  0.0259***  0.1130***  0.1151***  0.2544***
##                        (0.0025)   (0.0025)   (0.0051)   (0.0052)   (0.0069)  
## MTM Loss (z)            0.0004     0.0009     0.0122**   0.0161***  0.0071   
##                        (0.0030)   (0.0032)   (0.0054)   (0.0059)   (0.0076)  
## Uninsured Leverage (z)  0.0003     0.0009     0.0089     0.0131**   0.0151*  
##                        (0.0030)   (0.0031)   (0.0060)   (0.0064)   (0.0082)  
## MTM $\times$ Uninsured             0.0024                0.0160***           
##                                   (0.0024)              (0.0049)             
## Log(Assets)             0.0236***  0.0235***  0.0843***  0.0842***  0.1304***
##                        (0.0041)   (0.0041)   (0.0074)   (0.0074)   (0.0092)  
## Cash Ratio             -0.0048**  -0.0045*   -0.0040    -0.0025    -0.0158** 
##                        (0.0024)   (0.0024)   (0.0051)   (0.0051)   (0.0073)  
## Loan-to-Deposit        -0.0013    -0.0009    -0.0041    -0.0014     0.0208***
##                        (0.0027)   (0.0028)   (0.0054)   (0.0055)   (0.0076)  
## Book Equity Ratio       0.0010     0.0012    -0.0013    -3.36e-5    0.0009   
##                        (0.0024)   (0.0024)   (0.0042)   (0.0043)   (0.0065)  
## Wholesale Funding       0.0135***  0.0134***  0.0211***  0.0205***  0.0048   
##                        (0.0035)   (0.0036)   (0.0062)   (0.0062)   (0.0075)  
## ROA                    -0.0017    -0.0020    -0.0004    -0.0022    -0.0080   
##                        (0.0021)   (0.0021)   (0.0046)   (0.0046)   (0.0067)  
## ______________________ __________ __________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                3,988      3,988      3,668      3,668      3,549
## R2                        0.03540    0.03566    0.09279    0.09557    0.12653
## N(DW=1)                       100        100        393        393        887
## Period                   Pre-BTFP   Pre-BTFP      Acute      Acute       Post
## 
##                          (6) Post
## Dependent Var.:           dw_post
##                                  
## Constant                0.2568***
##                        (0.0070)  
## MTM Loss (z)            0.0118   
##                        (0.0080)  
## Uninsured Leverage (z)  0.0204** 
##                        (0.0086)  
## MTM $\times$ Uninsured  0.0193***
##                        (0.0063)  
## Log(Assets)             0.1301***
##                        (0.0092)  
## Cash Ratio             -0.0137*  
##                        (0.0073)  
## Loan-to-Deposit         0.0243***
##                        (0.0076)  
## Book Equity Ratio       0.0024   
##                        (0.0065)  
## Wholesale Funding       0.0039   
##                        (0.0075)  
## ROA                    -0.0100   
##                        (0.0067)  
## ______________________ __________
## S.E. type              Hete.-rob.
## Observations                3,549
## R2                        0.12864
## N(DW=1)                       887
## Period                       Post
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
# --- SAVE (LaTeX) ---
save_etable(models_t6_dw, "Table_6B_Temporal_DW",
            title_text = "DW Temporal: Pre-BTFP, Acute, and Post-Acute",
            notes_text = "LPM with robust SEs. Pre-BTFP: Mar 1--Mar 12. Acute: Mar 13--May 1. Post: May 2--Oct 31. DW data through Dec 2023.",
            extra_lines = t6_dw_extra)
## Saved: Table_6B_Temporal_DW.tex
# ==============================================================================
# TABLE 6-FHLB: FHLB TEMPORAL (BENCHMARK)
# ==============================================================================

models_t6_fhlb <- list(
  "(1) Acute"  = run_one(df_fhlb_s,      "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"  = run_one(df_fhlb_s,      "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Post"   = run_one(df_fhlb_post_s, "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Post"   = run_one(df_fhlb_post_s, "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Arb"    = run_one(df_fhlb_arb_s,  "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Arb"    = run_one(df_fhlb_arb_s,  "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(7) Wind"   = run_one(df_fhlb_wind_s, "fhlb_user", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(8) Wind"   = run_one(df_fhlb_wind_s, "fhlb_user", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 18 observations removed because of NA values (RHS: 18).
## NOTE: 18 observations removed because of NA values (RHS: 18).
t6_fhlb_extra <- list(
  "__N(FHLB=1)" = c(sum(df_fhlb_s$fhlb_user), sum(df_fhlb_s$fhlb_user),
                     sum(df_fhlb_post_s$fhlb_user), sum(df_fhlb_post_s$fhlb_user),
                     sum(df_fhlb_arb_s$fhlb_user), sum(df_fhlb_arb_s$fhlb_user),
                     sum(df_fhlb_wind_s$fhlb_user), sum(df_fhlb_wind_s$fhlb_user))
)

# --- DISPLAY (HTML) ---
etable(models_t6_fhlb, 
       fitstat = ~ n + r2,
       order = COEF_ORDER, 
       extralines = t6_fhlb_extra,
       se.below = TRUE,                                     # <--- SE below coefficient
       digits = 4,                                          # <--- 4 decimal places
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),    # <--- Standard stars
       title = "Table 6C: FHLB Temporal —   (Benchmark)")
##                         (1) Acute  (2) Acute   (3) Post   (4) Post    (5) Arb
## Dependent Var.:         fhlb_user  fhlb_user  fhlb_user  fhlb_user  fhlb_user
##                                                                              
## Constant                0.0894***  0.0887***  0.1121***  0.1114***  0.0600***
##                        (0.0048)   (0.0049)   (0.0060)   (0.0060)   (0.0042)  
## MTM Loss (z)            0.0047     0.0034     0.0042     0.0030     0.0052   
##                        (0.0053)   (0.0055)   (0.0062)   (0.0065)   (0.0046)  
## Uninsured Leverage (z)  0.0073     0.0060     0.0083     0.0071     0.0008   
##                        (0.0047)   (0.0050)   (0.0058)   (0.0062)   (0.0042)  
## MTM $\times$ Uninsured            -0.0044               -0.0037              
##                                   (0.0042)              (0.0048)             
## Log(Assets)             0.0254***  0.0254***  0.0378***  0.0377***  0.0047   
##                        (0.0063)   (0.0063)   (0.0077)   (0.0077)   (0.0040)  
## Cash Ratio             -0.0205*** -0.0209*** -0.0247*** -0.0251*** -0.0182***
##                        (0.0039)   (0.0039)   (0.0045)   (0.0045)   (0.0032)  
## Loan-to-Deposit         0.0248***  0.0240***  0.0292***  0.0286***  0.0151***
##                        (0.0050)   (0.0050)   (0.0058)   (0.0058)   (0.0038)  
## Book Equity Ratio       0.0102**   0.0098**   0.0129***  0.0126*** -0.0008   
##                        (0.0041)   (0.0041)   (0.0047)   (0.0047)   (0.0035)  
## Wholesale Funding       0.0017     0.0018    -0.0003    -0.0001     0.0078   
##                        (0.0050)   (0.0050)   (0.0058)   (0.0059)   (0.0051)  
## ROA                    -0.0093**  -0.0088**  -0.0124**  -0.0120**  -0.0014   
##                        (0.0042)   (0.0042)   (0.0050)   (0.0050)   (0.0037)  
## ______________________ __________ __________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                3,577      3,577      2,964      2,964      3,468
## R2                        0.03907    0.03932    0.05486    0.05501    0.02140
## N(FHLB=1)                     302        302        302        302        196
## 
##                           (6) Arb   (7) Wind   (8) Wind
## Dependent Var.:         fhlb_user  fhlb_user  fhlb_user
##                                                        
## Constant                0.0592***  0.0371***  0.0364***
##                        (0.0041)   (0.0030)   (0.0030)  
## MTM Loss (z)            0.0039     0.0011     1.25e-8  
##                        (0.0046)   (0.0035)   (0.0035)  
## Uninsured Leverage (z) -0.0006     0.0013     0.0001   
##                        (0.0044)   (0.0033)   (0.0033)  
## MTM $\times$ Uninsured -0.0058*              -0.0057** 
##                        (0.0034)              (0.0024)  
## Log(Assets)             0.0046    -0.0070**  -0.0070** 
##                        (0.0040)   (0.0035)   (0.0036)  
## Cash Ratio             -0.0188*** -0.0112*** -0.0118***
##                        (0.0032)   (0.0029)   (0.0029)  
## Loan-to-Deposit         0.0141***  0.0133***  0.0123***
##                        (0.0038)   (0.0033)   (0.0032)  
## Book Equity Ratio      -0.0014     0.0003    -0.0001   
##                        (0.0034)   (0.0029)   (0.0029)  
## Wholesale Funding       0.0079     0.0110***  0.0112***
##                        (0.0051)   (0.0041)   (0.0041)  
## ROA                    -0.0008     0.0016     0.0021   
##                        (0.0037)   (0.0032)   (0.0032)  
## ______________________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                3,468      3,959      3,959
## R2                        0.02210    0.01371    0.01466
## N(FHLB=1)                     196        145        145
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
# --- SAVE (LaTeX) ---
save_etable(models_t6_fhlb, "Table_6C_Temporal_FHLB",
            title_text = "FHLB Temporal:   (Benchmark)",
            notes_text = "LPM with robust SEs. FHLB = abnormal borrowing. If FHLB is collateral-based, interaction should be weak.",
            extra_lines = t6_fhlb_extra)
## Saved: Table_6C_Temporal_FHLB.tex

3 SPEC: FACILITY CHOICE — DW vs. BTFP

8a. Compare coefficients across facilities 8b. Multinomial logit: Neither / BTFP only / DW only / Both

Prediction: \(\beta_3^{DW} > \beta_3^{BTFP}\) (DW signals more severe run pressure).

# ==============================================================================
# SPEC 6: FACILITY CHOICE
# ==============================================================================

# ------------------------------------------------------------------------------
# 6a: Side-by-side comparison (LPM & Logit)
# ------------------------------------------------------------------------------
# We use EXPL_MTM_INTER to capture the Beta_3 interaction coefficient.
m_spec6_compare <- list(
  "BTFP: LPM"   = run_one(df_btfp_s, "btfp_acute", EXPL_MTM_INTER, "lpm",   controls = CONTROLS_MTM),
  "DW: LPM"     = run_one(df_dw_s,   "dw_acute",   EXPL_MTM_INTER, "lpm",   controls = CONTROLS_MTM),
  "BTFP: Logit" = run_one(df_btfp_s, "btfp_acute", EXPL_MTM_INTER, "logit", controls = CONTROLS_MTM),
  "DW: Logit"   = run_one(df_dw_s,   "dw_acute",   EXPL_MTM_INTER, "logit", controls = CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
# --- DISPLAY 6a (HTML) ---
etable(m_spec6_compare, 
       fitstat = ~ n + r2 + ll,
       drop = "Log|Cash|Loan-to|Wholesale|ROA|Book Equity", # Hide controls for cleaner view
       se.below = TRUE,
       digits = 4,
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),
       title = "Spec 6a: BTFP vs DW Coefficient Comparison (MTM Framework)")
##                         BTFP: LPM    DW: LPM BTFP: Lo..  DW: Logit
## Dependent Var.:        btfp_acute   dw_acute btfp_acute   dw_acute
##                                                                   
## Constant                0.1316***  0.1151*** -2.320***  -2.426*** 
##                        (0.0055)   (0.0052)   (0.0711)   (0.0672)  
## MTM Loss (z)            0.0243***  0.0161***  0.2141***  0.1944***
##                        (0.0059)   (0.0059)   (0.0622)   (0.0679)  
## Uninsured Leverage (z)  0.0199***  0.0131**   0.2089***  0.1603***
##                        (0.0068)   (0.0064)   (0.0626)   (0.0615)  
## MTM $\times$ Uninsured  0.0181***  0.0160***  0.0461     0.0832   
##                        (0.0051)   (0.0049)   (0.0569)   (0.0535)  
## ______________________ __________ __________ __________ __________
## Family                        OLS        OLS      Logit      Logit
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                3,737      3,668      3,737      3,668
## R2                        0.09017    0.09557         --         --
## Log-Likelihood            -973.38    -716.19   -1,214.5   -1,080.9
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
# --- SAVE 6a (LaTeX) ---
save_etable(m_spec6_compare, "Spec6a_FacilityChoice_Compare",
            title_text = "Spec 6a: BTFP vs. DW Coefficient Comparison (MTM Framework)",
            notes_text = "DV: facility-specific. Compare MTM x Uninsured interaction across facilities. Robust SEs. Controls: Log(Assets), Cash, Loan-to-Deposit, Wholesale, ROA, Book Equity.",
            fitstat_use = ~ n + r2 + ll)
## Saved: Spec6a_FacilityChoice_Compare.tex
# ------------------------------------------------------------------------------
# 6b: Multinomial Logit (Standardized Z-Scores)
# ------------------------------------------------------------------------------
cat("\n=== SPEC 6b: MULTINOMIAL LOGIT (Standardized) ===\n")
## 
## === SPEC 6b: MULTINOMIAL LOGIT (Standardized) ===
# 1. Prepare Data
# Filter for complete cases on the variables we need to avoid errors
df_mlogit <- df_acute %>%
  filter(!is.na(mtm_total) & !is.na(uninsured_lev)) %>%
  mutate(facility_choice = factor(user_group, levels = c("Neither", "BTFP_Only", "DW_Only", "Both")))

# 2. Fit Model (Define mlogit_fit)
# Using Z-SCORES (mtm_total, uninsured_lev) for consistency with other tables
mlogit_fit <- nnet::multinom(
  facility_choice ~ mtm_total + uninsured_lev +
    I(mtm_total * uninsured_lev) +
    ln_assets + cash_ratio + loan_to_deposit + wholesale + roa + book_equity_ratio,
  data = df_mlogit, trace = FALSE
)

# 3. Define Map for Output
coef_map_multinom <- c(
  "mtm_total"                    = "MTM Loss (z)",
  "uninsured_lev"                = "Uninsured Leverage (z)",
  "I(mtm_total * uninsured_lev)" = "MTM $\\times$ Uninsured",
  "ln_assets"                    = "Log(Assets)",
  "cash_ratio"                   = "Cash Ratio",
  "loan_to_deposit"              = "Loan-to-Deposit",
  "wholesale"                    = "Wholesale Funding",
  "roa"                          = "ROA",
  "book_equity_ratio"            = "Book Equity Ratio",
  "(Intercept)"                  = "Constant"
)

# 4. Save to LaTeX
modelsummary(
  mlogit_fit,
  output = file.path(TABLE_PATH, "Spec6b_Multinomial.tex"),
  shape = term ~ response,
  stars = c("*" = 0.1, "**" = 0.05, "***" = 0.01),
  coef_map = coef_map_multinom,
  gof_map = c("nobs", "r2.mcfadden"), 
  title = "Spec 6b: Multinomial Logit — Facility Choice (Ref: Neither)",
  notes = list("Standard errors in parentheses. Reference category: Neither. All regressors are z-standardized."),
  escape = FALSE
)
## Warning: To compile a LaTeX document with this table, the following commands must be placed in the document preamble:
## 
## \usepackage{tabularray}
## \usepackage{float}
## \usepackage{graphicx}
## \usepackage{codehigh}
## \usepackage[normalem]{ulem}
## \UseTblrLibrary{booktabs}
## \UseTblrLibrary{siunitx}
## \newcommand{\tinytableTabularrayUnderline}[1]{\underline{#1}}
## \newcommand{\tinytableTabularrayStrikeout}[1]{\sout{#1}}
## \NewTableCommand{\tinytableDefineColor}[3]{\definecolor{#1}{#2}{#3}}
## 
## To disable `siunitx` and prevent `modelsummary` from wrapping numeric entries in `\num{}`, call:
## 
## options("modelsummary_format_numeric_latex" = "plain")
##  This warning appears once per session.
# 5. Display 6b on Screen (HTML)
modelsummary(
  mlogit_fit,
  shape = term ~ response,
  stars = TRUE,
  coef_map = coef_map_multinom,
  title = "Spec 6b: Multinomial Logit (Screen Preview)"
)
(1)
Spec 6b: Multinomial Logit (Screen Preview)
BTFP_Only DW_Only Both
+ p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001
MTM Loss (z) 0.233*** 0.217** 0.080
(0.069) (0.075) (0.152)
Uninsured Leverage (z) 0.136* 0.077 0.405***
(0.069) (0.070) (0.118)
MTM $\times$ Uninsured 0.013 0.061 0.207+
(0.061) (0.061) (0.110)
Log(Assets) 0.465*** 0.716*** 1.002***
(0.069) (0.070) (0.121)
Cash Ratio -0.504*** 0.004 -0.340+
(0.109) (0.090) (0.198)
Loan-to-Deposit -0.008 0.105 -0.013
(0.076) (0.083) (0.153)
Wholesale Funding 0.158** 0.141* 0.281***
(0.050) (0.056) (0.084)
ROA 0.022 0.085 -0.106
(0.068) (0.071) (0.139)
Book Equity Ratio -0.356*** -0.142 -0.424*
(0.089) (0.087) (0.193)
Constant -2.567*** -2.698*** -4.423***
(0.075) (0.074) (0.181)
Num.Obs. 4282
R2 0.100
R2 Adj. 0.100
AIC 5003.5
BIC 5194.4
RMSE 0.27

4 Tercile/Quantile Analysis—Threshold Gradient

# ==============================================================================
# SPECIFICATION: THRESHOLD GRADIENT (Uninsured Leverage Terciles)
# Prediction: Beta_High > Beta_Med > Beta_Low
# ==============================================================================

# 1. Ensure Terciles are defined on the Acute Sample

df_gradient <- df_btfp_s %>%
  filter(!is.na(uninsured_lev_w)) %>%
  mutate(
    unins_tercile = cut(
      uninsured_lev_w,
      breaks = quantile(uninsured_lev_w, probs = c(0, 1/3, 2/3, 1), na.rm = TRUE),
      labels = c("Low", "Medium", "High"),
      include.lowest = TRUE
    )
  )

# 2. Run Regression for Each Tercile
#    Model: BTFP ~ MTM_Loss + Controls (Split by Tercile)
models_gradient <- list(
  "Low Fragility"    = run_one(df_gradient %>% filter(unins_tercile == "Low"),    
                               "btfp_acute", "mtm_total", controls = CONTROLS_MTM),
  "Medium Fragility" = run_one(df_gradient %>% filter(unins_tercile == "Medium"), 
                               "btfp_acute", "mtm_total", controls = CONTROLS_MTM),
  "High Fragility"   = run_one(df_gradient %>% filter(unins_tercile == "High"),   
                               "btfp_acute", "mtm_total", controls = CONTROLS_MTM)
)
## NOTE: 3 observations removed because of NA values (RHS: 3).
## NOTE: 1 observation removed because of NA values (RHS: 1).
## NOTE: 6 observations removed because of NA values (RHS: 6).
# 3. Save/Display Table
etable(models_gradient, 
       fitstat = ~ n + r2, 
       se.below = TRUE,
       digits = 4,
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),
       title = "Threshold Gradient: Effect of MTM Loss by Uninsured Leverage Tercile")
##                   Low Frag.. Medium F.. High Fra..
## Dependent Var.:   btfp_acute btfp_acute btfp_acute
##                                                   
## Constant           0.1050***  0.1278***  0.1431***
##                   (0.0115)   (0.0092)   (0.0112)  
## MTM Loss (z)       0.0075     0.0139     0.0355***
##                   (0.0070)   (0.0104)   (0.0127)  
## Log(Assets)        0.0623***  0.0615***  0.0801***
##                   (0.0117)   (0.0142)   (0.0128)  
## Cash Ratio        -0.0100    -0.0280*** -0.0332***
##                   (0.0061)   (0.0091)   (0.0095)  
## Loan-to-Deposit   -0.0015    -0.0183    -0.0077   
##                   (0.0068)   (0.0125)   (0.0121)  
## Book Equity Ratio -0.0083*   -0.0229*   -0.0211*  
##                   (0.0047)   (0.0122)   (0.0118)  
## Wholesale Funding  0.0017     0.0581***  0.0197   
##                   (0.0062)   (0.0136)   (0.0131)  
## ROA               -0.0071     0.0083    -0.0089   
##                   (0.0063)   (0.0097)   (0.0093)  
## _________________ __________ __________ __________
## S.E. type         Hete.-rob. Hete.-rob. Hete.-rob.
## Observations           1,246      1,248      1,243
## R2                   0.06536    0.08395    0.08979
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
save_etable(models_gradient, "Table_Threshold_Gradient",
            title_text = "Threshold Gradient: MTM Sensitivity by Liquidity Fragility",
            notes_text = "LPM with robust SEs. Sample split by terciles of Uninsured Leverage. We expect the coefficient on MTM Loss to increase (become more positive) as fragility increases.")
## Saved: Table_Threshold_Gradient.tex
# 4. Generate Figure (Coefficient Plot)
#    Extract MTM coefficients and plot them with 95% CIs
gradient_plot_data <- map_dfr(names(models_gradient), function(name) {
  mod <- models_gradient[[name]]
  tidy(mod, conf.int = TRUE) %>%
    filter(term == "mtm_total") %>%
    mutate(Group = factor(name, levels = c("Low Fragility", "Medium Fragility", "High Fragility")))
})

fig_gradient <- ggplot(gradient_plot_data, aes(x = Group, y = estimate)) +
  geom_bar(stat = "identity", fill = "#003049", width = 0.6, alpha = 0.9) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), 
                width = 0.2, color = "black", linewidth = 0.8) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_text(aes(label = round(estimate, 3)), vjust = -2.5, fontface = "bold") +
  scale_y_continuous(limits = c(min(0, min(gradient_plot_data$conf.low)), 
                                max(gradient_plot_data$conf.high) * 1.2)) +
  labs(
    title = "Figure: Threshold Gradient",
    subtitle = "Sensitivity of Borrowing to MTM Losses increases with Funding Fragility",
    x = "Uninsured Leverage Tercile",
    y = "MTM Loss Coefficient (Beta)"
  ) +
  theme_paper +
  theme(panel.grid.major.x = element_blank())

# Display and Save Figure
print(fig_gradient)

save_figure(fig_gradient, "Fig_Threshold_Gradient_MTM")
## Saved: Fig_Threshold_Gradient_MTM.pdf

5 SECTION 2: SOLVENT BANK ONLY ANALYSIS (Tables 2–6)

Subsample: Banks with Adjusted Equity ≥ 0. Among solvent banks, a significant UL coefficient means funding fragility drives borrowing even when the bank is fundamentally sound — the classic panic mechanism.

# ==============================================================================
# SOLVENT SUBSAMPLE — create all period-specific solvent samples
# ==============================================================================

# Acute (already created above)
# df_btfp_sol, df_dw_sol, df_fhlb_sol

# Intensive margin
df_btfp_int_sol <- df_btfp_int %>% filter(mtm_solvent == 1)

# Post-Acute
df_btfp_post_sol <- df_btfp_post_s %>% filter(mtm_solvent == 1)
df_dw_post_sol   <- df_dw_post_s   %>% filter(mtm_solvent == 1)

# Arbitrage
df_btfp_arb_sol  <- df_btfp_arb_s  %>% filter(mtm_solvent == 1)

# Wind-down
df_btfp_wind_sol <- df_btfp_wind_s %>% filter(mtm_solvent == 1)

cat("=== SOLVENT SUBSAMPLE COUNTS ===\n")
## === SOLVENT SUBSAMPLE COUNTS ===
cat("BTFP Acute:", nrow(df_btfp_sol), "(BTFP=1:", sum(df_btfp_sol$btfp_acute), ")\n")
## BTFP Acute: 3003 (BTFP=1: 330 )
cat("DW Acute:",   nrow(df_dw_sol),   "(DW=1:",   sum(df_dw_sol$dw_acute), ")\n")
## DW Acute: 2989 (DW=1: 316 )
cat("Intensive:",  nrow(df_btfp_int_sol), "\n")
## Intensive: 330

5.1 Table 2-S: Acute vs Arb — Solvent Banks

models_t2s <- list(
  "(1) Acute"  = run_one(df_btfp_sol,     "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"  = run_one(df_btfp_sol,     "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Arb"    = run_one(df_btfp_arb_sol, "btfp_arb",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Arb"    = run_one(df_btfp_arb_sol, "btfp_arb",   EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

t2s_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_sol$btfp_acute), sum(df_btfp_sol$btfp_acute),
                     sum(df_btfp_arb_sol$btfp_arb), sum(df_btfp_arb_sol$btfp_arb)),
  "__Subsample" = rep("Solvent", 4)
)

# --- DISPLAY (HTML) ---
etable(models_t2s, 
       fitstat = ~ n + r2, 
       order = COEF_ORDER, 
       extralines = t2s_extra,
       se.below = TRUE,                                     # <--- SE below coefficient
       digits = 4,                                          # <--- 4 decimal places
       signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),    # <--- Standard stars
       title = "Table 2-S: BTFP Acute vs Arb — Solvent Banks (LPM)")
##                         (1) Acute  (2) Acute    (3) Arb    (4) Arb
## Dependent Var.:        btfp_acute btfp_acute   btfp_arb   btfp_arb
##                                                                   
## Constant                0.1263***  0.1303***  0.1887***  0.1908***
##                        (0.0064)   (0.0068)   (0.0069)   (0.0070)  
## MTM Loss (z)            0.0193***  0.0262***  0.0192***  0.0225***
##                        (0.0062)   (0.0070)   (0.0073)   (0.0077)  
## Uninsured Leverage (z)  0.0162**   0.0255***  0.0147**   0.0204***
##                        (0.0068)   (0.0080)   (0.0068)   (0.0078)  
## MTM $\times$ Uninsured             0.0185***             0.0124** 
##                                   (0.0059)              (0.0059)  
## Log(Assets)             0.0621***  0.0610***  0.0520***  0.0515***
##                        (0.0080)   (0.0080)   (0.0076)   (0.0076)  
## Cash Ratio             -0.0236*** -0.0221*** -0.0348*** -0.0338***
##                        (0.0047)   (0.0047)   (0.0059)   (0.0059)  
## Loan-to-Deposit        -0.0111*   -0.0091    -0.0137**  -0.0121*  
##                        (0.0058)   (0.0057)   (0.0065)   (0.0066)  
## Book Equity Ratio      -0.0088**  -0.0074*   -0.0063    -0.0050   
##                        (0.0044)   (0.0045)   (0.0059)   (0.0059)  
## Wholesale Funding       0.0264***  0.0257***  0.1052***  0.1047***
##                        (0.0070)   (0.0070)   (0.0086)   (0.0086)  
## ROA                     0.0011    -0.0005    -0.0221*** -0.0233***
##                        (0.0049)   (0.0049)   (0.0060)   (0.0060)  
## ______________________ __________ __________ __________ __________
## S.E. type              Hete.-rob. Hete.-rob. Hete.-rob. Hete.-rob.
## Observations                3,003      3,003      3,256      3,256
## R2                        0.08692    0.08991    0.14620    0.14712
## N(BTFP=1)                     330        330        556        556
## Subsample                 Solvent    Solvent    Solvent    Solvent
## ---
## Signif. codes: 0 '***' 0.01 '**' 0.05 '*' 0.1 ' ' 1
# --- SAVE (LaTeX) ---
save_etable(models_t2s, "Table_2S_AcuteArb_Solvent",
            title_text = "BTFP Acute vs.\\ Arb: Solvent Banks Only",
            notes_text = "LPM with robust SEs. Solvent: AdjEquity $\\geq$ 0.",
            extra_lines = t2s_extra)
## Saved: Table_2S_AcuteArb_Solvent.tex

5.2 Table 3-S: OMO Losses — Solvent Banks

models_t3s <- list(
  "(1) OMO Base"  = run_one(df_btfp_sol, "btfp_acute", EXPL_OMO_BASE,  controls = CONTROLS_MTM),
  "(2) OMO Inter" = run_one(df_btfp_sol, "btfp_acute", EXPL_OMO_INTER, controls = CONTROLS_MTM)
)

etable(models_t3s, fitstat = ~ n + r2, order = COEF_ORDER,
       title = "Table 3-S: OMO Losses — Solvent Banks (LPM)")
##                                   (1) OMO Base       (2) OMO Inter
## Dependent Var.:                     btfp_acute          btfp_acute
##                                                                   
## Constant                    0.1222*** (0.0061)  0.1225*** (0.0061)
## MTM Loss OMO (z)              0.0150* (0.0070)    0.0165* (0.0073)
## Uninsured Leverage (z)        0.0142* (0.0067)    0.0169* (0.0068)
## MTM OMO $\times$ Uninsured                        0.0138* (0.0059)
## Log(Assets)                 0.0615*** (0.0079)  0.0599*** (0.0079)
## Cash Ratio                 -0.0269*** (0.0046) -0.0271*** (0.0046)
## Loan-to-Deposit               -0.0063 (0.0065)    -0.0060 (0.0065)
## Book Equity Ratio            -0.0082. (0.0044)   -0.0081. (0.0044)
## Wholesale Funding           0.0247*** (0.0070)  0.0239*** (0.0071)
## ROA                            0.0003 (0.0049)    3.44e-5 (0.0049)
## __________________________ ___________________ ___________________
## S.E. type                  Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                             3,003               3,003
## R2                                     0.08595             0.08779
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t3s, "Table_3S_OMO_Solvent",
            title_text = "OMO Losses Only: Solvent Banks",
            notes_text = "LPM with robust SEs. Solvent banks only.")
## Saved: Table_3S_OMO_Solvent.tex

5.3 Table 4-S: Intensive Margin — Solvent Banks

models_t4s <- list(
  "(1) Base"         = run_one(df_btfp_int_sol, "btfp_pct", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) +Interaction" = run_one(df_btfp_int_sol, "btfp_pct", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

etable(models_t4s, fitstat = ~ n + r2, order = COEF_ORDER,
       title = "Table 4-S: Intensive Margin — Solvent Banks (OLS)")
##                                 (1) Base (2) +Interaction
## Dependent Var.:                 btfp_pct         btfp_pct
##                                                          
## Constant               7.110*** (0.9645) 7.451*** (1.124)
## MTM Loss (z)              -1.687 (1.545)   -1.643 (1.502)
## Uninsured Leverage (z)    -2.486 (1.742)   -2.180 (1.535)
## MTM $\times$ Uninsured                      1.751 (1.194)
## Log(Assets)                2.280 (1.595)    2.167 (1.490)
## Cash Ratio                 2.284 (1.808)    2.677 (1.859)
## Loan-to-Deposit           -3.775 (2.434)   -3.314 (2.145)
## Book Equity Ratio          1.281 (1.181)    1.351 (1.242)
## Wholesale Funding       0.9530* (0.4574) 0.8395. (0.4719)
## ROA                       0.6988 (1.035)  0.5524 (0.9404)
## ______________________ _________________ ________________
## S.E. type              Heteroskeda.-rob. Heterosked.-rob.
## Observations                         330              330
## R2                               0.17019          0.18744
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t4s, "Table_4S_Intensive_Solvent",
            title_text = "Intensive Margin: Solvent Borrowers Only",
            notes_text = "OLS with robust SEs. BTFP borrowers with AdjEquity $\\geq$ 0.")
## Saved: Table_4S_Intensive_Solvent.tex

5.4 Table 5-S: Par Benefit — Solvent Banks

models_t5s <- list(
  "(1) Par Base"  = run_one(df_btfp_sol, "btfp_acute", EXPL_PAR_BASE,  controls = CONTROLS_MTM),
  "(2) Par Inter" = run_one(df_btfp_sol, "btfp_acute", EXPL_PAR_INTER, controls = CONTROLS_MTM)
)

etable(models_t5s, fitstat = ~ n + r2, order = COEF_ORDER,
       title = "Table 5-S: Par Benefit — Solvent Banks (LPM)")
##                                       (1) Par Base       (2) Par Inter
## Dependent Var.:                         btfp_acute          btfp_acute
##                                                                       
## Constant                        0.1220*** (0.0061)  0.1220*** (0.0061)
## Uninsured Leverage (z)            0.0133* (0.0066)    0.0122. (0.0067)
## Par Benefit $\times$ Uninsured                        -0.0057 (0.0048)
## Par Benefit (z)                    0.0013 (0.0041)     0.0008 (0.0043)
## Log(Assets)                     0.0641*** (0.0080)  0.0646*** (0.0080)
## Cash Ratio                     -0.0300*** (0.0045) -0.0304*** (0.0045)
## Loan-to-Deposit                  -0.0132* (0.0059)   -0.0133* (0.0059)
## Book Equity Ratio                -0.0086. (0.0044)   -0.0087. (0.0045)
## Wholesale Funding               0.0257*** (0.0071)  0.0257*** (0.0071)
## ROA                               -0.0014 (0.0048)    -0.0009 (0.0049)
## ______________________________ ___________________ ___________________
## S.E. type                      Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                                 3,003               3,003
## R2                                         0.08452             0.08500
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t5s, "Table_5S_ParBenefit_Solvent",
            title_text = "Par Benefit: Solvent Banks Only",
            notes_text = "LPM with robust SEs. Par Benefit among solvent banks.")
## Saved: Table_5S_ParBenefit_Solvent.tex

5.5 Table 6-S: Temporal Evolution — Solvent Banks

models_t6s <- list(
  "(1) Acute"  = run_one(df_btfp_sol,      "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"  = run_one(df_btfp_sol,      "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Post"   = run_one(df_btfp_post_sol, "btfp_post",  EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Post"   = run_one(df_btfp_post_sol, "btfp_post",  EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Arb"    = run_one(df_btfp_arb_sol,  "btfp_arb",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Arb"    = run_one(df_btfp_arb_sol,  "btfp_arb",   EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(7) Wind"   = run_one(df_btfp_wind_sol, "btfp_wind",  EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(8) Wind"   = run_one(df_btfp_wind_sol, "btfp_wind",  EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

t6s_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_sol$btfp_acute), sum(df_btfp_sol$btfp_acute),
                     sum(df_btfp_post_sol$btfp_post), sum(df_btfp_post_sol$btfp_post),
                     sum(df_btfp_arb_sol$btfp_arb), sum(df_btfp_arb_sol$btfp_arb),
                     sum(df_btfp_wind_sol$btfp_wind), sum(df_btfp_wind_sol$btfp_wind)),
  "__Subsample" = rep("Solvent", 8)
)

etable(models_t6s, fitstat = ~ n + r2, order = COEF_ORDER, extralines = t6s_extra,
       title = "Table 6-S: BTFP Temporal — Solvent Banks (LPM)")
##                                  (1) Acute           (2) Acute
## Dependent Var.:                 btfp_acute          btfp_acute
##                                                               
## Constant                0.1263*** (0.0064)  0.1303*** (0.0068)
## MTM Loss (z)             0.0193** (0.0062)  0.0262*** (0.0070)
## Uninsured Leverage (z)    0.0162* (0.0068)   0.0255** (0.0080)
## MTM $\times$ Uninsured                       0.0185** (0.0059)
## Log(Assets)             0.0621*** (0.0080)  0.0610*** (0.0080)
## Cash Ratio             -0.0236*** (0.0047) -0.0221*** (0.0047)
## Loan-to-Deposit          -0.0111. (0.0058)    -0.0091 (0.0057)
## Book Equity Ratio        -0.0088* (0.0044)   -0.0074. (0.0045)
## Wholesale Funding       0.0264*** (0.0070)  0.0257*** (0.0070)
## ROA                        0.0011 (0.0049)    -0.0005 (0.0049)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,003               3,003
## R2                                 0.08692             0.08991
## N(BTFP=1)                              330                 330
## Subsample                          Solvent             Solvent
## 
##                                   (3) Post            (4) Post
## Dependent Var.:                  btfp_post           btfp_post
##                                                               
## Constant                0.2331*** (0.0085)  0.2381*** (0.0088)
## MTM Loss (z)             0.0240** (0.0084)  0.0326*** (0.0094)
## Uninsured Leverage (z)     0.0136 (0.0087)    0.0253* (0.0102)
## MTM $\times$ Uninsured                       0.0222** (0.0074)
## Log(Assets)             0.0734*** (0.0100)  0.0720*** (0.0100)
## Cash Ratio             -0.0498*** (0.0069) -0.0476*** (0.0069)
## Loan-to-Deposit         -0.0241** (0.0079)  -0.0215** (0.0080)
## Book Equity Ratio       -0.0182** (0.0066)   -0.0163* (0.0066)
## Wholesale Funding         0.0168* (0.0085)    0.0156. (0.0085)
## ROA                       -0.0086 (0.0067)    -0.0107 (0.0068)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         2,742               2,742
## R2                                 0.08383             0.08636
## N(BTFP=1)                              561                 561
## Subsample                          Solvent             Solvent
## 
##                                    (5) Arb             (6) Arb
## Dependent Var.:                   btfp_arb            btfp_arb
##                                                               
## Constant                0.1887*** (0.0069)  0.1908*** (0.0070)
## MTM Loss (z)             0.0192** (0.0073)   0.0225** (0.0077)
## Uninsured Leverage (z)    0.0147* (0.0068)   0.0204** (0.0078)
## MTM $\times$ Uninsured                        0.0124* (0.0059)
## Log(Assets)             0.0520*** (0.0076)  0.0515*** (0.0076)
## Cash Ratio             -0.0348*** (0.0059) -0.0338*** (0.0059)
## Loan-to-Deposit          -0.0137* (0.0065)   -0.0121. (0.0066)
## Book Equity Ratio         -0.0063 (0.0059)    -0.0050 (0.0059)
## Wholesale Funding       0.1052*** (0.0086)  0.1047*** (0.0086)
## ROA                    -0.0221*** (0.0060) -0.0233*** (0.0060)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,256               3,256
## R2                                 0.14620             0.14712
## N(BTFP=1)                              556                 556
## Subsample                          Solvent             Solvent
## 
##                                   (7) Wind            (8) Wind
## Dependent Var.:                  btfp_wind           btfp_wind
##                                                               
## Constant                0.0542*** (0.0040)  0.0543*** (0.0041)
## MTM Loss (z)               0.0003 (0.0043)     0.0004 (0.0045)
## Uninsured Leverage (z)    0.0103* (0.0041)    0.0105* (0.0046)
## MTM $\times$ Uninsured                         0.0003 (0.0034)
## Log(Assets)               -0.0019 (0.0044)    -0.0019 (0.0044)
## Cash Ratio             -0.0131*** (0.0038) -0.0131*** (0.0038)
## Loan-to-Deposit          -0.0102* (0.0042)   -0.0101* (0.0042)
## Book Equity Ratio         -0.0025 (0.0035)    -0.0025 (0.0035)
## Wholesale Funding       0.0499*** (0.0063)  0.0499*** (0.0063)
## ROA                      -0.0071. (0.0040)   -0.0072. (0.0040)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,482               3,482
## R2                                 0.05877             0.05878
## N(BTFP=1)                              171                 171
## Subsample                          Solvent             Solvent
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t6s, "Table_6S_Temporal_Solvent",
            title_text = "BTFP Temporal: Solvent Banks Only",
            notes_text = "LPM with robust SEs. Solvent: AdjEquity $\\geq$ 0.",
            extra_lines = t6s_extra)
## Saved: Table_6S_Temporal_Solvent.tex

6 Tercile/Quantile Analysis—Threshold Gradient : SOLVENT VS INSOLVENT SUBSAMPLES

# ==============================================================================
# THRESHOLD GRADIENT: SOLVENT VS INSOLVENT SUBSAMPLES
# ==============================================================================

# Function to run gradient analysis on a specific subsample
run_gradient_analysis <- function(data, sub_name, color_fill) {
  
  # 1. Create Terciles WITHIN this subsample
  #    (Ensures balanced groups for regression even if N is small)
  df_grad <- data %>%
    filter(!is.na(uninsured_lev_w)) %>%
    mutate(
      unins_tercile = cut(
        uninsured_lev_w,
        breaks = quantile(uninsured_lev_w, probs = c(0, 1/3, 2/3, 1), na.rm = TRUE),
        labels = c("Low", "Med", "High"),
        include.lowest = TRUE
      )
    )
  
  # 2. Run Regressions (Low, Med, High)
  models <- list(
    "Low UL"  = run_one(df_grad %>% filter(unins_tercile == "Low"),  "btfp_acute", "mtm_total", controls = CONTROLS_MTM),
    "Med UL"  = run_one(df_grad %>% filter(unins_tercile == "Med"),  "btfp_acute", "mtm_total", controls = CONTROLS_MTM),
    "High UL" = run_one(df_grad %>% filter(unins_tercile == "High"), "btfp_acute", "mtm_total", controls = CONTROLS_MTM)
  )
  
  # 3. Print Table
  cat(paste0("\n=== TABLE: THRESHOLD GRADIENT (", sub_name, ") ===\n"))
  etable(models, fitstat = ~ n + r2, se.below = TRUE, digits = 4,
         signif.code = c("***"=0.01, "**"=0.05, "*"=0.10),
         title = paste0("Gradient: ", sub_name))
  
  # 4. Save Table
  save_etable(models, paste0("Table_Gradient_", sub_name),
              title_text = paste0("Threshold Gradient: ", sub_name, " Banks"),
              notes_text = paste0("Sample: ", sub_name, " banks only. Split by Uninsured Leverage terciles."))

  # 5. Create Plot
  plot_data <- map_dfr(names(models), function(name) {
    tidy(models[[name]], conf.int = TRUE) %>%
      filter(term == "mtm_total") %>%
      mutate(Group = factor(name, levels = c("Low UL", "Med UL", "High UL")))
  })
  
  p <- ggplot(plot_data, aes(x = Group, y = estimate)) +
    geom_bar(stat = "identity", fill = color_fill, width = 0.6, alpha = 0.9) +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2) +
    geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
    geom_text(aes(label = round(estimate, 3)), vjust = -2.5, fontface = "bold") +
    labs(title = paste0(sub_name, ": MTM Coefficient by Fragility"),
         y = "MTM Beta", x = "") +
    scale_y_continuous(limits = c(min(0, min(plot_data$conf.low)), 
                                  max(plot_data$conf.high) * 1.3)) +
    theme_paper
  
  return(p)
}

# --- RUN ANALYSIS FOR SOLVENT BANKS ---
# (Expectation: Strong gradient. Only fragile solvent banks run.)
plot_sol <- run_gradient_analysis(df_btfp_sol, "Solvent", "#2a9d8f")
## 
## === TABLE: THRESHOLD GRADIENT (Solvent) ===
## Saved: Table_Gradient_Solvent.tex
# --- RUN ANALYSIS FOR INSOLVENT BANKS ---
# (Expectation: Flatter gradient? Insolvent banks borrow regardless of leverage?)
plot_ins <- run_gradient_analysis(df_btfp_ins, "Insolvent", "#e76f51")
## 
## === TABLE: THRESHOLD GRADIENT (Insolvent) ===
## Saved: Table_Gradient_Insolvent.tex
# --- COMBINE AND SAVE PLOTS ---
combined_plot <- plot_sol + plot_ins + 
  plot_layout(ncol = 2) + 
  plot_annotation(
    title = "Threshold Gradient: Solvent vs. Insolvent Banks",
    subtitle = "Sensitivity to MTM Losses across Uninsured Leverage Terciles",
    theme = theme(plot.title = element_text(face = "bold", size = 14))
  )

print(combined_plot)

save_figure(combined_plot, "Fig_Threshold_Gradient_Split")
## Saved: Fig_Threshold_Gradient_Split.pdf

7 SECTION 3: INSOLVENT BANK ONLY ANALYSIS (Tables 2–6)

Subsample: Banks with Adjusted Equity < 0. Among insolvent banks, borrowing is expected regardless of fragility because the bank genuinely needs the money. The interaction term may be less informative here.

# ==============================================================================
# INSOLVENT SUBSAMPLE
# ==============================================================================

# Intensive margin
df_btfp_int_ins <- df_btfp_int %>% filter(mtm_insolvent == 1)

# Post-Acute
df_btfp_post_ins <- df_btfp_post_s %>% filter(mtm_insolvent == 1)
df_dw_post_ins   <- df_dw_post_s   %>% filter(mtm_insolvent == 1)

# Arbitrage
df_btfp_arb_ins  <- df_btfp_arb_s  %>% filter(mtm_insolvent == 1)

# Wind-down
df_btfp_wind_ins <- df_btfp_wind_s %>% filter(mtm_insolvent == 1)

cat("=== INSOLVENT SUBSAMPLE COUNTS ===\n")
## === INSOLVENT SUBSAMPLE COUNTS ===
cat("BTFP Acute:", nrow(df_btfp_ins), "(BTFP=1:", sum(df_btfp_ins$btfp_acute), ")\n")
## BTFP Acute: 734 (BTFP=1: 132 )
cat("DW Acute:",   nrow(df_dw_ins),   "(DW=1:",   sum(df_dw_ins$dw_acute), ")\n")
## DW Acute: 679 (DW=1: 77 )
cat("Intensive:",  nrow(df_btfp_int_ins), "\n")
## Intensive: 132

7.1 Table 2-I: Acute vs Arb — Insolvent Banks

models_t2i <- list(
  "(1) Acute"  = run_one(df_btfp_ins,     "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"  = run_one(df_btfp_ins,     "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Arb"    = run_one(df_btfp_arb_ins, "btfp_arb",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Arb"    = run_one(df_btfp_arb_ins, "btfp_arb",   EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

t2i_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_ins$btfp_acute), sum(df_btfp_ins$btfp_acute),
                     sum(df_btfp_arb_ins$btfp_arb), sum(df_btfp_arb_ins$btfp_arb)),
  "__Subsample" = rep("Insolvent", 4)
)

etable(models_t2i, fitstat = ~ n + r2, order = COEF_ORDER, extralines = t2i_extra,
       title = "Table 2-I: BTFP Acute vs Arb — Insolvent Banks (LPM)")
##                                 (1) Acute          (2) Acute
## Dependent Var.:                btfp_acute         btfp_acute
##                                                             
## Constant                  0.0017 (0.0544)    0.0168 (0.0541)
## MTM Loss (z)              0.0314 (0.0260)    0.0289 (0.0259)
## Uninsured Leverage (z)    0.0233 (0.0177)   -0.0213 (0.0262)
## MTM $\times$ Uninsured                      0.0443. (0.0226)
## Log(Assets)            0.1016*** (0.0207) 0.0995*** (0.0208)
## Cash Ratio             -0.0599** (0.0203) -0.0588** (0.0202)
## Loan-to-Deposit           0.0143 (0.0196)    0.0176 (0.0197)
## Book Equity Ratio      -0.1332** (0.0404) -0.1269** (0.0403)
## Wholesale Funding         0.0185 (0.0144)    0.0170 (0.0143)
## ROA                     -0.0341* (0.0146)  -0.0344* (0.0145)
## ______________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                          734                734
## R2                                0.08892            0.09341
## N(BTFP=1)                             132                132
## Subsample                       Insolvent          Insolvent
## 
##                                    (3) Arb             (4) Arb
## Dependent Var.:                   btfp_arb            btfp_arb
##                                                               
## Constant                 0.1688** (0.0593)   0.1782** (0.0596)
## MTM Loss (z)               0.0168 (0.0273)     0.0150 (0.0272)
## Uninsured Leverage (z)     0.0090 (0.0171)    -0.0208 (0.0284)
## MTM $\times$ Uninsured                         0.0273 (0.0229)
## Log(Assets)              0.0638** (0.0194)   0.0627** (0.0194)
## Cash Ratio             -0.0750*** (0.0188) -0.0727*** (0.0188)
## Loan-to-Deposit           0.0515* (0.0215)    0.0530* (0.0215)
## Book Equity Ratio         -0.0603 (0.0442)    -0.0560 (0.0442)
## Wholesale Funding       0.0841*** (0.0154)  0.0834*** (0.0155)
## ROA                       -0.0281 (0.0191)    -0.0292 (0.0192)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                           782                 782
## R2                                 0.11858             0.11993
## N(BTFP=1)                              210                 210
## Subsample                        Insolvent           Insolvent
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t2i, "Table_2I_AcuteArb_Insolvent",
            title_text = "BTFP Acute vs.\\ Arb: Insolvent Banks Only",
            notes_text = "LPM with robust SEs. Insolvent: AdjEquity $<$ 0.",
            extra_lines = t2i_extra)
## Saved: Table_2I_AcuteArb_Insolvent.tex

7.2 Table 3-I: OMO Losses — Insolvent Banks

models_t3i <- list(
  "(1) OMO Base"  = run_one(df_btfp_ins, "btfp_acute", EXPL_OMO_BASE,  controls = CONTROLS_MTM),
  "(2) OMO Inter" = run_one(df_btfp_ins, "btfp_acute", EXPL_OMO_INTER, controls = CONTROLS_MTM)
)

etable(models_t3i, fitstat = ~ n + r2, order = COEF_ORDER,
       title = "Table 3-I: OMO Losses — Insolvent Banks (LPM)")
##                                   (1) OMO Base       (2) OMO Inter
## Dependent Var.:                     btfp_acute          btfp_acute
##                                                                   
## Constant                       0.0507 (0.0357)     0.0506 (0.0357)
## MTM Loss OMO (z)               0.0083 (0.0126)     0.0089 (0.0126)
## Uninsured Leverage (z)         0.0209 (0.0175)     0.0235 (0.0180)
## MTM OMO $\times$ Uninsured                        -0.0046 (0.0122)
## Log(Assets)                 0.1015*** (0.0212)  0.1017*** (0.0212)
## Cash Ratio                 -0.0670*** (0.0196) -0.0673*** (0.0198)
## Loan-to-Deposit                0.0146 (0.0196)     0.0152 (0.0196)
## Book Equity Ratio           -0.1122** (0.0386)  -0.1126** (0.0386)
## Wholesale Funding              0.0173 (0.0143)     0.0171 (0.0143)
## ROA                          -0.0334* (0.0148)   -0.0335* (0.0148)
## __________________________ ___________________ ___________________
## S.E. type                  Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                               734                 734
## R2                                     0.08753             0.08772
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t3i, "Table_3I_OMO_Insolvent",
            title_text = "OMO Losses Only: Insolvent Banks",
            notes_text = "LPM with robust SEs. Insolvent banks only.")
## Saved: Table_3I_OMO_Insolvent.tex

7.3 Table 4-I: Intensive Margin — Insolvent Banks

models_t4i <- list(
  "(1) Base"         = run_one(df_btfp_int_ins, "btfp_pct", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) +Interaction" = run_one(df_btfp_int_ins, "btfp_pct", EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

etable(models_t4i, fitstat = ~ n + r2, order = COEF_ORDER,
       title = "Table 4-I: Intensive Margin — Insolvent Banks (OLS)")
##                                (1) Base (2) +Interaction
## Dependent Var.:                btfp_pct         btfp_pct
##                                                         
## Constant                -0.0052 (2.477)  -0.0487 (2.329)
## MTM Loss (z)             1.100 (0.8181)   1.124 (0.8628)
## Uninsured Leverage (z)  0.3530 (0.8325)   0.4801 (1.476)
## MTM $\times$ Uninsured                   -0.1052 (1.412)
## Log(Assets)             0.9710 (0.7586)  0.9736 (0.7490)
## Cash Ratio               0.1516 (1.206)   0.1765 (1.241)
## Loan-to-Deposit          -1.035 (1.062)   -1.044 (1.129)
## Book Equity Ratio        -3.118 (2.041)   -3.141 (1.935)
## Wholesale Funding      -0.2644 (0.3471) -0.2613 (0.3581)
## ROA                      -2.127 (1.373)   -2.117 (1.403)
## ______________________ ________________ ________________
## S.E. type              Heterosked.-rob. Heterosked.-rob.
## Observations                        132              132
## R2                              0.12500          0.12507
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t4i, "Table_4I_Intensive_Insolvent",
            title_text = "Intensive Margin: Insolvent Borrowers Only",
            notes_text = "OLS with robust SEs. BTFP borrowers with AdjEquity $<$ 0.")
## Saved: Table_4I_Intensive_Insolvent.tex

7.4 Table 5-I: Par Benefit — Insolvent Banks

models_t5i <- list(
  "(1) Par Base"  = run_one(df_btfp_ins, "btfp_acute", EXPL_PAR_BASE,  controls = CONTROLS_MTM),
  "(2) Par Inter" = run_one(df_btfp_ins, "btfp_acute", EXPL_PAR_INTER, controls = CONTROLS_MTM)
)

etable(models_t5i, fitstat = ~ n + r2, order = COEF_ORDER,
       title = "Table 5-I: Par Benefit — Insolvent Banks (LPM)")
##                                       (1) Par Base       (2) Par Inter
## Dependent Var.:                         btfp_acute          btfp_acute
##                                                                       
## Constant                           0.0493 (0.0355)     0.0500 (0.0356)
## Uninsured Leverage (z)             0.0207 (0.0175)     0.0230 (0.0173)
## Par Benefit $\times$ Uninsured                        -0.0182 (0.0158)
## Par Benefit (z)                    0.0022 (0.0150)     0.0011 (0.0152)
## Log(Assets)                     0.1041*** (0.0206)  0.1062*** (0.0205)
## Cash Ratio                     -0.0675*** (0.0197) -0.0661*** (0.0198)
## Loan-to-Deposit                    0.0123 (0.0199)     0.0119 (0.0199)
## Book Equity Ratio               -0.1154** (0.0381)  -0.1156** (0.0381)
## Wholesale Funding                  0.0175 (0.0143)     0.0169 (0.0144)
## ROA                              -0.0353* (0.0147)   -0.0353* (0.0147)
## ______________________________ ___________________ ___________________
## S.E. type                      Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                                   734                 734
## R2                                         0.08693             0.08790
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t5i, "Table_5I_ParBenefit_Insolvent",
            title_text = "Par Benefit: Insolvent Banks Only",
            notes_text = "LPM with robust SEs. Par Benefit among insolvent banks.")
## Saved: Table_5I_ParBenefit_Insolvent.tex

7.5 Table 6-I: Temporal Evolution — Insolvent Banks

models_t6i <- list(
  "(1) Acute"  = run_one(df_btfp_ins,      "btfp_acute", EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(2) Acute"  = run_one(df_btfp_ins,      "btfp_acute", EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(3) Post"   = run_one(df_btfp_post_ins, "btfp_post",  EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(4) Post"   = run_one(df_btfp_post_ins, "btfp_post",  EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(5) Arb"    = run_one(df_btfp_arb_ins,  "btfp_arb",   EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(6) Arb"    = run_one(df_btfp_arb_ins,  "btfp_arb",   EXPL_MTM_INTER, controls = CONTROLS_MTM),
  "(7) Wind"   = run_one(df_btfp_wind_ins, "btfp_wind",  EXPL_MTM_BASE,  controls = CONTROLS_MTM),
  "(8) Wind"   = run_one(df_btfp_wind_ins, "btfp_wind",  EXPL_MTM_INTER, controls = CONTROLS_MTM)
)

t6i_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_ins$btfp_acute), sum(df_btfp_ins$btfp_acute),
                     sum(df_btfp_post_ins$btfp_post), sum(df_btfp_post_ins$btfp_post),
                     sum(df_btfp_arb_ins$btfp_arb), sum(df_btfp_arb_ins$btfp_arb),
                     sum(df_btfp_wind_ins$btfp_wind), sum(df_btfp_wind_ins$btfp_wind)),
  "__Subsample" = rep("Insolvent", 8)
)

etable(models_t6i, fitstat = ~ n + r2, order = COEF_ORDER, extralines = t6i_extra,
       title = "Table 6-I: BTFP Temporal — Insolvent Banks (LPM)")
##                                 (1) Acute          (2) Acute
## Dependent Var.:                btfp_acute         btfp_acute
##                                                             
## Constant                  0.0017 (0.0544)    0.0168 (0.0541)
## MTM Loss (z)              0.0314 (0.0260)    0.0289 (0.0259)
## Uninsured Leverage (z)    0.0233 (0.0177)   -0.0213 (0.0262)
## MTM $\times$ Uninsured                      0.0443. (0.0226)
## Log(Assets)            0.1016*** (0.0207) 0.0995*** (0.0208)
## Cash Ratio             -0.0599** (0.0203) -0.0588** (0.0202)
## Loan-to-Deposit           0.0143 (0.0196)    0.0176 (0.0197)
## Book Equity Ratio      -0.1332** (0.0404) -0.1269** (0.0403)
## Wholesale Funding         0.0185 (0.0144)    0.0170 (0.0143)
## ROA                     -0.0341* (0.0146)  -0.0344* (0.0145)
## ______________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                          734                734
## R2                                0.08892            0.09341
## N(BTFP=1)                             132                132
## Subsample                       Insolvent          Insolvent
## 
##                                   (3) Post            (4) Post
## Dependent Var.:                  btfp_post           btfp_post
##                                                               
## Constant                   0.0955 (0.0679)     0.0975 (0.0687)
## MTM Loss (z)               0.0270 (0.0313)     0.0266 (0.0313)
## Uninsured Leverage (z)     0.0257 (0.0214)     0.0202 (0.0340)
## MTM $\times$ Uninsured                         0.0054 (0.0275)
## Log(Assets)              0.0720** (0.0253)   0.0718** (0.0253)
## Cash Ratio             -0.1026*** (0.0247) -0.1026*** (0.0247)
## Loan-to-Deposit            0.0145 (0.0253)     0.0148 (0.0254)
## Book Equity Ratio       -0.1556** (0.0516)  -0.1548** (0.0519)
## Wholesale Funding          0.0104 (0.0167)     0.0102 (0.0167)
## ROA                       -0.0294 (0.0204)    -0.0294 (0.0204)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                           695                 695
## R2                                 0.06098             0.06103
## N(BTFP=1)                              214                 214
## Subsample                        Insolvent           Insolvent
## 
##                                    (5) Arb             (6) Arb
## Dependent Var.:                   btfp_arb            btfp_arb
##                                                               
## Constant                 0.1688** (0.0593)   0.1782** (0.0596)
## MTM Loss (z)               0.0168 (0.0273)     0.0150 (0.0272)
## Uninsured Leverage (z)     0.0090 (0.0171)    -0.0208 (0.0284)
## MTM $\times$ Uninsured                         0.0273 (0.0229)
## Log(Assets)              0.0638** (0.0194)   0.0627** (0.0194)
## Cash Ratio             -0.0750*** (0.0188) -0.0727*** (0.0188)
## Loan-to-Deposit           0.0515* (0.0215)    0.0530* (0.0215)
## Book Equity Ratio         -0.0603 (0.0442)    -0.0560 (0.0442)
## Wholesale Funding       0.0841*** (0.0154)  0.0834*** (0.0155)
## ROA                       -0.0281 (0.0191)    -0.0292 (0.0192)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                           782                 782
## R2                                 0.11858             0.11993
## N(BTFP=1)                              210                 210
## Subsample                        Insolvent           Insolvent
## 
##                                  (7) Wind           (8) Wind
## Dependent Var.:                 btfp_wind          btfp_wind
##                                                             
## Constant                  0.0910 (0.0657)    0.0979 (0.0682)
## MTM Loss (z)             -0.0135 (0.0279)   -0.0153 (0.0283)
## Uninsured Leverage (z)   -0.0076 (0.0144)   -0.0253 (0.0283)
## MTM $\times$ Uninsured                       0.0146 (0.0220)
## Log(Assets)               0.0140 (0.0152)    0.0137 (0.0152)
## Cash Ratio                0.0100 (0.0172)    0.0112 (0.0172)
## Loan-to-Deposit           0.0033 (0.0155)    0.0043 (0.0157)
## Book Equity Ratio        -0.0193 (0.0402)   -0.0170 (0.0408)
## Wholesale Funding      0.0592*** (0.0140) 0.0587*** (0.0140)
## ROA                      -0.0005 (0.0155)    0.0002 (0.0157)
## ______________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                          561                561
## R2                                0.06076            0.06151
## N(BTFP=1)                              58                 58
## Subsample                       Insolvent          Insolvent
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_t6i, "Table_6I_Temporal_Insolvent",
            title_text = "BTFP Temporal: Insolvent Banks Only",
            notes_text = "LPM with robust SEs. Insolvent: AdjEquity $<$ 0.",
            extra_lines = t6i_extra)
## Saved: Table_6I_Temporal_Insolvent.tex

8 SECTION 4: LOGIT ROBUSTNESS

Repeat the main extensive-margin specifications using Logit instead of LPM. This checks whether the linear probability model results are robust to a nonlinear specification. Coefficients are in log-odds; marginal effects can be computed via marginaleffects.

# ==============================================================================
# LOGIT TABLE 1: EXTENSIVE MARGIN — BTFP (ACUTE)
# ==============================================================================

models_logit_t1 <- list(
  "(1) All"       = run_one(df_btfp_s,   "btfp_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(2) All"       = run_one(df_btfp_s,   "btfp_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(3) Solvent"   = run_one(df_btfp_sol, "btfp_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(4) Solvent"   = run_one(df_btfp_sol, "btfp_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(5) Insolvent" = run_one(df_btfp_ins, "btfp_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(6) Insolvent" = run_one(df_btfp_ins, "btfp_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
logit_t1_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_s$btfp_acute), sum(df_btfp_s$btfp_acute),
                     sum(df_btfp_sol$btfp_acute), sum(df_btfp_sol$btfp_acute),
                     sum(df_btfp_ins$btfp_acute), sum(df_btfp_ins$btfp_acute)),
  "__Subsample" = c("All", "All", "Solvent", "Solvent", "Insolvent", "Insolvent"),
  "__Method" = rep("Logit", 6)
)

etable(models_logit_t1, fitstat = ~ n + pr2,
       order = COEF_ORDER, extralines = logit_t1_extra,
       title = "Logit Table 1: BTFP Extensive Margin — Acute Period")
##                                    (1) All             (2) All
## Dependent Var.:                 btfp_acute          btfp_acute
##                                                               
## Constant                -2.330*** (0.0706)  -2.320*** (0.0711)
## MTM Loss (z)            0.2177*** (0.0619)  0.2141*** (0.0622)
## Uninsured Leverage (z)  0.2129*** (0.0625)  0.2089*** (0.0626)
## MTM $\times$ Uninsured                         0.0461 (0.0569)
## Log(Assets)             0.5738*** (0.0620)  0.5743*** (0.0619)
## Cash Ratio             -0.5236*** (0.1050) -0.5171*** (0.1050)
## Loan-to-Deposit           -0.0064 (0.0669)     0.0009 (0.0664)
## Book Equity Ratio      -0.3338*** (0.0817) -0.3289*** (0.0825)
## Wholesale Funding       0.1831*** (0.0466)  0.1826*** (0.0465)
## ROA                       -0.0127 (0.0628)    -0.0164 (0.0629)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,737               3,737
## Pseudo R2                          0.13099             0.13124
## N(BTFP=1)                              462                 462
## Subsample                              All                 All
## Method                               Logit               Logit
## 
##                                (3) Solvent         (4) Solvent
## Dependent Var.:                 btfp_acute          btfp_acute
##                                                               
## Constant                -2.294*** (0.0751)  -2.286*** (0.0762)
## MTM Loss (z)            0.2902*** (0.0801)  0.2888*** (0.0802)
## Uninsured Leverage (z)   0.2352** (0.0731)  0.2438*** (0.0737)
## MTM $\times$ Uninsured                         0.0401 (0.0737)
## Log(Assets)             0.5523*** (0.0715)  0.5507*** (0.0713)
## Cash Ratio             -0.4974*** (0.1101) -0.4927*** (0.1102)
## Loan-to-Deposit           -0.0307 (0.0777)    -0.0272 (0.0772)
## Book Equity Ratio      -0.3205*** (0.0973)  -0.3147** (0.0986)
## Wholesale Funding       0.2074*** (0.0552)  0.2065*** (0.0551)
## ROA                        0.0501 (0.0738)     0.0477 (0.0739)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,003               3,003
## Pseudo R2                          0.13709             0.13724
## N(BTFP=1)                              330                 330
## Subsample                          Solvent             Solvent
## Method                               Logit               Logit
## 
##                             (5) Insolvent      (6) Insolvent
## Dependent Var.:                btfp_acute         btfp_acute
##                                                             
## Constant               -3.096*** (0.4421) -2.971*** (0.4444)
## MTM Loss (z)              0.1991 (0.1905)    0.1508 (0.1928)
## Uninsured Leverage (z)    0.1866 (0.1247)   -0.1789 (0.2298)
## MTM $\times$ Uninsured                      0.3453. (0.1894)
## Log(Assets)            0.6566*** (0.1320) 0.6536*** (0.1350)
## Cash Ratio              -0.6931* (0.2953)  -0.6784* (0.2883)
## Loan-to-Deposit           0.1132 (0.1524)    0.1478 (0.1562)
## Book Equity Ratio      -0.9912** (0.3211) -0.9606** (0.3262)
## Wholesale Funding         0.1077 (0.0862)    0.1033 (0.0848)
## ROA                     -0.2328. (0.1188)  -0.2429* (0.1219)
## ______________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                          734                734
## Pseudo R2                         0.09733            0.10257
## N(BTFP=1)                             132                132
## Subsample                       Insolvent          Insolvent
## Method                              Logit              Logit
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t1, "Logit_Table_1_BTFP",
            title_text = "Logit: BTFP Extensive Margin (Acute Period)",
            notes_text = "Logit with robust SEs. Coefficients in log-odds. Sample: BTFP borrowers vs. pure non-borrowers.",
            fitstat_use = ~ n + pr2, extra_lines = logit_t1_extra)
## Saved: Logit_Table_1_BTFP.tex
# ==============================================================================
# LOGIT TABLE 1-DW: DW (ACUTE)
# ==============================================================================

models_logit_t1_dw <- list(
  "(1) All"       = run_one(df_dw_s,   "dw_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(2) All"       = run_one(df_dw_s,   "dw_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(3) Solvent"   = run_one(df_dw_sol, "dw_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(4) Solvent"   = run_one(df_dw_sol, "dw_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(5) Insolvent" = run_one(df_dw_ins, "dw_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(6) Insolvent" = run_one(df_dw_ins, "dw_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
logit_t1_dw_extra <- list(
  "__N(DW=1)" = c(sum(df_dw_s$dw_acute), sum(df_dw_s$dw_acute),
                   sum(df_dw_sol$dw_acute), sum(df_dw_sol$dw_acute),
                   sum(df_dw_ins$dw_acute), sum(df_dw_ins$dw_acute)),
  "__Method" = rep("Logit", 6)
)

etable(models_logit_t1_dw, fitstat = ~ n + pr2,
       order = COEF_ORDER, extralines = logit_t1_dw_extra,
       title = "Logit Table 1-DW: DW Extensive Margin — Acute Period")
##                                   (1) All            (2) All        (3) Solvent
## Dependent Var.:                  dw_acute           dw_acute           dw_acute
##                                                                                
## Constant               -2.441*** (0.0675) -2.426*** (0.0672) -2.373*** (0.0759)
## MTM Loss (z)            0.2034** (0.0675)  0.1944** (0.0679) 0.3046*** (0.0807)
## Uninsured Leverage (z)   0.1554* (0.0615)  0.1603** (0.0615)   0.1400* (0.0689)
## MTM $\times$ Uninsured                       0.0832 (0.0535)                   
## Log(Assets)            0.7773*** (0.0614) 0.7765*** (0.0615) 0.7738*** (0.0688)
## Cash Ratio               -0.0996 (0.0886)   -0.0884 (0.0886)   -0.0554 (0.0913)
## Loan-to-Deposit           0.0802 (0.0732)    0.0905 (0.0735)    0.0648 (0.0822)
## Book Equity Ratio       -0.1752* (0.0792)  -0.1668* (0.0795)  -0.2289* (0.0942)
## Wholesale Funding       0.1731** (0.0531)  0.1717** (0.0531)  0.1761** (0.0626)
## ROA                       0.0450 (0.0658)    0.0380 (0.0660)    0.0913 (0.0728)
## ______________________ __________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        3,668              3,668              2,989
## Pseudo R2                         0.13366            0.13452            0.14188
## N(DW=1)                               393                393                316
## Method                              Logit              Logit              Logit
## 
##                               (4) Solvent      (5) Insolvent      (6) Insolvent
## Dependent Var.:                  dw_acute           dw_acute           dw_acute
##                                                                                
## Constant               -2.363*** (0.0766) -3.356*** (0.5644) -3.181*** (0.5717)
## MTM Loss (z)           0.3012*** (0.0808)    0.1373 (0.2546)    0.0507 (0.2579)
## Uninsured Leverage (z)   0.1569* (0.0721)   0.2542. (0.1523)   -0.1630 (0.2776)
## MTM $\times$ Uninsured    0.0578 (0.0652)                      0.4016. (0.2221)
## Log(Assets)            0.7709*** (0.0690) 0.8253*** (0.1493) 0.8304*** (0.1565)
## Cash Ratio               -0.0491 (0.0911)   -0.5642 (0.3743)   -0.5283 (0.3587)
## Loan-to-Deposit           0.0684 (0.0823)    0.1490 (0.1871)    0.1812 (0.1898)
## Book Equity Ratio       -0.2211* (0.0940)  -0.7780* (0.3952)  -0.7438. (0.4101)
## Wholesale Funding       0.1744** (0.0625)    0.1435 (0.1054)    0.1468 (0.1069)
## ROA                       0.0871 (0.0730)   -0.1884 (0.1662)   -0.1988 (0.1676)
## ______________________ __________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        2,989                679                679
## Pseudo R2                         0.14222            0.12324            0.13058
## N(DW=1)                               316                 77                 77
## Method                              Logit              Logit              Logit
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t1_dw, "Logit_Table_1DW",
            title_text = "Logit: DW Extensive Margin (Acute Period)",
            notes_text = "Logit with robust SEs.",
            fitstat_use = ~ n + pr2, extra_lines = logit_t1_dw_extra)
## Saved: Logit_Table_1DW.tex
# ==============================================================================
# LOGIT TABLE 1-FHLB: FHLB (ACUTE)
# ==============================================================================

models_logit_t1_fhlb <- list(
  "(1) All"       = run_one(df_fhlb_s,   "fhlb_user", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(2) All"       = run_one(df_fhlb_s,   "fhlb_user", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(3) Solvent"   = run_one(df_fhlb_sol, "fhlb_user", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(4) Solvent"   = run_one(df_fhlb_sol, "fhlb_user", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(5) Insolvent" = run_one(df_fhlb_ins, "fhlb_user", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(6) Insolvent" = run_one(df_fhlb_ins, "fhlb_user", EXPL_MTM_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
logit_t1_fhlb_extra <- list(
  "__N(FHLB=1)" = c(sum(df_fhlb_s$fhlb_user), sum(df_fhlb_s$fhlb_user),
                     sum(df_fhlb_sol$fhlb_user), sum(df_fhlb_sol$fhlb_user),
                     sum(df_fhlb_ins$fhlb_user), sum(df_fhlb_ins$fhlb_user)),
  "__Method" = rep("Logit", 6)
)

etable(models_logit_t1_fhlb, fitstat = ~ n + pr2,
       order = COEF_ORDER, extralines = logit_t1_fhlb_extra,
       title = "Logit Table 1-FHLB: FHLB Extensive Margin — Acute Period")
##                                    (1) All             (2) All
## Dependent Var.:                  fhlb_user           fhlb_user
##                                                               
## Constant                -2.631*** (0.0718)  -2.653*** (0.0736)
## MTM Loss (z)               0.0801 (0.0692)     0.0597 (0.0712)
## Uninsured Leverage (z)    0.1342* (0.0650)    0.1157. (0.0673)
## MTM $\times$ Uninsured                       -0.0996. (0.0600)
## Log(Assets)             0.2474*** (0.0709)  0.2483*** (0.0710)
## Cash Ratio             -0.6115*** (0.1089) -0.6259*** (0.1088)
## Loan-to-Deposit         0.3964*** (0.0762)  0.3824*** (0.0764)
## Book Equity Ratio         0.1100. (0.0658)     0.0912 (0.0661)
## Wholesale Funding          0.0178 (0.0633)     0.0193 (0.0635)
## ROA                      -0.1163. (0.0649)    -0.1055 (0.0654)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,577               3,577
## Pseudo R2                          0.07943             0.08059
## N(FHLB=1)                              302                 302
## Method                               Logit               Logit
## 
##                                (3) Solvent         (4) Solvent
## Dependent Var.:                  fhlb_user           fhlb_user
##                                                               
## Constant                -2.610*** (0.0824)  -2.642*** (0.0847)
## MTM Loss (z)               0.0574 (0.0791)     0.0248 (0.0816)
## Uninsured Leverage (z)    0.1308. (0.0686)     0.0826 (0.0758)
## MTM $\times$ Uninsured                       -0.1290. (0.0688)
## Log(Assets)             0.2546*** (0.0755)  0.2600*** (0.0759)
## Cash Ratio             -0.6393*** (0.1100) -0.6567*** (0.1096)
## Loan-to-Deposit         0.3660*** (0.0839)  0.3544*** (0.0842)
## Book Equity Ratio          0.0817 (0.0739)     0.0541 (0.0752)
## Wholesale Funding          0.0203 (0.0692)     0.0230 (0.0694)
## ROA                      -0.1183. (0.0698)    -0.1075 (0.0703)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         2,930               2,930
## Pseudo R2                          0.08354             0.08529
## N(FHLB=1)                              257                 257
## Method                               Logit               Logit
## 
##                             (5) Insolvent      (6) Insolvent
## Dependent Var.:                 fhlb_user          fhlb_user
##                                                             
## Constant               -2.981*** (0.7069) -2.970*** (0.7213)
## MTM Loss (z)              0.5439 (0.3479)    0.5422 (0.3471)
## Uninsured Leverage (z)    0.1727 (0.2121)    0.1234 (0.4998)
## MTM $\times$ Uninsured                       0.0399 (0.3285)
## Log(Assets)               0.1371 (0.1968)    0.1367 (0.1969)
## Cash Ratio               -0.4029 (0.4686)   -0.4008 (0.4750)
## Loan-to-Deposit          0.3649* (0.1858)   0.3667* (0.1852)
## Book Equity Ratio         0.3470 (0.4489)    0.3506 (0.4508)
## Wholesale Funding         0.0125 (0.1596)    0.0116 (0.1566)
## ROA                      -0.1054 (0.1800)   -0.1070 (0.1785)
## ______________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                          647                647
## Pseudo R2                         0.06492            0.06497
## N(FHLB=1)                              45                 45
## Method                              Logit              Logit
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t1_fhlb, "Logit_Table_1FHLB",
            title_text = "Logit: FHLB Extensive Margin (Acute Period)",
            notes_text = "Logit with robust SEs.",
            fitstat_use = ~ n + pr2, extra_lines = logit_t1_fhlb_extra)
## Saved: Logit_Table_1FHLB.tex
# ==============================================================================
# LOGIT TABLE 2: ACUTE VS ARB
# ==============================================================================

models_logit_t2 <- list(
  "(1) Acute"  = run_one(df_btfp_s,     "btfp_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(2) Acute"  = run_one(df_btfp_s,     "btfp_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(3) Arb"    = run_one(df_btfp_arb_s, "btfp_arb",   EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(4) Arb"    = run_one(df_btfp_arb_s, "btfp_arb",   EXPL_MTM_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 17 observations removed because of NA values (RHS: 17).
etable(models_logit_t2, fitstat = ~ n + pr2, order = COEF_ORDER,
       title = "Logit Table 2: BTFP Acute vs Arb")
##                                  (1) Acute           (2) Acute
## Dependent Var.:                 btfp_acute          btfp_acute
##                                                               
## Constant                -2.330*** (0.0706)  -2.320*** (0.0711)
## MTM Loss (z)            0.2177*** (0.0619)  0.2141*** (0.0622)
## Uninsured Leverage (z)  0.2129*** (0.0625)  0.2089*** (0.0626)
## MTM $\times$ Uninsured                         0.0461 (0.0569)
## Log(Assets)             0.5738*** (0.0620)  0.5743*** (0.0619)
## Cash Ratio             -0.5236*** (0.1050) -0.5171*** (0.1050)
## Loan-to-Deposit           -0.0064 (0.0669)     0.0009 (0.0664)
## Book Equity Ratio      -0.3338*** (0.0817) -0.3289*** (0.0825)
## Wholesale Funding       0.1831*** (0.0466)  0.1826*** (0.0465)
## ROA                       -0.0127 (0.0628)    -0.0164 (0.0629)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,737               3,737
## Pseudo R2                          0.13099             0.13124
## 
##                                    (3) Arb             (4) Arb
## Dependent Var.:                   btfp_arb            btfp_arb
##                                                               
## Constant                -1.802*** (0.0529)  -1.805*** (0.0533)
## MTM Loss (z)             0.1648** (0.0526)   0.1648** (0.0526)
## Uninsured Leverage (z)   0.1416** (0.0509)   0.1433** (0.0510)
## MTM $\times$ Uninsured                        -0.0141 (0.0438)
## Log(Assets)             0.3645*** (0.0488)  0.3638*** (0.0488)
## Cash Ratio             -0.5258*** (0.0777) -0.5279*** (0.0777)
## Loan-to-Deposit            0.0327 (0.0540)     0.0314 (0.0543)
## Book Equity Ratio       -0.1666** (0.0588)  -0.1688** (0.0592)
## Wholesale Funding       0.5459*** (0.0382)  0.5463*** (0.0382)
## ROA                    -0.2242*** (0.0581) -0.2226*** (0.0583)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         4,038               4,038
## Pseudo R2                          0.15311             0.15314
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t2, "Logit_Table_2_AcuteArb",
            title_text = "Logit: BTFP Acute vs.\\ Arbitrage",
            notes_text = "Logit with robust SEs.",
            fitstat_use = ~ n + pr2)
## Saved: Logit_Table_2_AcuteArb.tex
# ==============================================================================
# LOGIT TABLE 3: OMO ONLY
# ==============================================================================

models_logit_t3 <- list(
  "(1) OMO Base"  = run_one(df_btfp_s, "btfp_acute", EXPL_OMO_BASE,  "logit", CONTROLS_MTM),
  "(2) OMO Inter" = run_one(df_btfp_s, "btfp_acute", EXPL_OMO_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
etable(models_logit_t3, fitstat = ~ n + pr2, order = COEF_ORDER,
       title = "Logit Table 3: OMO Losses Only")
##                                   (1) OMO Base       (2) OMO Inter
## Dependent Var.:                     btfp_acute          btfp_acute
##                                                                   
## Constant                    -2.321*** (0.0706)  -2.321*** (0.0706)
## MTM Loss OMO (z)               0.0853 (0.0548)     0.0848 (0.0562)
## Uninsured Leverage (z)       0.1806** (0.0610)   0.1803** (0.0620)
## MTM OMO $\times$ Uninsured                         0.0019 (0.0444)
## Log(Assets)                 0.5601*** (0.0640)  0.5600*** (0.0638)
## Cash Ratio                 -0.6052*** (0.1032) -0.6051*** (0.1032)
## Loan-to-Deposit               -0.0199 (0.0720)    -0.0198 (0.0720)
## Book Equity Ratio          -0.3769*** (0.0829) -0.3769*** (0.0830)
## Wholesale Funding           0.1697*** (0.0465)  0.1696*** (0.0465)
## ROA                           -0.0283 (0.0635)    -0.0284 (0.0635)
## __________________________ ___________________ ___________________
## S.E. type                  Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                             3,737               3,737
## Pseudo R2                              0.12784             0.12784
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t3, "Logit_Table_3_OMO",
            title_text = "Logit: OMO Losses Only",
            notes_text = "Logit with robust SEs.",
            fitstat_use = ~ n + pr2)
## Saved: Logit_Table_3_OMO.tex
# ==============================================================================
# LOGIT TABLE 5: PAR BENEFIT
# ==============================================================================

models_logit_t5 <- list(
  "(1) Par Base"  = run_one(df_btfp_s, "btfp_acute", EXPL_PAR_BASE,  "logit", CONTROLS_MTM),
  "(2) Par Inter" = run_one(df_btfp_s, "btfp_acute", EXPL_PAR_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
etable(models_logit_t5, fitstat = ~ n + pr2, order = COEF_ORDER,
       title = "Logit Table 5: Par Benefit")
##                                       (1) Par Base       (2) Par Inter
## Dependent Var.:                         btfp_acute          btfp_acute
##                                                                       
## Constant                        -2.323*** (0.0708)  -2.348*** (0.0729)
## Uninsured Leverage (z)           0.1752** (0.0604)   0.1838** (0.0617)
## Par Benefit $\times$ Uninsured                      -0.1938** (0.0695)
## Par Benefit (z)                   -0.0042 (0.0645)     0.0667 (0.0779)
## Log(Assets)                     0.5866*** (0.0616)  0.6033*** (0.0626)
## Cash Ratio                     -0.6239*** (0.1021) -0.6423*** (0.1026)
## Loan-to-Deposit                   -0.0627 (0.0650)    -0.0699 (0.0662)
## Book Equity Ratio              -0.3861*** (0.0836) -0.3899*** (0.0843)
## Wholesale Funding               0.1753*** (0.0464)  0.1726*** (0.0463)
## ROA                               -0.0416 (0.0629)    -0.0331 (0.0628)
## ______________________________ ___________________ ___________________
## S.E. type                      Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                                 3,737               3,737
## Pseudo R2                                  0.12701             0.13053
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t5, "Logit_Table_5_Par",
            title_text = "Logit: Par Benefit",
            notes_text = "Logit with robust SEs.",
            fitstat_use = ~ n + pr2)
## Saved: Logit_Table_5_Par.tex
# ==============================================================================
# LOGIT TABLE 6: TEMPORAL — BTFP
# ==============================================================================

models_logit_t6 <- list(
  "(1) Acute"  = run_one(df_btfp_s,      "btfp_acute", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(2) Acute"  = run_one(df_btfp_s,      "btfp_acute", EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(3) Post"   = run_one(df_btfp_post_s, "btfp_post",  EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(4) Post"   = run_one(df_btfp_post_s, "btfp_post",  EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(5) Arb"    = run_one(df_btfp_arb_s,  "btfp_arb",   EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(6) Arb"    = run_one(df_btfp_arb_s,  "btfp_arb",   EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(7) Wind"   = run_one(df_btfp_wind_s, "btfp_wind",  EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(8) Wind"   = run_one(df_btfp_wind_s, "btfp_wind",  EXPL_MTM_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 18 observations removed because of NA values (RHS: 18).
## NOTE: 18 observations removed because of NA values (RHS: 18).
logit_t6_extra <- list(
  "__N(BTFP=1)" = c(sum(df_btfp_s$btfp_acute), sum(df_btfp_s$btfp_acute),
                     sum(df_btfp_post_s$btfp_post), sum(df_btfp_post_s$btfp_post),
                     sum(df_btfp_arb_s$btfp_arb), sum(df_btfp_arb_s$btfp_arb),
                     sum(df_btfp_wind_s$btfp_wind), sum(df_btfp_wind_s$btfp_wind)),
  "__Method" = rep("Logit", 8)
)

etable(models_logit_t6, fitstat = ~ n + pr2,
       order = COEF_ORDER, extralines = logit_t6_extra,
       title = "Logit Table 6: BTFP Temporal")
##                                  (1) Acute           (2) Acute
## Dependent Var.:                 btfp_acute          btfp_acute
##                                                               
## Constant                -2.330*** (0.0706)  -2.320*** (0.0711)
## MTM Loss (z)            0.2177*** (0.0619)  0.2141*** (0.0622)
## Uninsured Leverage (z)  0.2129*** (0.0625)  0.2089*** (0.0626)
## MTM $\times$ Uninsured                         0.0461 (0.0569)
## Log(Assets)             0.5738*** (0.0620)  0.5743*** (0.0619)
## Cash Ratio             -0.5236*** (0.1050) -0.5171*** (0.1050)
## Loan-to-Deposit           -0.0064 (0.0669)     0.0009 (0.0664)
## Book Equity Ratio      -0.3338*** (0.0817) -0.3289*** (0.0825)
## Wholesale Funding       0.1831*** (0.0466)  0.1826*** (0.0465)
## ROA                       -0.0127 (0.0628)    -0.0164 (0.0629)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,737               3,737
## Pseudo R2                          0.13099             0.13124
## N(BTFP=1)                              462                 462
## Method                               Logit               Logit
## 
##                                   (3) Post            (4) Post
## Dependent Var.:                  btfp_post           btfp_post
##                                                               
## Constant                -1.372*** (0.0477)  -1.366*** (0.0481)
## MTM Loss (z)             0.1280** (0.0490)   0.1307** (0.0493)
## Uninsured Leverage (z)    0.1229* (0.0513)    0.1222* (0.0514)
## MTM $\times$ Uninsured                         0.0319 (0.0433)
## Log(Assets)             0.3959*** (0.0527)  0.3964*** (0.0526)
## Cash Ratio             -0.5106*** (0.0707) -0.5062*** (0.0710)
## Loan-to-Deposit          -0.0987. (0.0511)   -0.0942. (0.0516)
## Book Equity Ratio      -0.2212*** (0.0560) -0.2169*** (0.0563)
## Wholesale Funding         0.0741. (0.0414)    0.0734. (0.0414)
## ROA                      -0.0804. (0.0489)   -0.0831. (0.0490)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         3,437               3,437
## Pseudo R2                          0.08889             0.08902
## N(BTFP=1)                              775                 775
## Method                               Logit               Logit
## 
##                                    (5) Arb             (6) Arb
## Dependent Var.:                   btfp_arb            btfp_arb
##                                                               
## Constant                -1.802*** (0.0529)  -1.805*** (0.0533)
## MTM Loss (z)             0.1648** (0.0526)   0.1648** (0.0526)
## Uninsured Leverage (z)   0.1416** (0.0509)   0.1433** (0.0510)
## MTM $\times$ Uninsured                        -0.0141 (0.0438)
## Log(Assets)             0.3645*** (0.0488)  0.3638*** (0.0488)
## Cash Ratio             -0.5258*** (0.0777) -0.5279*** (0.0777)
## Loan-to-Deposit            0.0327 (0.0540)     0.0314 (0.0543)
## Book Equity Ratio       -0.1666** (0.0588)  -0.1688** (0.0592)
## Wholesale Funding       0.5459*** (0.0382)  0.5463*** (0.0382)
## ROA                    -0.2242*** (0.0581) -0.2226*** (0.0583)
## ______________________ ___________________ ___________________
## S.E. type              Heteroskedast.-rob. Heteroskedast.-rob.
## Observations                         4,038               4,038
## Pseudo R2                          0.15311             0.15314
## N(BTFP=1)                              766                 766
## Method                               Logit               Logit
## 
##                                  (7) Wind           (8) Wind
## Dependent Var.:                 btfp_wind          btfp_wind
##                                                             
## Constant               -3.170*** (0.0842) -3.183*** (0.0857)
## MTM Loss (z)              0.0424 (0.0897)    0.0421 (0.0898)
## Uninsured Leverage (z)   0.1775* (0.0872)   0.1852* (0.0869)
## MTM $\times$ Uninsured                      -0.0689 (0.0743)
## Log(Assets)               0.0162 (0.0838)    0.0130 (0.0842)
## Cash Ratio             -0.3306** (0.1042) -0.3401** (0.1046)
## Loan-to-Deposit         -0.1729. (0.0886)  -0.1801* (0.0888)
## Book Equity Ratio       -0.2008* (0.0971)  -0.2080* (0.0976)
## Wholesale Funding      0.6113*** (0.0491) 0.6136*** (0.0493)
## ROA                     -0.1758. (0.0988)  -0.1715. (0.0983)
## ______________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        4,043              4,043
## Pseudo R2                         0.11320            0.11368
## N(BTFP=1)                             229                229
## Method                              Logit              Logit
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t6, "Logit_Table_6_Temporal",
            title_text = "Logit: BTFP Temporal Evolution",
            notes_text = "Logit with robust SEs. Coefficients in log-odds.",
            fitstat_use = ~ n + pr2, extra_lines = logit_t6_extra)
## Saved: Logit_Table_6_Temporal.tex
# ==============================================================================
# LOGIT TABLE 7: PRE-BTFP DW
# ==============================================================================

models_logit_t7 <- list(
  "(1) Mar10"     = run_one(df_dw_mar10_s,    "dw_mar10",    EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(2) Mar10"     = run_one(df_dw_mar10_s,    "dw_mar10",    EXPL_MTM_INTER, "logit", CONTROLS_MTM),
  "(3) Mar10-13"  = run_one(df_dw_mar10_13_s, "dw_mar10_13", EXPL_MTM_BASE,  "logit", CONTROLS_MTM),
  "(4) Mar10-13"  = run_one(df_dw_mar10_13_s, "dw_mar10_13", EXPL_MTM_INTER, "logit", CONTROLS_MTM)
)
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
logit_t7_extra <- list(
  "__N(DW=1)" = c(sum(df_dw_mar10_s$dw_mar10), sum(df_dw_mar10_s$dw_mar10),
                   sum(df_dw_mar10_13_s$dw_mar10_13), sum(df_dw_mar10_13_s$dw_mar10_13)),
  "__Method" = rep("Logit", 4)
)

etable(models_logit_t7, fitstat = ~ n + pr2,
       order = COEF_ORDER, extralines = logit_t7_extra,
       title = "Logit Table 7: Pre-BTFP DW")
##                                 (1) Mar10          (2) Mar10       (3) Mar10-13
## Dependent Var.:                  dw_mar10           dw_mar10        dw_mar10_13
##                                                                                
## Constant               -5.752*** (0.4085) -5.770*** (0.3956) -4.779*** (0.2065)
## MTM Loss (z)             -0.2155 (0.2137)   -0.1931 (0.2259)   -0.0909 (0.1527)
## Uninsured Leverage (z)    0.1593 (0.1599)    0.1622 (0.1618)  0.3690** (0.1222)
## MTM $\times$ Uninsured                      -0.0641 (0.1644)                   
## Log(Assets)            0.8648*** (0.1447) 0.8642*** (0.1451) 0.9365*** (0.1125)
## Cash Ratio               -1.376* (0.5494)   -1.390* (0.5415)  -0.6538* (0.2732)
## Loan-to-Deposit           0.0591 (0.2057)    0.0520 (0.2092)   -0.0094 (0.1566)
## Book Equity Ratio       -0.4911. (0.2717)  -0.4930. (0.2693)  -0.3050. (0.1824)
## Wholesale Funding      0.3329*** (0.0986) 0.3344*** (0.0996)  0.2374** (0.0853)
## ROA                     -0.3268. (0.1717)  -0.3265. (0.1722)    0.0252 (0.1352)
## ______________________ __________________ __________________ __________________
## S.E. type              Heteroskedas.-rob. Heteroskedas.-rob. Heteroskedas.-rob.
## Observations                        3,986              3,986              3,988
## Pseudo R2                         0.18573            0.18604            0.19815
## N(DW=1)                                47                 47                 90
## Method                              Logit              Logit              Logit
## 
##                              (4) Mar10-13
## Dependent Var.:               dw_mar10_13
##                                          
## Constant               -4.762*** (0.2047)
## MTM Loss (z)             -0.1653 (0.1668)
## Uninsured Leverage (z)  0.3781** (0.1200)
## MTM $\times$ Uninsured    0.1289 (0.1073)
## Log(Assets)            0.9310*** (0.1120)
## Cash Ratio              -0.6415* (0.2726)
## Loan-to-Deposit           0.0069 (0.1592)
## Book Equity Ratio       -0.3044. (0.1840)
## Wholesale Funding       0.2361** (0.0850)
## ROA                       0.0214 (0.1343)
## ______________________ __________________
## S.E. type              Heteroskedas.-rob.
## Observations                        3,988
## Pseudo R2                         0.19968
## N(DW=1)                                90
## Method                              Logit
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
save_etable(models_logit_t7, "Logit_Table_7_PreBTFP_DW",
            title_text = "Logit: Pre-BTFP Discount Window",
            notes_text = "Logit with robust SEs.",
            fitstat_use = ~ n + pr2, extra_lines = logit_t7_extra)
## Saved: Logit_Table_7_PreBTFP_DW.tex

9 KEY FIGURES

9.1 Figure 1: AE Coefficient by Uninsured Leverage Tercile (Threshold Gradient)

Goldstein-Pauzner prediction: The AE coefficient should be steeper among banks with high uninsured leverage, because the run threshold shifts when fragility is high.

# ==============================================================================
# THRESHOLD GRADIENT — AE coefficient across UL terciles
# ==============================================================================

tercile_coefs <- map_dfr(c("Low", "Med", "High"), function(terc) {
  df_sub <- df_btfp_s %>% filter(unins_lev_tercile == terc)
  mod <- feols(btfp_acute ~ adjusted_equity + uninsured_lev + ln_assets + cash_ratio +
                 loan_to_deposit + wholesale + roa, data = df_sub, vcov = "hetero")
  tidy(mod) %>%
    filter(term == "adjusted_equity") %>%
    mutate(tercile = terc, n = nrow(df_sub), n_btfp = sum(df_sub$btfp_acute))
})
## NOTE: 3 observations removed because of NA values (RHS: 3).
## NOTE: 1 observation removed because of NA values (RHS: 1).
## NOTE: 6 observations removed because of NA values (RHS: 6).
tercile_coefs$tercile <- factor(tercile_coefs$tercile, levels = c("Low", "Med", "High"))

fig1 <- ggplot(tercile_coefs, aes(x = tercile, y = estimate)) +
  geom_col(fill = "#003049", width = 0.6) +
  geom_errorbar(aes(ymin = estimate - 1.96 * std.error,
                     ymax = estimate + 1.96 * std.error),
                width = 0.2, linewidth = 0.7) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  labs(title = "Figure 1: Threshold Gradient — AE Coefficient by Uninsured Leverage Tercile",
       subtitle = "BTFP Acute Period | LPM with robust SEs",
       x = "Uninsured Leverage Tercile", y = "AE Coefficient (LPM)") +
  theme_paper

fig1

save_figure(fig1, "Fig1_ThresholdGradient_AE")
## Saved: Fig1_ThresholdGradient_AE.pdf

9.2 Figure 2: Temporal Coefficient Evolution (BTFP)

# ==============================================================================
# TEMPORAL COEFFICIENT EVOLUTION
# ==============================================================================

temporal_data <- list(
  list(data = df_btfp_s,      dv = "btfp_acute", period = "Acute"),
  list(data = df_btfp_post_s, dv = "btfp_post",  period = "Post"),
  list(data = df_btfp_arb_s,  dv = "btfp_arb",   period = "Arb"),
  list(data = df_btfp_wind_s, dv = "btfp_wind",  period = "Wind")
)

temporal_coefs <- map_dfr(temporal_data, function(item) {
  mod <- run_one(item$data, item$dv, EXPL_MTM_INTER, controls = CONTROLS_MTM)
  tidy(mod) %>%
    filter(term %in% c("adjusted_equity", "uninsured_lev", "ae_x_uninsured")) %>%
    mutate(period = item$period)
})
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 10 observations removed because of NA values (RHS: 10).
## NOTE: 17 observations removed because of NA values (RHS: 17).
## NOTE: 18 observations removed because of NA values (RHS: 18).
temporal_coefs$period <- factor(temporal_coefs$period,
                                 levels = c("Acute", "Post", "Arb", "Wind"))

fig2 <- ggplot(temporal_coefs, aes(x = period, y = estimate, color = term, group = term)) +
  geom_point(size = 3, position = position_dodge(0.3)) +
  geom_errorbar(aes(ymin = estimate - 1.96 * std.error,
                     ymax = estimate + 1.96 * std.error),
                width = 0.2, position = position_dodge(0.3)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  scale_color_manual(values = c("adjusted_equity" = "#003049",
                                 "uninsured_lev" = "#D62828",
                                 "ae_x_uninsured" = "#F77F00"),
                      labels = c("Adj. Equity", "Uninsured Leverage", "AE × UL")) +
  labs(title = "Figure 2: Temporal Coefficient Evolution — BTFP",
       subtitle = "  | LPM with robust SEs",
       x = "Period", y = "Coefficient", color = "") +
  theme_paper

fig2

save_figure(fig2, "Fig2_Temporal_Coefs_BTFP")
## Saved: Fig2_Temporal_Coefs_BTFP.pdf

10 FHLB Stat

# ==============================================================================
# DESCRIPTIVE STATS: FHLB BORROWING BY PERIOD
# ==============================================================================

# 1. Define the raw variable list
fhlb_vars <- c(
  "fhlb_adv",                         # Total Advances
  "fhlb_less_than_1yr", "fhlb_1to3yr", # Maturities
  "fhlb_3to5yr", "fhlb_more_than_5yr",
  "change_fhlb_adv_fwd_q",            # Change in advances
  "abnormal_fhlb_borrowing_10pct"     # Abnormal indicator
)

# 2. Variable Labels for clean output
fhlb_labels <- c(
  "Total FHLB Advances ($000s)",
  "Maturity: < 1 Year",
  "Maturity: 1-3 Years",
  "Maturity: 3-5 Years",
  "Maturity: > 5 Years",
  "Change in FHLB Adv. (Next Q)",
  "Abnormal Borrowing (10% Threshold)"
)

# 3. Calculate Summary Stats for FHLB Users in the Acute Sample
fhlb_stats_table <- df_fhlb_s %>%
  filter(fhlb_user == 1) %>%  # Restrict to actual FHLB borrowers
  select(all_of(fhlb_vars)) %>%
  # USE CUSTOM SEPARATOR (___) so we don't split variable names with underscores
  summarise(across(everything(), list(
    Mean = ~ mean(., na.rm = TRUE),
    SD   = ~ sd(., na.rm = TRUE),
    Median = ~ median(., na.rm = TRUE)
  ), .names = "{col}___{fn}")) %>% 
  pivot_longer(everything(), names_to = c("Variable", "Stat"), names_sep = "___") %>%
  pivot_wider(names_from = Stat, values_from = value) %>%
  mutate(
    Variable = factor(Variable, levels = fhlb_vars, labels = fhlb_labels),
    Mean = formatC(Mean, format = "f", digits = 2, big.mark = ","),
    SD   = formatC(SD,   format = "f", digits = 2, big.mark = ","),
    Median = formatC(Median, format = "f", digits = 2, big.mark = ",")
  )

# 4. Display Table (HTML)
kbl(fhlb_stats_table, caption = "FHLB Borrowing Characteristics (Acute Period Users)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = F)
FHLB Borrowing Characteristics (Acute Period Users)
Variable Mean SD Median
Total FHLB Advances ($000s) 114,622.40 712,943.60 10,000.00
Maturity: < 1 Year 83,365.01 648,685.55 4,000.00
Maturity: 1-3 Years 11,961.41 58,688.95 282.50
Maturity: 3-5 Years 9,282.11 65,918.11 0.00
Maturity: > 5 Years 10,013.87 115,988.88 0.00
Change in FHLB Adv. (Next Q) 1,311.63 8,921.94 120.00
Abnormal Borrowing (10% Threshold) 1.00 0.00 1.00
# 5. Save Table (LaTeX)
latex_fhlb_stats <- kable(fhlb_stats_table, format = "latex", booktabs = TRUE,
      caption = "FHLB Borrowing Amounts and Maturities (Acute Period Users). \\textit{Note: Amounts in thousands.}")

safe_writeLines(as.character(latex_fhlb_stats), file.path(TABLE_PATH, "Table_Desc_FHLB_Details.tex"))
message("Saved: Table_Desc_FHLB_Details.tex")
## Saved: Table_Desc_FHLB_Details.tex
# ==============================================================================
# DESCRIPTIVE STATS: FHLB BORROWING BY TEMPORAL PERIOD
# ==============================================================================

# 1. Define Period Datasets
fhlb_periods <- list(
  "Acute"      = df_fhlb_s,
  "Post-Acute" = df_fhlb_post_s,
  "Arbitrage"  = df_fhlb_arb_s,
  "Wind-down"  = df_fhlb_wind_s
)

# 2. Function to Calculate Weighted Average Term (Years)
#    Midpoints: <1yr (0.5), 1-3yr (2.0), 3-5yr (4.0), >5yr (7.0)
calc_wa_term <- function(df) {
  # Avoid division by zero
  total_adv <- sum(df$fhlb_adv, na.rm = TRUE)
  if (total_adv == 0) return(NA)
  
  w_sum <- sum(
    (df$fhlb_less_than_1yr * 0.5) +
    (df$fhlb_1to3yr        * 2.0) +
    (df$fhlb_3to5yr        * 4.0) +
    (df$fhlb_more_than_5yr * 7.0),
    na.rm = TRUE
  )
  return(w_sum / total_adv)
}

# 3. Generate Summary Data
fhlb_temporal_stats <- map_dfr(names(fhlb_periods), function(p_name) {
  
  # Full sample (for "Banks" count)
  df_all <- fhlb_periods[[p_name]]
  
  # Borrowers only (for amounts and term)
  df_bor <- df_all %>% filter(fhlb_user == 1)
  
  tibble(
    Period    = p_name,
    Abnormal10pct     = nrow(df_bor),                         # Number of Borrowers
    Banks     = nrow(df_all),                         # Total Sample N
    Total_B   = sum(df_bor$fhlb_adv, na.rm = TRUE) / 1e6, # Billions
    Mean_M    = mean(df_bor$fhlb_adv, na.rm = TRUE) / 1e3, # Millions
    Median_M  = median(df_bor$fhlb_adv, na.rm = TRUE) / 1e3, # Millions
    Term_Yrs  = calc_wa_term(df_bor)
  )
})

# 4. Format for Display
fhlb_display <- fhlb_temporal_stats %>%
  mutate(
    `Total ($B)`   = formatC(Total_B, format = "f", digits = 2, big.mark = ","),
    `Mean ($M)`    = formatC(Mean_M,  format = "f", digits = 1, big.mark = ","),
    `Median ($M)`  = formatC(Median_M,format = "f", digits = 1, big.mark = ","),
    `Term (Years)` = formatC(Term_Yrs,format = "f", digits = 2)
  ) %>%
  select(Period, Abnormal10pct , Banks, `Total ($B)`, `Mean ($M)`, `Median ($M)`, `Term (Years)`)

# 5. Create LaTeX Table with Custom Header
#    We use kable listing the bottom row of headers, then add the top row with add_header_above
kbl(fhlb_display, booktabs = TRUE, format = "latex", align = "lccrrrr",
    caption = "FHLB Borrowing Characteristics by Period") %>%
  add_header_above(c(" " = 3, "Total" = 1, "Mean" = 1, "Median" = 1, "Term" = 1)) %>%
  kable_styling(latex_options = c("hold_position")) %>%
  save_kable(file.path(TABLE_PATH, "Table_Desc_FHLB_Temporal.tex"))

# 6. HTML Preview
kbl(fhlb_display, caption = "FHLB Borrowing Characteristics by Period") %>%
  kable_styling(bootstrap_options = "striped", full_width = F) %>%
  add_header_above(c(" " = 3, "Total" = 1, "Mean" = 1, "Median" = 1, "Term" = 1))
FHLB Borrowing Characteristics by Period
Total
Mean
Median
Term
Period Abnormal10pct Banks Total (\(B) </th> <th style="text-align:left;"> Mean (\)M) Median ($M) Term (Years)
Acute 302 3587 34.62 114.6 10.0 1.51
Post-Acute 302 2974 34.62 114.6 10.0 1.51
Arbitrage 196 3485 18.18 92.8 10.0 2.17
Wind-down 145 3977 12.05 83.1 10.1 1.19

cat("\n=== SESSION COMPLETE ===\n")
## 
## === SESSION COMPLETE ===
cat("Tables saved to:", TABLE_PATH, "\n")
## Tables saved to: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/analysis_all_specification/tables
cat("Figures saved to:", FIG_PATH, "\n")
## Figures saved to: C:/Users/mohua/OneDrive - Louisiana State University/Finance_PhD/DW_Stigma_paper/Liquidity_project_2025/03_documentation/analysis_all_specification/figures
sessionInfo()
## R version 4.3.1 (2023-06-16 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 11 x64 (build 26200)
## 
## Matrix products: default
## 
## 
## locale:
## [1] LC_COLLATE=English_United States.utf8 
## [2] LC_CTYPE=English_United States.utf8   
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.utf8    
## 
## time zone: America/Chicago
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] readxl_1.4.5           readr_2.1.5            patchwork_1.3.2       
##  [4] scales_1.4.0           gridExtra_2.3          ggplot2_3.5.2         
##  [7] DescTools_0.99.60      kableExtra_1.4.0       knitr_1.50            
## [10] modelsummary_2.4.0     broom_1.0.9            nnet_7.3-19           
## [13] marginaleffects_0.25.1 fixest_0.12.1          tibble_3.2.1          
## [16] purrr_1.0.4            lubridate_1.9.4        stringr_1.5.1         
## [19] tidyr_1.3.1            dplyr_1.1.4            data.table_1.17.0     
## 
## loaded via a namespace (and not attached):
##  [1] tidyselect_1.2.1    Exact_3.3           viridisLite_0.4.2  
##  [4] rootSolve_1.8.2.4   farver_2.1.2        fastmap_1.2.0      
##  [7] bayestestR_0.16.1   digest_0.6.33       timechange_0.3.0   
## [10] estimability_1.5.1  lifecycle_1.0.4     dreamerr_1.4.0     
## [13] lmom_3.2            magrittr_2.0.3      compiler_4.3.1     
## [16] rlang_1.1.1         sass_0.4.10         tools_4.3.1        
## [19] yaml_2.3.10         labeling_0.4.3      bit_4.6.0          
## [22] xml2_1.3.8          RColorBrewer_1.1-3  tinytable_0.13.0   
## [25] expm_1.0-0          withr_3.0.2         numDeriv_2016.8-1.1
## [28] datawizard_1.2.0    grid_4.3.1          fansi_1.0.6        
## [31] xtable_1.8-4        e1071_1.7-16        emmeans_1.11.2-8   
## [34] MASS_7.3-60         insight_1.3.1       cli_3.6.1          
## [37] mvtnorm_1.3-3       crayon_1.5.3        rmarkdown_2.29     
## [40] ragg_1.3.3          generics_0.1.4      performance_0.15.0 
## [43] rstudioapi_0.17.1   httr_1.4.7          tzdb_0.5.0         
## [46] parameters_0.27.0   gld_2.6.8           cachem_1.1.0       
## [49] proxy_0.4-27        parallel_4.3.1      cellranger_1.1.0   
## [52] stringmagic_1.1.2   vctrs_0.6.5         boot_1.3-28.1      
## [55] Matrix_1.5-4.1      sandwich_3.1-1      jsonlite_2.0.0     
## [58] litedown_0.7        hms_1.1.3           bit64_4.6.0-1      
## [61] Formula_1.2-5       systemfonts_1.2.2   jquerylib_0.1.4    
## [64] glue_1.8.0          stringi_1.8.7       gtable_0.3.6       
## [67] tables_0.9.31       pillar_1.11.0       htmltools_0.5.9    
## [70] R6_2.6.1            textshaping_1.0.0   vroom_1.6.5        
## [73] evaluate_1.0.4      lattice_0.21-8      haven_2.5.4        
## [76] backports_1.5.0     bslib_0.9.0         class_7.3-22       
## [79] Rcpp_1.0.14         checkmate_2.3.2     svglite_2.1.3      
## [82] coda_0.19-4.1       nlme_3.1-162        xfun_0.52          
## [85] fs_1.6.5            zoo_1.8-13          forcats_1.0.0      
## [88] pkgconfig_2.0.3