Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
FdBlackScholesBase Class Reference

#include <ored/scripting/models/fdblackscholesbase.hpp>

+ Inheritance diagram for FdBlackScholesBase:
+ Collaboration diagram for FdBlackScholesBase:

Public Member Functions

 FdBlackScholesBase (const Size stateGridPoints, const std::vector< std::string > &currencies, const std::vector< Handle< YieldTermStructure > > &curves, const std::vector< Handle< Quote > > &fxSpots, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< InterestRateIndex > > > &irIndices, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > &infIndices, const std::vector< std::string > &indices, const std::vector< std::string > &indexCurrencies, const std::set< std::string > &payCcys_, const Handle< BlackScholesModelWrapper > &model, const std::map< std::pair< std::string, std::string >, Handle< QuantExt::CorrelationTermStructure > > &correlations, const std::set< Date > &simulationDates, const IborFallbackConfig &iborFallbackConfig, const std::string &calibration, const std::map< std::string, std::vector< Real > > &calibrationStrikes={}, const Real mesherEpsilon=1E-4, const Real mesherScaling=1.5, const Real mesherConcentration=0.1, const Size mesherMaxConcentratingPoints=9999, const bool staticMesher=false)
 
 FdBlackScholesBase (const Size stateGridPoints, const std::string &currency, const Handle< YieldTermStructure > &curve, const std::string &index, const std::string &indexCurrency, const Handle< BlackScholesModelWrapper > &model, const std::set< Date > &simulationDates, const IborFallbackConfig &iborFallbackConfig, const std::string &calibration, const std::vector< Real > &calibrationStrikes={}, const Real mesherEpsilon=1E-4, const Real mesherScaling=1.5, const Real mesherConcentration=0.1, const Size mesherMaxConcentratingPoints=9999, const bool staticMesher=false)
 
Type type () const override
 
const Date & referenceDate () const override
 
RandomVariable npv (const RandomVariable &amount, const Date &obsdate, const Filter &filter, const boost::optional< long > &memSlot, const RandomVariable &addRegressor1, const RandomVariable &addRegressor2) const override
 
RandomVariable fwdCompAvg (const bool isAvg, const std::string &index, const Date &obsdate, const Date &start, const Date &end, const Real spread, const Real gearing, const Integer lookback, const Natural rateCutoff, const Natural fixingDays, const bool includeSpread, const Real cap, const Real floor, const bool nakedOption, const bool localCapFloor) const override
 
void releaseMemory () override
 
Real extractT0Result (const RandomVariable &result) const override
 
const std::string & baseCcy () const override
 
RandomVariable pay (const RandomVariable &amount, const Date &obsdate, const Date &paydate, const std::string &currency) const override
 
- Public Member Functions inherited from ModelImpl
 ModelImpl (const DayCounter &dayCounter, const Size size, const std::vector< std::string > &currencies, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< InterestRateIndex > > > &irIndices, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > &infIndices, const std::vector< std::string > &indices, const std::vector< std::string > &indexCurrencies, const std::set< Date > &simulationDates, const IborFallbackConfig &iborFallbackConfig)
 
const std::string & baseCcy () const override
 
Real dt (const Date &d1, const Date &d2) const override
 
RandomVariable pay (const RandomVariable &amount, const Date &obsdate, const Date &paydate, const std::string &currency) const override
 
RandomVariable discount (const Date &obsdate, const Date &paydate, const std::string &currency) const override
 
RandomVariable eval (const std::string &index, const Date &obsdate, const Date &fwddate, const bool returnMissingMissingAsNull=false, const bool ignoreTodaysFixing=false) const override
 
Real fxSpotT0 (const std::string &forCcy, const std::string &domCcy) const override
 
RandomVariable barrierProbability (const std::string &index, const Date &obsdate1, const Date &obsdate2, const RandomVariable &barrier, const bool above) const override
 
Real extractT0Result (const RandomVariable &value) const override
 
- Public Member Functions inherited from Model
 Model (const Size n)
 
virtual ~Model ()
 
virtual Type type () const =0
 
virtual Size size () const
 
virtual Size trainingSamples () const
 
virtual void toggleTrainingPaths () const
 
virtual const Date & referenceDate () const =0
 
virtual const std::string & baseCcy () const =0
 
virtual Real dt (const Date &d1, const Date &d2) const
 
Real timeFromReference (const Date &d) const
 
virtual RandomVariable pay (const RandomVariable &amount, const Date &obsdate, const Date &paydate, const std::string &currency) const =0
 
virtual RandomVariable discount (const Date &obsdate, const Date &paydate, const std::string &currency) const =0
 
virtual RandomVariable npv (const RandomVariable &amount, const Date &obsdate, const Filter &filter, const boost::optional< long > &memSlot, const RandomVariable &addRegressor1, const RandomVariable &addRegressor2) const =0
 
virtual RandomVariable eval (const std::string &index, const Date &obsdate, const Date &fwddate, const bool returnMissingFixingAsNull=false, const bool ignoreTodaysFixing=false) const =0
 
virtual RandomVariable fwdCompAvg (const bool isAvg, const std::string &index, const Date &obsdate, const Date &start, const Date &end, const Real spread, const Real gearing, const Integer lookback, const Natural rateCutoff, const Natural fixingDays, const bool includeSpread, const Real cap, const Real floor, const bool nakedOption, const bool localCapFloor) const =0
 
