1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003 Neil Firth
5 Copyright (C) 2003 Ferdinando Ametrano
6 Copyright (C) 2007 StatPro Italia srl
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
22#include <ql/exercise.hpp>
23#include <ql/instruments/barrieroption.hpp>
24#include <ql/instruments/dividendbarrieroption.hpp>
25#include <ql/instruments/impliedvolatility.hpp>
26#include <ql/pricingengines/barrier/analyticbarrierengine.hpp>
27#include <ql/pricingengines/barrier/fdblackscholesbarrierengine.hpp>
28#include <memory>
29
30namespace QuantLib {
31
32 BarrierOption::BarrierOption(
33 Barrier::Type barrierType,
34 Real barrier,
35 Real rebate,
36 const ext::shared_ptr<StrikedTypePayoff>& payoff,
37 const ext::shared_ptr<Exercise>& exercise)
38 : OneAssetOption(payoff, exercise),
39 barrierType_(barrierType), barrier_(barrier), rebate_(rebate) {}
40
41 void BarrierOption::setupArguments(PricingEngine::arguments* args) const {
42
43 OneAssetOption::setupArguments(args);
44
45 auto* moreArgs = dynamic_cast<BarrierOption::arguments*>(args);
46 QL_REQUIRE(moreArgs != nullptr, "wrong argument type");
47 moreArgs->barrierType = barrierType_;
48 moreArgs->barrier = barrier_;
49 moreArgs->rebate = rebate_;
50
51 /* this is a workaround in case an engine is used for both barrier
52 and dividend options. The dividends might have been set by another
53 instrument and need to be cleared. */
54 QL_DEPRECATED_DISABLE_WARNING
55 auto* arguments = dynamic_cast<DividendBarrierOption::arguments*>(args);
56 if (arguments != nullptr) {
57 arguments->cashFlow.clear();
58 }
59 QL_DEPRECATED_ENABLE_WARNING
60 }
61
62
63 Volatility BarrierOption::impliedVolatility(
64 Real targetValue,
65 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process,
66 Real accuracy,
67 Size maxEvaluations,
68 Volatility minVol,
69 Volatility maxVol) const {
70 return impliedVolatility(price: targetValue, process, dividends: DividendSchedule(),
71 accuracy, maxEvaluations, minVol, maxVol);
72 }
73
74 Volatility BarrierOption::impliedVolatility(
75 Real targetValue,
76 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process,
77 const DividendSchedule& dividends,
78 Real accuracy,
79 Size maxEvaluations,
80 Volatility minVol,
81 Volatility maxVol) const {
82 QL_REQUIRE(!isExpired(), "option expired");
83
84 ext::shared_ptr<SimpleQuote> volQuote(new SimpleQuote);
85
86 ext::shared_ptr<GeneralizedBlackScholesProcess> newProcess =
87 detail::ImpliedVolatilityHelper::clone(process, volQuote);
88
89 // engines are built-in for the time being
90 std::unique_ptr<PricingEngine> engine;
91 switch (exercise_->type()) {
92 case Exercise::European:
93 if (dividends.empty())
94 engine = std::make_unique<AnalyticBarrierEngine>(args&: newProcess);
95 else
96 engine = std::make_unique<FdBlackScholesBarrierEngine>(args&: newProcess, args: dividends);
97 break;
98 case Exercise::American:
99 case Exercise::Bermudan:
100 QL_FAIL("engine not available for non-European barrier option");
101 break;
102 default:
103 QL_FAIL("unknown exercise type");
104 }
105
106 return detail::ImpliedVolatilityHelper::calculate(instrument: *this,
107 engine: *engine,
108 volQuote&: *volQuote,
109 targetValue,
110 accuracy,
111 maxEvaluations,
112 minVol, maxVol);
113 }
114
115
116 BarrierOption::arguments::arguments()
117 : barrierType(Barrier::Type(-1)), barrier(Null<Real>()),
118 rebate(Null<Real>()) {}
119
120 void BarrierOption::arguments::validate() const {
121 OneAssetOption::arguments::validate();
122
123 switch (barrierType) {
124 case Barrier::DownIn:
125 case Barrier::UpIn:
126 case Barrier::DownOut:
127 case Barrier::UpOut:
128 break;
129 default:
130 QL_FAIL("unknown type");
131 }
132
133 QL_REQUIRE(barrier != Null<Real>(), "no barrier given");
134 QL_REQUIRE(rebate != Null<Real>(), "no rebate given");
135 }
136
137 bool BarrierOption::engine::triggered(Real underlying) const {
138 switch (arguments_.barrierType) {
139 case Barrier::DownIn:
140 case Barrier::DownOut:
141 return underlying < arguments_.barrier;
142 case Barrier::UpIn:
143 case Barrier::UpOut:
144 return underlying > arguments_.barrier;
145 default:
146 QL_FAIL("unknown type");
147 }
148 }
149
150}
151
152

source code of quantlib/ql/instruments/barrieroption.cpp

Morty Proxy This is a proxified and sanitized view of the page, visit original site.