[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) 2011 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis
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 "extensibleoptions.hpp"
21#include "utilities.hpp"
22#include <ql/experimental/exoticoptions/holderextensibleoption.hpp>
23#include <ql/experimental/exoticoptions/writerextensibleoption.hpp>
24#include <ql/experimental/exoticoptions/analyticholderextensibleoptionengine.hpp>
25#include <ql/experimental/exoticoptions/analyticwriterextensibleoptionengine.hpp>
26#include <ql/quotes/simplequote.hpp>
27#include <ql/utilities/dataformatters.hpp>
28#include <ql/time/calendars/target.hpp>
29#include <ql/time/daycounters/actual360.hpp>
30
31using namespace QuantLib;
32using namespace boost::unit_test_framework;
33
34void ExtensibleOptionsTest::testAnalyticHolderExtensibleOptionEngine() {
35 BOOST_TEST_MESSAGE(
36 "Testing analytic engine for holder-extensible option...");
37
38 Option::Type type = Option::Call;
39 Real strike1 = 100.0;
40 Real strike2 = 105.0;
41 DayCounter dc = Actual360();
42 Date today = Settings::instance().evaluationDate();
43 Date exDate1 = today + 180;
44 Date exDate2 = today + 270;
45 Real premium = 1.0;
46
47 ext::shared_ptr<SimpleQuote> spot = ext::make_shared<SimpleQuote>(args: 100.0);
48 ext::shared_ptr<SimpleQuote> qRate = ext::make_shared<SimpleQuote>(args: 0.0);
49 ext::shared_ptr<SimpleQuote> rRate = ext::make_shared<SimpleQuote>(args: 0.08);
50 ext::shared_ptr<SimpleQuote> vol = ext::make_shared<SimpleQuote>(args: 0.25);
51
52 ext::shared_ptr<StrikedTypePayoff> payoff =
53 ext::make_shared<PlainVanillaPayoff>(args&: type, args&: strike1);
54 ext::shared_ptr<Exercise> exercise =
55 ext::make_shared<EuropeanExercise>(args&: exDate1);
56
57 HolderExtensibleOption option(type, premium,
58 exDate2, strike2,
59 payoff, exercise);
60
61 Handle<Quote> underlying(spot);
62 Handle<YieldTermStructure> dividendTS(flatRate(today, forward: qRate, dc));
63 Handle<YieldTermStructure> riskFreeTS(flatRate(today, forward: rRate, dc));
64 Handle<BlackVolTermStructure> blackVolTS(flatVol(today, volatility: vol, dc));
65
66 const ext::shared_ptr<BlackScholesMertonProcess> process =
67 ext::make_shared<BlackScholesMertonProcess>(args&: underlying,
68 args&: dividendTS,
69 args&: riskFreeTS,
70 args&: blackVolTS);
71
72 option.setPricingEngine(
73 ext::make_shared<AnalyticHolderExtensibleOptionEngine>(args: process));
74
75 Real calculated = option.NPV();
76 Real expected = 9.4233;
77 Real error = std::fabs(x: calculated-expected);
78 Real tolerance = 1e-4;
79 if (error > tolerance)
80 BOOST_ERROR("Failed to reproduce holder-extensible option value"
81 << "\n expected: " << expected
82 << "\n calculated: " << calculated
83 << "\n error: " << error);
84}
85
86
87void ExtensibleOptionsTest::testAnalyticWriterExtensibleOptionEngine() {
88 BOOST_TEST_MESSAGE("Testing analytic engine for writer-extensible option...");
89
90 // What we need for the option (tests):
91 Option::Type type = Option::Call;
92 Real strike1 = 90.0;
93 Real strike2 = 82.0;
94 DayCounter dc = Actual360();
95 Date today = Settings::instance().evaluationDate();
96 Date exDate1 = today + 180;
97 Date exDate2 = today + 270;
98
99 ext::shared_ptr<SimpleQuote> spot = ext::make_shared<SimpleQuote>(args: 80.0);
100 ext::shared_ptr<SimpleQuote> qRate = ext::make_shared<SimpleQuote>(args: 0.0);
101 ext::shared_ptr<YieldTermStructure> dividendTS =
102 flatRate(today, forward: qRate, dc);
103 ext::shared_ptr<SimpleQuote> rRate = ext::make_shared<SimpleQuote>(args: 0.10);
104 ext::shared_ptr<YieldTermStructure> riskFreeTS =
105 flatRate(today, forward: rRate, dc);
106 ext::shared_ptr<SimpleQuote> vol = ext::make_shared<SimpleQuote>(args: 0.30);
107 ext::shared_ptr<BlackVolTermStructure> blackVolTS =
108 flatVol(today, volatility: vol, dc);
109
110 // B&S process (needed for the engine):
111 const ext::shared_ptr<GeneralizedBlackScholesProcess> process =
112 ext::make_shared<GeneralizedBlackScholesProcess>(
113 args: Handle<Quote>(spot),
114 args: Handle<YieldTermStructure>(dividendTS),
115 args: Handle<YieldTermStructure>(riskFreeTS),
116 args: Handle<BlackVolTermStructure>(blackVolTS));
117
118 // The engine:
119 ext::shared_ptr<PricingEngine> engine =
120 ext::make_shared<AnalyticWriterExtensibleOptionEngine>(args: process);
121
122 // Create the arguments:
123 ext::shared_ptr<PlainVanillaPayoff> payoff1 =
124 ext::make_shared<PlainVanillaPayoff>(args&: type, args&: strike1);
125 ext::shared_ptr<Exercise> exercise1 =
126 ext::make_shared<EuropeanExercise>(args&: exDate1);
127 ext::shared_ptr<PlainVanillaPayoff> payoff2 =
128 ext::make_shared<PlainVanillaPayoff>(args&: type, args&: strike2);
129 ext::shared_ptr<Exercise> exercise2 =
130 ext::make_shared<EuropeanExercise>(args&: exDate2);
131
132 // Create the option by calling the constructor:
133 WriterExtensibleOption option(payoff1, exercise1,
134 payoff2, exercise2);
135
136 //Set the engine of our option:
137 option.setPricingEngine(engine);
138
139 //Compare the calculated NPV value to the theoretical value:
140 Real calculated = option.NPV();
141 Real expected = 6.8238;
142 Real error = std::fabs(x: calculated-expected);
143 Real tolerance = 1e-4;
144 if (error > tolerance)
145 BOOST_ERROR("Failed to reproduce writer-extensible option value"
146 << "\n expected: " << expected
147 << "\n calculated: " << calculated
148 << "\n error: " << error);
149}
150
151test_suite* ExtensibleOptionsTest::suite() {
152 auto* suite = BOOST_TEST_SUITE("Extensible option tests");
153
154 suite->add(QUANTLIB_TEST_CASE(
155 &ExtensibleOptionsTest::testAnalyticHolderExtensibleOptionEngine));
156 suite->add(QUANTLIB_TEST_CASE(
157 &ExtensibleOptionsTest::testAnalyticWriterExtensibleOptionEngine));
158
159 return suite;
160}
161

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