virtual RandomVariable barrierProbability (const std::string &index, const Date &obsdate1, const Date &obsdate2, const RandomVariable &barrier, const bool above) const =0
 
virtual Real fxSpotT0 (const std::string &forCcy, const std::string &domCcy) const =0
 
virtual Real extractT0Result (const RandomVariable &value) const =0
 
virtual void releaseMemory ()
 
virtual void resetNPVMem ()
 
const std::map< std::string, boost::any > & additionalResults () const
 

Protected Member Functions

void performCalculations () const override
 
RandomVariable getIndexValue (const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const override
 
RandomVariable getIrIndexValue (const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const override
 
RandomVariable getInfIndexValue (const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const override
 
RandomVariable getDiscount (const Size idx, const Date &s, const Date &t) const override
 
RandomVariable getNumeraire (const Date &s) const override
 
Real getFxSpot (const Size idx) const override
 
RandomVariable getFutureBarrierProb (const std::string &index, const Date &obsdate1, const Date &obsdate2, const RandomVariable &barrier, const bool above) const override
 
Matrix getCorrelation () const
 
virtual RandomVariable getIndexValue (const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const =0
 
virtual RandomVariable getIrIndexValue (const Size indexNo, const Date &d, const Date &fwd=Null< Date >()) const =0
 
virtual RandomVariable getInfIndexValue (const Size indexNo, const Date &d, const Date &fwd) const =0
 
virtual RandomVariable getDiscount (const Size idx, const Date &s, const Date &t) const =0
 
virtual RandomVariable getNumeraire (const Date &s) const =0
 
virtual Real getFxSpot (const Size idx) const =0
 
virtual RandomVariable getFutureBarrierProb (const std::string &index, const Date &obsdate1, const Date &obsdate2, const RandomVariable &barrier, const bool above) const =0
 
- Protected Member Functions inherited from Model
void performCalculations () const override
 

Protected Attributes

const std::vector< Handle< YieldTermStructure > > curves_
 
const std::vector< Handle< Quote > > fxSpots_
 
const std::set< std::string > payCcys_
 
const Handle< BlackScholesModelWrappermodel_
 
const std::map< std::pair< std::string, std::string >, Handle< QuantExt::CorrelationTermStructure > > correlations_
 
const std::vector< Date > simulationDates_
 
const std::string calibration_
 
const std::map< std::string, std::vector< Real > > calibrationStrikes_
 
const Real mesherEpsilon_
 
const Real mesherScaling_
 
const Real mesherConcentration_
 
const Size mesherMaxConcentratingPoints_
 
const bool staticMesher_
 
bool applyQuantoAdjustment_ = false
 
Size quantoSourceCcyIndex_
 
Size quantoTargetCcyIndex_
 
Real quantoCorrelationMultiplier_
 
std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > basisFns_
 
Date referenceDate_
 
std::set< Date > effectiveSimulationDates_
 
TimeGrid timeGrid_
 
std::vector< Size > positionInTimeGrid_
 
QuantLib::ext::shared_ptr< FdmMesher > mesher_
 
QuantLib::ext::shared_ptr< FdmLinearOpCompositeoperator_
 
QuantLib::ext::shared_ptr< FdmBackwardSolver > solver_
 
RandomVariable underlyingValues_
 
- Protected Attributes inherited from ModelImpl
const DayCounter dayCounter_
 
const std::vector< std::string > currencies_
 
const std::vector< std::string > indexCurrencies_
 
const std::set< Date > simulationDates_
 
const IborFallbackConfig iborFallbackConfig_
 
std::vector< std::pair< IndexInfo, QuantLib::ext::shared_ptr< InterestRateIndex > > > irIndices_
 
std::vector< std::pair< IndexInfo, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > infIndices_
 
std::vector< IndexInfoindices_
 
- Protected Attributes inherited from Model
std::map< std::string, boost::any > additionalResults_
 

Additional Inherited Members

- Public Types inherited from Model
enum class  Type { MC , FD }
 

Detailed Description

Definition at line 44 of file fdblackscholesbase.hpp.

Constructor & Destructor Documentation

◆ FdBlackScholesBase() [1/2]

FdBlackScholesBase ( const Size  stateGridPoints,
const std::vector< std::string > &  currencies,
const std::vector< Handle< YieldTermStructure > > &  curves,
const std::vector< Handle< Quote > > &  fxSpots,
const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< InterestRateIndex > > > &  irIndices,
const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > &  infIndices,
const std::vector< std::string > &  indices,
const std::vector< std::string > &  indexCurrencies,
const std::set< std::string > &  payCcys_,
const Handle< BlackScholesModelWrapper > &  model,
const std::map< std::pair< std::string, std::string >, Handle< QuantExt::CorrelationTermStructure > > &  correlations,
const std::set< Date > &  simulationDates,
const IborFallbackConfig iborFallbackConfig,
const std::string &  calibration,
const std::map< std::string, std::vector< Real > > &  calibrationStrikes = {},
const Real  mesherEpsilon = 1E-4,
const Real  mesherScaling = 1.5,
const Real  mesherConcentration = 0.1,
const Size  mesherMaxConcentratingPoints = 9999,
const bool  staticMesher = false 
)

Definition at line 57 of file fdblackscholesbase.cpp.

69 : ModelImpl(curves.at(0)->dayCounter(), stateGridPoints, currencies, irIndices, infIndices, indices,
70 indexCurrencies, simulationDates, iborFallbackConfig),
71 curves_(curves), fxSpots_(fxSpots), payCcys_(payCcys), model_(model), correlations_(correlations),
72 calibration_(calibration), calibrationStrikes_(calibrationStrikes), mesherEpsilon_(mesherEpsilon),
73 mesherScaling_(mesherScaling), mesherConcentration_(mesherConcentration),
74 mesherMaxConcentratingPoints_(mesherMaxConcentratingPoints), staticMesher_(staticMesher) {
75
76 // check inputs
77
78 QL_REQUIRE(!model_.empty(), "model is empty");
79 QL_REQUIRE(!curves_.empty(), "no curves given");
80 QL_REQUIRE(currencies_.size() == curves_.size(), "number of currencies (" << currencies_.size()
81 << ") does not match number of curves ("
82 << curves_.size() << ")");
83 QL_REQUIRE(currencies_.size() == fxSpots_.size() + 1,
84 "number of currencies (" << currencies_.size() << ") does not match number of fx spots ("
85 << fxSpots_.size() << ") + 1");
86
87 QL_REQUIRE(indices_.size() == model_->processes().size(),
88 "mismatch of processes size (" << model_->processes().size() << ") and number of indices ("
89 << indices_.size() << ")");
90
91 for (auto const& c : payCcys) {
92 QL_REQUIRE(std::find(currencies_.begin(), currencies_.end(), c) != currencies_.end(),
93 "pay ccy '" << c << "' not found in currencies list.");
94 }
95
96 // register with observables
97
98 for (auto const& o : fxSpots_)
99 registerWith(o);
100 for (auto const& o : correlations_)
101 registerWith(o.second);
102
103 registerWith(model_);
104
105 // if we have one (or no) underlying, everything works as usual
106
107 if (model_->processes().size() <= 1)
108 return;
109
110 // if we have one underlying + one FX index, we do a 1D PDE with a quanto adjustment under certain circumstances
111
112 if (model_->processes().size() == 2) {
113 // check whether we have exactly one pay ccy ...
114 if (payCcys.size() == 1) {
115 std::string payCcy = *payCcys.begin();
116 // ... and the second index is an FX index suitable to do a quanto adjustment
117 // from the first index's currency to the pay ccy ...
118 std::string mainIndexCcy = indexCurrencies_[0];
119 if (indices_[0].isFx()) {
120 mainIndexCcy = indices_[0].fx()->targetCurrency().code();
121 }
122 if (indices_[1].isFx()) {
123 std::string ccy1 = indices_[1].fx()->sourceCurrency().code();
124 std::string ccy2 = indices_[1].fx()->targetCurrency().code();
125 if ((ccy1 == mainIndexCcy && ccy2 == payCcy) || (ccy1 == payCcy && ccy2 == mainIndexCcy)) {
127 quantoSourceCcyIndex_ = std::distance(
128 currencies.begin(), std::find(currencies.begin(), currencies.end(), mainIndexCcy));
130 std::distance(currencies.begin(), std::find(currencies.begin(), currencies.end(), payCcy));
131 quantoCorrelationMultiplier_ = ccy2 == payCcy ? 1.0 : -1.0;
132 }
133 DLOG("FdBlackScholesBase model will be run for index '"
134 << indices_[0].name() << "' with a quanto-adjustment " << currencies_[quantoSourceCcyIndex_]
135 << " => " << currencies_[quantoTargetCcyIndex_] << " derived from index '" << indices_[1].name()
136 << "'");
137 return;
138 }
139 }
140 }
141
142 // otherwise we need more than one dimension, which we currently not support
143
144 QL_FAIL("FdBlackScholesBase: model does not support multi-dim fd schemes currently.");
145
146} // FdBlackScholesBase ctor
const std::set< std::string > payCcys_
const std::vector< Handle< Quote > > fxSpots_
const Handle< BlackScholesModelWrapper > model_
const std::map< std::string, std::vector< Real > > calibrationStrikes_
const std::map< std::pair< std::string, std::string >, Handle< QuantExt::CorrelationTermStructure > > correlations_
const std::vector< Handle< YieldTermStructure > > curves_
const std::vector< std::string > currencies_
Definition: modelimpl.hpp:107
ModelImpl(const DayCounter &dayCounter, const Size size, const std::vector< std::string > &currencies, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< InterestRateIndex > > > &irIndices, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > &infIndices, const std::vector< std::string > &indices, const std::vector< std::string > &indexCurrencies, const std::set< Date > &simulationDates, const IborFallbackConfig &iborFallbackConfig)
Definition: modelimpl.cpp:35
std::vector< IndexInfo > indices_
Definition: modelimpl.hpp:114
const std::vector< std::string > indexCurrencies_
Definition: modelimpl.hpp:108
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
string name

◆ FdBlackScholesBase() [2/2]

FdBlackScholesBase ( const Size  stateGridPoints,
const std::string &  currency,
const Handle< YieldTermStructure > &  curve,
const std::string &  index,
const std::string &  indexCurrency,
const Handle< BlackScholesModelWrapper > &  model,
const std::set< Date > &  simulationDates,
const IborFallbackConfig iborFallbackConfig,
const std::string &  calibration,
const std::vector< Real > &  calibrationStrikes = {},
const Real  mesherEpsilon = 1E-4,
const Real  mesherScaling = 1.5,
const Real  mesherConcentration = 0.1,
const Size  mesherMaxConcentratingPoints = 9999,
const bool  staticMesher = false 
)

Definition at line 44 of file fdblackscholesbase.cpp.

52 : FdBlackScholesBase(stateGridPoints, {currency}, {curve}, {}, {}, {}, {index}, {indexCurrency}, {currency}, model,
53 {}, simulationDates, iborFallbackConfig, calibration, {{index, calibrationStrikes}},
54 mesherEpsilon, mesherScaling, mesherConcentration, mesherMaxConcentratingPoints,
55 staticMesher) {}
FdBlackScholesBase(const Size stateGridPoints, const std::vector< std::string > &currencies, const std::vector< Handle< YieldTermStructure > > &curves, const std::vector< Handle< Quote > > &fxSpots, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< InterestRateIndex > > > &irIndices, const std::vector< std::pair< std::string, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > &infIndices, const std::vector< std::string > &indices, const std::vector< std::string > &indexCurrencies, const std::set< std::string > &payCcys_, const Handle< BlackScholesModelWrapper > &model, const std::map< std::pair< std::string, std::string >, Handle< QuantExt::CorrelationTermStructure > > &correlations, const std::set< Date > &simulationDates, const IborFallbackConfig &iborFallbackConfig, const std::string &calibration, const std::map< std::string, std::vector< Real > > &calibrationStrikes={}, const Real mesherEpsilon=1E-4, const Real mesherScaling=1.5, const Real mesherConcentration=0.1, const Size mesherMaxConcentratingPoints=9999, const bool staticMesher=false)

Member Function Documentation

◆ type()

Type type ( ) const
overridevirtual

Implements Model.

Definition at line 75 of file fdblackscholesbase.hpp.

◆ referenceDate()

const Date & referenceDate ( ) const
overridevirtual

Implements Model.

Definition at line 168 of file fdblackscholesbase.cpp.

168 {
169 calculate();
170 return referenceDate_;
171}
+ Here is the caller graph for this function:

◆ npv()

RandomVariable npv ( const RandomVariable amount,
const Date &  obsdate,
const Filter filter,
const boost::optional< long > &  memSlot,
const RandomVariable addRegressor1,
const RandomVariable addRegressor2 
) const
overridevirtual

Implements Model.

Definition at line 398 of file fdblackscholesbase.cpp.

400 {
401
402 QL_REQUIRE(!memSlot, "FdBlackScholesBase::npv(): mem slot not allowed");
403 QL_REQUIRE(!filter.initialised(), "FdBlackScholesBase::npv(). filter not allowed");
404 QL_REQUIRE(!addRegressor1.initialised(), "FdBlackScholesBase::npv(). addRegressor1 not allowed");
405 QL_REQUIRE(!addRegressor2.initialised(), "FdBlackScholesBase::npv(). addRegressor2 not allowed");
406
407 calculate();
408
409 Real t1 = amount.time();
410 Real t0 = timeFromReference(obsdate);
411
412 // handle case when amount is deterministic
413
414 if (amount.deterministic()) {
415 RandomVariable result(amount);
416 result.setTime(t0);
417 return result;
418 }
419
420 // handle stochastic amount
421
422 QL_REQUIRE(t1 != Null<Real>(),
423 "FdBlackScholesBase::npv(): can not roll back amount wiithout time attached (to t0=" << t0 << ")");
424
425 // might throw if t0, t1 are not found in timeGrid_
426
427 Size ind1 = timeGrid_.index(t1);
428 Size ind0 = timeGrid_.index(t0);
429
430 // check t0 <= t1, i.e. ind0 <= ind1
431
432 QL_REQUIRE(ind0 <= ind1, "FdBlackScholesBase::npv(): can not roll back from t1= "
433 << t1 << " (index " << ind1 << ") to t0= " << t0 << " (" << ind0 << ")");
434
435 // if t0 = t1, no rollback is necessary and we can return the input random variable
436
437 if (ind0 == ind1)
438 return amount;
439
440 // if t0 < t1, we roll back on the time grid
441
442 Array workingArray(amount.size());
443 amount.copyToArray(workingArray);
444
445 for (int j = static_cast<int>(ind1) - 1; j >= static_cast<int>(ind0); --j) {
446 solver_->rollback(workingArray, timeGrid_[j + 1], timeGrid_[j], 1, 0);
447 }
448
449 // return the rolled back value
450
451 return RandomVariable(workingArray, t0);
452}
QuantLib::ext::shared_ptr< FdmBackwardSolver > solver_
Real timeFromReference(const Date &d) const
Definition: model.hpp:92
SafeStack< Filter > filter
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fwdCompAvg()

RandomVariable fwdCompAvg ( const bool  isAvg,
const std::string &  index,
const Date &  obsdate,
const Date &  start,
const Date &  end,
const Real  spread,
const Real  gearing,
const Integer  lookback,
const Natural  rateCutoff,
const Natural  fixingDays,
const bool  includeSpread,
const Real  cap,
const Real  floor,
const bool  nakedOption,
const bool  localCapFloor 
) const
overridevirtual

Implements Model.

Definition at line 356 of file fdblackscholesbase.cpp.

361 {
362 calculate();
363 IndexInfo indexInfo(indexInput);
364 auto index = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(indexInfo.irIbor());
365 QL_REQUIRE(index, "BlackScholesBase::fwdCompAvg(): expected on index for " << indexInput);
366 // if we want to support cap / floors we need the OIS CF surface
367 QL_REQUIRE(cap > 999998.0 && floor < -999998.0,
368 "BlackScholesCGBase:fwdCompAvg(): cap (" << cap << ") / floor (" << floor << ") not supported");
369 QuantLib::ext::shared_ptr<QuantLib::FloatingRateCoupon> coupon;
370 QuantLib::ext::shared_ptr<QuantLib::FloatingRateCouponPricer> pricer;
371 if (isAvg) {
372 coupon = QuantLib::ext::make_shared<QuantExt::AverageONIndexedCoupon>(
373 end, 1.0, start, end, index, gearing, spread, rateCutoff, DayCounter(), lookback * Days, fixingDays);
374 pricer = QuantLib::ext::make_shared<AverageONIndexedCouponPricer>();
375 } else {
376 coupon = QuantLib::ext::make_shared<QuantExt::OvernightIndexedCoupon>(
377 end, 1.0, start, end, index, gearing, spread, Date(), Date(), DayCounter(), false, includeSpread,
378 lookback * Days, rateCutoff, fixingDays);
379 pricer = QuantLib::ext::make_shared<OvernightIndexedCouponPricer>();
380 }
381 coupon->setPricer(pricer);
382 return RandomVariable(size(), coupon->rate());
383}
virtual Size size() const
Definition: model.hpp:71
+ Here is the call graph for this function:

◆ releaseMemory()

void releaseMemory ( )
overridevirtual

Reimplemented from Model.

Definition at line 454 of file fdblackscholesbase.cpp.

454{}

◆ extractT0Result()

Real extractT0Result ( const RandomVariable result) const
overridevirtual

Implements Model.

Definition at line 462 of file fdblackscholesbase.cpp.

462 {
463
464 calculate();
465
466 // roll back to today (if necessary)
467
468 RandomVariable r = npv(value, referenceDate(), Filter(), boost::none, RandomVariable(), RandomVariable());
469
470 // if result is deterministic, return the value
471
472 if (r.deterministic())
473 return r.at(0);
474
475 // otherwise interpolate the result at the spot of the underlying process
476
477 Array x(underlyingValues_.size());
478 Array y(underlyingValues_.size());
480 r.copyToArray(y);
481 MonotonicCubicNaturalSpline interpolation(x.begin(), x.end(), y.begin());
482 interpolation.enableExtrapolation();
483 return interpolation(model_->processes()[0]->x0());
484}
RandomVariable npv(const RandomVariable &amount, const Date &obsdate, const Filter &filter, const boost::optional< long > &memSlot, const RandomVariable &addRegressor1, const RandomVariable &addRegressor2) const override
const Date & referenceDate() const override
SafeStack< ValueType > value
void copyToArray(QuantLib::Array &array) const
+ Here is the call graph for this function:

◆ baseCcy()

const std::string & baseCcy ( ) const
overridevirtual

Implements Model.

Definition at line 508 of file fdblackscholesbase.cpp.

508 {
510 return ModelImpl::baseCcy();
511
513}
const std::string & baseCcy() const override
Definition: modelimpl.hpp:72
+ Here is the call graph for this function:

◆ pay()

RandomVariable pay ( const RandomVariable amount,
const Date &  obsdate,
const Date &  paydate,
const std::string &  currency 
) const
overridevirtual

Implements Model.

Definition at line 486 of file fdblackscholesbase.cpp.

487 {
488
489 calculate();
490
492 auto res = ModelImpl::pay(amount, obsdate, paydate, currency);
493 res.setTime(timeFromReference(obsdate));
494 return res;
495 }
496
497 QL_REQUIRE(currency == currencies_[quantoTargetCcyIndex_],
498 "pay ccy is '" << currency << "', expected '" << currencies_[quantoTargetCcyIndex_]
499 << "' in quanto-adjusted FDBlackScholesBase model");
500
501 Date effectiveDate = std::max(obsdate, referenceDate());
502
503 auto res = amount * getDiscount(quantoTargetCcyIndex_, effectiveDate, paydate) / getNumeraire(effectiveDate);
504 res.setTime(timeFromReference(obsdate));
505 return res;
506}
RandomVariable getNumeraire(const Date &s) const override
RandomVariable getDiscount(const Size idx, const Date &s, const Date &t) const override
RandomVariable pay(const RandomVariable &amount, const Date &obsdate, const Date &paydate, const std::string &currency) const override
Definition: modelimpl.cpp:101
+ Here is the call graph for this function:

◆ performCalculations()

void performCalculations ( ) const
overrideprotected

Definition at line 173 of file fdblackscholesbase.cpp.

173 {
174
175 referenceDate_ = curves_.front()->referenceDate();
176
177 // 0a set up time grid
178
179 effectiveSimulationDates_ = model_->effectiveSimulationDates();
180
181 std::vector<Real> times;
182 for (auto const& d : effectiveSimulationDates_) {
183 times.push_back(timeFromReference(d));
184 }
185
186 timeGrid_ = model_->discretisationTimeGrid();
187 positionInTimeGrid_.resize(times.size());
188 for (Size i = 0; i < positionInTimeGrid_.size(); ++i)
189 positionInTimeGrid_[i] = timeGrid_.index(times[i]);
190
191 // 0b nothing to do if we do not have any indices
192
193 if (indices_.empty())
194 return;
195
196 // 0c if we only have one effective sim date (today), we set the underlying values = spot
197
198 if (effectiveSimulationDates_.size() == 1) {
199 underlyingValues_ = RandomVariable(size(), model_->processes()[0]->x0());
200 return;
201 }
202
203 // 1 set the calibration strikes
204
205 std::vector<Real> calibrationStrikes;
206 if (calibration_ == "ATM") {
207 calibrationStrikes.resize(indices_.size(), Null<Real>());
208 } else if (calibration_ == "Deal") {
209 for (Size i = 0; i < indices_.size(); ++i) {
210 auto f = calibrationStrikes_.find(indices_[i].name());
211 if (f != calibrationStrikes_.end() && !f->second.empty()) {
212 calibrationStrikes.push_back(f->second[0]);
213 TLOG("calibration strike for index '" << indices_[i] << "' is " << f->second[0]);
214 } else {
215 calibrationStrikes.push_back(Null<Real>());
216 TLOG("calibration strike for index '" << indices_[i] << "' is ATMF");
217 }
218 }
219 } else {
220 QL_FAIL("FdBlackScholes: calibration '" << calibration_ << "' not supported, expected ATM, Deal");
221 }
222
223 // 1b set up the critical points for the mesher
224
225 std::vector<std::vector<QuantLib::ext::tuple<Real, Real, bool>>> cPoints;
226 for (Size i = 0; i < indices_.size(); ++i) {
227 cPoints.push_back(std::vector<QuantLib::ext::tuple<Real, Real, bool>>());
228 auto f = calibrationStrikes_.find(indices_[i].name());
229 if (f != calibrationStrikes_.end()) {
230 for (Size j = 0; j < std::min(f->second.size(), mesherMaxConcentratingPoints_); ++j) {
231 cPoints.back().push_back(QuantLib::ext::make_tuple(std::log(f->second[j]), mesherConcentration_, false));
232 TLOG("added critical point at strike " << f->second[j] << " with concentration "
234 }
235 }
236 }
237
238 // 2 set up mesher if we do not have one already or if we want to rebuild it every time
239
240 if (mesher_ == nullptr || !staticMesher_) {
241 mesher_ = QuantLib::ext::make_shared<FdmMesherComposite>(QuantLib::ext::make_shared<QuantExt::FdmBlackScholesMesher>(
242 size(), model_->processes()[0], timeGrid_.back(),
243 calibrationStrikes[0] == Null<Real>()
244 ? atmForward(model_->processes()[0]->x0(), model_->processes()[0]->riskFreeRate(),
245 model_->processes()[0]->dividendYield(), timeGrid_.back())
246 : calibrationStrikes[0],
247 Null<Real>(), Null<Real>(), mesherEpsilon_, mesherScaling_, cPoints[0]));
248 }
249
250 // 3 set up operator using atmf vol and without discounting, floor forward variances at zero
251
252 QuantLib::ext::shared_ptr<QuantExt::FdmQuantoHelper> quantoHelper;
253
255 Real quantoCorr = quantoCorrelationMultiplier_ * getCorrelation()[0][1];
256 quantoHelper = QuantLib::ext::make_shared<QuantExt::FdmQuantoHelper>(
258 *model_->processes()[1]->blackVolatility(), quantoCorr, Null<Real>(), model_->processes()[1]->x0(), false,
259 true);
260 }
261
262 operator_ =
263 QuantLib::ext::make_shared<QuantExt::FdmBlackScholesOp>(mesher_, model_->processes()[0], calibrationStrikes[0], false,
264 -static_cast<Real>(Null<Real>()), 0, quantoHelper, false, true);
265
266 // 4 set up bwd solver, hardcoded Douglas scheme (= CrankNicholson)
267
268 solver_ = QuantLib::ext::make_shared<FdmBackwardSolver>(
269 operator_, std::vector<QuantLib::ext::shared_ptr<BoundaryCondition<FdmLinearOp>>>(), nullptr, FdmSchemeDesc::Douglas());
270
271 // 5 fill random variable with underlying values, these are valid for all times
272
273 auto locations = mesher_->locations(0);
274 underlyingValues_ = exp(RandomVariable(locations));
275
276 // set additional results provided by this model
277
278 for (Size i = 0; i < calibrationStrikes.size(); ++i) {
279 additionalResults_["FdBlackScholes.CalibrationStrike_" + indices_[i].name()] =
280 (calibrationStrikes[i] == Null<Real>() ? "ATMF" : std::to_string(calibrationStrikes[i]));
281 }
282
283 for (Size i = 0; i < indices_.size(); ++i) {
284 Size timeStep = 0;
285 for (auto const& d : effectiveSimulationDates_) {
286 Real t = timeGrid_[positionInTimeGrid_[timeStep]];
287 Real forward = atmForward(model_->processes()[i]->x0(), model_->processes()[i]->riskFreeRate(),
288 model_->processes()[i]->dividendYield(), t);
289 if (timeStep > 0) {
290 Real volatility = model_->processes()[i]->blackVolatility()->blackVol(
291 t, calibrationStrikes[i] == Null<Real>() ? forward : calibrationStrikes[i]);
292 additionalResults_["FdBlackScholes.Volatility_" + indices_[i].name() + "_" + ore::data::to_string(d)] =
293 volatility;
294 }
295 additionalResults_["FdBlackScholes.Forward_" + indices_[i].name() + "_" + ore::data::to_string(d)] =
296 forward;
297 ++timeStep;
298 }
299 }
300}
QuantLib::ext::shared_ptr< FdmLinearOpComposite > operator_
QuantLib::ext::shared_ptr< FdmMesher > mesher_
std::vector< Size > positionInTimeGrid_
std::map< std::string, boost::any > additionalResults_
Definition: model.hpp:153
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
RandomVariable exp(RandomVariable x)
Real atmForward(const Real s0, const Handle< YieldTermStructure > &r, const Handle< YieldTermStructure > &q, const Real t)
helper function that computes the atm forward
Definition: utilities.cpp:483
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
+ Here is the call graph for this function:

◆ getIndexValue()

RandomVariable getIndexValue ( const Size  indexNo,
const Date &  d,
const Date &  fwd = Null<Date>() 
) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 302 of file fdblackscholesbase.cpp.

302 {
303
304 QL_REQUIRE(indexNo == 0, "FdBlackScholesBase::getIndexValue(): indexNo (" << indexNo << ") must be 0");
305
306 // determine the effective forward date (if applicable)
307
308 Date effFwd = fwd;
309 if (indices_[indexNo].isComm()) {
310 const Date& expiry = indices_[indexNo].comm(d)->expiryDate();
311 // if a future is referenced we set the forward date effectively used below to the future's expiry date
312 if (expiry != Date())
313 effFwd = expiry;
314 // if the future expiry is past the obsdate, we return the spot as of the obsdate, i.e. we
315 // freeze the future value after its expiry, but keep it available for observation
316 // TOOD should we throw an exception instead?
317 effFwd = std::max(effFwd, d);
318 }
319
320 // init the result with the underlying values themselves
321
322 RandomVariable res(underlyingValues_);
323
324 // compute forwarding factor and multiply the result by this factor
325
326 if (effFwd != Null<Date>()) {
327 auto p = model_->processes().at(indexNo);
328 res *= RandomVariable(size(), p->dividendYield()->discount(effFwd) / p->dividendYield()->discount(d) /
329 (p->riskFreeRate()->discount(effFwd) / p->riskFreeRate()->discount(d)));
330 }
331
332 // set the observation time in the result random variable
333 res.setTime(timeFromReference(d));
334
335 // return the result
336
337 return res;
338}
+ Here is the call graph for this function:

◆ getIrIndexValue()

RandomVariable getIrIndexValue ( const Size  indexNo,
const Date &  d,
const Date &  fwd = Null<Date>() 
) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 340 of file fdblackscholesbase.cpp.

340 {
341 Date effFixingDate = d;
342 if (fwd != Null<Date>())
343 effFixingDate = fwd;
344 // ensure a valid fixing date
345 effFixingDate = irIndices_.at(indexNo).second->fixingCalendar().adjust(effFixingDate);
346 return RandomVariable(size(), irIndices_.at(indexNo).second->fixing(effFixingDate));
347}
std::vector< std::pair< IndexInfo, QuantLib::ext::shared_ptr< InterestRateIndex > > > irIndices_
Definition: modelimpl.hpp:112
+ Here is the call graph for this function:

◆ getInfIndexValue()

RandomVariable getInfIndexValue ( const Size  indexNo,
const Date &  d,
const Date &  fwd = Null<Date>() 
) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 349 of file fdblackscholesbase.cpp.

349 {
350 Date effFixingDate = d;
351 if (fwd != Null<Date>())
352 effFixingDate = fwd;
353 return RandomVariable(size(), infIndices_.at(indexNo).second->fixing(effFixingDate));
354}
std::vector< std::pair< IndexInfo, QuantLib::ext::shared_ptr< ZeroInflationIndex > > > infIndices_
Definition: modelimpl.hpp:113
+ Here is the call graph for this function:

◆ getDiscount()

RandomVariable getDiscount ( const Size  idx,
const Date &  s,
const Date &  t 
) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 385 of file fdblackscholesbase.cpp.

385 {
386 return RandomVariable(size(), curves_.at(idx)->discount(t) / curves_.at(idx)->discount(s));
387}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getNumeraire()

RandomVariable getNumeraire ( const Date &  s) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 389 of file fdblackscholesbase.cpp.

389 {
391 return RandomVariable(size(), 1.0 / curves_.at(0)->discount(s));
392 else
393 return RandomVariable(size(), 1.0 / curves_.at(quantoTargetCcyIndex_)->discount(s));
394}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFxSpot()

Real getFxSpot ( const Size  idx) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 396 of file fdblackscholesbase.cpp.

396{ return fxSpots_.at(idx)->value(); }

◆ getFutureBarrierProb()

RandomVariable getFutureBarrierProb ( const std::string &  index,
const Date &  obsdate1,
const Date &  obsdate2,
const RandomVariable barrier,
const bool  above 
) const
overrideprotectedvirtual

Implements ModelImpl.

Definition at line 456 of file fdblackscholesbase.cpp.

458 {
459 QL_FAIL("FdBlackScholesBase::getFutureBarrierProb(): not supported");
460}

◆ getCorrelation()

Matrix getCorrelation ( ) const
protected

Definition at line 148 of file fdblackscholesbase.cpp.

148 {
149 Matrix correlation(indices_.size(), indices_.size(), 0.0);
150 for (Size i = 0; i < indices_.size(); ++i)
151 correlation[i][i] = 1.0;
152 for (auto const& c : correlations_) {
153 IndexInfo inf1(c.first.first), inf2(c.first.second);
154 auto ind1 = std::find(indices_.begin(), indices_.end(), inf1);
155 auto ind2 = std::find(indices_.begin(), indices_.end(), inf2);
156 if (ind1 != indices_.end() && ind2 != indices_.end()) {
157 // EQ, FX, COMM index
158 Size i1 = std::distance(indices_.begin(), ind1);
159 Size i2 = std::distance(indices_.begin(), ind2);
160 correlation[i1][i2] = correlation[i2][i1] = c.second->correlation(0.0); // we assume a constant correlation!
161 }
162 }
163 TLOG("FdBlackScholesBase correlation matrix:");
164 TLOGGERSTREAM(correlation);
165 return correlation;
166}
#define TLOGGERSTREAM(text)
Definition: log.hpp:633
+ Here is the caller graph for this function:

Member Data Documentation

◆ curves_

const std::vector<Handle<YieldTermStructure> > curves_
protected

Definition at line 109 of file fdblackscholesbase.hpp.

◆ fxSpots_

const std::vector<Handle<Quote> > fxSpots_
protected

Definition at line 110 of file fdblackscholesbase.hpp.

◆ payCcys_

const std::set<std::string> payCcys_
protected

Definition at line 111 of file fdblackscholesbase.hpp.

◆ model_

const Handle<BlackScholesModelWrapper> model_
protected

Definition at line 112 of file fdblackscholesbase.hpp.

◆ correlations_

const std::map<std::pair<std::string, std::string>, Handle<QuantExt::CorrelationTermStructure> > correlations_
protected

Definition at line 113 of file fdblackscholesbase.hpp.

◆ simulationDates_

const std::vector<Date> simulationDates_
protected

Definition at line 114 of file fdblackscholesbase.hpp.

◆ calibration_

const std::string calibration_
protected

Definition at line 115 of file fdblackscholesbase.hpp.

◆ calibrationStrikes_

const std::map<std::string, std::vector<Real> > calibrationStrikes_
protected

Definition at line 116 of file fdblackscholesbase.hpp.

◆ mesherEpsilon_

const Real mesherEpsilon_
protected

Definition at line 117 of file fdblackscholesbase.hpp.

◆ mesherScaling_

const Real mesherScaling_
protected

Definition at line 117 of file fdblackscholesbase.hpp.

◆ mesherConcentration_

const Real mesherConcentration_
protected

Definition at line 117 of file fdblackscholesbase.hpp.

◆ mesherMaxConcentratingPoints_

const Size mesherMaxConcentratingPoints_
protected

Definition at line 118 of file fdblackscholesbase.hpp.

◆ staticMesher_

const bool staticMesher_
protected

Definition at line 119 of file fdblackscholesbase.hpp.

◆ applyQuantoAdjustment_

bool applyQuantoAdjustment_ = false
protected

Definition at line 122 of file fdblackscholesbase.hpp.

◆ quantoSourceCcyIndex_

Size quantoSourceCcyIndex_
protected

Definition at line 123 of file fdblackscholesbase.hpp.

◆ quantoTargetCcyIndex_

Size quantoTargetCcyIndex_
protected

Definition at line 123 of file fdblackscholesbase.hpp.

◆ quantoCorrelationMultiplier_

Real quantoCorrelationMultiplier_
protected

Definition at line 124 of file fdblackscholesbase.hpp.

◆ basisFns_

std::vector<std::function<RandomVariable(const std::vector<const RandomVariable*>&)> > basisFns_
mutableprotected

Definition at line 127 of file fdblackscholesbase.hpp.

◆ referenceDate_

Date referenceDate_
mutableprotected

Definition at line 128 of file fdblackscholesbase.hpp.

◆ effectiveSimulationDates_

std::set<Date> effectiveSimulationDates_
mutableprotected

Definition at line 129 of file fdblackscholesbase.hpp.

◆ timeGrid_

TimeGrid timeGrid_
mutableprotected

Definition at line 130 of file fdblackscholesbase.hpp.

◆ positionInTimeGrid_

std::vector<Size> positionInTimeGrid_
mutableprotected

Definition at line 131 of file fdblackscholesbase.hpp.

◆ mesher_

QuantLib::ext::shared_ptr<FdmMesher> mesher_
mutableprotected

Definition at line 132 of file fdblackscholesbase.hpp.

◆ operator_

QuantLib::ext::shared_ptr<FdmLinearOpComposite> operator_
mutableprotected

Definition at line 133 of file fdblackscholesbase.hpp.

◆ solver_

QuantLib::ext::shared_ptr<FdmBackwardSolver> solver_
mutableprotected

Definition at line 134 of file fdblackscholesbase.hpp.

◆ underlyingValues_

RandomVariable underlyingValues_
mutableprotected

Definition at line 135 of file fdblackscholesbase.hpp.