QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
analyticbsmhullwhiteengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Klaus Spanderen
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#include <ql/pricingengines/vanilla/analyticbsmhullwhiteengine.hpp>
25#include <ql/pricingengines/vanilla/analyticeuropeanengine.hpp>
26#include <ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp>
27#include <utility>
28
29namespace QuantLib {
30
31 namespace {
32
33 class ShiftedBlackVolTermStructure : public BlackVolTermStructure {
34 public:
35 ShiftedBlackVolTermStructure(
36 Real varianceOffset,
37 const Handle<BlackVolTermStructure> & volTS)
38 : BlackVolTermStructure(volTS->referenceDate(),
39 volTS->calendar(),
41 volTS->dayCounter()),
42 varianceOffset_(varianceOffset),
43 volTS_(volTS) { }
44
45 Real minStrike() const override { return volTS_->minStrike(); }
46 Real maxStrike() const override { return volTS_->maxStrike(); }
47 Date maxDate() const override { return volTS_->maxDate(); }
48
49 protected:
50 Real blackVarianceImpl(Time t, Real strike) const override {
51 return volTS_->blackVariance(t, strike, true)+varianceOffset_;
52 }
53 Volatility blackVolImpl(Time t, Real strike) const override {
54 Time nonZeroMaturity = (t==0.0 ? 0.00001 : t);
55 Real var = blackVarianceImpl(nonZeroMaturity, strike);
56 return std::sqrt(var/nonZeroMaturity);
57 }
58
59 private:
60 const Real varianceOffset_;
61 const Handle<BlackVolTermStructure> volTS_;
62 };
63 }
64
66 Real equityShortRateCorrelation,
67 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
68 const ext::shared_ptr<HullWhite>& model)
70 rho_(equityShortRateCorrelation), process_(std::move(process)) {
71 QL_REQUIRE(process_, "no Black-Scholes process specified");
72 QL_REQUIRE(!model_.empty(), "no Hull-White model specified");
74 }
75
77
78 QL_REQUIRE(process_->x0() > 0.0, "negative or null underlying given");
79
80 const ext::shared_ptr<StrikedTypePayoff> payoff =
81 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
82 QL_REQUIRE(payoff, "non-striked payoff given");
83
84 const ext::shared_ptr<Exercise> exercise = arguments_.exercise;
85
86 Time t = process_->riskFreeRate()->dayCounter().yearFraction(
87 process_->riskFreeRate()->referenceDate(),
88 exercise->lastDate());
89
90 const Real a = model_->params()[0];
91 const Real sigma = model_->params()[1];
92 const Real eta =
93 process_->blackVolatility()->blackVol(exercise->lastDate(),
94 payoff->strike());
95
96 Real varianceOffset;
97 if (a*t > std::pow(QL_EPSILON, 0.25)) {
98 const Real v = sigma*sigma/(a*a)
99 *(t + 2/a*std::exp(-a*t) - 1/(2*a)*std::exp(-2*a*t) - 3/(2*a));
100 const Real mu = 2*rho_*sigma*eta/a*(t-1/a*(1-std::exp(-a*t)));
101
102 varianceOffset = v + mu;
103 }
104 else {
105 // low-a algebraic limit
106 const Real v = sigma*sigma*t*t*t*(1/3.0-0.25*a*t+7/60.0*a*a*t*t);
107 const Real mu = rho_*sigma*eta*t*t*(1-a*t/3.0+a*a*t*t/12.0);
108
109 varianceOffset = v + mu;
110 }
111
113 ext::shared_ptr<BlackVolTermStructure>(
114 new ShiftedBlackVolTermStructure(varianceOffset,
115 process_->blackVolatility())));
116
117 ext::shared_ptr<GeneralizedBlackScholesProcess> adjProcess(
118 new GeneralizedBlackScholesProcess(process_->stateVariable(),
119 process_->dividendYield(),
120 process_->riskFreeRate(),
121 volTS));
122
123 ext::shared_ptr<AnalyticEuropeanEngine> bsmEngine(
124 new AnalyticEuropeanEngine(adjProcess));
125
126 VanillaOption(payoff, exercise).setupArguments(
127 bsmEngine->getArguments());
128 bsmEngine->calculate();
129
130 results_ = *dynamic_cast<const OneAssetOption::results*>(
131 bsmEngine->getResults());
132 }
133}
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
AnalyticBSMHullWhiteEngine(Real equityShortRateCorrelation, ext::shared_ptr< GeneralizedBlackScholesProcess >, const ext::shared_ptr< HullWhite > &)
Pricing engine for European vanilla options using analytical formulae.
Generalized Black-Scholes stochastic process.
Base class for some pricing engine on a particular model.
Shared handle to an observable.
Definition: handle.hpp:41
bool empty() const
checks if the contained shared pointer points to anything
Definition: handle.hpp:166
Single-factor Hull-White (extended Vasicek) model class.
Definition: hullwhite.hpp:49
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Results from single-asset option calculation
Vanilla option (no discrete dividends, no barriers) on a single asset.
void setupArguments(PricingEngine::arguments *) const override
#define QL_EPSILON
Definition: qldefines.hpp:178
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Volatility
volatility
Definition: types.hpp:78
Definition: any.hpp:35
STL namespace.