113 {
114
115
116
117 BOOST_TEST_MESSAGE("Testing martingale property in the COM Schwartz model ...");
118
120 QuantLib::ext::shared_ptr<StochasticProcess> process = data.model->stateProcess();
121 QL_REQUIRE(process != NULL, "process has null pointer!");
122
123 Size n = 100000;
124 Size seed = 42;
125 Time t = 10.0;
126 Time T = 20.0;
127
128
129 TimeGrid grid(t,
steps);
130 LowDiscrepancy::rsg_type sg = LowDiscrepancy::make_sequence_generator(
steps, seed);
131 MultiPathGenerator<LowDiscrepancy::rsg_type> pg(process, grid, sg, false);
132
133
134 accumulator_set<double, stats<tag::mean, tag::variance, tag::error_of<tag::mean>>> acc_price, acc_state;
135
136 Array state(1);
137 for (Size j = 0; j < n; ++j) {
138 Sample<MultiPath> path = pg.next();
139 Size l = path.value[0].length() - 1;
140 state[0] = path.value[0][l];
141 Real price = data.model->forwardPrice(t, T, state);
142 acc_price(price);
143 acc_state(state[0]);
144 }
145
146 BOOST_TEST_MESSAGE("sigma = " << data.model->parametrization()->sigmaParameter());
147 BOOST_TEST_MESSAGE("kappa = " << data.model->parametrization()->kappaParameter());
148 BOOST_TEST_MESSAGE("samples = " << n);
149 BOOST_TEST_MESSAGE(
"steps = " <<
steps);
150 BOOST_TEST_MESSAGE("t = " << t);
151 BOOST_TEST_MESSAGE("T = " << T);
152
153
154 {
155 Real found = mean(acc_price);
156 Real expected = data.parametrization->priceCurve()->price(T);
157 Real error = error_of<tag::mean>(acc_price);
158
159 BOOST_TEST_MESSAGE("Check that E[F(t,T)] = F(0,T)");
160 BOOST_TEST_MESSAGE("Avg = " << found
161 << " +- " << error
162 << " vs expected " << expected);
163 BOOST_TEST(fabs(found - expected) < error, "Martingale test failed for F(t,T) evolution, found " << found << ", expected " << expected);
164 }
165
166
167 {
168 Real found = mean(acc_state);
169 Real expected = 0;
170 Real error = error_of<tag::mean>(acc_state);
171
172 BOOST_TEST_MESSAGE("Check that the mean of the state variable is zero");
173 BOOST_TEST_MESSAGE("Avg = " << found
174 << " +- " << error_of<tag::mean>(acc_state)
175 << " vs expected " << expected);
176 BOOST_TEST(fabs(found - expected) < error, "Martingale test failed for the state variable, found " << found << ", expected " << expected);
177 }
178
179
180 {
182 Real expected = data.parametrization->variance(t);
183
184 Real error = error_of<tag::mean>(acc_state);
185
186 QuantLib::ext::shared_ptr<CommoditySchwartzStateProcess> stateProcess = QuantLib::ext::dynamic_pointer_cast<CommoditySchwartzStateProcess>(process);
187 QL_REQUIRE(stateProcess, "state process is null");
188 Real expected2 = stateProcess->variance(0.0, 0.0, t);
189
190
191 BOOST_TEST(fabs(expected - expected2) < 1e-10, "Inconsistent state variable variance " << expected << " vs " << expected2);
192
193 BOOST_TEST_MESSAGE("Check that the variance of the state variable matches expectation");
194 BOOST_TEST_MESSAGE("Var = " << found
195 << " +- " << error
196 << " vs expected " << expected);
197 BOOST_TEST(fabs(found - expected2) < error,
198 "Simulated variance of the state variable does match expectation, found " << found << ", expected " << expected);
199
200 }
201
202}
RandomVariable variance(const RandomVariable &r)
std::vector< bool > driftFreeState
std::vector< Size > steps