QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
fdsabrvanillaengine.cpp
Go to the documentation of this file.
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
20/*! \file fdsabrvanillaengine.hpp */
21
22#include <ql/exercise.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
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
const Instrument::results * results_
Definition: cdsoption.cpp:63
risk neutral density calculator for the constant elasticity of variance (CEV) model
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.
One-dimensional grid mesher concentrating around critical points.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Option exercise classes and payoff function.
One-dimensional mesher for the CEV model.
const ext::shared_ptr< YieldTermStructure > rTS_
discounted value on Dirichlet boundary conditions
layer of abstraction to calculate the inner value
FdmMesher which is a composite of Fdm1dMesher.
FDM operator for the SABR model.
composite of fdm step conditions
Finite-Differences pricing engine for the SABR model.
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
Real rho
ext::shared_ptr< QuantLib::Payoff > payoff
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.
normal, cumulative and inverse cumulative distributions
Real beta
Definition: sabr.cpp:200
Real nu
Definition: sabr.cpp:200
Real alpha
Definition: sabr.cpp:200
SABR functions.
Interest-rate term structure.