[go: up one dir, main page]

1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 StatPro Italia srl
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
20#include "everestoption.hpp"
21#include "utilities.hpp"
22#include <ql/experimental/exoticoptions/everestoption.hpp>
23#include <ql/experimental/exoticoptions/mceverestengine.hpp>
24#include <ql/math/randomnumbers/rngtraits.hpp>
25#include <ql/time/daycounters/actual360.hpp>
26#include <ql/quotes/simplequote.hpp>
27
28using namespace QuantLib;
29using namespace boost::unit_test_framework;
30
31void EverestOptionTest::testCached() {
32
33 BOOST_TEST_MESSAGE("Testing Everest option against cached values...");
34
35 Date today = Settings::instance().evaluationDate();
36
37 DayCounter dc = Actual360();
38 Date exerciseDate = today+360;
39 ext::shared_ptr<Exercise> exercise(new EuropeanExercise(exerciseDate));
40
41 Real notional = 1.0;
42 Rate guarantee = 0.0;
43 EverestOption option(notional, guarantee, exercise);
44
45 Handle<YieldTermStructure> riskFreeRate(flatRate(today, forward: 0.05, dc));
46
47 std::vector<ext::shared_ptr<StochasticProcess1D> > processes(4);
48 Handle<Quote> dummyUnderlying(ext::shared_ptr<Quote>(
49 new SimpleQuote(1.0)));
50 processes[0] = ext::shared_ptr<StochasticProcess1D>(
51 new BlackScholesMertonProcess(
52 dummyUnderlying,
53 Handle<YieldTermStructure>(flatRate(today, forward: 0.01, dc)),
54 riskFreeRate,
55 Handle<BlackVolTermStructure>(flatVol(today, volatility: 0.30, dc))));
56 processes[1] = ext::shared_ptr<StochasticProcess1D>(
57 new BlackScholesMertonProcess(
58 dummyUnderlying,
59 Handle<YieldTermStructure>(flatRate(today, forward: 0.05, dc)),
60 riskFreeRate,
61 Handle<BlackVolTermStructure>(flatVol(today, volatility: 0.35, dc))));
62 processes[2] = ext::shared_ptr<StochasticProcess1D>(
63 new BlackScholesMertonProcess(
64 dummyUnderlying,
65 Handle<YieldTermStructure>(flatRate(today, forward: 0.04, dc)),
66 riskFreeRate,
67 Handle<BlackVolTermStructure>(flatVol(today, volatility: 0.25, dc))));
68 processes[3] = ext::shared_ptr<StochasticProcess1D>(
69 new BlackScholesMertonProcess(
70 dummyUnderlying,
71 Handle<YieldTermStructure>(flatRate(today, forward: 0.03, dc)),
72 riskFreeRate,
73 Handle<BlackVolTermStructure>(flatVol(today, volatility: 0.20, dc))));
74
75 Matrix correlation(4,4);
76 correlation[0][0] = 1.00;
77 correlation[0][1] = 0.50;
78 correlation[0][2] = 0.30;
79 correlation[0][3] = 0.10;
80 correlation[1][0] = 0.50;
81 correlation[1][1] = 1.00;
82 correlation[1][2] = 0.20;
83 correlation[1][3] = 0.40;
84 correlation[2][0] = 0.30;
85 correlation[2][1] = 0.20;
86 correlation[2][2] = 1.00;
87 correlation[2][3] = 0.60;
88 correlation[3][0] = 0.10;
89 correlation[3][1] = 0.40;
90 correlation[3][2] = 0.60;
91 correlation[3][3] = 1.00;
92
93
94
95 BigNatural seed = 86421;
96 Size fixedSamples = 1023;
97 Real minimumTol = 1.0e-2;
98
99 ext::shared_ptr<StochasticProcessArray> process(
100 new StochasticProcessArray(processes, correlation));
101
102 option.setPricingEngine(MakeMCEverestEngine<PseudoRandom>(process)
103 .withStepsPerYear(steps: 1)
104 .withSamples(samples: fixedSamples)
105 .withSeed(seed));
106
107 Real value = option.NPV();
108 Real storedValue = 0.75784944;
109 Real tolerance = 1.0e-8;
110
111 if (std::fabs(x: value-storedValue) > tolerance)
112 BOOST_FAIL(std::setprecision(10)
113 << " calculated value: " << value << "\n"
114 << " expected: " << storedValue);
115
116 tolerance = option.errorEstimate();
117 tolerance = std::min<Real>(a: tolerance/2.0, b: minimumTol*value);
118
119 option.setPricingEngine(MakeMCEverestEngine<PseudoRandom>(process)
120 .withStepsPerYear(steps: 1)
121 .withAbsoluteTolerance(tolerance)
122 .withSeed(seed));
123
124 option.NPV();
125 Real accuracy = option.errorEstimate();
126 if (accuracy > tolerance)
127 BOOST_FAIL(std::setprecision(10)
128 << " reached accuracy: " << accuracy << "\n"
129 << " expected: " << tolerance);
130}
131
132
133test_suite* EverestOptionTest::suite() {
134 auto* suite = BOOST_TEST_SUITE("Everest-option tests");
135 suite->add(QUANTLIB_TEST_CASE(&EverestOptionTest::testCached));
136 return suite;
137}
138
139

source code of quantlib/test-suite/everestoption.cpp