Calibration and Parameter Estimation in Models › Practical Calibration Workflows
Quantitative FinanceAll chapters Calibration and Parameter Estimation in Models › Practical Calibration WorkflowsOne section · Sections in this chapter14 / 17 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Real-world calibration requires clean data and stable optimization, backed by ongoing monitoring.
Data Preparation
Before calibration, market data must be cleaned and prepared:
-
Quote filtering removes stale, erroneous, or illiquid quotes. Options with very low open interest or wide bid-ask spreads may contain noise that degrades calibration.
-
Consistency checks detect possible static-arbitrage violations. Check strike convexity using correctly weighted long butterfly spreads. Calendar consistency requires the carry-adjusted or forward-moneyness conditions appropriate to the instruments; raw same-strike price monotonicity is not universal with dividends or other carry. Selected checks alone do not certify an entire interpolated surface.
-
Standardization converts raw prices to a common format. Options at different maturities should use appropriate day-count conventions and settlement rules.
Multi-Start Optimization
Multiple starting points are often useful for checking a non-convex fit's sensitivity to initialization:
def multi_start_sabr_calibration(
strikes, market_vols, F, T, beta, n_starts=10, rng=None
):
"""Return the best successful finite candidate among explicit starts."""
strikes, market_vols = validate_sabr_quotes(strikes, market_vols, F, T, beta)
if not isinstance(n_starts, (int, np.integer)) or n_starts <= 0:
raise ValueError("n_starts must be a positive integer")
rng = np.random.default_rng(42) if rng is None else rng
best_result = None
rejected = 0
for _ in range(n_starts):
start = [rng.uniform(0.1, 0.5), rng.uniform(-0.8, 0.2), rng.uniform(0.2, 0.8)]
try:
result = minimize(
calibration_objective,
start,
args=(F, T, strikes, market_vols, beta),
method="L-BFGS-B",
bounds=[(0.01, 1.0), (-0.99, 0.99), (0.01, 2.0)],
)
except (ValueError, FloatingPointError, OverflowError):
rejected += 1
continue
if (
not result.success
or not np.isfinite(result.fun)
or not np.all(np.isfinite(result.x))
):
rejected += 1
continue
if best_result is None or result.fun < best_result.fun:
best_result = result
print(
f"Multi-start fits accepted: {n_starts - rejected}/{n_starts}; rejected: {rejected}"
)
if best_result is None:
raise RuntimeError("No successful finite SABR calibration candidate")
return best_result
# Run multi-start
multistart_result = multi_start_sabr_calibration(
strikes, market_vols_noisy, F_true, sabr_maturity, beta_fixed, n_starts=20
)
alpha_ms, rho_ms, nu_ms = multistart_result.xMulti-Start Calibration Results: Best SSE found: 0.00011966 Parameters: α=0.2264, ρ=-0.2940, ν=0.3909
The multi-start comparison uses the same one-year SABR quotes and maturity as the initial calibration, with sabr_maturity kept separate from the Heston examples' maturity loops. The best multi-start run reaches a similar parameter region to the initial run. Agreement across these starting points is evidence of stability in these runs, not a proof of global optimality or unique parameter identification.


Calibration Monitoring
In production, monitor calibration for problems:
-
Fit quality metrics track calibration RMSE over time. Sudden increases may indicate market regime changes or data problems.
-
Parameter drift monitors how fitted parameters evolve. Large daily changes can reflect market moves, data changes, weak identification, optimization instability or overfitting; they are a warning to investigate, not a diagnosis.
-
Constraint binding tracks how often fitted parameters reach their bounds. Repeated bound hits warrant checking the bounds, data, objective and numerical diagnostics; they do not by themselves establish model inadequacy.