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
PairwiseVarianceSwapEngine Class Reference

#include <qle/pricingengines/pairwisevarianceswapengine.hpp>

+ Inheritance diagram for PairwiseVarianceSwapEngine:
+ Collaboration diagram for PairwiseVarianceSwapEngine:

Public Member Functions

 PairwiseVarianceSwapEngine (const QuantLib::ext::shared_ptr< QuantLib::Index > &index1, const QuantLib::ext::shared_ptr< QuantLib::Index > &index2, const QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > &process1, const QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > &process2, const Handle< YieldTermStructure > &discountingTS, Handle< Quote > correlation)
 
void calculate () const override
 

Protected Member Functions

Variances calculateVariances (const Schedule &valuationSchedule, const Schedule &laggedValuationSchedule, const Date &evalDate) const
 

Protected Attributes

QuantLib::ext::shared_ptr< Index > index1_
 
QuantLib::ext::shared_ptr< Index > index2_
 
QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > process1_
 
QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > process2_
 
Handle< YieldTermStructure > discountingTS_
 
Handle< Quote > correlation_
 

Detailed Description

Definition at line 64 of file pairwisevarianceswapengine.hpp.

Constructor & Destructor Documentation

◆ PairwiseVarianceSwapEngine()

PairwiseVarianceSwapEngine ( const QuantLib::ext::shared_ptr< QuantLib::Index > &  index1,
const QuantLib::ext::shared_ptr< QuantLib::Index > &  index2,
const QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > &  process1,
const QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > &  process2,
const Handle< YieldTermStructure > &  discountingTS,
Handle< Quote >  correlation 
)

Definition at line 41 of file pairwisevarianceswapengine.cpp.

46 : index1_(index1), index2_(index2), process1_(process1), process2_(process2), discountingTS_(discountingTS),
47 correlation_(correlation) {
48
49 QL_REQUIRE(process1_ && process2_, "Black-Scholes process not present.");
50
51 registerWith(process1_);
52 registerWith(process2_);
53 registerWith(discountingTS_);
54}
QuantLib::ext::shared_ptr< Index > index2_
QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > process2_
QuantLib::ext::shared_ptr< GeneralizedBlackScholesProcess > process1_
QuantLib::ext::shared_ptr< Index > index1_

Member Function Documentation

◆ calculate()

void calculate ( ) const
override

Definition at line 56 of file pairwisevarianceswapengine.cpp.

