Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
spreadedsmilesection2.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
20
22
23#include <iostream>
24
25namespace QuantExt {
26
27SpreadedSmileSection2::SpreadedSmileSection2(const QuantLib::ext::shared_ptr<SmileSection>& base,
28 const std::vector<Real>& volSpreads, const std::vector<Real>& strikes,
29 const bool strikesRelativeToAtm, const Real baseAtmLevel,
30 const Real simulatedAtmLevel, const bool stickyAbsMoney)
31 : SmileSection(base->exerciseTime(), base->dayCounter(), base->volatilityType(),
32 base->volatilityType() == ShiftedLognormal ? base->shift() : 0.0),
33 base_(base), volSpreads_(volSpreads), strikes_(strikes), strikesRelativeToAtm_(strikesRelativeToAtm),
34 baseAtmLevel_(baseAtmLevel), simulatedAtmLevel_(simulatedAtmLevel), stickyAbsMoney_(stickyAbsMoney) {
35 registerWith(base_);
36 QL_REQUIRE(!strikes_.empty(), "SpreadedSmileSection2: strikes empty");
37 QL_REQUIRE(strikes_.size() == volSpreads_.size(), "SpreadedSmileSection2: strike spreads ("
38 << strikes_.size() << ") inconsistent with vol spreads ("
39 << volSpreads_.size() << ")");
40 if ((strikesRelativeToAtm_ && strikes.size() > 1) || stickyAbsMoney) {
41 QL_REQUIRE(baseAtmLevel_ != Null<Real>() || base_->atmLevel() != Null<Real>(),
42 "SpreadedSmileSection2: if strikeRelativeToATM is true and more than one strike is given, or if "
43 "stickyAbsMoney is true, the base atm level must be given.");
44 }
45 if (stickyAbsMoney) {
46 QL_REQUIRE(simulatedAtmLevel_ != Null<Real>(),
47 "SpreadedSmileSection2: if stickyAbsMoney is true, the simulatedAtmLevel must be given");
48 }
49 if (volSpreads_.size() > 1) {
51 volSpreadInterpolation_.enableExtrapolation();
52 }
53}
54
55Rate SpreadedSmileSection2::minStrike() const { return base_->minStrike(); }
56Rate SpreadedSmileSection2::maxStrike() const { return base_->maxStrike(); }
58 return baseAtmLevel_ != Null<Real>() ? baseAtmLevel_ : base_->atmLevel();
59}
60
61Volatility SpreadedSmileSection2::volatilityImpl(Rate strike) const {
62 Real effStrike;
63 if (stickyAbsMoney_) {
64 effStrike = strike - (simulatedAtmLevel_ - atmLevel());
65 } else {
66 effStrike = strike;
67 }
68 if (volSpreads_.size() == 1)
69 return base_->volatility(effStrike) + volSpreads_.front();
70 else if (strikesRelativeToAtm_) {
71 Real f = atmLevel();
72 QL_REQUIRE(f != Null<Real>(), "SpreadedSmileSection2: atm level required");
73 return base_->volatility(effStrike) + volSpreadInterpolation_(strike - f);
74 } else {
75 return base_->volatility(effStrike) + volSpreadInterpolation_(effStrike);
76 }
77}
78
79} // namespace QuantExt
Linear-interpolation and flat extrapolation factory and traits
Interpolation interpolate(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
SpreadedSmileSection2(const QuantLib::ext::shared_ptr< SmileSection > &base, const std::vector< Real > &volSpreads, const std::vector< Real > &strikes, const bool strikesRelativeToAtm=false, const Real baseAtmLevel=Null< Real >(), const Real simulatedAtmLevel=Null< Real >(), const bool stickyAbsMoney=false)
Volatility volatilityImpl(Rate strike) const override
QuantLib::ext::shared_ptr< SmileSection > base_
flat interpolation decorator
smile section with linear interpolated vol spreads
vector< Real > strikes