Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
optionwrapper.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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#include <ql/option.hpp>
21#include <ql/settings.hpp>
22
23using namespace QuantLib;
24using namespace std;
25
26namespace ore {
27namespace data {
28
29OptionWrapper::OptionWrapper(const QuantLib::ext::shared_ptr<Instrument>& inst, const bool isLongOption,
30 const std::vector<Date>& exerciseDate, const bool isPhysicalDelivery,
31 const std::vector<QuantLib::ext::shared_ptr<Instrument>>& undInst, const Real multiplier,
32 const Real undMultiplier,
33 const std::vector<QuantLib::ext::shared_ptr<QuantLib::Instrument>>& additionalInstruments,
34 const std::vector<Real>& additionalMultipliers)
35 : InstrumentWrapper(inst, multiplier, additionalInstruments, additionalMultipliers), isLong_(isLongOption),
36 isPhysicalDelivery_(isPhysicalDelivery), contractExerciseDates_(exerciseDate),
37 effectiveExerciseDates_(exerciseDate), underlyingInstruments_(undInst),
38 activeUnderlyingInstrument_(undInst.at(0)), undMultiplier_(undMultiplier), exercised_(false), exercisable_(true),
39 exerciseDate_(Date()) {
40 QL_REQUIRE(exerciseDate.size() == undInst.size(), "number of exercise dates ("
41 << exerciseDate.size()
42 << ") must be equal to underlying instrument vector size ("
43 << undInst.size() << ")");
44}
45
46void OptionWrapper::initialise(const vector<Date>& dateGrid) {
47 // set "effective" exercise dates which get used to determine exercise during cube valuation
48 // this is necessary since there is no guarantee that actual exercise dates are included in
49 // the valuation date grid
50 Date today = Settings::instance().evaluationDate();
51 for (Size i = 0; i < contractExerciseDates_.size(); ++i) {
52 effectiveExerciseDates_[i] = Null<Date>();
53 if (contractExerciseDates_[i] > today && contractExerciseDates_[i] <= dateGrid.back()) {
54 // Find the effective exercise date in our grid. We simulate the exercise just after the actual
55 // exercise.This ensures that the QL instrument's NPV is a proper continuation value, i.e.
56 // does not contain the possibility of exercising in to the underlying on the current exercise
57 // date and can therefore it be used as such in the exercise decision made in the exercise()
58 // method of derived classes.
59 auto it = std::lower_bound(dateGrid.begin(), dateGrid.end(), contractExerciseDates_[i]);
61 }
62 }
63}
64
66 exercised_ = false;
67 exerciseDate_ = Date();
68}
69
70Real OptionWrapper::NPV() const {
71 Real addNPV = additionalInstrumentsNPV();
72
73 Date today = Settings::instance().evaluationDate();
74 if (!exercised_) {
75 for (Size i = 0; i < effectiveExerciseDates_.size(); ++i) {
76 if (today == effectiveExerciseDates_[i]) {
77 if (exercise()) {
78 exercised_ = true;
79 exerciseDate_ = today;
80 }
81 }
82 }
83 }
84 if (exercised_) {
85 // if exercised, return underlying npv for physical settlement and also for
86 // cash settlement if we are still on the exercise date (since the cash
87 // settlement takes place strictly after the exercise date usually)
88 // FIXME: we assume that the settlement date lies strictly after the exercise
89 // date, but before or on the next simulation date. Check this explicitly
90 // by introducing the cash settlement date into the option wrapper (note
91 // that we will probably need an effective cash settlement date then to
92 // maintain the relative position to the effective exercise date).
93 Real npv = (isPhysicalDelivery_ || today == exerciseDate_)
95 : 0.0;
96 return npv + addNPV;
97 } else {
98 // if not exercised we just return the original option's NPV
100 return npv + addNPV;
101 }
102}
103
104const std::map<std::string, boost::any>& OptionWrapper::additionalResults() const {
105 static std::map<std::string, boost::any> emptyMap;
106 NPV();
107 if (exercised_) {
108 if (activeUnderlyingInstrument_ != nullptr)
109 return activeUnderlyingInstrument_->additionalResults();
110 else
111 return emptyMap;
112 } else {
113 return instrument_->additionalResults();
114 }
115}
116
118 if (!exercisable_)
119 return false;
120
121 // for European Exercise, we only require that underlying has positive PV
123 return res;
124}
125
127 if (!exercisable_)
128 return false;
129
130 if (Settings::instance().evaluationDate() == effectiveExerciseDates_.back()) {
132 return res;
133 } else {
135 return res;
136 }
137}
138
140 if (!exercisable_)
141 return false;
142
143 // set active underlying instrument
144 Date today = Settings::instance().evaluationDate();
145 for (Size i = 0; i < effectiveExerciseDates_.size(); ++i) {
146 if (today == effectiveExerciseDates_[i]) {
148 break;
149 }
150 }
152 return exercise;
153}
154} // namespace data
155} // namespace ore
bool exercise() const override
bool exercise() const override
bool exercise() const override
QuantLib::Real additionalInstrumentsNPV() const
Real getTimedNPV(const QuantLib::ext::shared_ptr< QuantLib::Instrument > &instr) const
QuantLib::ext::shared_ptr< QuantLib::Instrument > instrument_
const QuantLib::Date & exerciseDate() const
the (actual) date the option was exercised
QuantLib::Real NPV() const override
Return the NPV of this instrument.
QuantLib::Date exerciseDate_
OptionWrapper(const QuantLib::ext::shared_ptr< QuantLib::Instrument > &inst, const bool isLongOption, const std::vector< QuantLib::Date > &exerciseDate, const bool isPhysicalDelivery, const std::vector< QuantLib::ext::shared_ptr< QuantLib::Instrument > > &undInst, const Real multiplier=1.0, const Real undMultiplier=1.0, const std::vector< QuantLib::ext::shared_ptr< QuantLib::Instrument > > &additionalInstruments=std::vector< QuantLib::ext::shared_ptr< QuantLib::Instrument > >(), const std::vector< Real > &additionalMultipliers=std::vector< Real >())
Constructor.
virtual bool exercise() const =0
const std::map< std::string, boost::any > & additionalResults() const override
Return the additional results of this instrument.
std::vector< QuantLib::Date > effectiveExerciseDates_
void initialise(const std::vector< QuantLib::Date > &dates) override
Initialise with the given date grid.
QuantLib::ext::shared_ptr< QuantLib::Instrument > activeUnderlyingInstrument_
Real multiplier2() const override
void reset() override
reset is called every time a new path is about to be priced.
std::vector< QuantLib::ext::shared_ptr< QuantLib::Instrument > > underlyingInstruments_
std::vector< QuantLib::Date > contractExerciseDates_
@ data
Definition: log.hpp:77
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Wrapper for option instruments, tracks whether option has been exercised or not.