Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cashsettledeuropeanoption.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
19#include <ql/event.hpp>
20#include <ql/exercise.hpp>
21#include <ql/settings.hpp>
23
24using QuantLib::BusinessDayConvention;
25using QuantLib::Calendar;
26using QuantLib::Date;
27using QuantLib::EuropeanExercise;
28using QuantLib::Index;
29using QuantLib::Natural;
30using QuantLib::Null;
31using QuantLib::Option;
32using QuantLib::PlainVanillaPayoff;
33using QuantLib::CashOrNothingPayoff;
34using QuantLib::PricingEngine;
35using QuantLib::Real;
36using QuantLib::Settings;
37using QuantLib::StrikedTypePayoff;
38using QuantLib::VanillaOption;
39using QuantLib::io::iso_date;
40
41namespace {
42
43// Shared check of arguments
44void check(const Date& expiryDate, const Date& paymentDate, bool automaticExercise,
45 const QuantLib::ext::shared_ptr<Index>& underlying, bool exercised, Real priceAtExercise) {
46
47 using QuantLib::io::iso_date;
48
49 QL_REQUIRE(paymentDate >= expiryDate, "Cash settled European option payment date ("
50 << iso_date(paymentDate)
51 << ") must be greater than or equal to the expiry date ("
52 << iso_date(expiryDate) << ")");
53
54 if (automaticExercise) {
55 QL_REQUIRE(underlying, "Cash settled European option has automatic exercise so we need a valid underlying.");
56 }
57
58 if (exercised) {
59 QL_REQUIRE(priceAtExercise != Null<Real>(), "Cash settled European option was exercised so we need "
60 << "a valid exercise price.");
61 }
62}
63
64} // namespace
65
66namespace QuantExt {
67
68CashSettledEuropeanOption::CashSettledEuropeanOption(Option::Type type, Real strike, const Date& expiryDate,
69 const Date& paymentDate, bool automaticExercise,
70 const QuantLib::ext::shared_ptr<Index>& underlying, bool exercised,
71 Real priceAtExercise)
72 : VanillaOption(QuantLib::ext::make_shared<PlainVanillaPayoff>(type, strike),
73 QuantLib::ext::make_shared<EuropeanExercise>(expiryDate)),
74 paymentDate_(paymentDate), automaticExercise_(automaticExercise), underlying_(underlying), exercised_(false),
75 priceAtExercise_(Null<Real>()) {
76
77 init(exercised, priceAtExercise);
78
79 check(exercise_->lastDate(), paymentDate_, automaticExercise_, underlying_, exercised_, priceAtExercise_);
80}
81
82CashSettledEuropeanOption::CashSettledEuropeanOption(Option::Type type, Real strike, const Date& expiryDate,
83 Natural paymentLag, const Calendar& paymentCalendar,
84 BusinessDayConvention paymentConvention, bool automaticExercise,
85 const QuantLib::ext::shared_ptr<Index>& underlying, bool exercised,
86 Real priceAtExercise)
87 : VanillaOption(QuantLib::ext::make_shared<PlainVanillaPayoff>(type, strike),
88 QuantLib::ext::make_shared<EuropeanExercise>(expiryDate)),
89 automaticExercise_(automaticExercise), underlying_(underlying), exercised_(false),
90 priceAtExercise_(Null<Real>()) {
91
92 init(exercised, priceAtExercise);
93
94 // Derive payment date from exercise date using the lag, calendar and convention.
95 paymentDate_ = paymentCalendar.advance(expiryDate, paymentLag * QuantLib::Days, paymentConvention);
96
97 check(exercise_->lastDate(), paymentDate_, automaticExercise_, underlying_, exercised_, priceAtExercise_);
98}
99
100CashSettledEuropeanOption::CashSettledEuropeanOption(Option::Type type, Real strike, Real cashPayoff,
101 const Date& expiryDate, const Date& paymentDate,
102 bool automaticExercise, const QuantLib::ext::shared_ptr<Index>& underlying,
103 bool exercised, Real priceAtExercise)
104 : VanillaOption(QuantLib::ext::make_shared<CashOrNothingPayoff>(type, strike, cashPayoff),
105 QuantLib::ext::make_shared<EuropeanExercise>(expiryDate)),
106 paymentDate_(paymentDate), automaticExercise_(automaticExercise), underlying_(underlying), exercised_(false),
107 priceAtExercise_(Null<Real>()) {
108
109 init(exercised, priceAtExercise);
110
111 check(exercise_->lastDate(), paymentDate_, automaticExercise_, underlying_, exercised_, priceAtExercise_);
112}
113
114CashSettledEuropeanOption::CashSettledEuropeanOption(Option::Type type, Real strike, Real cashPayoff,
115 const Date& expiryDate, Natural paymentLag,
116 const Calendar& paymentCalendar,
117 BusinessDayConvention paymentConvention, bool automaticExercise,
118 const QuantLib::ext::shared_ptr<Index>& underlying, bool exercised,
119 Real priceAtExercise)
120 : VanillaOption(QuantLib::ext::make_shared<CashOrNothingPayoff>(type, strike, cashPayoff),
121 QuantLib::ext::make_shared<EuropeanExercise>(expiryDate)),
122 automaticExercise_(automaticExercise), underlying_(underlying), exercised_(false),
123 priceAtExercise_(Null<Real>()) {
124
125 init(exercised, priceAtExercise);
126
127 // Derive payment date from exercise date using the lag, calendar and convention.
128 paymentDate_ = paymentCalendar.advance(expiryDate, paymentLag * QuantLib::Days, paymentConvention);
129
130 check(exercise_->lastDate(), paymentDate_, automaticExercise_, underlying_, exercised_, priceAtExercise_);
131}
132
133void CashSettledEuropeanOption::init(bool exercised, Real priceAtExercise) {
134 if (exercised)
135 exercise(priceAtExercise);
136
137 if (automaticExercise_ && underlying_)
138 registerWith(underlying_);
139}
140
141bool CashSettledEuropeanOption::isExpired() const { return QuantLib::detail::simple_event(paymentDate_).hasOccurred(); }
142
143void CashSettledEuropeanOption::setupArguments(PricingEngine::arguments* args) const {
144
145 VanillaOption::setupArguments(args);
146
148
149 // We have a VanillaOption engine that will ignore the deferred payment.
150 if (!arguments)
151 return;
152
153 // Set up the arguments specific to cash settled european option.
154 arguments->paymentDate = paymentDate_;
155 arguments->automaticExercise = automaticExercise_;
156 arguments->underlying = underlying_;
157 arguments->exercised = exercised_;
158 arguments->priceAtExercise = priceAtExercise_;
159}
160
161void CashSettledEuropeanOption::exercise(Real priceAtExercise) {
162 QL_REQUIRE(priceAtExercise != Null<Real>(), "Cannot exercise with a null price.");
163 QL_REQUIRE(Settings::instance().evaluationDate() >= exercise_->lastDate(),
164 "European option cannot be "
165 << "exercised before expiry date. Valuation date " << iso_date(Settings::instance().evaluationDate())
166 << " is before expiry date " << iso_date(exercise_->lastDate()) << ".");
167 exercised_ = true;
168 priceAtExercise_ = priceAtExercise;
169 update();
170}
171
172const Date& CashSettledEuropeanOption::paymentDate() const { return paymentDate_; }
173
174bool CashSettledEuropeanOption::automaticExercise() const { return automaticExercise_; }
175
176const QuantLib::ext::shared_ptr<Index>& CashSettledEuropeanOption::underlying() const { return underlying_; }
177
178bool CashSettledEuropeanOption::exercised() const { return exercised_; }
179
180Real CashSettledEuropeanOption::priceAtExercise() const { return priceAtExercise_; }
181
182void CashSettledEuropeanOption::arguments::validate() const {
183 QuantLib::VanillaOption::arguments::validate();
184 check(exercise->lastDate(), paymentDate, automaticExercise, underlying, exercised, priceAtExercise);
185}
186
187} // namespace QuantExt
cash settled european vanilla option.
QuantLib::ext::shared_ptr< QuantLib::Index > underlying
CashSettledEuropeanOption(QuantLib::Option::Type type, QuantLib::Real strike, const QuantLib::Date &expiryDate, const QuantLib::Date &paymentDate, bool automaticExercise, const QuantLib::ext::shared_ptr< QuantLib::Index > &underlying=nullptr, bool exercised=false, QuantLib::Real priceAtExercise=QuantLib::Null< QuantLib::Real >())
Constructor for cash settled vanilla European option.