Complete Methodology
Framework / What / Why / How
Credit Risk and Dollarization in Cambodia: A Dual-Currency Analysis Using Interest Rate Spreads (2013–2025)
This section presents the complete methodological framework for constructing currency-specific and system-wide Credit Risk Indices (CRIs) for Cambodia’s dual-currency banking sector. Each methodology is structured around four dimensions: Framework (the conceptual basis), What (what is being done), Why (the justification), and How (the implementation). The framework applies identically to both USD and KHR segments, enabling direct cross-currency comparison.
3.1 Data Selection Rationale
Framework | What | Why | How
### Framework
Constructing a reliable credit risk signal requires selecting interest rate data that is clean, comparable across currencies, and responsive to changing credit conditions. The National Bank of Cambodia (NBC) publishes monthly interest rate data for deposit money banks, disaggregated by currency (KHR and USD), product type, and rate version. Three deliberate choices shape our data selection: rate version, loan product, and deposit product.
### What
We select Weighted Average Rates on New Amounts for Term Loans (asset side) and Term Deposits (liability side) in both USD and KHR. These are sourced from NBC’s published monthly banking statistics covering January 2013 – December 2025 (156 monthly observations per currency).
| Dimension | Selection |
|---|---|
| Rate Version | New Amount (not Outstanding Amount) |
| Loan Product | Term Loans only |
| Deposit Product | Term Deposits only |
### Why
Rate Version — New Amount over Outstanding Amount:
| Version | Speed of Response | Implication |
|---|---|---|
| New Amount | Fast — reflects banks’ current risk pricing | Best for early warning |
| Outstanding Amount | Slow — diluted by legacy contracts from prior years | Lags true conditions |
When a bank perceives rising credit risk, it immediately adjusts rates on new loans; outstanding amount rates remain anchored by legacy contracts issued months or years earlier. An effective early warning indicator must use the series that reacts fastest to changing conditions.
Product Selection:
| Product | Selected? | Rationale |
|---|---|---|
| Term Loans | Yes | Fixed maturity; pricing directly reflects credit assessment |
| Overdraft | No | Priced for liquidity provision, not pure credit risk |
| Credit Card | No | Bundles convenience premiums and unsecured risk |
| Other Loans | No | Ambiguous composition makes interpretation unreliable |
| Term Deposits | Yes | Best maturity match with term loans; reflects time value of money |
| Demand Deposits | No | Near-zero rates driven by liquidity, not credit dynamics |
| Saving Deposits | No | Partially liquidity-driven; poor maturity match |
| Other Deposits | No | Ambiguous composition |
### How
- Download the NBC monthly interest rate tables for Deposit Money Banks.
- Filter to rows corresponding to: (a) New Amount, (b) Term Loans, (c) Term Deposits.
- Split into two separate DataFrames — one for USD, one for KHR.
- Align on a common monthly date index from January 2013 to December 2025.
- Outstanding Amount rates are retained as a separate dataset for robustness checks (Section 3.12).
3.2 Interest Rate Spread Definition
Framework | What | Why | How
### Framework
The interest rate spread — the gap between lending rates and deposit rates — is a classical proxy for credit risk compensation in banking. A widening spread signals that banks are demanding a higher premium for bearing credit risk, while a narrowing spread indicates easing risk conditions. This spread forms the core input series for all subsequent modeling.
### What
For each currency \(c \in \{\text{USD}, \text{KHR}\}\), we compute the credit spread as:
\[ S_t^c = r_{\text{Term Loans},t}^{c} - r_{\text{Term Deposits},t}^{c} \]
where: - \(r_{\text{Term Loans},t}^{c}\) = weighted average rate on new term loans in currency \(c\) at month \(t\) - \(r_{\text{Term Deposits},t}^{c}\) = weighted average rate on new term deposits in currency \(c\) at month \(t\)
This yields two time series — \(S_t^{\text{USD}}\) and \(S_t^{\text{KHR}}\) — each with 156 monthly observations.
### Why
USD and KHR lending operate under fundamentally different risk environments:
- USD lending is influenced by global dollar conditions, U.S. Federal Reserve monetary policy, and international capital flows.
- KHR lending is more sensitive to domestic monetary policy, NBC reserve requirement changes, and exchange rate expectations.
Just as credit risk practitioners build separate models for different portfolio segments — a principle enshrined in the Basel framework — constructing separate spreads for each currency allows us to capture these distinct dynamics rather than masking them through aggregation. Pooling the two currencies into a single spread would conflate structurally different risk premia.
### How
- For each month \(t\) and each currency \(c\), subtract the term deposit rate from the term loan rate: \(S_t^c = r_{\text{loan},t}^c - r_{\text{deposit},t}^c\).
- Inspect for missing values; interpolate linearly if gaps are isolated (≤ 2 consecutive months).
- Plot both spread series to verify plausibility: KHR spreads should be structurally wider than USD spreads due to the exchange rate risk premium embedded in riel lending.
- Store as two pandas Series indexed by date:
spread_usdandspread_khr.
3.3 The Ornstein–Uhlenbeck (OU) Stochastic Model
Framework | What | Why | How
### Framework
Interest rate spreads are not random walks — they are pulled back toward a long-run equilibrium by market forces (competition, arbitrage, monetary policy). The Ornstein–Uhlenbeck (OU) process, first introduced into finance by Vasicek (1977) for short-rate modeling, is the canonical continuous-time model for mean-reverting processes. It provides a mathematically tractable yet economically realistic description of spread dynamics.
### What
For each currency \(c\), we model the spread as a mean-reverting diffusion process governed by the stochastic differential equation (SDE):
\[ dS_t^c = \kappa^c\left(\theta^c - S_t^c\right)dt + \sigma^c\,dW_t^c \]
where \(W_t^c\) is a standard Wiener process (Brownian motion), and the three parameters are:
| Parameter | Symbol | Economic Meaning | Cross-Currency Comparison |
|---|---|---|---|
| Long-run equilibrium | \(\theta^c\) | The “normal” spread level toward which the process gravitates | Is the structural spread higher for KHR or USD? |
| Mean-reversion speed | \(\kappa^c\) | How quickly the spread returns to equilibrium after a shock | Which currency recovers faster from credit stress? |
| Volatility | \(\sigma^c\) | The magnitude of random fluctuations around the mean | Which currency exhibits more spread instability? |
A useful derived quantity is the half-life — the time for a shock to decay to half its initial magnitude:
\[ t_{1/2}^c = \frac{\ln 2}{\kappa^c} \]
### Why
Mean reversion is economically natural: Competitive forces, monetary policy, and arbitrage pull spreads back toward a long-run level. A pure random walk model (e.g., Geometric Brownian Motion) would imply that spreads drift to zero or infinity — economically implausible.
Analytical tractability: The OU process has a closed-form Gaussian transition density, enabling exact Maximum Likelihood Estimation and analytical computation of crisis probabilities without Monte Carlo simulation.
Parsimony: Only three parameters per currency are estimated from 156 observations — a well-identified, statistically stable estimation problem.
### How
The SDE has the closed-form solution:
\[ S_t^c = \theta^c + \left(S_0^c - \theta^c\right)e^{-\kappa^c t} + \sigma^c\int_0^t e^{-\kappa^c(t-s)}\,dW_s^c \]
Since the stochastic integral of a deterministic function with respect to Brownian motion is Gaussian, the spread follows a normal distribution \(S_t^c \sim \mathcal{N}\!\left(m^c(t),\; v^c(t)\right)\) with:
\[ m^c(t) = \theta^c + \left(S_0^c - \theta^c\right)e^{-\kappa^c t}, \qquad v^c(t) = \frac{(\sigma^c)^2}{2\kappa^c}\left(1 - e^{-2\kappa^c t}\right) \]
Implementation steps: 1. Define the three-parameter OU model class for each currency. 2. Derive the conditional mean \(m^c(t)\) and variance \(v^c(t)\) expressions. 3. Compute the half-life \(t_{1/2}^c = \ln 2 / \kappa^c\) as a reported diagnostic. 4. A half-life of 6 months, for instance, means a spread shocked 2 pp above equilibrium will be approximately 1 pp above equilibrium six months later.
3.4 Parameter Estimation: Maximum Likelihood Estimation (MLE)
Framework | What | Why | How
### Framework
Given a parametric model with known distributional form, Maximum Likelihood Estimation (MLE) finds the parameter values that make the observed data most probable. Because the OU process has an exact Gaussian transition density, MLE is both feasible and optimal for our setting — it yields consistent, asymptotically efficient estimates with known standard errors.
### What
For discretely observed data with equal time spacing \(\Delta t = 1/12\) (monthly), the exact transition density gives:
\[ S_{t_{i+1}}^c \mid S_{t_i}^c \sim \mathcal{N}\!\left(\mu_i^c,\;\gamma^{c\,2}\right) \]
\[ \mu_i^c = \theta^c + \left(S_{t_i}^c - \theta^c\right)e^{-\kappa^c \Delta t}, \qquad \gamma^{c\,2} = \frac{(\sigma^c)^2}{2\kappa^c}\left(1 - e^{-2\kappa^c \Delta t}\right) \]
Given \(n\) transitions, the log-likelihood is:
\[ \ell\!\left(\kappa^c, \theta^c, \sigma^c\right) = -\frac{n}{2}\ln(2\pi) - \frac{n}{2}\ln\!\left(\gamma^{c\,2}\right) - \sum_{i=1}^{n}\frac{\left(S_{t_i}^c - \mu_{i-1}^c\right)^2}{2\,\gamma^{c\,2}} \]
We additionally cross-check via the AR(1) equivalence: the OU process observed at discrete intervals is equivalent to:
\[ S_{t+1}^c = a^c + b^c S_t^c + \varepsilon_t^c, \qquad \varepsilon_t^c \sim \mathcal{N}(0, \gamma^{c\,2}) \]
| AR(1) Parameter | OU Equivalent |
|---|---|
| \(b^c = e^{-\kappa^c \Delta t}\) | \(\kappa^c = -\frac{\ln b^c}{\Delta t}\) |
| \(a^c = \theta^c(1 - b^c)\) | \(\theta^c = \frac{a^c}{1 - b^c}\) |
| \(\text{Var}(\varepsilon^c)\) | \(\sigma^c = \sqrt{\frac{2\kappa^c \cdot \text{Var}(\varepsilon^c)}{1 - (b^c)^2}}\) |
### Why
- MLE is optimal for Gaussian models: it is consistent, asymptotically unbiased, and achieves the Cramér–Rao lower bound. No simulation is required.
- Exact transition density: unlike approximate methods (e.g., Euler–Maruyama discretization), the Gaussian transition density is exact for the OU process, so our likelihood is free of discretization bias.
- AR(1) cross-check: simple OLS regression of \(S_{t+1}\) on \(S_t\) provides an independent validation. Agreement between MLE and AR(1)-derived parameters adds credibility and helps detect numerical optimization failures.
### How
- Define the negative log-likelihood function
neg_loglik(params, spread, dt)for each currency. - Maximize via
scipy.optimize.minimizeusing the L-BFGS-B method (or Nelder-Mead as fallback), with positivity constraints on \(\kappa\) and \(\sigma\). - Recover MLE estimates \(\hat{\kappa}^c\), \(\hat{\theta}^c\), \(\hat{\sigma}^c\).
- Compute standard errors from the inverse Hessian (Fisher information matrix) at the optimum. Construct 95% confidence intervals as \(\hat{\psi} \pm 1.96 \cdot \text{SE}(\hat{\psi})\).
- Cross-check via OLS: regress \(S_{t+1}\) on \(S_t\) using
statsmodels.OLS; convert AR(1) coefficients \((a, b)\) to OU parameters using the mapping in the table above. - Flag any discrepancy between MLE and AR(1) estimates exceeding 10% as a diagnostic warning.
3.5 Crisis Threshold Definition
Framework | What | Why | How
### Framework
A credit risk index requires a reference point — a threshold above which spread conditions are classified as abnormal or crisis-level. Rather than imposing an arbitrary absolute threshold, we derive thresholds empirically from each currency’s own historical distribution, anchoring the definition of “crisis” in observed data.
### What
For each currency, we define the crisis threshold \(S_c^c\) as the 95th percentile of the historical spread distribution:
\[ S_c^{\text{USD}} = P_{95}\!\left(S_t^{\text{USD}}\right), \qquad S_c^{\text{KHR}} = P_{95}\!\left(S_t^{\text{KHR}}\right) \]
Sensitivity thresholds at the 90th and 99th percentiles are also computed for robustness analysis.
### Why
- Currency-specific thresholds are essential: KHR spreads are structurally wider than USD spreads due to the exchange rate risk premium embedded in riel lending. A single absolute threshold applied to both currencies would be economically meaningless — what is “normal” for KHR would register as “crisis” for USD.
- Empirical calibration: The 95th percentile anchors the crisis threshold to the actual historical distribution of each currency rather than to an externally imposed absolute level, which would be arbitrary in Cambodia’s context.
- Sensitivity analysis at 90th and 99th percentiles verifies that the CRI’s qualitative behavior and the relative risk ranking of USD vs. KHR are robust to threshold choice.
### How
- For each currency series
spread_usdandspread_khr, compute:threshold_usd = np.percentile(spread_usd, 95)andthreshold_khr = np.percentile(spread_khr, 95). - Store the primary (95th) and alternative (90th, 99th) thresholds in a dictionary for downstream use.
- Plot horizontal threshold lines on the spread time series charts to visually confirm that the threshold correctly identifies historically stressed periods.
3.6 Crisis Probability
Framework | What | Why | How
### Framework
Rather than a binary signal (“in crisis” or “not in crisis”), a probabilistic approach provides a continuous, time-varying measure of how close the system is to crisis conditions. The Gaussian structure of the OU model makes this probability analytically computable at every point in time without simulation.
### What
Using the OU model’s Gaussian transition density, we compute the probability that the spread exceeds the crisis threshold at each time \(t\):
\[ P\!\left(S_t^c > S_c^c\right) = 1 - \Phi\!\left(\frac{S_c^c - m^c(t)}{\sqrt{v^c(t)}}\right) \]
where: - \(\Phi(\cdot)\) is the standard normal CDF - \(m^c(t)\) is the conditional mean of the spread at time \(t\) (from Section 3.3) - \(v^c(t)\) is the conditional variance at time \(t\) (from Section 3.3)
### Why
- Continuous risk signal: a probability smoothly interpolates between “low risk” and “high risk”, providing more information than a binary crisis flag and making it easier to track the build-up and unwinding of credit stress over time.
- Model-consistency: the probability is derived directly from the OU model’s own distributional assumptions, ensuring it is internally consistent with the parameter estimates.
- No simulation required: the analytical Gaussian CDF formula eliminates Monte Carlo noise and computational overhead, making the approach fast and reproducible.
### How
- At each month \(t\), compute \(m^c(t)\) and \(v^c(t)\) using the fitted parameters \((\hat{\kappa}^c, \hat{\theta}^c, \hat{\sigma}^c)\) and the current spread level \(S_t^c\) as the starting condition.
- Compute the standardized distance to threshold:
z = (threshold_c - m) / np.sqrt(v). - Compute crisis probability:
prob_crisis = 1 - scipy.stats.norm.cdf(z). - Store the resulting time series
prob_crisis_usdandprob_crisis_khr. - Verify that crisis probability is high (close to 1) during known stress episodes (e.g., COVID-19 peak) and low (close to 0) during calm periods.
3.7 Currency-Specific Credit Risk Index (CRI)
Framework | What | Why | How
### Framework
A composite index that combines multiple risk dimensions captures credit risk more completely than any single measure alone. The CRI is designed to reflect two complementary aspects of risk: the inherent volatility of the spread environment and the proximity of current conditions to historically extreme levels. This dual-component structure is inspired by financial stress indices used in the literature (e.g., the Kansas City Fed’s FSI).
### What
For each currency \(c\), the Credit Risk Index is defined as:
\[ \text{CRI}^c = \alpha \cdot \hat{\sigma}^c_{\text{norm}} + \beta \cdot P\!\left(S_t^c > S_c^c\right) \]
where: - \(\hat{\sigma}^c_{\text{norm}}\) is the OU volatility parameter normalized to \([0,1]\) across currencies - \(P(S_t^c > S_c^c)\) is the model-implied crisis probability from Section 3.6 - Baseline weights: \(\alpha = \beta = 0.5\) (equal weight to both dimensions)
Each component captures a distinct dimension:
| Component | Captures | High Value Signals |
|---|---|---|
| \(\hat{\sigma}^c_{\text{norm}}\) | Spread volatility — how erratically spreads move | Unstable risk environment |
| \(P(S_t^c > S_c^c)\) | Crisis proximity — how close to historically extreme levels | Imminent credit stress |
### Why
- Volatility alone is insufficient: a period of stably high spreads would not trigger high volatility even though it reflects persistent elevated risk. Crisis probability captures this dimension.
- Crisis probability alone is insufficient: a period of rapidly fluctuating spreads (high volatility) may not yet have breached the threshold. Volatility captures the instability before the threshold is crossed.
- Equal weighting as baseline: in the absence of a strong prior reason to favor one component, equal weights provide a neutral baseline. Robustness checks (\(\alpha = 0.3, \beta = 0.7\) and \(\alpha = 0.7, \beta = 0.3\)) verify that findings are not weight-sensitive.
### How
- Normalize \(\hat{\sigma}^c\) across the two currencies using min-max normalization:
sigma_norm = (sigma - sigma_min) / (sigma_max - sigma_min). - Compute
CRI_c = 0.5 * sigma_norm_c + 0.5 * prob_crisis_cfor each currency. - Produce time series plots of
CRI_usdandCRI_khron the same axis for direct visual comparison. - Repeat with alternative weights \((0.3, 0.7)\) and \((0.7, 0.3)\) for robustness.
3.8 System-Wide Composite CRI
Framework | What | Why | How
### Framework
Policy makers and financial regulators require a single system-level indicator of banking sector credit risk, not two separate currency-specific indicators. Aggregating the currency CRIs into a system-wide index requires a weighting scheme that reflects the economic importance of each currency segment.
### What
The System CRI is a weighted average of the two currency CRIs:
\[ \text{CRI}_{\text{System}} = w_{\text{USD}} \cdot \text{CRI}^{\text{USD}} + w_{\text{KHR}} \cdot \text{CRI}^{\text{KHR}} \]
Three weighting schemes are considered:
| Weighting Approach | \(w_{\text{USD}}\) | \(w_{\text{KHR}}\) | Rationale |
|---|---|---|---|
| Loan-share weighted (primary) | ~0.80 | ~0.20 | Reflects actual composition of Cambodia’s banking system |
| Equal weighted | 0.50 | 0.50 | Gives equal attention to both currency segments |
| Time-varying | Changes annually | Changes annually | Captures the gradual de-dollarization trend |
### Why
- Loan-share weighting is the primary specification because it reflects economic reality: a shock to USD lending (~80% of the system) has a far larger systemic impact than an equivalent shock to KHR lending (~20%). A system-level index must be proportional to actual exposure.
- Equal weighting serves as a robustness check and is appropriate from a supervisory standpoint — both currency segments matter regardless of size for financial stability monitoring.
- Time-varying weighting captures Cambodia’s ongoing de-dollarization policy and prevents the index from ignoring the growing KHR share in later years.
### How
- Obtain annual loan-share weights from NBC statistical bulletins: \(w_{\text{USD},t}\) and \(w_{\text{KHR},t} = 1 - w_{\text{USD},t}\).
- Compute primary system CRI:
CRI_system = 0.80 * CRI_usd + 0.20 * CRI_khr. - Compute equal-weighted alternative:
CRI_equal = 0.50 * CRI_usd + 0.50 * CRI_khr. - Compute time-varying version by merging annual weights onto the monthly index and applying them dynamically.
- Plot all three system CRI variants on a single chart to assess robustness to aggregation method.
3.9 Stress Testing
Framework | What | Why | How
### Framework
Stress testing is a standard tool in prudential risk management (mandated under Basel III/IV and IMF financial sector assessment programs) for evaluating how a risk indicator responds to hypothetical adverse shocks. Rather than relying solely on historical data, stress tests simulate how the CRI would behave if credit conditions deteriorate beyond observed levels.
### What
We apply multiplicative stress shocks to the observed spreads:
\[ S_t^{c,\text{stress}} = S_t^c\left(1 + \delta\right) \]
Three stress scenarios are applied:
| Scenario | Shock (\(\delta\)) | Economic Interpretation |
|---|---|---|
| Mild | 0.10 (10%) | Minor economic slowdown or sectoral stress |
| Moderate | 0.30 (30%) | Significant financial stress (comparable to a regional crisis) |
| Severe | 0.50 (50%) | Major crisis scenario (comparable to the GFC or severe pandemic impact) |
Under each scenario, \(\text{CRI}^{\text{USD}}\), \(\text{CRI}^{\text{KHR}}\), and \(\text{CRI}_{\text{System}}\) are recomputed and compared to the baseline.
### Why
- Identifies which segment is more fragile: if the dominant USD segment (80% of lending) is more stress-sensitive, the current dollarized structure poses greater systemic risk. If the KHR segment is more sensitive, this informs the risk management of the de-dollarization transition.
- Multiplicative shocks are scale-invariant: they preserve the proportional structure of spreads across currencies, avoiding the problem that an additive shock of equal magnitude would be trivial for KHR (which has high baseline spreads) but severe for USD.
- Three scenarios bracket a plausible adverse range without requiring specific scenario narratives, keeping the analysis tractable and comparable across currencies.
### How
- For each scenario \(\delta \in \{0.10, 0.30, 0.50\}\) and each currency: compute
spread_stressed = spread_c * (1 + delta). - Re-estimate OU parameters via MLE on the stressed spreads.
- Recompute crisis probability and CRI using the stressed parameters.
- Tabulate: baseline CRI vs. stressed CRI for each scenario and each currency.
- Compute the stress sensitivity ratio: \(\Delta\text{CRI} / \delta\) per currency to identify which segment amplifies stress more strongly.
3.10 COVID-19 Sub-Period Analysis
Framework | What | Why | How
### Framework
Sub-period analysis partitions a long time series around a known structural event to test whether model parameters shift — and whether those shifts are temporary or permanent. This is the “difference-in-differences” logic applied to time series: the COVID-19 pandemic acts as an exogenous shock whose effect on each currency segment’s credit risk dynamics can be isolated.
### What
The 13-year sample is divided into three sub-periods, treating COVID-19 as a natural experiment:
| Period | Dates | Label | Observations |
|---|---|---|---|
| Pre-COVID | Jan 2013 – Dec 2019 | Baseline | 84 |
| COVID | Jan 2020 – Dec 2021 | Shock | 24 |
| Post-COVID | Jan 2022 – Dec 2025 | Recovery | 48 |
For each sub-period and each currency, OU parameters \((\kappa^c, \theta^c, \sigma^c)\) are re-estimated via MLE, and crisis probabilities and CRIs are recomputed.
### Why
- COVID-19 is the most significant exogenous shock in the sample period, making it the ideal event for testing the CRI’s responsiveness and for identifying parameter instability.
- Sub-period estimation reveals whether changes are structural: if post-COVID parameters have not reverted to pre-COVID levels, this indicates a permanent shift in Cambodia’s credit risk dynamics rather than a transitory shock.
- Currency-differentiated impact: the USD and KHR segments were exposed differently to COVID (USD via global trade disruption; KHR via domestic economic contraction). Comparing parameter shifts across currencies reveals which segment absorbed more of the shock.
### How
- Slice the spread data:
spread_pre = spread[:'2019-12'],spread_covid = spread['2020-01':'2021-12'],spread_post = spread['2022-01':]. - For each sub-period and each currency, run MLE estimation to obtain period-specific \((\hat{\kappa}, \hat{\theta}, \hat{\sigma})\).
- Compile a summary table comparing parameters across the three periods for both currencies.
- Use confidence intervals to test whether post-COVID parameters are statistically distinguishable from pre-COVID parameters.
- Key questions to answer: Did COVID cause a temporary or structural shift? Which currency was more affected? Has a new equilibrium emerged post-COVID?
3.11 Rolling Window Analysis
Framework | What | Why | How
### Framework
Full-sample estimation assumes parameter stationarity over the entire 13-year period — an assumption that may be violated given structural changes in Cambodia’s banking sector (de-dollarization, post-COVID recovery, external shocks). Rolling window estimation relaxes this assumption by tracking parameter evolution over time, producing a dynamic view of credit risk dynamics.
### What
A 36-month rolling window re-estimation is applied: at each month \(t\) (starting from month 37), the OU parameters are estimated using only the most recent 36 observations:
\[ \{S_{t-35}^c, S_{t-34}^c, \ldots, S_t^c\} \quad\longrightarrow\quad \hat{\kappa}_t^c,\; \hat{\theta}_t^c,\; \hat{\sigma}_t^c \]
This produces time series of parameter estimates that show how credit risk dynamics have evolved across the full sample.
### Why
| Consideration | Shorter Window (24 months) | 36-Month Window |
|---|---|---|
| Responsiveness | More responsive | Moderately responsive |
| Estimation stability | Noisy — only 23 transitions for 3 parameters | 35 transitions provide statistically stable MLE |
| Output length | Shorter output | Good balance of history and coverage |
With 35 transitions (from 36 observations), the MLE for 3 parameters is well-identified. A shorter window would produce an ill-conditioned log-likelihood surface and unreliable estimates, while a longer window (e.g., 48 months) would be less responsive to structural changes.
### How
- Set
window = 36. Initialize empty lists for rolling parameter estimates. - Loop: for each
tfromwindowtoT: fit MLE onspread[t-window:t]; append \(\hat{\kappa}_t, \hat{\theta}_t, \hat{\sigma}_t\) to lists. - Convert lists to time series indexed from month 37 onward.
- Produce a three-panel figure showing rolling \(\hat{\kappa}_t, \hat{\theta}_t, \hat{\sigma}_t\) for both currencies on the same axes.
- Annotate the plots with key events (COVID onset, Fed rate hike cycle, NBC policy changes) to identify visible parameter shifts.
- Assess whether USD and KHR risk dynamics are converging or diverging over time.
3.12 Robustness Checks
Framework | What | Why | How
### Framework
Every empirical methodology requires verification that findings are not artifacts of specific modeling choices. Robustness checks systematically vary key assumptions and test whether the principal conclusions are preserved. This is standard practice in applied econometrics and financial risk research.
### What
We perform a battery of four robustness checks:
| Check | What Is Varied | Purpose |
|---|---|---|
| Alternative rate measure | Outstanding Amount rates instead of New Amount | Confirms results hold regardless of rate version |
| Alternative crisis thresholds | 90th and 99th percentiles instead of 95th | Shows CRI behavior is not threshold-sensitive |
| Alternative CRI component weights | \((\alpha=0.3, \beta=0.7)\) and \((\alpha=0.7, \beta=0.3)\) | Shows relative ranking of USD vs. KHR is stable |
| Alternative system weights | Equal (0.50/0.50) vs. loan-share (0.80/0.20) | Shows System CRI is robust to aggregation method |
### Why
Robustness checks are essential because: - Data choices (rate version) could bias results if New Amount rates are anomalously volatile. - Threshold choices are inherently arbitrary; the 95th percentile is conventional but other values could change the crisis probability dynamics. - Index weight choices are not uniquely determined by theory; showing the principal findings survive re-weighting strengthens the argument for the baseline.
If the core findings — the relative risk ranking of USD and KHR, the temporal pattern of the CRI, and the directional response to COVID-19 — are preserved across all four variations, the framework’s validity is reinforced.
### How
- Outstanding Amount rates: load the alternative rate dataset; rerun Sections 3.2–3.7 end-to-end; compare CRI time series and parameter estimates to the baseline.
- Alternative thresholds: substitute
percentile=90andpercentile=99; recompute crisis probabilities and CRIs; overlay on the baseline CRI chart. - Alternative CRI weights: recompute
CRI_c = alpha * sigma_norm + beta * prob_crisisfor \((0.3, 0.7)\) and \((0.7, 0.3)\); tabulate the USD/KHR risk ratio under each specification. - Alternative system weights: recompute
CRI_systemunder equal weighting; compare time series patterns. - Summarize all robustness results in a single comparison table, flagging any specification where qualitative conclusions change.
Extended Analyses
3.13 Regime-Switching Ornstein–Uhlenbeck Model
Framework | What | Why | How
### Framework
The standard OU model assumes constant parameters throughout the entire sample. In reality, financial systems often alternate between distinct regimes — “calm” and “stress” — with different dynamics in each. The Markov Regime-Switching model (Hamilton, 1989) extends the OU framework by allowing parameters to shift between latent states, capturing structural breaks without requiring the researcher to prespecify their timing.
### What
We extend to a two-state Markov Regime-Switching OU (RS-OU) model:
\[ dS_t^c = \kappa_{s_t}^c\!\left(\theta_{s_t}^c - S_t^c\right)dt + \sigma_{s_t}^c\,dW_t^c, \qquad s_t \in \{1, 2\} \]
where the latent state \(s_t\) follows a first-order Markov chain with transition probability matrix:
\[ \mathbf{P} = \begin{pmatrix} p_{11} & 1 - p_{11} \\ 1 - p_{22} & p_{22} \end{pmatrix} \]
- State 1 (“Calm”): lower volatility, stable spread dynamics
- State 2 (“Stress”): higher volatility, potentially different mean-reversion behavior
Model selection between the single-regime OU and the RS-OU is based on the Bayesian Information Criterion (BIC).
### Why
- The standard OU model may mask regime heterogeneity: if calm and stress periods follow different dynamics, pooling them into a single set of parameters produces biased estimates and misleading risk signals.
- Endogenous break detection: unlike the COVID sub-period analysis (Section 3.10), which fixes regime boundaries exogenously, the RS-OU model lets the data determine when regime switches occur — providing an independent check on the timing of structural breaks.
- Do USD and KHR share the same regime structure? If the KHR segment switches between calm and stress regimes more frequently, this corroborates the finding of higher KHR instability from the standard OU analysis using a fully different methodology.
### How
- Define the RS-OU likelihood using the Hamilton filter (forward pass): iteratively compute filtered state probabilities \(P(s_t = j | S_{1:t})\) using the Gaussian emission densities from the OU model in each state.
- Apply the Kim smoother (backward pass) to obtain smoothed probabilities \(P(s_t = j | S_{1:T})\) using the full sample.
- Maximize the full log-likelihood over \((\kappa_1, \theta_1, \sigma_1, \kappa_2, \theta_2, \sigma_2, p_{11}, p_{22})\) using
scipy.optimize.minimize. - Compare BIC of the RS-OU against the single-regime OU: if \(\text{BIC}_{\text{RS-OU}} < \text{BIC}_{\text{OU}}\), the regime-switching extension is supported by the data.
- Plot smoothed state probabilities alongside the spread series to identify when each currency operated in the stress regime.
3.14 Dynamic Threshold CRI
Framework | What | Why | How
### Framework
The baseline CRI uses a static threshold calibrated on the full sample. However, if the structural level of spreads has shifted over time (e.g., due to financial sector development or de-dollarization), a threshold anchored to early high-spread observations may become irrelevant for later periods. A dynamic threshold adapts the reference point to the evolving distribution of spreads, providing a more locally calibrated risk measure.
### What
Instead of a fixed 95th percentile, we compute a rolling 36-month threshold that updates each month:
\[ S_{c,t}^c = P_{95}\!\left(\{S_{t-35}^c, \ldots, S_t^c\}\right) \]
This produces a time-varying threshold \(S_{c,t}^c\) that is directly compared against the static-threshold CRI.
### Why
- KHR spreads exhibit structural compression over time: as Cambodia’s financial sector develops and riel lending matures, KHR spreads have declined from their early-sample highs. A static threshold calibrated on 2013–2015 KHR spreads would be irrelevant for assessing crisis conditions in 2023–2025.
- Dynamic thresholds provide locally calibrated signals: what constitutes “abnormal” spread behavior should be judged against recent history, not a fixed historical benchmark that may no longer reflect current conditions.
- Comparison against static CRI: if the two approaches tell the same story, it validates the simpler static threshold. If they diverge, it highlights periods where structural spread compression (or expansion) materially changes the risk signal.
### How
- Compute rolling 36-month 95th percentile thresholds for each currency:
threshold_dynamic_t = spread[:t].rolling(36).quantile(0.95). - Substitute
threshold_dynamic_tfor the static threshold in the crisis probability formula (Section 3.6). - Recompute dynamic CRI series
CRI_dynamic_usdandCRI_dynamic_khr. - Plot static vs. dynamic CRI on the same axes for both currencies.
- Identify periods of divergence and interpret whether they correspond to known structural shifts in Cambodia’s banking sector.
3.15 Implied Default Probability
Framework | What | Why | How
### Framework
Reduced-form credit risk models (Duffie & Singleton, 1999; Jarrow & Turnbull, 1995) link observed credit spreads to implied default intensities via a no-arbitrage pricing identity: the spread compensates lenders for expected losses (default probability × loss given default). This identity allows us to extract market-implied default probabilities from the observed spreads, translating an abstract index into a concrete, economically interpretable quantity.
### What
Under the assumption that the spread compensates for expected losses:
\[ S_t^c \approx h_t^c \cdot (1 - R^c) \]
where \(h_t^c\) is the instantaneous hazard rate (default intensity) and \(R^c\) is the recovery rate (baseline assumption: \(R = 0.40\), the standard Basel assumption).
The extracted hazard rate and 1-year cumulative default probability are:
\[ h_t^c = \frac{S_t^c}{1 - R^c}, \qquad \text{PD}_{1\text{yr}}^c(t) = 1 - \exp\!\left(-h_t^c\right) \]
Recovery rate sensitivity is assessed across \(R \in \{0.20, 0.30, 0.40, 0.50, 0.60\}\).
### Why
- Concrete interpretation: while the CRI is a dimensionless index, the implied PD is expressed in probability units — directly comparable to non-performing loan ratios, regulatory risk weights, and external credit rating benchmarks.
- Bridging CRI to existing risk frameworks: policymakers familiar with Basel-style default probability metrics can immediately relate the CRI signal to standard credit risk terminology.
- Recovery rate sensitivity is critical for Cambodia: empirical recovery rate data is scarce in the Cambodian context. The sensitivity analysis makes transparent how much implied PD estimates depend on this assumption, quantifying the uncertainty in the recovery rate mapping.
### How
- Set baseline recovery rate:
R = 0.40. - For each currency and each month:
hazard_t = spread_t / (1 - R);PD_1yr_t = 1 - np.exp(-hazard_t). - Plot
PD_1yr_usdandPD_1yr_khrtime series. - Conduct sensitivity analysis: loop over
R_values = [0.20, 0.30, 0.40, 0.50, 0.60]; recomputePD_1yrfor each; display as a fan chart showing the range of PD estimates under different recovery assumptions. - Report the range of PD estimates at the most recent observation to communicate model uncertainty to the reader.
3.16 Policy Divergence Analysis (VAR Framework)
Framework | What | Why | How
### Framework
Vector Autoregression (VAR) models the joint dynamics of multiple time series without imposing a priori restrictions on which variables cause which. Developed by Sims (1980) as an atheoretical alternative to structural macroeconomic models, VAR is the standard tool for examining transmission channels and dynamic interdependencies between macroeconomic and financial variables. In this context, it allows us to test empirically whether Cambodia’s dollarization effectively transmits U.S. monetary policy into domestic credit risk conditions.
### What
We employ a VAR model with the following variable vector:
\[ \mathbf{Y}_t = \mathbf{c} + \sum_{j=1}^{p} \mathbf{A}_j \mathbf{Y}_{t-j} + \mathbf{u}_t, \qquad \mathbf{Y}_t = \begin{pmatrix} S_t^{\text{USD}} \\ S_t^{\text{KHR}} \\ \text{FedFunds}_t \end{pmatrix} \]
where \(p\) is the optimal lag order selected by the BIC. Three analytical tools are applied:
| Tool | Question Answered |
|---|---|
| Granger Causality Tests | Does the Fed Funds Rate Granger-cause USD or KHR spreads? Does one currency’s spread predict the other’s? |
| Impulse Response Functions (IRFs) | How do USD and KHR spreads respond dynamically to a one-SD shock in the Fed Funds Rate? How long does the effect persist? |
| Variance Decomposition | What share of forecast error variance in each spread is attributable to Fed policy shocks vs. innovations in the other currency’s spread? |
### Why
- Testing the “monetary policy outsourcing” hypothesis: Cambodia’s lack of an independent monetary policy instrument (due to high dollarization) is a central policy concern. If USD spreads respond strongly to Fed shocks while KHR spreads do not, this provides empirical support for the argument that de-dollarization would enhance NBC’s policy autonomy.
- Granger causality reveals information flow: knowing whether Fed policy leads or lags domestic credit spreads helps NBC anticipate when to deploy macroprudential tools.
- IRFs quantify the duration and magnitude of external shocks on domestic credit conditions — directly relevant for stress scenario design and macroprudential policy timing.
- VAR is appropriate for non-structural policy analysis: without imposing a specific structural model, VAR allows the data to reveal the empirical transmission dynamics.
### How
- Pre-estimation tests: apply ADF unit root tests to each variable; difference as needed to achieve stationarity. Test for cointegration if variables are integrated.
- Lag selection: estimate VAR models for \(p = 1, \ldots, 12\); select optimal \(p\) by minimizing BIC.
- Estimation: fit the VAR(\(p\)) model using
statsmodels.tsa.vector_ar.var_model.VAR. - Granger causality: use
var_result.test_causality()for each direction; report \(\chi^2\) statistics and \(p\)-values. - IRFs: compute orthogonalized IRFs using Cholesky decomposition (ordering: FedFunds → USD spread → KHR spread, reflecting the hypothesis that global policy drives USD conditions which in turn influence KHR conditions). Plot 12-month IRFs with 95% bootstrap confidence bands.
- Variance decomposition: compute and display forecast error variance decomposition at horizons 1, 3, 6, and 12 months.
- Interpret results against the de-dollarization policy context: does the data support the hypothesis that NBC lacks effective monetary transmission?
Complete Methodological Pipeline
The following table summarizes the complete analytical pipeline:
| Step | Method | Formula / Description | Applied Per Currency? |
|---|---|---|---|
| 1 | Spread computation | \(S_t^c = r_{\text{loan},t}^c - r_{\text{deposit},t}^c\) | Yes (USD + KHR) |
| 2 | OU model fitting | \(dS_t^c = \kappa^c(\theta^c - S_t^c)dt + \sigma^c dW_t^c\) | Yes |
| 3 | MLE estimation | Maximize log-likelihood for \((\kappa^c, \theta^c, \sigma^c)\) | Yes |
| 4 | AR(1) cross-check | Regress \(S_{t+1}^c\) on \(S_t^c\), recover OU parameters | Yes |
| 5 | Crisis threshold | \(S_c^c = P_{95}(S_t^c)\) | Yes |
| 6 | Crisis probability | \(P(S_t^c > S_c^c) = 1 - \Phi\!\left(\frac{S_c^c - m^c(t)}{\sqrt{v^c(t)}}\right)\) | Yes |
| 7 | Currency CRI | \(\text{CRI}^c = 0.5\hat{\sigma}^c + 0.5 P(S_t^c > S_c^c)\) | Yes |
| 8 | System CRI | \(\text{CRI}_{\text{Sys}} = w_{\text{USD}}\text{CRI}^{\text{USD}} + w_{\text{KHR}}\text{CRI}^{\text{KHR}}\) | Once (combined) |
| 9 | Stress testing | \(S_t^{c,\text{stress}} = S_t^c(1+\delta)\); recompute CRIs | Yes |
| 10 | COVID sub-periods | Re-estimate steps 2–7 for pre/during/post COVID | Yes |
| 11 | Rolling window | Re-estimate steps 2–7 on 36-month rolling window | Yes |
| 12 | Robustness | Repeat with Outstanding Amount rates + alternative specifications | Yes |
| 13 | Regime switching | 2-state Markov RS-OU with Hamilton filter + Kim smoother | Yes |
| 14 | Dynamic threshold | Rolling 36-month crisis threshold; dynamic CRI vs. static CRI | Yes |
| 15 | Implied PD | Hazard rate extraction; 1-year default probability; recovery sensitivity | Yes |
| 16 | Policy divergence | VAR model; Granger causality; impulse response functions | Once (multivariate) |
Methodological Flow Diagram
┌──────────────────────────────────────────────────────────────────┐
│ NBC INTEREST RATE DATA │
│ Term Loan + Term Deposit rates (USD & KHR), New Amount │
│ January 2013 – December 2025 (156 monthly observations) │
└──────────────────────────┬───────────────────────────────────────┘
│
┌──────────┴──────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ USD Spread │ │ KHR Spread │
│ Sᵗ(USD) │ │ Sᵗ(KHR) │
└──────┬──────┘ └──────┬──────┘
│ │
┌────────┴────────┐ ┌────────┴────────┐
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ OU Model │ │ RS-OU │ │ OU Model │ │ RS-OU │
│ (MLE) │ │ Model │ │ (MLE) │ │ Model │
│ κ, θ, σ │ │ 2-state │ │ κ, θ, σ │ │ 2-state │
└────┬─────┘ └──────────┘ └────┬─────┘ └──────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ Crisis │ │ Crisis │
│ Prob + │ │ Prob + │
│ CRI(USD) │ │ CRI(KHR) │
└────┬─────┘ └────┬─────┘
│ │
├───────── Compare ─────────────┤
│ │
└──────────┬────────────────────┘
▼
┌───────────────┐
│ CRI (System) │
│ = wUSD × USD │
│ + wKHR × KHR │
└───────┬───────┘
│
┌────────────┼────────────┬───────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐
│ Stress │ │ COVID │ │ Rolling │ │ VAR / │
│ Tests │ │ Sub- │ │ Window │ │ Granger / │
│ δ=0.1, │ │ Period │ │ (36-mo) │ │ IRF │
│ 0.3,0.5│ │ Analysis │ │ Analysis │ │ Analysis │
└────────┘ └──────────┘ └──────────┘ └────────────┘