Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
blackvolsurfaceproxy.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include "toplevelfixture.hpp"
20#include <boost/make_shared.hpp>
21#include <boost/test/unit_test.hpp>
22#include <ql/currencies/america.hpp>
23#include <ql/math/matrix.hpp>
24#include <ql/quotes/simplequote.hpp>
25#include <ql/termstructures/volatility/equityfx/blackvariancesurface.hpp>
26#include <ql/termstructures/yield/flatforward.hpp>
27#include <ql/time/calendars/unitedstates.hpp>
28#include <ql/time/daycounters/actualactual.hpp>
31
32using namespace boost::unit_test_framework;
33using namespace QuantLib;
34using namespace QuantExt;
35using namespace std;
36
37BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, qle::test::TopLevelFixture)
38
39BOOST_AUTO_TEST_SUITE(BlackVolSurfaceProxy)
40
41BOOST_AUTO_TEST_CASE(testBlackVolSurfaceProxy) {
42
43 BOOST_TEST_MESSAGE("Testing QuantExt::BlackVolSurfaceProxy...");
44
45 // take an index and one of it's underlyings, proxy the underlyings vol surface off the
46 // index vol surface, check that the forward ATM vols are the same
47
48 Date today = Date(1, Jan, 2020);
49 DayCounter dc = ActualActual(ActualActual::ISDA);
50
51 Settings::instance().evaluationDate() = today;
52
53 vector<Date> dates;
54 dates.push_back(Date(3, Feb, 2020));
55 dates.push_back(Date(2, Mar, 2020));
56 dates.push_back(Date(1, Apr, 2020));
57 dates.push_back(Date(4, Jan, 2021));
58
59 vector<Real> strikes;
60 strikes.push_back(500);
61 strikes.push_back(1000);
62 strikes.push_back(1500);
63
64 Matrix vols = Matrix(3, 4);
65 vols[0][0] = 0.12;
66 vols[1][0] = 0.10;
67 vols[2][0] = 0.13;
68 vols[0][1] = 0.22;
69 vols[1][1] = 0.20;
70 vols[2][1] = 0.23;
71 vols[0][2] = 0.32;
72 vols[1][2] = 0.30;
73 vols[2][2] = 0.33;
74 vols[0][3] = 0.42;
75 vols[1][3] = 0.40;
76 vols[2][3] = 0.43;
77
78 // spots for the index and underlying
79 Handle<Quote> indexSpot = Handle<Quote>(QuantLib::ext::shared_ptr<Quote>(new SimpleQuote(1000)));
80 Handle<Quote> underlyingSpot = Handle<Quote>(QuantLib::ext::shared_ptr<Quote>(new SimpleQuote(150)));
81
82 // forecast and dividend yields for the index
83 Handle<YieldTermStructure> indexForecast = Handle<YieldTermStructure>(
84 QuantLib::ext::make_shared<FlatForward>(today, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.03)), dc));
85 Handle<YieldTermStructure> indexDividend = Handle<YieldTermStructure>(
86 QuantLib::ext::make_shared<FlatForward>(today, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.02)), dc));
87
88 // forecast and dividend yields for the underlying
89 Handle<YieldTermStructure> underlyingForecast = Handle<YieldTermStructure>(
90 QuantLib::ext::make_shared<FlatForward>(today, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.02)), dc));
91 Handle<YieldTermStructure> underlyingDividend = Handle<YieldTermStructure>(
92 QuantLib::ext::make_shared<FlatForward>(today, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.01)), dc));
93
94 // set up EquityIndexes for the index and underlying
95 QuantLib::ext::shared_ptr<EquityIndex2> index = QuantLib::ext::make_shared<EquityIndex2>("Index", UnitedStates(UnitedStates::Settlement), USDCurrency(),
96 indexSpot, indexForecast, indexDividend);
97 QuantLib::ext::shared_ptr<EquityIndex2> underlying = QuantLib::ext::make_shared<EquityIndex2>(
98 "Underlying", UnitedStates(UnitedStates::Settlement), USDCurrency(), underlyingSpot, underlyingForecast, underlyingDividend);
99
100 // set up a vol surface for the index
101 QuantLib::ext::shared_ptr<BlackVolTermStructure> indexVolSurface =
102 QuantLib::ext::make_shared<BlackVarianceSurface>(today, UnitedStates(UnitedStates::Settlement), dates, strikes, vols, dc);
103
104 // set up a vol surface for the underlying, to be proxied from the index surface
105 QuantLib::ext::shared_ptr<BlackVolatilitySurfaceProxy> underlyingVolSurface =
106 QuantLib::ext::make_shared<BlackVolatilitySurfaceProxy>(indexVolSurface, underlying, index);
107
108 // Check the ATM forward vols
109 for (auto d : dates) {
110 // underlying forward
111 Real underlyingF = underlying->fixing(d);
112 // vol from proxy surface
113 Real underlyingVol = underlyingVolSurface->blackVol(d, underlyingF);
114
115 // index forward
116 Real indexF = index->fixing(d);
117 // vol from index surface
118 Real indexVol = indexVolSurface->blackVol(d, indexF);
119
120 BOOST_CHECK_CLOSE(underlyingVol, indexVol, 0.001);
121 }
122}
123
124BOOST_AUTO_TEST_SUITE_END()
125
126BOOST_AUTO_TEST_SUITE_END()
Wrapper class for a BlackVolTermStructure when using proxy vols.
equity index class for holding equity fixing histories and forwarding.
vector< Real > strikes
BOOST_AUTO_TEST_CASE(testBlackVolSurfaceProxy)
Fixture that can be used at top level.