Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
equityforwardcurvestripper.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include "toplevelfixture.hpp"
20#include <boost/algorithm/string.hpp>
21#include <boost/lexical_cast.hpp>
22#include <boost/make_shared.hpp>
23#include <boost/test/unit_test.hpp>
24#include <ql/quotes/simplequote.hpp>
25#include <ql/time/calendars/target.hpp>
26#include <ql/time/daycounters/actual365fixed.hpp>
29
30#include <ql/instruments/vanillaoption.hpp>
31#include <ql/pricingengines/vanilla/baroneadesiwhaleyengine.hpp>
32#include <ql/pricingengines/vanilla/fdblackscholesvanillaengine.hpp>
33#include <ql/processes/blackscholesprocess.hpp>
34#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
35#include <ql/termstructures/yield/flatforward.hpp>
36#include <ql/time/calendars/nullcalendar.hpp>
37#include <ql/time/daycounters/actual360.hpp>
38
39#include <chrono>
40
41using namespace boost::unit_test_framework;
42using namespace QuantLib;
43using namespace QuantExt;
44using namespace std;
45
46BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, qle::test::TopLevelFixture)
47
48BOOST_AUTO_TEST_SUITE(EquityForwardCurveStripper)
49
50BOOST_AUTO_TEST_CASE(testEquityForwardCurveStripperEuropean) {
51 BOOST_TEST_MESSAGE("Testing equity forward stripper with European Option prices");
52
53 SavedSettings backup;
54
55 Settings::instance().evaluationDate() = Date(24, Apr, 2019);
56 Date today = Settings::instance().evaluationDate();
57
58 // Market Date with Options premiums for .STOX50E from 24th April 2019, on EUREX exchange
59 vector<string> dates(
60 { "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
61 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
62 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
63 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
64 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
65 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
66 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
67 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
68 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
69 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
70 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
71 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
72 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
73 "2019-06-21", "2019-06-21", "2019-06-21", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
74 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
75 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
76 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
77 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
78 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
79 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
80 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
81 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
82 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
83 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
84 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
85 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
86 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
87 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
88 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
89 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
90 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
91 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
92 "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16", "2019-08-16",
93 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
94 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
95 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
96 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
97 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
98 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
99 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
100 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
101 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
102 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
103 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
104 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-10-18", "2019-10-18", "2019-10-18",
105 "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18",
106 "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18",
107 "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18",
108 "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-10-18", "2019-12-20", "2019-12-20",
109 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
110 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
111 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
112 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
113 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
114 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
115 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
116 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
117 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
118 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
119 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
120 "2019-12-20", "2019-12-20", "2019-12-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
121 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
122 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
123 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
124 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
125 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
126 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
127 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
128 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
129 "2020-03-20", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19" });
130
131 vector<Real> strikes(
132 { 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2050, 2100,
133 2150, 2200, 2250, 2300, 2350, 2400, 2450, 2500, 2550, 2575, 2600, 2625, 2650, 2675, 2700, 2725, 2750, 2775,
134 2800, 2825, 2850, 2875, 2900, 2925, 2950, 2975, 3000, 3025, 3050, 3075, 3100, 3125, 3150, 3175, 3200, 3225,
135 3250, 3275, 3300, 3325, 3350, 3375, 3400, 3425, 3450, 3475, 3500, 3525, 3550, 3575, 3600, 3625, 3650, 3675,
136 3700, 3725, 3750, 3775, 3800, 3825, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350, 4400,
137 4600, 5000, 6000, 10000, 1700, 1800, 1900, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2325, 2350, 2375, 2400,
138 2425, 2450, 2475, 2500, 2525, 2550, 2575, 2600, 2625, 2650, 2675, 2700, 2725, 2750, 2775, 2800, 2825, 2850,
139 2875, 2900, 2925, 2950, 2975, 3000, 3025, 3050, 3075, 3100, 3125, 3150, 3175, 3200, 3225, 3250, 3275, 3300,
140 3325, 3350, 3375, 3400, 3425, 3450, 3475, 3500, 3525, 3550, 3575, 3600, 3625, 3650, 3675, 3700, 3725, 3750,
141 3775, 3800, 3825, 3850, 3900, 4000, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2350, 2400, 2450, 2500,
142 2550, 2600, 2625, 2650, 2675, 2700, 2750, 2800, 2850, 2900, 2925, 2950, 2975, 3000, 3025, 3050, 3075, 3100,
143 3125, 3150, 3175, 3200, 3225, 3250, 3275, 3300, 3325, 3350, 3375, 3400, 3425, 3450, 3475, 3500, 3525, 3550,
144 3575, 3600, 3625, 3650, 3675, 3700, 3725, 3750, 3775, 3800, 3825, 3850, 3900, 4000, 4100, 500, 600, 800,
145 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200,
146 2250, 2300, 2350, 2400, 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 2950, 2975, 3000, 3025,
147 3050, 3075, 3100, 3125, 3150, 3175, 3200, 3225, 3250, 3275, 3300, 3325, 3350, 3375, 3400, 3425, 3450, 3475,
148 3500, 3525, 3550, 3575, 3600, 3625, 3650, 3675, 3700, 3725, 3750, 3775, 3800, 3825, 3850, 3900, 3950, 4000,
149 4050, 4100, 4200, 4250, 6000, 10000, 3150, 3175, 3200, 3225, 3250, 3275, 3300, 3325, 3350, 3375, 3400, 3425,
150 3450, 3475, 3500, 3525, 3550, 3575, 3600, 3625, 3650, 3675, 3700, 3725, 3750, 3775, 3800, 3825, 3850, 250,
151 500, 600, 700, 800, 900, 1000, 1200, 1300, 1400, 1450, 1500, 1600, 1650, 1700, 1750, 1800, 1850, 1900,
152 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400, 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800,
153 2850, 2900, 2925, 2950, 3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450, 3500, 3550, 3600, 3650,
154 3700, 3750, 3775, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4250, 4300, 4350, 4400, 4500, 4600,
155 4700, 4800, 5000, 5200, 5400, 5600, 5800, 6000, 10000, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700,
156 1800, 1900, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400, 2450, 2500, 2550, 2600, 2650, 2700, 2750,
157 2800, 2850, 2900, 2950, 3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450, 3500, 3550, 3600, 3650,
158 3700, 3750, 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, 4200, 4300, 4400, 4500, 4600, 4700, 500, 600,
159 800, 900, 1000 });
160
161 vector<Real> callPremiums(
162 { 2932.9, 2832.8, 2732.8, 2632.7, 2532.7, 2432.6, 2332.5, 2232.5, 2132.4, 2032.3, 1932.3, 1832.2, 1732.2,
163 1632.2, 1532.1, 1432.1, 1382.1, 1332.1, 1282.1, 1232.1, 1182.2, 1132.2, 1082.2, 1032.3, 982.3, 932.4,
164 882.5, 857.6, 832.6, 807.7, 782.8, 757.9, 733, 708.1, 683.2, 658.4, 633.6, 608.8, 584,
165 559.2, 534.5, 509.9, 485.3, 460.7, 436.2, 411.8, 387.5, 363.3, 339.3, 315.4, 291.7, 268.2,
166 245.1, 222.4, 200.1, 178.4, 157.3, 137.1, 117.7, 99.4, 82.5, 67, 53.2, 41.3, 31.1,
167 22.7, 16.2, 11.3, 7.6, 5.1, 3.3, 2.2, 1.4, 1, 0.7, 0.5, 0.3, 0.2,
168 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
169 0.1, 0.1, 0.1, 1728.8, 1628.8, 1528.7, 1428.8, 1378.8, 1328.8, 1278.9, 1228.9, 1179, 1129.1,
170 1104.1, 1079.2, 1054.3, 1029.3, 1004.4, 979.5, 954.6, 929.7, 904.8, 879.9, 855.1, 830.2, 805.4,
171 780.6, 755.9, 731.1, 706.4, 681.8, 657.1, 632.5, 608, 583.5, 559.1, 534.7, 510.4, 486.2,
172 462.1, 438.1, 414.3, 390.6, 367, 343.7, 320.6, 297.8, 275.3, 253.3, 231.7, 210.6, 190.1,
173 170.2, 151, 132.7, 115.4, 99.2, 84.1, 70.4, 58.1, 47.2, 37.7, 29.7, 23.1, 17.7,
174 13.5, 10.2, 7.6, 5.6, 4.2, 3.1, 2.3, 1.7, 1.3, 1, 0.7, 0.3, 1824.7,
175 1724.7, 1624.7, 1524.7, 1424.8, 1324.9, 1225.1, 1125.5, 1075.7, 1026, 976.4, 926.8, 877.4, 828,
176 803.4, 778.8, 754.3, 729.8, 680.9, 632.3, 583.9, 536, 512.1, 488.4, 464.8, 441.4, 418.2,
177 395.1, 372.2, 349.6, 327.3, 305.3, 283.7, 262.5, 241.7, 221.4, 201.6, 182.4, 163.8, 146.1,
178 129.3, 113.3, 98.4, 84.7, 72.2, 60.9, 50.8, 42, 34.4, 27.8, 22.3, 17.7, 14,
179 11, 8.6, 6.7, 5.2, 4.1, 3.2, 2.5, 1.6, 0.6, 0.3, 2924.7, 2824.5, 2624.2,
180 2524, 2423.9, 2323.7, 2223.6, 2123.5, 2023.4, 1923.4, 1823.3, 1723.3, 1623.4, 1573.4, 1523.5, 1473.6,
181 1423.7, 1373.9, 1324.1, 1274.3, 1224.6, 1174.9, 1125.3, 1075.8, 1026.4, 977, 927.8, 878.8, 829.9,
182 781.2, 732.8, 684.6, 636.8, 589.3, 542.2, 495.7, 472.6, 449.8, 427.1, 404.6, 382.4, 360.4,
183 338.8, 317.4, 296.4, 275.7, 255.5, 235.8, 216.7, 198.2, 180.4, 163.3, 147, 131.4, 116.7,
184 102.9, 90, 78, 67.1, 57.4, 48.8, 41.1, 34.4, 28.5, 23.4, 19.1, 15.5, 12.5,
185 10.1, 8.2, 6.6, 5.3, 3.5, 2.3, 1.5, 1, 0.7, 0.4, 0.3, 0.1, 0.1,
186 320.1, 299.8, 279.9, 260.4, 241.4, 222.9, 205, 187.6, 170.9, 154.9, 139.7, 125, 111.4,
187 98.6, 86.8, 76, 66.2, 57.2, 49.2, 42.1, 35.7, 30.1, 25.3, 21.1, 17.5, 14.5,
188 11.9, 9.8, 8, 3162.7, 2912, 2811.8, 2711.6, 2611.3, 2511.1, 2411, 2210.7, 2110.6, 2010.6,
189 1960.6, 1910.6, 1810.7, 1760.8, 1710.9, 1661.1, 1611.3, 1561.5, 1511.8, 1462.1, 1412.5, 1362.9, 1313.4,
190 1264, 1214.7, 1165.6, 1116.5, 1067.6, 1018.8, 970.2, 921.8, 873.6, 825.8, 778.2, 730.9, 684.1,
191 637.7, 591.9, 546.7, 524.3, 502.2, 458.5, 415.7, 374, 333.8, 295.1, 258, 223.1, 190.2,
192 159.7, 132.2, 107.6, 86.2, 67.8, 52.4, 39.7, 29.5, 25.3, 21.6, 15.7, 11.3, 8.1,
193 5.8, 4.2, 3.1, 2.2, 1.6, 1.2, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.1,
194 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 2499.7, 2399.5, 2299.3, 2199.2, 2099.3, 1999.4,
195 1899.6, 1800, 1700.6, 1601.3, 1502.3, 1403.5, 1354.3, 1305.2, 1256.1, 1207.2, 1158.4, 1109.9, 1061.5,
196 1013.4, 965.5, 918, 870.7, 823.8, 777.2, 731.1, 685.5, 640.5, 596, 552.3, 509.5, 467.5,
197 426.6, 386.9, 348.4, 311.7, 276.5, 242.8, 211.4, 182, 155.1, 130.6, 108.7, 89.5, 72.6,
198 58.2, 46.1, 36, 27.9, 21.4, 16.3, 12.4, 9.4, 7.1, 5.4, 4.1, 2.4, 1.4,
199 0.9, 0.6, 0.4, 2822, 2721.7, 2521.1, 2420.9, 2320.8 });
200
201 vector<Real> putPremiums(
202 { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
203 0.1, 0.1, 0.2, 0.2, 0.2, 0.3, 0.3, 0.4, 0.5, 0.5, 0.6, 0.7, 0.8,
204 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2, 2.2, 2.4, 2.6,
205 2.9, 3.2, 3.5, 3.9, 4.4, 4.9, 5.5, 6.2, 7.1, 8, 9.2, 10.5, 12,
206 13.9, 16.2, 19, 22.3, 26.3, 31, 36.7, 43.4, 51.4, 61, 72.3, 85.3, 100.1,
207 116.8, 135.2, 155.4, 176.8, 199.2, 222.4, 246.3, 270.6, 295.2, 319.9, 344.7, 369.6, 394.5,
208 419.5, 469.4, 519.4, 569.4, 619.4, 669.4, 719.5, 769.5, 819.5, 869.6, 919.6, 969.6, 1169.8,
209 1570, 2570.7, 6573.3, 0.2, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
210 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 2, 2.1, 2.3, 2.5, 2.7,
211 2.9, 3.2, 3.5, 3.8, 4.1, 4.5, 5, 5.4, 6, 6.6, 7.2, 8, 8.8,
212 9.7, 10.8, 11.9, 13.2, 14.7, 16.4, 18.3, 20.6, 23.1, 26.1, 29.5, 33.5, 38,
213 43.1, 49, 55.7, 63.4, 72.2, 82.2, 93.5, 106.2, 120.3, 135.8, 152.9, 171.3, 190.9,
214 211.7, 233.4, 255.9, 278.9, 302.5, 326.4, 350.7, 375.1, 399.7, 424.5, 474.2, 573.9, 0.2,
215 0.3, 0.5, 0.6, 0.9, 1.1, 1.5, 1.9, 2.2, 2.6, 3, 3.5, 4.1, 4.9,
216 5.3, 5.7, 6.2, 6.7, 7.9, 9.4, 11.1, 13.2, 14.4, 15.7, 17.1, 18.8, 20.5,
217 22.5, 24.7, 27.1, 29.8, 32.9, 36.3, 40.1, 44.3, 49, 54.3, 60.1, 66.6, 73.9,
218 82.1, 91.2, 101.3, 112.6, 125.1, 138.9, 153.9, 170.1, 187.4, 205.9, 225.4, 245.9, 267.2,
219 289.2, 311.9, 335, 358.6, 382.5, 406.6, 430.9, 480.1, 579.3, 679.1, 0.1, 0.1, 0.1,
220 0.1, 0.1, 0.1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 0.9, 1, 1.2, 1.4,
221 1.6, 1.8, 2.1, 2.4, 2.7, 3.2, 3.6, 4.2, 4.9, 5.6, 6.5, 7.6, 8.8,
222 10.2, 11.8, 13.7, 15.9, 18.5, 21.6, 25.1, 27.1, 29.3, 31.6, 34.2, 37, 40.1,
223 43.5, 47.2, 51.2, 55.6, 60.4, 65.8, 71.7, 78.3, 85.5, 93.4, 102.2, 111.7, 121.9,
224 133.2, 145.3, 158.4, 172.6, 187.9, 204.3, 221.7, 239.9, 259.1, 279, 299.8, 321.2, 343.3,
225 365.9, 389, 412.5, 436.3, 484.5, 533.4, 582.7, 632.3, 682.1, 781.9, 831.9, 2584.6, 6591.3,
226 54.6, 59.4, 64.5, 70.1, 76.2, 82.7, 89.8, 97.6, 105.9, 115, 124.7, 135.2, 146.5,
227 158.8, 172.1, 186.3, 201.4, 217.7, 234.7, 252.6, 271.3, 290.8, 311, 331.8, 353.3, 375.3,
228 397.8, 420.7, 444, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.5, 0.6, 0.9,
229 1, 1.2, 1.5, 1.7, 2, 2.3, 2.6, 3, 3.4, 3.8, 4.3, 4.9, 5.5,
230 6.2, 7.1, 8, 9.1, 10.3, 11.6, 13.2, 14.9, 16.9, 19.1, 21.6, 24.5, 27.8,
231 31.6, 35.9, 40.8, 43.5, 46.4, 52.9, 60.2, 68.7, 78.6, 90, 103.1, 118.2, 135.5,
232 155.2, 177.8, 203.3, 232, 263.7, 298.4, 335.9, 375.8, 396.7, 418.1, 462.2, 508, 554.9,
233 602.8, 651.3, 700.3, 749.6, 799.1, 848.8, 898.6, 948.5, 998.5, 1098.6, 1198.7, 1298.9, 1399.1,
234 1599.6, 1800.1, 2000.6, 2201.1, 2401.6, 2602.1, 6612.4, 0.2, 0.3, 0.5, 0.7, 1.1, 1.6,
235 2.2, 2.9, 3.8, 4.9, 6.2, 7.8, 8.7, 9.7, 10.9, 12.1, 13.5, 15.1, 16.9,
236 19, 21.3, 23.9, 26.8, 30.1, 33.7, 37.8, 42.3, 47.4, 53.2, 59.7, 67, 75.2,
237 84.5, 94.9, 106.6, 119.9, 134.9, 151.5, 170.2, 191, 214.3, 240, 268.4, 299.2, 332.5,
238 368.4, 406.3, 446.4, 488.5, 532.2, 577.3, 623.5, 670.6, 718.5, 767, 815.8, 914.5, 1013.9,
239 1113.7, 1213.7, 1313.9, 0.1, 0.1, 0.4, 0.7, 1 });
240
241 vector<Date> expiries;
242 for (Size i = 0; i < dates.size(); i++) {
243 vector<string> tokens;
244 boost::split(tokens, dates[i], boost::is_any_of("-"));
245 expiries.push_back(Date(boost::lexical_cast<Integer>(tokens[2]), Month(boost::lexical_cast<Integer>(tokens[1])),
246 boost::lexical_cast<Integer>(tokens[0])));
247 }
248
249 // build option price surfaces from the market data
250 QuantLib::ext::shared_ptr<OptionPriceSurface> callSurface =
251 QuantLib::ext::make_shared<OptionPriceSurface>(today, expiries, strikes, callPremiums, Actual365Fixed());
252 QuantLib::ext::shared_ptr<OptionPriceSurface> putSurface =
253 QuantLib::ext::make_shared<OptionPriceSurface>(today, expiries, strikes, putPremiums, Actual365Fixed());
254
255 // forecast curve - discount rates taken bootstrapped EUR-EONIA curve on asof date
256 vector<Time> forecastTimes({ 0.00000, 0.00273, 0.03287, 0.05205, 0.07123, 0.09315, 0.17534, 0.26301, 0.34246,
257 0.42739, 0.51506, 0.59452, 0.68493, 0.76438, 0.84657, 0.92602, 1.01369, 1.26301,
258 1.51232, 1.76438, 2.01095, 3.01095, 4.01095, 5.01917, 6.01917, 7.01643, 8.01369,
259 9.01643, 10.0164, 11.0219, 12.0219, 15.0191, 20.0219, 25.0273, 30.0301 });
260
261 vector<Real> forecastValues({ 1.00000, 1.00001, 1.00013, 1.00021, 1.00025, 1.00037, 1.00069, 1.00104, 1.00135,
262 1.00169, 1.00204, 1.00236, 1.00273, 1.00305, 1.00339, 1.00371, 1.00406, 1.00476,
263 1.00566, 1.00652, 1.00720, 1.00937, 1.00987, 1.00824, 1.00418, 0.99821, 0.99160,
264 0.98014, 0.96879, 0.95619, 0.94282, 0.90144, 0.83797, 0.78690, 0.74930 });
265
266 vector<Handle<Quote> > forecastQuotes;
267 for (Size i = 0; i < forecastValues.size(); i++)
268 forecastQuotes.push_back(Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(forecastValues[i])));
269
270 Handle<YieldTermStructure> forecastCurve(
271 QuantLib::ext::make_shared<InterpolatedDiscountCurve>(forecastTimes, forecastQuotes, 0, TARGET(), Actual365Fixed()));
272
273 // equity spot for asof date
274 Handle<Quote> equitySpot = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(3502.63));
275
276 // equity forward stripper
277 QuantLib::ext::shared_ptr<QuantExt::EquityForwardCurveStripper> efcs =
278 QuantLib::ext::make_shared<QuantExt::EquityForwardCurveStripper>(callSurface, putSurface, forecastCurve, equitySpot,
279 Exercise::Type::European);
280
281 // get terms and quotes from the stripper
282 vector<Date> forwardExpiries = efcs->expiries();
283 vector<Real> forwardQuotes = efcs->forwards();
284
285 // expected results
286 vector<Date> expectedExpiries({ Date(21, Jun, 2019), Date(19, Jul, 2019), Date(16, Aug, 2019), Date(20, Sep, 2019),
287 Date(18, Oct, 2019), Date(20, Dec, 2019), Date(20, Mar, 2020),
288 Date(19, Jun, 2020) });
289 vector<Real> expectedQuotes(
290 { 3430.973, 3426.9000, 3422.0999, 3419.7771, 3414.8812, 3404.4913, 3391.0358, 3309.4997 });
291
292 Real tolerance = 1e-3;
293 for (Size i = 0; i < expectedQuotes.size(); i++) {
294 BOOST_CHECK_EQUAL(forwardExpiries[i], expectedExpiries[i]);
295 BOOST_CHECK_CLOSE(forwardQuotes[i], expectedQuotes[i], tolerance);
296 }
297
298 // Compare to Actual Future prices on day
299 // STXE Futures on EUREX from asof data
300 vector<Date> futureExpiries(
301 { Date(21, Jun, 2019), Date(20, Sep, 2019), Date(20, Dec, 2019), Date(20, Mar, 2020), Date(19, Jun, 2020) });
302 vector<Real> futureQuotes({ 3431, 3420, 3404, 3391, 3310 });
303
304 // allow a bigger tolerance - futues quotes have no decimal places
305 tolerance = 1;
306 for (Size i = 0; i < futureQuotes.size(); i++) {
307 vector<Date>::iterator found = find(forwardExpiries.begin(), forwardExpiries.end(), futureExpiries[i]);
308 if (found == forwardExpiries.end())
309 BOOST_TEST_ERROR("Failed to find expiry " << futureExpiries[i] << " in forward expiries.");
310 Size j = distance(forwardExpiries.begin(), found); // index of expiry
311 BOOST_CHECK_CLOSE(forwardQuotes[j], futureQuotes[i], tolerance);
312 }
313}
314
315BOOST_AUTO_TEST_CASE(testEquityForwardCurveStripperAmerican) {
316 BOOST_TEST_MESSAGE("Testing stripper with American Option prices");
317
318 SavedSettings backup;
319
320 Settings::instance().evaluationDate() = Date(24, Apr, 2019);
321 Date today = Settings::instance().evaluationDate();
322
323 // Market Date with Options premiums for ALVG.DE from 24th April 2019, on EUREX exchange
324 vector<string> dates(
325 { "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
326 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
327 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
328 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
329 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21",
330 "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-06-21", "2019-07-19",
331 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
332 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
333 "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19", "2019-07-19",
334 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
335 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
336 "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20", "2019-09-20",
337 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
338 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
339 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
340 "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20", "2019-12-20",
341 "2019-12-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
342 "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20", "2020-03-20",
343 "2020-03-20", "2020-03-20", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19",
344 "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19",
345 "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19", "2020-06-19",
346 "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18",
347 "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18",
348 "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18", "2020-12-18",
349 "2020-12-18", "2021-06-18", "2021-06-18", "2021-06-18", "2021-06-18", "2021-06-18", "2021-06-18",
350 "2021-06-18", "2021-06-18", "2021-12-17", "2021-12-17", "2021-12-17", "2021-12-17", "2021-12-17",
351 "2021-12-17", "2021-12-17", "2021-12-17", "2021-12-17", "2022-12-16", "2022-12-16", "2022-12-16",
352 "2022-12-16", "2022-12-16", "2022-12-16", "2022-12-16", "2022-12-16", "2022-12-16", "2023-12-15",
353 "2023-12-15", "2023-12-15", "2023-12-15", "2023-12-15", "2023-12-15", "2023-12-15", "2023-12-15" });
354
355 vector<Real> strikes(
356 { 84, 92, 100, 120, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 182, 184, 185, 186, 188, 190, 192,
357 194, 195, 196, 198, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260, 280, 320, 360, 182,
358 184, 186, 188, 190, 192, 194, 196, 198, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260,
359 120, 130, 140, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 220, 225, 230, 240, 250,
360 84, 92, 100, 105, 120, 140, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 220, 225,
361 230, 240, 250, 260, 270, 280, 320, 360, 120, 140, 160, 175, 180, 185, 190, 195, 200, 210, 215, 220, 230,
362 240, 250, 100, 120, 140, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 210, 220, 240, 280, 320,
363 84, 92, 100, 120, 140, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 210, 220, 240, 280, 320,
364 360, 120, 140, 160, 180, 200, 240, 280, 320, 100, 120, 140, 160, 180, 200, 240, 280, 320, 100, 120, 140,
365 160, 180, 200, 240, 280, 320, 120, 140, 160, 180, 200, 240, 280, 320 });
366
367 vector<Real> callPremiums(
368 { 127.95, 119.95, 111.95, 91.96, 76.95, 71.96, 66.95, 61.95, 56.96, 51.95, 46.96, 41.96, 36.96, 31.96,
369 29.96, 27.96, 26.96, 25.96, 23.95, 21.96, 19.96, 17.96, 16.97, 15.97, 14, 12.05, 7.41, 3.65,
370 1.44, 0.54, 0.23, 0.12, 0.07, 0.05, 0.03, 0.03, 0.02, 0.02, 0.02, 0.01, 0.01, 29.96,
371 27.95, 25.96, 23.96, 21.96, 19.96, 17.97, 15.99, 14.03, 12.11, 7.62, 4.13, 1.99, 0.96, 0.5,
372 0.27, 0.15, 0.09, 0.06, 0.05, 0.03, 0.03, 91.95, 81.95, 71.95, 61.95, 56.95, 51.95, 46.95,
373 41.96, 36.95, 31.96, 26.96, 21.97, 17.07, 12.42, 8.42, 5.42, 2.15, 1.35, 0.83, 0.32, 0.13,
374 127.96, 119.96, 111.95, 106.96, 91.95, 71.95, 61.95, 56.96, 51.95, 46.96, 41.95, 36.96, 31.96, 26.97,
375 22.09, 17.45, 13.35, 10, 7.44, 3.96, 2.81, 1.96, 0.93, 0.43, 0.21, 0.11, 0.06, 0.01,
376 0.01, 91.96, 71.95, 51.96, 36.95, 31.97, 27.09, 22.45, 18.25, 14.65, 9.29, 7.27, 5.59, 3.18,
377 1.74, 0.93, 111.95, 91.96, 71.95, 61.95, 56.96, 51.96, 46.95, 41.96, 36.95, 31.97, 27.12, 22.61,
378 18.64, 15.31, 10.23, 6.56, 2.36, 0.26, 0.04, 127.96, 119.95, 111.95, 91.95, 71.95, 61.96, 56.95,
379 51.95, 46.95, 41.95, 36.97, 32.06, 27.51, 23.41, 19.85, 16.85, 11.99, 8.25, 3.64, 0.64, 0.14,
380 0.04, 91.96, 71.95, 51.95, 32.17, 18.05, 4.97, 1.19, 0.3, 111.96, 91.96, 71.96, 51.96, 32.41,
381 19.36, 6.31, 1.83, 0.52, 111.96, 91.96, 71.96, 51.96, 32.79, 20.64, 7.92, 2.89, 1.06, 91.96,
382 71.95, 51.95, 32.91, 21.59, 9.23, 3.9, 1.68 });
383
384 vector<Real> putPremiums(
385 { 0.01, 0.01, 0.01, 0.01, 0.04, 0.06, 0.08, 0.11, 0.14, 0.18, 0.23, 0.3, 0.4, 0.56,
386 0.64, 0.75, 0.82, 0.89, 1.06, 1.27, 1.53, 1.86, 2.04, 2.24, 2.73, 3.31, 5.34, 8.33,
387 12.19, 16.63, 21.38, 26.28, 31.23, 36.21, 41.2, 46.2, 51.2, 56.2, 76.2, 116.21, 156.23, 1.08,
388 1.25, 1.46, 1.69, 1.98, 2.32, 2.71, 3.19, 3.74, 4.39, 6.49, 9.36, 12.96, 17.15, 21.71,
389 26.48, 31.37, 36.32, 41.29, 46.28, 51.27, 56.27, 0.15, 0.21, 0.3, 0.43, 0.53, 0.67, 0.85,
390 1.1, 1.45, 1.93, 2.61, 3.54, 4.81, 6.49, 8.67, 11.39, 18.49, 22.68, 27.17, 36.67, 46.5,
391 0.07, 0.11, 0.15, 0.18, 0.29, 0.6, 0.89, 1.1, 1.37, 1.72, 2.16, 2.74, 3.49, 4.45,
392 5.65, 7.15, 8.99, 11.21, 13.88, 20.46, 24.32, 28.49, 37.47, 47, 56.8, 66.72, 76.69, 116.73,
393 156.81, 0.42, 0.9, 2.08, 3.97, 4.91, 6.06, 7.44, 9.09, 11.03, 15.92, 18.93, 22.27, 29.89,
394 38.48, 47.69, 0.34, 0.76, 1.73, 2.59, 3.18, 3.89, 4.72, 5.74, 6.95, 8.37, 10.01, 11.94,
395 14.12, 16.62, 22.52, 29.58, 46.38, 84.9, 124.88, 0.33, 0.46, 0.64, 1.41, 2.94, 4.18, 4.97,
396 5.9, 6.96, 8.2, 9.6, 11.2, 13, 15.02, 17.26, 19.77, 25.53, 32.29, 48.28, 85.71, 125.42,
397 165.52, 2.68, 5.13, 9.43, 16.4, 26.61, 56.53, 93.71, 133.21, 1.72, 3.32, 6.22, 11.09, 18.6,
398 29.11, 58.39, 94.6, 133.63, 3.22, 5.83, 10.08, 16.49, 25.44, 37.06, 67.08, 102.95, 141.53, 8.79,
399 14.28, 21.98, 32.07, 44.5, 75.16, 110.84, 149.06 });
400
401 vector<Date> expiries;
402 for (Size i = 0; i < dates.size(); i++) {
403 vector<string> tokens;
404 boost::split(tokens, dates[i], boost::is_any_of("-"));
405 expiries.push_back(Date(boost::lexical_cast<Integer>(tokens[2]), Month(boost::lexical_cast<Integer>(tokens[1])),
406 boost::lexical_cast<Integer>(tokens[0])));
407 }
408
409 // build option price surfaces from the market data
410 QuantLib::ext::shared_ptr<OptionPriceSurface> callSurface =
411 QuantLib::ext::make_shared<OptionPriceSurface>(today, expiries, strikes, callPremiums, Actual365Fixed());
412 QuantLib::ext::shared_ptr<OptionPriceSurface> putSurface =
413 QuantLib::ext::make_shared<OptionPriceSurface>(today, expiries, strikes, putPremiums, Actual365Fixed());
414
415 // forecast curve - discount rates taken bootstrapped EUR-EONIA curve on asof date
416 vector<Time> forecastTimes({ 0.00000, 0.00273, 0.03287, 0.05205, 0.07123, 0.09315, 0.17534, 0.26301, 0.34246,
417 0.42739, 0.51506, 0.59452, 0.68493, 0.76438, 0.84657, 0.92602, 1.01369, 1.26301,
418 1.51232, 1.76438, 2.01095, 3.01095, 4.01095, 5.01917, 6.01917, 7.01643, 8.01369,
419 9.01643, 10.0164, 11.0219, 12.0219, 15.0191, 20.0219, 25.0273, 30.0301 });
420
421 vector<Real> forecastValues({ 1.00000, 1.00001, 1.00013, 1.00021, 1.00025, 1.00037, 1.00069, 1.00104, 1.00135,
422 1.00169, 1.00204, 1.00236, 1.00273, 1.00305, 1.00339, 1.00371, 1.00406, 1.00476,
423 1.00566, 1.00652, 1.00720, 1.00937, 1.00987, 1.00824, 1.00418, 0.99821, 0.99160,
424 0.98014, 0.96879, 0.95619, 0.94282, 0.90144, 0.83797, 0.78690, 0.74930 });
425
426 vector<Handle<Quote> > forecastQuotes;
427 for (Size i = 0; i < forecastValues.size(); i++)
428 forecastQuotes.push_back(Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(forecastValues[i])));
429
430 Handle<YieldTermStructure> forecastCurve(
431 QuantLib::ext::make_shared<InterpolatedDiscountCurve>(forecastTimes, forecastQuotes, 0, TARGET(), Actual365Fixed()));
432
433 // equity spot for asof date
434 Handle<Quote> equitySpot = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(211.95));
435
436 // equity forward stripper
437 QuantLib::ext::shared_ptr<QuantExt::EquityForwardCurveStripper> efcs =
438 QuantLib::ext::make_shared<QuantExt::EquityForwardCurveStripper>(callSurface, putSurface, forecastCurve, equitySpot,
439 Exercise::Type::American);
440
441 // get terms and quotes from the stripper
442 vector<Date> forwardExpiries = efcs->expiries();
443 vector<Real> forwardQuotes = efcs->forwards();
444
445 // expected results
446 vector<Date> expectedExpiries({ Date(21, Jun, 2019), Date(19, Jul, 2019), Date(20, Sep, 2019), Date(20, Dec, 2019),
447 Date(20, Mar, 2020), Date(19, Jun, 2020), Date(18, Dec, 2020), Date(18, Jun, 2021),
448 Date(17, Dec, 2021), Date(16, Dec, 2022), Date(15, Dec, 2023) });
449 vector<Real> expectedQuotes({ 205.2629, 204.4040, 203.0444, 202.0064, 201.6156, 195.2973, 193.2561, 186.5055,
450 184.5692, 176.6890, 169.6185 });
451
452 Real tolerance = 1e-3;
453 for (Size i = 0; i < expectedQuotes.size(); i++) {
454 BOOST_CHECK_EQUAL(forwardExpiries[i], expectedExpiries[i]);
455 BOOST_CHECK_CLOSE(forwardQuotes[i], expectedQuotes[i], tolerance);
456 }
457}
458
459BOOST_AUTO_TEST_SUITE_END()
460
461BOOST_AUTO_TEST_SUITE_END()
Imply equity forwards from option put/call parity.
interpolated discount term structure
vector< Real > strikes
BOOST_AUTO_TEST_CASE(testEquityForwardCurveStripperEuropean)
Fixture that can be used at top level.