QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
mcvarianceswapengine.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Warren Chou
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 <http://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
24#ifndef quantlib_mc_varianceswap_engine_hpp
25#define quantlib_mc_varianceswap_engine_hpp
26
27#include <ql/instruments/varianceswap.hpp>
28#include <ql/math/integrals/segmentintegral.hpp>
29#include <ql/pricingengines/mcsimulation.hpp>
30#include <ql/processes/blackscholesprocess.hpp>
31#include <utility>
32
33namespace QuantLib {
34
36
47 template <class RNG = PseudoRandom, class S = Statistics>
49 public McSimulation<SingleVariate,RNG,S> {
50 public:
51 typedef
54 typedef
59 // constructor
60 MCVarianceSwapEngine(ext::shared_ptr<GeneralizedBlackScholesProcess> process,
61 Size timeSteps,
62 Size timeStepsPerYear,
63 bool brownianBridge,
64 bool antitheticVariate,
65 Size requiredSamples,
66 Real requiredTolerance,
67 Size maxSamples,
68 BigNatural seed);
69 // calculate variance via Monte Carlo
70 void calculate() const override {
75 this->mcModel_->sampleAccumulator().mean();
76
77 DiscountFactor riskFreeDiscount =
78 process_->riskFreeRate()->discount(arguments_.maturityDate);
79 Real multiplier;
80 switch (arguments_.position) {
81 case Position::Long:
82 multiplier = 1.0;
83 break;
84 case Position::Short:
85 multiplier = -1.0;
86 break;
87 default:
88 QL_FAIL("Unknown position");
89 }
90 multiplier *= riskFreeDiscount * arguments_.notional;
91
93 multiplier * (results_.variance - arguments_.strike);
94
95 if (RNG::allowsErrorEstimate) {
96 Real varianceError =
97 this->mcModel_->sampleAccumulator().errorEstimate();
98 results_.errorEstimate = multiplier * varianceError;
99 }
100 }
101
102 protected:
103 // McSimulation implementation
104 ext::shared_ptr<path_pricer_type> pathPricer() const override;
105 TimeGrid timeGrid() const override;
106
107 ext::shared_ptr<path_generator_type> pathGenerator() const override {
108
109 Size dimensions = process_->factors();
110
111 TimeGrid grid = timeGrid();
112 typename RNG::rsg_type gen =
113 RNG::make_sequence_generator(dimensions*(grid.size()-1),seed_);
114
115 return ext::shared_ptr<path_generator_type>(
116 new path_generator_type(process_, grid, gen,
118 }
119 // data members
120 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
126 };
127
128
130 template <class RNG = PseudoRandom, class S = Statistics>
132 public:
133 MakeMCVarianceSwapEngine(ext::shared_ptr<GeneralizedBlackScholesProcess> process);
134 // named parameters
143 // conversion to pricing engine
144 operator ext::shared_ptr<PricingEngine>() const;
145 private:
146 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
147 bool antithetic_ = false;
150 bool brownianBridge_ = false;
152 };
153
154 class VariancePathPricer : public PathPricer<Path> {
155 public:
156 VariancePathPricer(ext::shared_ptr<GeneralizedBlackScholesProcess> process)
157 : process_(std::move(process)) {}
158 Real operator()(const Path& path) const override;
159
160 private:
161 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
162 };
163
164 // inline definitions
165
166 template <class RNG, class S>
168 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
169 Size timeSteps,
170 Size timeStepsPerYear,
171 bool brownianBridge,
172 bool antitheticVariate,
173 Size requiredSamples,
174 Real requiredTolerance,
175 Size maxSamples,
176 BigNatural seed)
177 : McSimulation<SingleVariate, RNG, S>(antitheticVariate, false), process_(std::move(process)),
178 timeSteps_(timeSteps), timeStepsPerYear_(timeStepsPerYear), requiredSamples_(requiredSamples),
179 maxSamples_(maxSamples), requiredTolerance_(requiredTolerance),
180 brownianBridge_(brownianBridge), seed_(seed) {
181 QL_REQUIRE(timeSteps != Null<Size>() ||
182 timeStepsPerYear != Null<Size>(),
183 "no time steps provided");
184 QL_REQUIRE(timeSteps == Null<Size>() ||
185 timeStepsPerYear == Null<Size>(),
186 "both time steps and time steps per year were provided");
187 QL_REQUIRE(timeSteps != 0,
188 "timeSteps must be positive, " << timeSteps <<
189 " not allowed");
190 QL_REQUIRE(timeStepsPerYear != 0,
191 "timeStepsPerYear must be positive, " << timeStepsPerYear <<
192 " not allowed");
193 }
194
195
196 template <class RNG, class S>
198
199 Time t = this->process_->time(this->arguments_.maturityDate);
200
201 if (timeSteps_ != Null<Size>()) {
202 return TimeGrid(t, this->timeSteps_);
203 } else if (timeStepsPerYear_ != Null<Size>()) {
204 Size steps = static_cast<Size>(timeStepsPerYear_*t);
205 return TimeGrid(t, std::max<Size>(steps, 1));
206 } else {
207 QL_FAIL("time steps not specified");
208 }
209 }
210
211
212 template <class RNG, class S>
213 inline
214 ext::shared_ptr<
217
218 return ext::shared_ptr<
220 new VariancePathPricer(process_));
221 }
222
223
224 template <class RNG, class S>
226 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
227 : process_(std::move(process)), steps_(Null<Size>()), stepsPerYear_(Null<Size>()),
228 samples_(Null<Size>()), maxSamples_(Null<Size>()), tolerance_(Null<Real>()) {}
229
230 template <class RNG, class S>
233 steps_ = steps;
234 return *this;
235 }
236
237 template <class RNG, class S>
240 stepsPerYear_ = steps;
241 return *this;
242 }
243
244 template <class RNG, class S>
247 QL_REQUIRE(tolerance_ == Null<Real>(),
248 "tolerance already set");
249 samples_ = samples;
250 return *this;
251 }
252
253 template <class RNG, class S>
256 QL_REQUIRE(samples_ == Null<Size>(),
257 "number of samples already set");
258 QL_REQUIRE(RNG::allowsErrorEstimate,
259 "chosen random generator policy "
260 "does not allow an error estimate");
261 tolerance_ = tolerance;
262 return *this;
263 }
264
265 template <class RNG, class S>
268 maxSamples_ = samples;
269 return *this;
270 }
271
272 template <class RNG, class S>
275 seed_ = seed;
276 return *this;
277 }
278
279 template <class RNG, class S>
282 brownianBridge_ = brownianBridge;
283 return *this;
284 }
285
286 template <class RNG, class S>
289 antithetic_ = b;
290 return *this;
291 }
292
293 template <class RNG, class S>
295 operator ext::shared_ptr<PricingEngine>() const {
296 QL_REQUIRE(steps_ != Null<Size>() || stepsPerYear_ != Null<Size>(),
297 "number of steps not given");
298 QL_REQUIRE(steps_ == Null<Size>() || stepsPerYear_ == Null<Size>(),
299 "number of steps overspecified");
300 return ext::shared_ptr<PricingEngine>(
301 new MCVarianceSwapEngine<RNG,S>(process_,
302 steps_,
303 stepsPerYear_,
304 brownianBridge_,
305 antithetic_,
306 samples_, tolerance_,
307 maxSamples_,
308 seed_));
309 }
310
311
312 namespace detail {
313
314 class Integrand {
315 public:
316 Integrand(Path path, ext::shared_ptr<GeneralizedBlackScholesProcess> process)
317 : path_(std::move(path)), process_(std::move(process)) {}
319 Size i = static_cast<Size>(t/path_.timeGrid().dt(0));
320 Real sigma = process_->diffusion(t,path_[i]);
321 return sigma*sigma;
322 }
323 private:
325 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
326 };
327
328 }
329
330
331 inline Real VariancePathPricer::operator()(const Path& path) const {
332 QL_REQUIRE(path.length() > 0, "the path cannot be empty");
333 Time t0 = path.timeGrid().front();
334 Time t = path.timeGrid().back();
335 Time dt = path.timeGrid().dt(0);
336 SegmentIntegral integrator(static_cast<Size>(t/dt));
338 return integrator(f,t0,t)/t;
339 }
340
341}
342
343
344#endif
Variance-swap pricing engine using Monte Carlo simulation,.
McSimulation< SingleVariate, RNG, S >::path_generator_type path_generator_type
ext::shared_ptr< path_generator_type > pathGenerator() const override
McSimulation< SingleVariate, RNG, S >::stats_type stats_type
MCVarianceSwapEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process, Size timeSteps, Size timeStepsPerYear, bool brownianBridge, bool antitheticVariate, Size requiredSamples, Real requiredTolerance, Size maxSamples, BigNatural seed)
ext::shared_ptr< path_pricer_type > pathPricer() const override
McSimulation< SingleVariate, RNG, S >::path_pricer_type path_pricer_type
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
TimeGrid timeGrid() const override
Monte Carlo variance-swap engine factory.
MakeMCVarianceSwapEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
MakeMCVarianceSwapEngine & withSeed(BigNatural seed)
MakeMCVarianceSwapEngine & withAbsoluteTolerance(Real tolerance)
MakeMCVarianceSwapEngine & withSamples(Size samples)
MakeMCVarianceSwapEngine & withSteps(Size steps)
MakeMCVarianceSwapEngine & withMaxSamples(Size samples)
MakeMCVarianceSwapEngine & withStepsPerYear(Size steps)
MakeMCVarianceSwapEngine & withAntitheticVariate(bool b=true)
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
MakeMCVarianceSwapEngine & withBrownianBridge(bool b=true)
base class for Monte Carlo engines
MonteCarloModel< MC, RNG, S >::path_generator_type path_generator_type
ext::shared_ptr< MonteCarloModel< MC, RNG, S > > mcModel_
void calculate(Real requiredTolerance, Size requiredSamples, Size maxSamples) const
basic calculate method provided to inherited pricing engines
MonteCarloModel< MC, RNG, S >::path_pricer_type path_pricer_type
template class providing a null value for a given type.
Definition: null.hpp:76
single-factor random walk
Definition: path.hpp:40
Size length() const
Definition: path.hpp:94
const TimeGrid & timeGrid() const
time grid
Definition: path.hpp:142
base class for path pricers
Definition: pathpricer.hpp:40
Integral of a one-dimensional function.
time grid class
Definition: timegrid.hpp:43
Time back() const
Definition: timegrid.hpp:171
Time dt(Size i) const
Definition: timegrid.hpp:154
Time front() const
Definition: timegrid.hpp:170
Size size() const
Definition: timegrid.hpp:164
VariancePathPricer(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
Real operator()(const Path &path) const override
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
base class for variance-swap engines
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Integrand(Path path, ext::shared_ptr< GeneralizedBlackScholesProcess > process)
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
unsigned QL_BIG_INTEGER BigNatural
large positive integer
Definition: types.hpp:46
STL namespace.
default Monte Carlo traits for single-variate models
Definition: mctraits.hpp:39