QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.38
Loading...
Searching...
No Matches
overnightindexfuture.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) 2018 Roy Zywina
5 Copyright (C) 2019 Eisuke Tani
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
23#include <ql/event.hpp>
24#include <utility>
25
26namespace QuantLib {
27
28 OvernightIndexFuture::OvernightIndexFuture(ext::shared_ptr<OvernightIndex> overnightIndex,
29 const Date& valueDate,
30 const Date& maturityDate,
31 Handle<Quote> convexityAdjustment,
32 RateAveraging::Type averagingMethod)
33 : overnightIndex_(std::move(overnightIndex)), valueDate_(valueDate),
34 maturityDate_(maturityDate), convexityAdjustment_(std::move(convexityAdjustment)),
35 averagingMethod_(averagingMethod) {
36 QL_REQUIRE(overnightIndex_, "null overnight index");
39 registerWith(Settings::instance().evaluationDate());
40 }
41
44 Calendar calendar = overnightIndex_->fixingCalendar();
45 DayCounter dayCounter = overnightIndex_->dayCounter();
46 Handle<YieldTermStructure> forwardCurve = overnightIndex_->forwardingTermStructure();
47 Real avg = 0;
48 Date d1 = valueDate_;
49 // d1 could be a holiday
50 Date fixingDate = calendar.adjust(d1, Preceding);
51 const auto& history = overnightIndex_->timeSeries();
52 Real fwd;
53 while (d1 < maturityDate_) {
54 Date d2 = calendar.advance(d1, 1, Days);
55 if (fixingDate < today) {
56 fwd = history[fixingDate];
57 QL_REQUIRE(fwd != Null<Real>(),
58 "missing rate on " << fixingDate << " for index " << overnightIndex_->name());
59 } else if (fixingDate == today) {
60 fwd = history[fixingDate];
61 if (fwd == Null<Real>())
62 fwd = forwardCurve->forwardRate(fixingDate, d2, dayCounter, Simple).rate();
63 } else {
64 fwd = forwardCurve->forwardRate(fixingDate, d2, dayCounter, Simple).rate();
65 }
66 // The rate is accrued starting from d1 even when the fixing date is earlier.
67 // d2 might be beyond the maturity date if the latter is a holiday.
68 avg += fwd * dayCounter.yearFraction(d1, std::min(d2, maturityDate_));
69 fixingDate = d1 = d2;
70 }
71
72 return avg / dayCounter.yearFraction(valueDate_, maturityDate_);
73 }
74
77 Calendar calendar = overnightIndex_->fixingCalendar();
78 DayCounter dayCounter = overnightIndex_->dayCounter();
79 Handle<YieldTermStructure> forwardCurve = overnightIndex_->forwardingTermStructure();
80 Real prod = 1;
81 Date forwardDiscountStart = valueDate_;
82 if (today > valueDate_) {
83 // can't value on a weekend inside reference period because we
84 // won't know the reset rate until start of next business day.
85 // user can supply an estimate if they really want to do this
86 today = calendar.adjust(today);
87 forwardDiscountStart = today;
88 // for valuations inside the reference period, index quotes
89 // must have been populated in the history
90 const auto& history = overnightIndex_->timeSeries();
91 Date d1 = valueDate_;
92 // d1 could be a holiday
93 Date fixingDate = calendar.adjust(d1, Preceding);
94 while (d1 < today) {
95 Real r = history[fixingDate];
97 "missing rate on " << fixingDate << " for index " << overnightIndex_->name());
98 Date d2 = calendar.advance(d1, 1, Days);
99 // The rate is accrued starting from d1 even when the fixing date is earlier.
100 // We can't get to the maturity date inside this loop,
101 // so we don't need to cap d2 like we do in averagedRate above.
102 prod *= 1 + r * dayCounter.yearFraction(d1, d2);
103 fixingDate = d1 = d2;
104 }
105 // here d1 == today, and we might have today's fixing already
106 if (today < maturityDate_) {
107 Real r = history[today];
108 if (r != Null<Real>()) {
109 Date tomorrow = calendar.advance(today, 1, Days);
110 prod *= 1 + r * dayCounter.yearFraction(today, tomorrow);
111 forwardDiscountStart = tomorrow;
112 }
113 }
114 }
115 // the telescopic part goes from the end of the last known fixing to the maturity
116 DiscountFactor forwardDiscount =
117 forwardCurve->discount(maturityDate_) / forwardCurve->discount(forwardDiscountStart);
118 prod /= forwardDiscount;
119
120 return (prod - 1) / dayCounter.yearFraction(valueDate_, maturityDate_);
121 }
122
124 switch (averagingMethod_) {
126 return averagedRate();
128 return compoundedRate();
129 default:
130 QL_FAIL("unknown compounding convention (" << Integer(averagingMethod_) << ")");
131 }
132 }
133
136 }
137
139 return convexityAdjustment_.empty() ? 0.0 : convexityAdjustment_->value();
140 }
141
143 Rate R = convexityAdjustment() + rate();
144 NPV_ = 100.0 * (1.0 - R);
145 }
146
147}
calendar class
Definition: calendar.hpp:61
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Definition: calendar.cpp:84
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
Definition: calendar.cpp:130
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
virtual bool hasOccurred(const Date &refDate=Date(), ext::optional< bool > includeRefDate=ext::nullopt) const
returns true if an event has already occurred before a date
Definition: event.cpp:28
Shared handle to an observable.
Definition: handle.hpp:41
template class providing a null value for a given type.
Definition: null.hpp:59
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:226
ext::shared_ptr< OvernightIndex > overnightIndex_
void performCalculations() const override
bool isExpired() const override
returns whether the instrument might have value greater than zero.
OvernightIndexFuture(ext::shared_ptr< OvernightIndex > overnightIndex, const Date &valueDate, const Date &maturityDate, Handle< Quote > convexityAdjustment=Handle< Quote >(), RateAveraging::Type averagingMethod=RateAveraging::Compound)
DateProxy & evaluationDate()
the date at which pricing is to be performed.
Definition: settings.hpp:147
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
Base class for events associated with a given date.
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
QL_INTEGER Integer
integer number
Definition: types.hpp:35
Real Rate
interest rates
Definition: types.hpp:70
global repository for past index fixings
Definition: any.hpp:37
Array prod(const SparseMatrix &A, const Array &x)
STL namespace.
Overnight Index Future.
ext::shared_ptr< YieldTermStructure > r