22#include <ql/math/matrixutilities/pseudosqrt.hpp>
23#include <ql/processes/eulerdiscretization.hpp>
25#include <boost/make_shared.hpp>
31using namespace CrossAssetAnalytics;
36inline void setValue(Matrix& m,
const Real& value,
const QuantLib::ext::shared_ptr<const QuantExt::CrossAssetModel>& model,
39 const Size& offset2 = 0) {
40 Size i = model->pIdx(t1, i1, offset1);
41 Size j = model->pIdx(t2, i2, offset2);
42 m[i][j] = m[j][i] = value;
45inline void setValue2(Matrix& m,
const Real& value,
const QuantLib::ext::shared_ptr<const QuantExt::CrossAssetModel>& model,
48 const Size& offset2 = 0) {
49 Size i = model->pIdx(t1, i1, offset1);
50 Size j = model->wIdx(t2, i2, offset2);
59 discretization_ = QuantLib::ext::make_shared<EulerDiscretization>();
62 QuantLib::ext::make_shared<CrossAssetStateProcess::ExactDiscretization>(
model_,
model_->salvagingAlgorithm());
73 crCirpp_.push_back(QuantLib::ext::shared_ptr<CrCirppStateProcess>());
88 if (
auto tmp = QuantLib::ext::dynamic_pointer_cast<CrossAssetStateProcess::ExactDiscretization>(discretization_))
89 tmp->resetCache(timeSteps);
100 Array res(
model_->dimension(), 0.0);
114 QL_REQUIRE(
crCirpp_[i],
"crcirpp is null!");
115 Array r =
crCirpp_[i]->initialValues();
124 std::log(
model_->infjy(i)->index()->fxSpotToday()->value());
132 Array res(
model_->dimension(), 0.0);
135 Real H0 =
model_->irlgm1f(0)->H(t);
136 Real Hprime0 =
model_->irlgm1f(0)->Hprime(t);
137 Real alpha0 =
model_->irlgm1f(0)->alpha(t);
138 Real zeta0 =
model_->irlgm1f(0)->zeta(t);
141 for (Size i = 0; i < n; ++i) {
142 Real Hi =
model_->irlgm1f(i)->H(t);
143 Real alphai =
model_->irlgm1f(i)->alpha(t);
151 Real sigmai =
model_->fxbs(i - 1)->sigma(t);
162 -Hi * alphai * alphai + H0 * alpha0 * alphai * rhozz0i - sigmai * alphai * rhozxii;
165 H0 * alpha0 * sigmai * rhozx0i +
166 model_->irlgm1f(0)->termStructure()->forwardRate(t, t, Continuous) -
167 model_->irlgm1f(i)->termStructure()->forwardRate(t, t, Continuous) - 0.5 * sigmai * sigmai;
176 for (Size k = 0; k < n_eq; ++k) {
179 Real eps_ccy = (i == 0) ? 0.0 : 1.0;
183 Real sigmask =
model_->eqbs(k)->sigma(t);
185 Real sigmaxi = (i == 0) ? 0.0 :
model_->fxbs(i - 1)->sigma(t);
195 Real fr_i =
model_->eqbs(k)->equityIrCurveToday()->forwardRate(t, t, Continuous);
197 Real fq_k =
model_->eqbs(k)->equityDivYieldCurveToday()->forwardRate(t, t, Continuous);
199 (eps_ccy * rhoxsik * sigmaxi * sigmask) -
200 (0.5 * sigmask * sigmask);
208 auto p =
model_->infjy(j);
209 Size i_j =
model_->ccyIndex(p->currency());
212 Real H_y_j = p->realRate()->H(t);
213 Real Hp_y_j = p->realRate()->Hprime(t);
214 Real zeta_y_j = p->realRate()->zeta(t);
215 Real alpha_y_j = p->realRate()->alpha(t);
216 Real sigma_c_j = p->index()->sigma(t);
219 Real H_i_j =
model_->irlgm1f(i_j)->H(t);
220 Real Hp_i_j =
model_->irlgm1f(i_j)->Hprime(t);
221 Real zeta_i_j =
model_->irlgm1f(i_j)->zeta(t);
232 auto rrDrift = -alpha_y_j * alpha_y_j * H_y_j + rho_zy_0j * alpha0 * alpha_y_j * H_y_j -
233 rho_yc_ij * alpha_y_j * sigma_c_j;
236 Real sigma_x_i_j =
model_->fxbs(i_j - 1)->sigma(t);
239 rrDrift -= rho_yx_j_i_j * alpha_y_j * sigma_x_i_j;
245 auto indexDrift = rho_zc_0j * alpha0 * sigma_c_j * H0 - 0.5 * sigma_c_j * sigma_c_j +
246 zeta_i_j * Hp_i_j * H_i_j - zeta_y_j * Hp_y_j * H_y_j;
250 auto ts = p->realRate()->termStructure();
252 Time t1 = std::max(t - dt / 2.0, 0.0);
254 auto z_t = ts->zeroRate(t);
255 auto z_t1 = ts->zeroRate(t1);
256 auto z_t2 = ts->zeroRate(t2);
257 indexDrift += std::log(1 + z_t) + (t / (1 + z_t)) * ((z_t2 - z_t1) / dt);
260 Real sigma_x_i_j =
model_->fxbs(i_j - 1)->sigma(t);
263 indexDrift -= rho_cx_j_i_j * sigma_c_j * sigma_x_i_j;
281 for (Size i = 1; i < n; ++i) {
283 Real Hi =
model_->irlgm1f(i)->H(t);
284 Real Hprimei =
model_->irlgm1f(i)->Hprime(t);
285 Real zetai =
model_->irlgm1f(i)->zeta(t);
290 for (Size k = 0; k < n_eq; ++k) {
295 Real Hi =
model_->irlgm1f(i)->H(t);
296 Real Hprimei =
model_->irlgm1f(i)->Hprime(t);
297 Real zetai =
model_->irlgm1f(i)->zeta(t);
306 auto p =
model_->infjy(j);
307 Size i_j =
model_->ccyIndex(p->currency());
310 Real Hp_y_j = p->realRate()->Hprime(t);
313 Real Hp_i_j =
model_->irlgm1f(i_j)->Hprime(t);
323 for (Size k = 0; k < n_com; ++k) {
324 auto cm = QuantLib::ext::dynamic_pointer_cast<CommoditySchwartzModel>(
model_->comModel(k));
325 QL_REQUIRE(cm,
"CommoditySchwartzModel not set");
326 if (!cm->parametrization()->driftFreeState()) {
328 Real kap = cm->parametrization()->kappaParameter();
362 Matrix res(
model_->dimension(),
model_->brownians(), 0.0);
371 for (Size i = 0; i < n; ++i) {
372 Real alphai =
model_->irlgm1f(i)->alpha(t);
376 for (Size i = 0; i < m; ++i) {
377 Real sigmai =
model_->fxbs(i)->sigma(t);
381 for (Size i = 0; i < d; ++i) {
383 Real alphai =
model_->infdk(i)->alpha(t);
384 Real Hi =
model_->infdk(i)->H(t);
392 auto p =
model_->infjy(i);
401 for (Size i = 0; i < c; ++i) {
405 Real alphai =
model_->crlgm1f(i)->alpha(t);
406 Real Hi =
model_->crlgm1f(i)->H(t);
413 for (Size i = 0; i < e; ++i) {
414 Real sigmai =
model_->eqbs(i)->sigma(t);
418 for (Size i = 0; i < com; ++i) {
419 Real sigmai =
model_->combs(i)->sigma(t);
423 for (Size i = 0; i < crstates; ++i) {
430 Real H0 =
model_->irlgm1f(0)->H(t);
431 Real alpha0 =
model_->irlgm1f(0)->alpha(t);
439Array getProjectedArray(
const Array& source, Size start, Size length) {
440 QL_REQUIRE(source.size() >= start + length,
"getProjectedArray(): internal errors: source size "
441 << source.size() <<
", start" << start <<
", length " << length);
442 return Array(std::next(source.begin(), start), std::next(source.begin(), start + length));
445void applyFxDriftAdjustment(Array& state,
const QuantLib::ext::shared_ptr<const CrossAssetModel>& model, Size i, Time t0,
454 "applyFxDrifAdjustment(): can only handle discretization Euler at the moment.");
455 Matrix corrTmp(model->irModel(i)->m(), 1);
456 for (Size k = 0; k < model->irModel(i)->m(); ++k) {
460 Matrix driftAdj = dt * model->fxbs(i - 1)->sigma(t0) * (transpose(model->irhw(i)->sigma_x(t0)) * corrTmp);
462 for (
auto c = driftAdj.column_begin(0); c != driftAdj.column_end(0); ++c, ++s) {
467 QL_FAIL(
"applyFxDriftAdjustment(): can only handle ir model type HW and fx model type BS currently.");
481 "CrossAssetStateProcess::evolve(): hw-based model only supports Euler discretization.");
485 res = Array(
model_->dimension());
491 auto p =
model_->irModel(i)->stateProcess();
492 auto r = p->evolve(t0,
497 model_->irModel(i)->m() +
model_->irModel(i)->m_aux()));
499 shortRates[i] =
model_->irModel(i)->shortRate(
506 applyFxDriftAdjustment(res,
model_, i, t0, dt);
512 auto r =
model_->fxModel(i)->eulerStep(
515 shortRates[0], shortRates[i + 1]);
522 auto p =
model_->comModel(i)->stateProcess();
535 model_->parametrizations().size(),
536 "CrossAssetStateProcess::evolve(): currently only IR, FX, COM supported.");
546 res = apply(
expectation(t0, x0, dt), df * dz * std::sqrt(dt));
556 Array x0Tmp(2), dwTmp(2);
562 auto r =
crCirpp_[i]->evolve(t0, x0Tmp, dt, dwTmp);
570 QL_REQUIRE(
cirppCount_ == 0,
"only euler discretization is supported for CIR++");
571 res = StochasticProcess::evolve(t0, x0, dt, dw);
578 SalvagingAlgorithm::Type salvaging)
579 : model_(std::move(model)), salvaging_(salvaging) {
582 "CrossAssetStateProces::ExactDiscretization is only supported by LGM1F IR model types.");
589 res = driftImpl1(p, t0, x0, dt);
600 Array res2 = driftImpl2(p, t0, x0, dt);
601 for (Size i = 0; i < res.size(); ++i) {
610 Matrix res = pseudoSqrt(
covariance(p, t0, x0, dt), salvaging_);
628 if (cacheNotReady_v_) {
629 Matrix res = covarianceImpl(p, t0, x0, dt);
630 if (timeStepsToCache_v_ > 0) {
631 cache_v_.push_back(res);
632 if (cache_v_.size() == timeStepsToCache_v_)
633 cacheNotReady_v_ =
false;
637 Matrix res = cache_v_[timeStepCache_v_++];
638 if (timeStepCache_v_ == timeStepsToCache_v_)
639 timeStepCache_v_ = 0;
649 Array res(
model_->dimension(), 0.0);
650 for (Size i = 0; i < n; ++i) {
653 for (Size j = 0; j < m; ++j) {
656 for (Size k = 0; k < e; ++k) {
680 Array res(
model_->dimension(), 0.0);
688 for (Size i = 0; i < n; ++i) {
692 for (Size j = 0; j < m; ++j) {
698 for (Size k = 0; k < e; ++k) {
699 Size eqCcyIdx =
model_->ccyIndex(
model_->eqbs(k)->currency());
708 auto i_i =
model_->ccyIndex(
model_->infjy(i)->currency());
726 for (Size i = 0; i < c; ++i) {
735 for (Size i = 0; i < com; ++i) {
738 auto cm = QuantLib::ext::dynamic_pointer_cast<CommoditySchwartzModel>(
model_->comModel(i));
739 QL_REQUIRE(cm,
"CommoditySchwartzModel not set");
741 if (cm->parametrization()->driftFreeState()) {
744 Real kap = cm->parametrization()->kappaParameter();
759 Matrix res(
model_->dimension(),
model_->dimension(), 0.0);
773 for (Size j = 0; j < n; ++j) {
778 for (Size j = 0; j < m; ++j) {
784 for (Size i = 0; i < n; ++i) {
785 for (Size j = 0; j <= i; ++j) {
791 for (Size i = 0; i < n; ++i) {
792 for (Size j = 0; j < m; ++j) {
798 for (Size i = 0; i < m; ++i) {
799 for (Size j = 0; j <= i; ++j) {
805 for (Size j = 0; j < d; ++j) {
806 for (Size i = 0; i <= j; ++i) {
819 for (Size i = 0; i < n; ++i) {
826 for (Size i = 0; i < (n - 1); ++i) {
835 for (Size j = 0; j < c; ++j) {
839 for (Size i = 0; i <= j; ++i) {
855 for (Size i = 0; i < n; ++i) {
862 for (Size i = 0; i < (n - 1); ++i) {
869 for (Size i = 0; i < d; ++i) {
883 for (Size j = 0; j < e; ++j) {
884 for (Size i = 0; i <= j; ++i) {
889 for (Size i = 0; i < n; ++i) {
894 for (Size i = 0; i < (n - 1); ++i) {
899 for (Size i = 0; i < d; ++i) {
906 for (Size i = 0; i < c; ++i) {
919 for (Size j = 0; j < com; ++j) {
920 for (Size i = 0; i <= j; ++i) {
925 for (Size i = 0; i < n; ++i) {
930 for (Size i = 0; i < (n - 1); ++i) {
935 for (Size i = 0; i < d; ++i) {
942 for (Size i = 0; i < c; ++i) {
952 for (Size i = 0; i < e; ++i) {
960 for (Size i = 0; i < n; ++i) {
961 for (Size j = 0; j < u; ++j) {
966 for (Size i = 0; i < m; ++i) {
967 for (Size j = 0; j < u; ++j) {
972 for (Size i = 0; i < u; ++i) {
973 for (Size j = 0; j <= i; ++j) {
virtual Matrix diffusion(const StochasticProcess &, Time t0, const Array &x0, Time dt) const override
virtual Matrix covariance(const StochasticProcess &, Time t0, const Array &x0, Time dt) const override
virtual Array driftImpl2(const StochasticProcess &, Time t0, const Array &x0, Time dt) const
virtual Matrix covarianceImpl(const StochasticProcess &, Time t0, const Array &x0, Time dt) const
virtual Array drift(const StochasticProcess &, Time t0, const Array &x0, Time dt) const override
QuantLib::ext::shared_ptr< const CrossAssetModel > model_
void resetCache(const Size timeSteps) const
ExactDiscretization(QuantLib::ext::shared_ptr< const CrossAssetModel > model, SalvagingAlgorithm::Type salvaging=SalvagingAlgorithm::Spectral)
virtual Array driftImpl1(const StochasticProcess &, Time t0, const Array &x0, Time dt) const
std::vector< QuantLib::ext::shared_ptr< StochasticProcess > > crCirpp_
Array drift(Time t, const Array &x) const override
Size size() const override
std::vector< Array > cache_m_
Array evolve(Time t0, const Array &x0, Time dt, const Array &dw) const override
virtual Matrix diffusionOnCorrelatedBrowniansImpl(Time t, const Array &x) const
Matrix diffusion(Time t, const Array &x) const override
std::vector< Matrix > cache_d_
Size factors() const override
virtual Matrix diffusionOnCorrelatedBrownians(Time t, const Array &x) const
CrossAssetStateProcess(QuantLib::ext::shared_ptr< const CrossAssetModel > model)
void updateSqrtCorrelation() const
Array initialValues() const override
QuantLib::ext::shared_ptr< const CrossAssetModel > model_
void resetCache(const Size timeSteps) const
analytics for the cross asset model
Real ir_expectation_2(const CrossAssetModel &, const Size, const Real zi_0)
Real com_com_covariance(const CrossAssetModel &x, const Size k, const Size l, const Time t0, const Time dt)
Real fx_fx_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_fx_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real fx_infy_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real infy_infy_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real cry_eq_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real ir_cry_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_infy_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real fx_cry_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_eq_covariance(const CrossAssetModel &x, const Size j, const Size k, const Time t0, const Time dt)
Real infz_infy_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real fx_infz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real infy_crz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_expectation_1(const CrossAssetModel &x, const Size i, const Time t0, const Real dt)
Real ir_crz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real infz_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real eq_expectation_1(const CrossAssetModel &x, const Size k, const Time t0, const Real dt)
Real fx_crz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real crz_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real aux_fx_covariance(const CrossAssetModel &x, const Size j, const Time t0, const Time dt)
Real eq_expectation_2(const CrossAssetModel &x, const Size k, const Time t0, const Real sk_0, const Real zi_0, const Real dt)
Real infz_infz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real cry_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real infz_eq_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real infy_cry_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real crz_cry_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real eq_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real fx_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real infz_crz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real fx_expectation_2(const CrossAssetModel &x, const Size i, const Time t0, const Real xi_0, const Real zi_0, const Real z0_0, const Real dt)
Real infy_com_covariance(const CrossAssetModel &model, const Size i, const Size j, const Time t0, const Time dt)
Real ir_ir_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_infz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real aux_ir_covariance(const CrossAssetModel &x, const Size j, const Time t0, const Time dt)
Real aux_aux_covariance(const CrossAssetModel &x, const Time t0, const Time dt)
Real crstate_crstate_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real fx_eq_covariance(const CrossAssetModel &x, const Size j, const Size k, const Time t0, const Time dt)
Real cry_cry_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real crz_eq_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real ir_crstate_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real fx_crstate_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real infz_cry_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real infy_eq_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real crz_crz_covariance(const CrossAssetModel &x, const Size i, const Size j, const Time t0, const Time dt)
Real eq_eq_covariance(const CrossAssetModel &x, const Size k, const Size l, const Time t0, const Time dt)
Real fx_expectation_1(const CrossAssetModel &x, const Size i, const Time t0, const Real dt)
pair< Real, Real > inf_jy_expectation_1(const CrossAssetModel &x, Size i, Time t0, Real dt)
pair< Real, Real > inf_jy_expectation_2(const CrossAssetModel &x, Size i, Time t0, const pair< Real, Real > &state_0, Real zi_i_0, Real dt)
RandomVariable covariance(const RandomVariable &r, const RandomVariable &s)
RandomVariable expectation(const RandomVariable &r)