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>
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>
41using namespace boost::unit_test_framework;
51 BOOST_TEST_MESSAGE(
"Testing equity forward stripper with European Option prices");
55 Settings::instance().evaluationDate() = Date(24, Apr, 2019);
56 Date today = Settings::instance().evaluationDate();
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" });
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,
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 });
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 });
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])));
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());
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 });
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 });
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])));
270 Handle<YieldTermStructure> forecastCurve(
271 QuantLib::ext::make_shared<InterpolatedDiscountCurve>(forecastTimes, forecastQuotes, 0, TARGET(), Actual365Fixed()));
274 Handle<Quote> equitySpot = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(3502.63));
277 QuantLib::ext::shared_ptr<QuantExt::EquityForwardCurveStripper> efcs =
278 QuantLib::ext::make_shared<QuantExt::EquityForwardCurveStripper>(callSurface, putSurface, forecastCurve, equitySpot,
279 Exercise::Type::European);
282 vector<Date> forwardExpiries = efcs->expiries();
283 vector<Real> forwardQuotes = efcs->forwards();
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 });
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);
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 });
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);
311 BOOST_CHECK_CLOSE(forwardQuotes[j], futureQuotes[i], tolerance);
316 BOOST_TEST_MESSAGE(
"Testing stripper with American Option prices");
318 SavedSettings backup;
320 Settings::instance().evaluationDate() = Date(24, Apr, 2019);
321 Date today = Settings::instance().evaluationDate();
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" });
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 });
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 });
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 });
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])));
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());
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 });
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 });
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])));
430 Handle<YieldTermStructure> forecastCurve(
431 QuantLib::ext::make_shared<InterpolatedDiscountCurve>(forecastTimes, forecastQuotes, 0, TARGET(), Actual365Fixed()));
434 Handle<Quote> equitySpot = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(211.95));
437 QuantLib::ext::shared_ptr<QuantExt::EquityForwardCurveStripper> efcs =
438 QuantLib::ext::make_shared<QuantExt::EquityForwardCurveStripper>(callSurface, putSurface, forecastCurve, equitySpot,
439 Exercise::Type::American);
442 vector<Date> forwardExpiries = efcs->expiries();
443 vector<Real> forwardQuotes = efcs->forwards();
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 });
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);
459BOOST_AUTO_TEST_SUITE_END()
461BOOST_AUTO_TEST_SUITE_END()
Imply equity forwards from option put/call parity.
interpolated discount term structure
BOOST_AUTO_TEST_CASE(testEquityForwardCurveStripperEuropean)
Fixture that can be used at top level.