Bayesian MCMC calibration

The Duan MLE calibrator returns a single point estimate plus asymptotic standard errors. For thinner data, non-standard priors, or any time you need a full posterior on (\mu, \sigma_A), reach for the Bayesian MCMC calibrator.

Setup

Install the optional extra:

uv pip install "merton[mcmc]"

This pulls in emcee (affine-invariant ensemble sampler) and arviz (posterior diagnostics).

Posterior

The likelihood is the Duan (1994) transformed-data likelihood — same as

func:

merton.calibration.duan_mle. The default prior is uniform on a generous box:

  • \mu \in [-5,\, 5] (asset drift in decimal),

  • \sigma_A \in [0.001,\, 5] (annualised asset vol).

Pass prior_log_pdf=... to override.

Sampling

import numpy as np
from merton.calibration import bayesian_mcmc

eq_series = ...  # 1-D numpy array, ≥30 observations

result = bayesian_mcmc(
    equity_series=eq_series,
    debt=35.0, rf=0.04, T=1.0,
    n_walkers=32, n_steps=4000,
    burn_in=1000, thin=5, seed=42,
)
print("MAP σ_A:", result.asset_vol)
print("MAP μ  :", result.asset_drift)
print("acceptance fraction:", result.acceptance_fraction)

Credible intervals

ci_sigma = result.credible_interval("asset_vol", level=0.95)
ci_mu    = result.credible_interval("asset_drift", level=0.95)
print(f"σ_A 95% CI: [{ci_sigma.lower:.4f}, {ci_sigma.upper:.4f}]")
print(f"μ   95% CI: [{ci_mu.lower:.4f}, {ci_mu.upper:.4f}]")

The full chain is available as result.chain (shape (n_samples, 2)) and the per-sample log-probabilities as result.log_probs. Both feed directly into arviz for trace plots, R-hat diagnostics, and posterior predictive checks.

Diagnostics

import arviz as az

idata = az.from_emcee(
    sampler=None,
    posterior={"mu": result.chain[:, 0], "sigma_A": result.chain[:, 1]},
)
az.plot_trace(idata)
az.summary(idata, round_to=4)

The integrated autocorrelation time (result.autocorr_time) helps choose burn-in and thinning. The emcee user guide recommends running the chain for at least 50 × τ steps; anything shorter gets a warning.

When to prefer Bayesian over MLE

  • Short equity histories (< 6 months) where the MLE asymptotic approximations break down.

  • Strong priors from analyst judgement (e.g. “σ_A is between 25% and 35% for this industry”) that a uniform prior wouldn’t capture.

  • Downstream uncertainty propagation — passing samples through the model to get credible intervals on DD, PD, and spread is far cleaner than the delta method.