如何在Heston模型校准中固定部分参数并执行优化?
Great question! I’ve worked with QuantLib’s Heston calibration routines extensively, and fixing specific parameters (like initial variance v0 and mean reversion kappa) while optimizing the rest is totally feasible. Let’s walk through how to adapt the testsuite/hestonmodel.cpp example to do this, aligned with the approach from Janek & Wystup’s The Heston Model for the FX Smile.
Key Background
First, recall the standard Heston parameter order in QuantLib:
kappa: Mean reversion ratetheta: Long-term variancesigma: Volatility of variancerho: Correlation between asset returns and variancev0: Initial variance
Your goal is to fix kappa and v0, leaving theta, sigma, and rho as the optimization variables.
Step-by-Step Modification to the Testsuite Example
The testsuite/hestonmodel.cpp example calibrates all 5 parameters by default, but you can adjust it to lock specific parameters with these changes:
1. Define Fixed Parameters Upfront
Start by hardcoding or loading your fixed values for kappa and v0 instead of including them in the optimization guess:
// Fixed parameters (set these to your desired values) const Real fixed_kappa = 0.15; const Real fixed_v0 = 0.03; // Initial guesses ONLY for parameters to optimize: theta, sigma, rho Array initial_guess(3); initial_guess[0] = 0.04; // Theta initial guess initial_guess[1] = 0.25; // Sigma initial guess initial_guess[2] = -0.4; // Rho initial guess
2. Use a Custom Model Builder Function
Instead of letting QuantLib build the model directly from the full parameter vector, create a lambda function that injects your fixed parameters into the Heston model, using only the optimized variables:
// Assume you've already set up your spot, dividend curve, and risk-free curve ext::shared_ptr<Quote> spot = ...; ext::shared_ptr<YieldTermStructure> dividend_ts = ...; ext::shared_ptr<YieldTermStructure> risk_free_ts = ...; // Lambda to build Heston model with fixed kappa and v0 auto model_builder = [&](const Array& optimized_params) { Real theta = optimized_params[0]; Real sigma = optimized_params[1]; Real rho = optimized_params[2]; // Build process with fixed kappa/v0 and optimized theta/sigma/rho ext::shared_ptr<HestonProcess> process = ext::make_shared<HestonProcess>( risk_free_ts, dividend_ts, spot, fixed_v0, fixed_kappa, theta, sigma, rho ); return ext::make_shared<HestonModel>(process); };
3. Run Calibration with Constrained Parameters
Pass this custom model builder to the calibration routine, along with your calibration helpers (e.g., FX smile options) and Levenberg-Marquardt optimizer:
// Populate calibration helpers with your FX smile instruments std::vector<ext::shared_ptr<CalibrationHelper>> helpers; // ... add EuropeanOptionHelper or similar for each strike/maturity in your smile ... // Set up optimizer and end criteria LevenbergMarquardt optimizer; optimizer.setMaxIterations(100); optimizer.setTolerance(1e-6); EndCriteria end_criteria(100, 10, 1e-8, 1e-8, 1e-8); // Perform calibration - only theta, sigma, rho will be optimized ext::shared_ptr<HestonModel> calibrated_model = ext::dynamic_pointer_cast<HestonModel>( CalibratedModel::calibrate(helpers, optimizer, end_criteria, NoConstraint(), model_builder) ); // Extract optimized parameters Real calibrated_theta = calibrated_model->theta(); Real calibrated_sigma = calibrated_model->sigma(); Real calibrated_rho = calibrated_model->rho();
4. Verify the Testsuite Alignment
Looking at testsuite/hestonmodel.cpp, you’ll notice the original code uses a full 5-parameter vector and builds the model directly. The core difference in your approach is replacing that full parameter setup with the custom model builder that locks kappa and v0. This ensures the Levenberg-Marquardt algorithm only adjusts the three parameters you care about.
Alignment with Janek & Wystup’s Work
The approach above matches the constrained calibration method described in The Heston Model for the FX Smile. By fixing v0 and kappa, you’re reducing the optimization dimensionality, which can lead to more stable results (especially if you have prior knowledge or want to enforce these parameters from historical data).
内容的提问来源于stack exchange,提问作者alex