56 {
57
58 QL_REQUIRE(!discountingTS_.empty(), "Empty discounting term structure handle");
59
60 results_.value = 0.0;
61
62 Date today = QuantLib::Settings::instance().evaluationDate();
63 const Date& maturityDate = arguments_.settlementDate;
64
65 if (today > maturityDate)
66 return;
67
68 // Variance is defined here as the annualised volatility squared.
69 Variances variances = calculateVariances(arguments_.valuationSchedule, arguments_.laggedValuationSchedule, today);
70 results_.additionalResults["accruedVariance1"] = variances.accruedVariance1;
71 results_.additionalResults["accruedVariance2"] = variances.accruedVariance2;
72 results_.additionalResults["accruedBasketVariance"] = variances.accruedBasketVariance;
73 results_.additionalResults["futureVariance1"] = variances.futureVariance1;
74 results_.additionalResults["futureVariance2"] = variances.futureVariance2;
75 results_.additionalResults["futureBasketVariance"] = variances.futureBasketVariance;
76 results_.additionalResults["totalVariance1"] = variances.totalVariance1;
77 results_.additionalResults["totalVariance2"] = variances.totalVariance2;
78 results_.additionalResults["totalBasketVariance"] = variances.totalBasketVariance;
79
80 Real variance1 = variances.totalVariance1;
81 Real variance2 = variances.totalVariance2;
82 Real basketVariance = variances.totalBasketVariance;
83 results_.variance1 = variance1;
84 results_.variance2 = variance2;
85 results_.basketVariance = basketVariance;
86
87 Real strike1 = arguments_.strike1 * arguments_.strike1;
88 Real strike2 = arguments_.strike2 * arguments_.strike2;
89 Real basketStrike = arguments_.basketStrike * arguments_.basketStrike;
90
91 if (!QuantLib::close_enough(arguments_.floor, 0.0)) {
92 Real floor = arguments_.floor * arguments_.floor;
93 variance1 = std::max(floor * strike1, variance1);
94 variance2 = std::max(floor * strike2, variance2);
95 basketVariance = std::max(floor * basketStrike, basketVariance);
96 }
97
98 if (!QuantLib::close_enough(arguments_.cap, 0.0)) {
99 Real cap = arguments_.cap * arguments_.cap;
100 variance1 = std::min(cap * strike1, variance1);
101 variance2 = std::min(cap * strike2, variance2);
102 basketVariance = std::min(cap * basketStrike, basketVariance);
103 }
104
105 results_.finalVariance1 = variance1;
106 results_.finalVariance2 = variance2;
107 results_.finalBasketVariance = basketVariance;
108 results_.additionalResults["finalVariance1"] = variance1;
109 results_.additionalResults["finalVariance2"] = variance2;
110 results_.additionalResults["finalBasketVariance"] = basketVariance;
111
112 Real currentNotional1 = 10000.0 * arguments_.notional1 / (2.0 * 100.0 * arguments_.strike1);
113 Real currentNotional2 = 10000.0 * arguments_.notional2 / (2.0 * 100.0 * arguments_.strike2);
114 Real currentBasketNotional = 10000.0 * arguments_.basketNotional / (2.0 * 100.0 * arguments_.basketStrike);
115
116 results_.additionalResults["varianceAmount1"] = currentNotional1;
117 results_.additionalResults["varianceAmount2"] = currentNotional2;
118 results_.additionalResults["basketVarianceAmount"] = currentBasketNotional;
119
120 Real equityAmount1 = currentNotional1 * (variance1 - strike1);
121 Real equityAmount2 = currentNotional2 * (variance2 - strike2);
122 Real equityAmountBasket = currentBasketNotional * (basketVariance - basketStrike);
123
124 results_.equityAmount1 = equityAmount1;
125 results_.equityAmount2 = equityAmount2;
126 results_.equityAmountBasket = equityAmountBasket;
127 results_.additionalResults["equityAmount1"] = equityAmount1;
128 results_.additionalResults["equityAmount2"] = equityAmount2;
129 results_.additionalResults["equityAmountBasket"] = equityAmountBasket;
130
131 Real pairwiseEquityAmount = equityAmount1 + equityAmount2 + equityAmountBasket;
132
133 results_.pairwiseEquityAmount = pairwiseEquityAmount;
134
135 if (!QuantLib::close_enough(arguments_.payoffLimit, 0.0)) {
136 Real equityAmountCap =
137 arguments_.payoffLimit * (std::abs(arguments_.notional1) + std::abs(arguments_.notional2));
138 Real equityAmountFloor = -1.0 * equityAmountCap;
139 pairwiseEquityAmount = std::max(equityAmountFloor, pairwiseEquityAmount);
140 pairwiseEquityAmount = std::min(equityAmountCap, pairwiseEquityAmount);
141 }
142
143 results_.finalEquityAmount = pairwiseEquityAmount;
144 results_.additionalResults["finalEquityAmount"] = pairwiseEquityAmount;
145
146 Real multiplier = arguments_.position == Position::Long ? 1.0 : -1.0;
147 DiscountFactor df = discountingTS_->discount(arguments_.settlementDate);
148
149 results_.value = multiplier * df * pairwiseEquityAmount;
150}
const Instrument::results * results_
Definition: cdsoption.cpp:81
Variances calculateVariances(const Schedule &valuationSchedule, const Schedule &laggedValuationSchedule, const Date &evalDate) const
Swap::arguments * arguments_
+ Here is the call graph for this function:

◆ calculateVariances()

Variances calculateVariances ( const Schedule &  valuationSchedule,
const Schedule &  laggedValuationSchedule,
const Date &  evalDate 
) const
protected

Definition at line 152 of file pairwisevarianceswapengine.cpp.

