@@ -50,7 +50,7 @@ class SabrStrippedOptionletAdapter : public QuantLib::OptionletVolatilityStructu
5050 const QuantExt::SabrParametricVolatility::ModelVariant modelVariant,
5151 const TimeInterpolator& ti = TimeInterpolator(),
5252 const boost::optional<QuantLib::VolatilityType> outputVolatilityType = boost::none,
53- const std::vector<std::pair<Real, bool >>& initialModelParameters = {},
53+ const std::vector<std::vector<std:: pair<Real, bool > >>& initialModelParameters = {},
5454 const QuantLib::Size maxCalibrationAttempts = 10 ,
5555 const QuantLib::Real exitEarlyErrorThreshold = 0.005 ,
5656 const QuantLib::Real maxAcceptableError = 0.05 );
@@ -62,7 +62,7 @@ class SabrStrippedOptionletAdapter : public QuantLib::OptionletVolatilityStructu
6262 const QuantExt::SabrParametricVolatility::ModelVariant modelVariant,
6363 const TimeInterpolator& ti = TimeInterpolator(),
6464 const boost::optional<QuantLib::VolatilityType> outputVolatilityType = boost::none,
65- const std::vector<std::pair<Real, bool >>& initialModelParameters = {},
65+ const std::vector<std::vector<std:: pair<Real, bool > >>& initialModelParameters = {},
6666 const QuantLib::Size maxCalibrationAttempts = 10 ,
6767 const QuantLib::Real exitEarlyErrorThreshold = 0.005 ,
6868 const QuantLib::Real maxAcceptableError = 0.05 );
@@ -120,7 +120,7 @@ class SabrStrippedOptionletAdapter : public QuantLib::OptionletVolatilityStructu
120120 // ! SABR specific inputs
121121 QuantExt::SabrParametricVolatility::ModelVariant modelVariant_;
122122 boost::optional<QuantLib::VolatilityType> outputVolatilityType_;
123- std::vector<std::pair<Real, bool >> initialModelParameters_;
123+ std::vector<std::vector<std:: pair<Real, bool > >> initialModelParameters_;
124124 QuantLib::Size maxCalibrationAttempts_;
125125 QuantLib::Real exitEarlyErrorThreshold_;
126126 QuantLib::Real maxAcceptableError_;
@@ -136,8 +136,9 @@ SabrStrippedOptionletAdapter<TimeInterpolator>::SabrStrippedOptionletAdapter(
136136 const QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>& sob,
137137 const QuantExt::SabrParametricVolatility::ModelVariant modelVariant, const TimeInterpolator& ti,
138138 const boost::optional<QuantLib::VolatilityType> outputVolatilityType,
139- const std::vector<std::pair<Real, bool >>& initialModelParameters, const QuantLib::Size maxCalibrationAttempts,
140- const QuantLib::Real exitEarlyErrorThreshold, const QuantLib::Real maxAcceptableError)
139+ const std::vector<std::vector<std::pair<Real, bool >>>& initialModelParameters,
140+ const QuantLib::Size maxCalibrationAttempts, const QuantLib::Real exitEarlyErrorThreshold,
141+ const QuantLib::Real maxAcceptableError)
141142 : OptionletVolatilityStructure(sob->settlementDays (), sob->calendar(), sob->businessDayConvention(),
142143 sob->dayCounter()),
143144 optionletBase_(sob), ti_(ti), modelVariant_(modelVariant), outputVolatilityType_(outputVolatilityType),
@@ -151,8 +152,9 @@ SabrStrippedOptionletAdapter<TimeInterpolator>::SabrStrippedOptionletAdapter(
151152 const QuantLib::Date& referenceDate, const QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>& sob,
152153 const QuantExt::SabrParametricVolatility::ModelVariant modelVariant, const TimeInterpolator& ti,
153154 const boost::optional<QuantLib::VolatilityType> outputVolatilityType,
154- const std::vector<std::pair<Real, bool >>& initialModelParameters, const QuantLib::Size maxCalibrationAttempts,
155- const QuantLib::Real exitEarlyErrorThreshold, const QuantLib::Real maxAcceptableError)
155+ const std::vector<std::vector<std::pair<Real, bool >>>& initialModelParameters,
156+ const QuantLib::Size maxCalibrationAttempts, const QuantLib::Real exitEarlyErrorThreshold,
157+ const QuantLib::Real maxAcceptableError)
156158 : OptionletVolatilityStructure(referenceDate, sob->calendar (), sob->businessDayConvention(), sob->dayCounter()),
157159 optionletBase_(sob), ti_(ti), modelVariant_(modelVariant), outputVolatilityType_(outputVolatilityType),
158160 initialModelParameters_(initialModelParameters), maxCalibrationAttempts_(maxCalibrationAttempts),
@@ -203,6 +205,11 @@ inline void SabrStrippedOptionletAdapter<TimeInterpolator>::performCalculations(
203205
204206 std::vector<ParametricVolatility::MarketSmile> marketSmiles;
205207 std::map<std::pair<QuantLib::Real, QuantLib::Real>, std::vector<std::pair<Real, bool >>> modelParameters;
208+ QL_REQUIRE (initialModelParameters_.empty () ||
209+ initialModelParameters_.size () == this ->optionletBase ()->optionletFixingTimes ().size (),
210+ " SabrStrippedOptionletAdapter: initial model parameters must be empty or their size ("
211+ << initialModelParameters_.size () << " must match the number of optionlet fixing times ("
212+ << this ->optionletBase ()->optionletFixingTimes ().size () << " )" );
206213 for (Size i = 0 ; i < this ->optionletBase ()->optionletFixingTimes ().size (); ++i) {
207214 Real forward = atmInterpolation_->operator ()(this ->optionletBase ()->optionletFixingTimes ()[i]);
208215 marketSmiles.push_back (ParametricVolatility::MarketSmile{this ->optionletBase ()->optionletFixingTimes ()[i],
@@ -212,9 +219,10 @@ inline void SabrStrippedOptionletAdapter<TimeInterpolator>::performCalculations(
212219 {},
213220 this ->optionletBase ()->optionletStrikes (i),
214221 this ->optionletBase ()->optionletVolatilities (i)});
215- if (!initialModelParameters_.empty ())
222+ if (!initialModelParameters_.empty ()) {
216223 modelParameters[std::make_pair (this ->optionletBase ()->optionletFixingTimes ()[i], Null<Real>())] =
217- initialModelParameters_;
224+ initialModelParameters_.size () == 1 ? initialModelParameters_.front () : initialModelParameters_[i];
225+ }
218226 }
219227
220228 parametricVolatility_ = QuantLib::ext::make_shared<SabrParametricVolatility>(
0 commit comments