/src/quantlib/ql/methods/finitedifferences/utilities/fdmaffinemodelswapinnervalue.hpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2011 Klaus Spanderen |
5 | | |
6 | | This file is part of QuantLib, a free-software/open-source library |
7 | | for financial quantitative analysts and developers - http://quantlib.org/ |
8 | | |
9 | | QuantLib is free software: you can redistribute it and/or modify it |
10 | | under the terms of the QuantLib license. You should have received a |
11 | | copy of the license along with this program; if not, please email |
12 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
13 | | <https://www.quantlib.org/license.shtml>. |
14 | | |
15 | | This program is distributed in the hope that it will be useful, but WITHOUT |
16 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
17 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
18 | | */ |
19 | | |
20 | | /*! \file fdmaffinemodelswapinnervalue.hpp |
21 | | */ |
22 | | |
23 | | #ifndef quantlib_fdm_affine_model_swap_inner_value_hpp |
24 | | #define quantlib_fdm_affine_model_swap_inner_value_hpp |
25 | | |
26 | | #include <ql/cashflows/coupon.hpp> |
27 | | #include <ql/indexes/iborindex.hpp> |
28 | | #include <ql/instruments/vanillaswap.hpp> |
29 | | #include <ql/methods/finitedifferences/meshers/fdmmesher.hpp> |
30 | | #include <ql/methods/finitedifferences/utilities/fdmaffinemodeltermstructure.hpp> |
31 | | #include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp> |
32 | | #include <ql/models/shortrate/onefactormodels/hullwhite.hpp> |
33 | | #include <ql/pricingengines/swap/discountingswapengine.hpp> |
34 | | #include <map> |
35 | | #include <utility> |
36 | | |
37 | | namespace QuantLib { |
38 | | |
39 | | template <class ModelType> |
40 | | class FdmAffineModelSwapInnerValue : public FdmInnerValueCalculator { |
41 | | public: |
42 | | FdmAffineModelSwapInnerValue(ext::shared_ptr<ModelType> disModel, |
43 | | ext::shared_ptr<ModelType> fwdModel, |
44 | | const ext::shared_ptr<FixedVsFloatingSwap>& swap, |
45 | | std::map<Time, Date> exerciseDates, |
46 | | ext::shared_ptr<FdmMesher> mesher, |
47 | | Size direction); |
48 | | |
49 | | Real innerValue(const FdmLinearOpIterator& iter, Time t) override; |
50 | | Real avgInnerValue(const FdmLinearOpIterator& iter, Time t) override; |
51 | | |
52 | | private: |
53 | | Array getState(const ext::shared_ptr<ModelType>& model, |
54 | | Time t, |
55 | | const FdmLinearOpIterator& iter) const; |
56 | | |
57 | | RelinkableHandle<YieldTermStructure> disTs_, fwdTs_; |
58 | | const ext::shared_ptr<ModelType> disModel_, fwdModel_; |
59 | | |
60 | | const ext::shared_ptr<IborIndex> index_; |
61 | | const ext::shared_ptr<FixedVsFloatingSwap> swap_; |
62 | | const std::map<Time, Date> exerciseDates_; |
63 | | const ext::shared_ptr<FdmMesher> mesher_; |
64 | | const Size direction_; |
65 | | }; |
66 | | |
67 | | template <class ModelType> |
68 | | inline FdmAffineModelSwapInnerValue<ModelType>::FdmAffineModelSwapInnerValue( |
69 | | ext::shared_ptr<ModelType> disModel, |
70 | | ext::shared_ptr<ModelType> fwdModel, |
71 | | const ext::shared_ptr<FixedVsFloatingSwap>& swap, |
72 | | std::map<Time, Date> exerciseDates, |
73 | | ext::shared_ptr<FdmMesher> mesher, |
74 | | Size direction) |
75 | 0 | : disModel_(std::move(disModel)), fwdModel_(std::move(fwdModel)), index_(swap->iborIndex()), |
76 | 0 | swap_(ext::make_shared<VanillaSwap>(swap->type(), |
77 | 0 | swap->nominal(), |
78 | 0 | swap->fixedSchedule(), |
79 | 0 | swap->fixedRate(), |
80 | 0 | swap->fixedDayCount(), |
81 | 0 | swap->floatingSchedule(), |
82 | 0 | swap->iborIndex()->clone(fwdTs_), |
83 | 0 | swap->spread(), |
84 | 0 | swap->floatingDayCount(), |
85 | 0 | swap->paymentConvention())), |
86 | 0 | exerciseDates_(std::move(exerciseDates)), mesher_(std::move(mesher)), direction_(direction) {}Unexecuted instantiation: QuantLib::FdmAffineModelSwapInnerValue<QuantLib::G2>::FdmAffineModelSwapInnerValue(boost::shared_ptr<QuantLib::G2>, boost::shared_ptr<QuantLib::G2>, boost::shared_ptr<QuantLib::FixedVsFloatingSwap> const&, std::__1::map<double, QuantLib::Date, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, QuantLib::Date> > >, boost::shared_ptr<QuantLib::FdmMesher>, unsigned long) Unexecuted instantiation: QuantLib::FdmAffineModelSwapInnerValue<QuantLib::HullWhite>::FdmAffineModelSwapInnerValue(boost::shared_ptr<QuantLib::HullWhite>, boost::shared_ptr<QuantLib::HullWhite>, boost::shared_ptr<QuantLib::FixedVsFloatingSwap> const&, std::__1::map<double, QuantLib::Date, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, QuantLib::Date> > >, boost::shared_ptr<QuantLib::FdmMesher>, unsigned long) |
87 | | |
88 | | template <class ModelType> inline |
89 | | Real FdmAffineModelSwapInnerValue<ModelType>::innerValue( |
90 | 0 | const FdmLinearOpIterator& iter, Time t) { |
91 | |
|
92 | 0 | const Date& iterExerciseDate = exerciseDates_.find(t)->second; |
93 | |
|
94 | 0 | const Array disRate(getState(disModel_, t, iter)); |
95 | 0 | const Array fwdRate(getState(fwdModel_, t, iter)); |
96 | |
|
97 | 0 | if (disTs_.empty() || iterExerciseDate != disTs_->referenceDate()) { |
98 | |
|
99 | 0 | const Handle<YieldTermStructure> discount |
100 | 0 | = disModel_->termStructure(); |
101 | |
|
102 | 0 | disTs_.linkTo(ext::shared_ptr<YieldTermStructure>( |
103 | 0 | new FdmAffineModelTermStructure(disRate, |
104 | 0 | discount->calendar(), discount->dayCounter(), |
105 | 0 | iterExerciseDate, discount->referenceDate(), |
106 | 0 | disModel_))); |
107 | |
|
108 | 0 | const Handle<YieldTermStructure> fwd = fwdModel_->termStructure(); |
109 | |
|
110 | 0 | fwdTs_.linkTo(ext::shared_ptr<YieldTermStructure>( |
111 | 0 | new FdmAffineModelTermStructure(fwdRate, |
112 | 0 | fwd->calendar(), fwd->dayCounter(), |
113 | 0 | iterExerciseDate, fwd->referenceDate(), |
114 | 0 | fwdModel_))); |
115 | |
|
116 | 0 | } |
117 | 0 | else { |
118 | 0 | ext::dynamic_pointer_cast<FdmAffineModelTermStructure>( |
119 | 0 | disTs_.currentLink())->setVariable(disRate); |
120 | 0 | ext::dynamic_pointer_cast<FdmAffineModelTermStructure>( |
121 | 0 | fwdTs_.currentLink())->setVariable(fwdRate); |
122 | 0 | } |
123 | |
|
124 | 0 | Real npv = 0.0; |
125 | 0 | for (Size j = 0; j < 2; j++) { |
126 | 0 | for (const auto& i : swap_->leg(j)) { |
127 | 0 | npv += |
128 | 0 | ext::dynamic_pointer_cast<Coupon>(i)->accrualStartDate() >= iterExerciseDate ? |
129 | 0 | Real(i->amount() * disTs_->discount(i->date())) : |
130 | 0 | 0.0; |
131 | 0 | } |
132 | 0 | if (j == 0) |
133 | 0 | npv *= -1.0; |
134 | 0 | } |
135 | 0 | if (swap_->type() == Swap::Receiver) |
136 | 0 | npv *= -1.0; |
137 | |
|
138 | 0 | return std::max(0.0, npv); |
139 | 0 | } Unexecuted instantiation: QuantLib::FdmAffineModelSwapInnerValue<QuantLib::G2>::innerValue(QuantLib::FdmLinearOpIterator const&, double) Unexecuted instantiation: QuantLib::FdmAffineModelSwapInnerValue<QuantLib::HullWhite>::innerValue(QuantLib::FdmLinearOpIterator const&, double) |
140 | | |
141 | | template <class ModelType> inline |
142 | | Real FdmAffineModelSwapInnerValue<ModelType>::avgInnerValue( |
143 | 0 | const FdmLinearOpIterator& iter, Time t) { |
144 | 0 | return innerValue(iter, t); |
145 | 0 | } Unexecuted instantiation: QuantLib::FdmAffineModelSwapInnerValue<QuantLib::G2>::avgInnerValue(QuantLib::FdmLinearOpIterator const&, double) Unexecuted instantiation: QuantLib::FdmAffineModelSwapInnerValue<QuantLib::HullWhite>::avgInnerValue(QuantLib::FdmLinearOpIterator const&, double) |
146 | | |
147 | | } |
148 | | #endif |