154 {
155
156 const Date& accrStartDate = valuationSchedule.dates().back();
157 const Date& accrEndDate = laggedValuationSchedule.dates().back();
158
159 Variances res;
160
161 for (Size i = 0; i < valuationSchedule.size(); i++) {
162 const Date& vd = valuationSchedule.dates()[i];
163 const Date& lvd = laggedValuationSchedule.dates()[i];
164
165 // Calculate accrued (squared) variations, i.e. both val date and lagged val date are known
166 if (lvd <= evalDate) {
167 Real price1 = index1_->fixing(vd);
168 Real laggedPrice1 = index1_->fixing(lvd);
169 Real variation1 = std::log(laggedPrice1 / price1);
170 res.accruedVariance1 += variation1 * variation1;
171
172 Real price2 = index2_->fixing(vd);
173 Real laggedPrice2 = index2_->fixing(lvd);
174 Real variation2 = std::log(laggedPrice2 / price2);
175 res.accruedVariance2 += variation2 * variation2;
176
177 Real basketPrice = price1 + price2;
178 Real laggedBasketPrice = laggedPrice1 + laggedPrice2;
179 Real basketVariation = std::log(laggedBasketPrice / basketPrice);
180 res.accruedBasketVariance += basketVariation * basketVariation;
181 } else {
182 // At this point, all variation contributions have been accrued, so now calculate the accrued variance
183 Real expectedN = valuationSchedule.dates().size() - 1.0;
184 Real factor = 252 / (expectedN * arguments_.accrualLag);
185 res.accruedVariance1 *= factor;
186 res.accruedVariance2 *= factor;
187 res.accruedBasketVariance *= factor;
188
189 // Calculate future variance
190 Real t = ActualActual(ActualActual::ISDA).yearFraction(evalDate, accrEndDate);
191 Real F1 =
192 process1_->x0() / process1_->riskFreeRate()->discount(t) * process1_->dividendYield()->discount(t);
193 Real F2 =
194 process2_->x0() / process2_->riskFreeRate()->discount(t) * process2_->dividendYield()->discount(t);
195
196 Real variance1 = process1_->blackVolatility()->blackVariance(t, F1);
197 Real variance2 = process2_->blackVolatility()->blackVariance(t, F2);
198 Real basketVariance =
199 variance1 + variance2 + 2.0 * std::sqrt(variance1) * std::sqrt(variance2) * correlation_->value();
200
201 res.futureVariance1 = variance1;
202 res.futureVariance2 = variance2;
203 res.futureBasketVariance = basketVariance;
204 break;
205 }
206 }
207
208 Calendar jointCal =
209 JointCalendar(std::vector<Calendar>{valuationSchedule.calendar(), laggedValuationSchedule.calendar(),
210 index1_->fixingCalendar(), index2_->fixingCalendar()});
211 Real accrTime = std::abs(jointCal.businessDaysBetween(accrStartDate, evalDate, true, true));
212 Real futTime = std::abs(jointCal.businessDaysBetween(evalDate, accrEndDate, true, false));
213 Real totalTime = accrTime + futTime;
214 Real accrFactor = accrTime / totalTime;
215 Real futFactor = futTime / totalTime;
216
217 res.totalVariance1 = (res.accruedVariance1 * accrFactor) + (res.futureVariance1 * futFactor);
218 res.totalVariance2 = (res.accruedVariance2 * accrFactor) + (res.futureVariance2 * futFactor);
219 res.totalBasketVariance = (res.accruedBasketVariance * accrFactor) + (res.futureBasketVariance * futFactor);
220
221 return res;
222}
+ Here is the caller graph for this function:

Member Data Documentation

◆ index1_

QuantLib::ext::shared_ptr<Index> index1_
protected

Definition at line 78 of file pairwisevarianceswapengine.hpp.

◆ index2_

QuantLib::ext::shared_ptr<Index> index2_
protected

Definition at line 79 of file pairwisevarianceswapengine.hpp.

◆ process1_

QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> process1_
protected

Definition at line 80 of file pairwisevarianceswapengine.hpp.

◆ process2_

QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> process2_
protected

Definition at line 81 of file pairwisevarianceswapengine.hpp.

◆ discountingTS_

Handle<YieldTermStructure> discountingTS_
protected

Definition at line 82 of file pairwisevarianceswapengine.hpp.

◆ correlation_

Handle<Quote> correlation_
protected

Definition at line 83 of file pairwisevarianceswapengine.hpp.