QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
fdsabrvanillaengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2019 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
22#include <ql/exercise.hpp>
23#include <ql/math/distributions/normaldistribution.hpp>
24#include <ql/methods/finitedifferences/meshers/concentrating1dmesher.hpp>
25#include <ql/methods/finitedifferences/meshers/fdmcev1dmesher.hpp>
26#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
27#include <ql/methods/finitedifferences/operators/fdmsabrop.hpp>
28#include <ql/methods/finitedifferences/solvers/fdm2dimsolver.hpp>
29#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
30#include <ql/methods/finitedifferences/utilities/cevrndcalculator.hpp>
31#include <ql/methods/finitedifferences/utilities/fdmdiscountdirichletboundary.hpp>
32#include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp>
33#include <ql/pricingengines/vanilla/fdsabrvanillaengine.hpp>
34#include <ql/termstructures/volatility/sabr.hpp>
35#include <ql/termstructures/yieldtermstructure.hpp>
36#include <utility>
37
38namespace QuantLib {
39
41 Real alpha,
42 Real beta,
43 Real nu,
44 Real rho,
46 Size tGrid,
47 Size fGrid,
48 Size xGrid,
49 Size dampingSteps,
50 Real scalingFactor,
51 Real eps,
52 const FdmSchemeDesc& schemeDesc)
53 : f0_(f0), alpha_(alpha), beta_(beta), nu_(nu), rho_(rho), rTS_(std::move(rTS)), tGrid_(tGrid),
54 fGrid_(fGrid), xGrid_(xGrid), dampingSteps_(dampingSteps), scalingFactor_(scalingFactor),
55 eps_(eps), schemeDesc_(schemeDesc) {
56
57 validateSabrParameters(alpha, 0.5, nu, rho);
58
59 QL_REQUIRE(beta<1.0, "beta must be smaller than 1.0: "
60 << beta << " not allowed");
61
62 registerWith(rTS_);
63 }
64
66 // 1. Mesher
67 const ext::shared_ptr<StrikedTypePayoff> payoff =
68 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
69 QL_REQUIRE(payoff, "non-striked payoff given");
70
71 const DayCounter dc = rTS_->dayCounter();
72
73 const Date referenceDate = rTS_->referenceDate();
74 const Date maturityDate = arguments_.exercise->lastDate();
75 const Time maturityTime = dc.yearFraction(referenceDate, maturityDate);
76
77 const Real upperAlpha = alpha_*
78 std::exp(nu_*std::sqrt(maturityTime)*InverseCumulativeNormal()(0.75));
79
80 const ext::shared_ptr<Fdm1dMesher> cevMesher =
81 ext::make_shared<FdmCEV1dMesher>(
82 fGrid_, f0_, upperAlpha, beta_,
83 maturityTime, eps_, scalingFactor_,
84 std::make_pair(payoff->strike(), 0.025));
85
86 const Real normInvEps = InverseCumulativeNormal()(1-eps_);
87 const Real logDrift = -0.5*nu_*nu_*maturityTime;
88 const Real volRange =
89 nu_*std::sqrt(maturityTime)*normInvEps*scalingFactor_;
90
91 const Real xMin = std::log(alpha_) + logDrift - volRange;
92 const Real xMax = std::log(alpha_) + logDrift + volRange;
93
94 const ext::shared_ptr<Fdm1dMesher> xMesher =
95 ext::make_shared<Concentrating1dMesher>(
96 xMin, xMax, xGrid_, std::make_pair(std::log(alpha_), 0.1));
97
98 const ext::shared_ptr<FdmMesher> mesher =
99 ext::make_shared<FdmMesherComposite>(cevMesher, xMesher);
100
101 // 2. Calculator
102 const ext::shared_ptr<FdmInnerValueCalculator> calculator =
103 ext::make_shared<FdmCellAveragingInnerValue>(payoff, mesher, 0);
104
105 // 3. Step conditions
106 const ext::shared_ptr<FdmStepConditionComposite> conditions =
108 DividendSchedule(), arguments_.exercise,
109 mesher, calculator, referenceDate, dc);
110
111 // 4. Boundary conditions
112 FdmBoundaryConditionSet boundaries;
113
114 const Real lowerBound = cevMesher->locations().front();
115 const Real upperBound = cevMesher->locations().back();
116
117 boundaries.push_back(
118 ext::make_shared<FdmDiscountDirichletBoundary>(
119 mesher, rTS_.currentLink(),
120 maturityTime, (*payoff)(upperBound),
122
123 boundaries.push_back(
124 ext::make_shared<FdmDiscountDirichletBoundary>(
125 mesher, rTS_.currentLink(),
126 maturityTime, (*payoff)(lowerBound),
128
129 // 5. Solver
130 const FdmSolverDesc solverDesc = {
131 mesher, boundaries, conditions,
132 calculator, maturityTime, tGrid_, dampingSteps_
133 };
134
135 const ext::shared_ptr<FdmLinearOpComposite> op =
136 ext::make_shared<FdmSabrOp>(
137 mesher, rTS_.currentLink(),
138 f0_, alpha_, beta_, nu_, rho_);
139
140 const ext::shared_ptr<Fdm2DimSolver> solver =
141 ext::make_shared<Fdm2DimSolver>(solverDesc, schemeDesc_, op);
142
143 results_.value = solver->interpolateAt(f0_, std::log(alpha_));
144 }
145}
146
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
FdSabrVanillaEngine(Real f0, Real alpha, Real beta, Real nu, Real rho, Handle< YieldTermStructure > rTS, Size tGrid=50, Size fGrid=400, Size xGrid=50, Size dampingSteps=0, Real scalingFactor=1.0, Real eps=1e-4, const FdmSchemeDesc &schemeDesc=FdmSchemeDesc::Hundsdorfer())
const Handle< YieldTermStructure > rTS_
static ext::shared_ptr< FdmStepConditionComposite > vanillaComposite(const DividendSchedule &schedule, const ext::shared_ptr< Exercise > &exercise, const ext::shared_ptr< FdmMesher > &mesher, const ext::shared_ptr< FdmInnerValueCalculator > &calculator, const Date &refDate, const DayCounter &dayCounter)
Shared handle to an observable.
Definition: handle.hpp:41
Inverse cumulative normal distribution function.
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
std::vector< ext::shared_ptr< Dividend > > DividendSchedule
void validateSabrParameters(Real alpha, Real beta, Real nu, Real rho)
Definition: sabr.cpp:145
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet
STL namespace.