1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Allen Kuo
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20/*! \file forward.hpp
21 \brief Base forward class
22*/
23
24#ifndef quantlib_forward_hpp
25#define quantlib_forward_hpp
26
27#include <ql/instrument.hpp>
28#include <ql/position.hpp>
29#include <ql/time/calendar.hpp>
30#include <ql/time/daycounter.hpp>
31#include <ql/interestrate.hpp>
32#include <ql/types.hpp>
33#include <ql/handle.hpp>
34#include <ql/payoff.hpp>
35#include <ql/termstructures/yieldtermstructure.hpp>
36
37namespace QuantLib {
38
39 //! Abstract base forward class
40 /*! Derived classes must implement the virtual functions
41 spotValue() (NPV or spot price) and spotIncome() associated
42 with the specific relevant underlying (e.g. bond, stock,
43 commodity, loan/deposit). These functions must be used to set the
44 protected member variables underlyingSpotValue_ and
45 underlyingIncome_ within performCalculations() in the derived
46 class before the base-class implementation is called.
47
48 spotIncome() refers generically to the present value of
49 coupons, dividends or storage costs.
50
51 discountCurve_ is the curve used to discount forward contract
52 cash flows back to the evaluation day, as well as to obtain
53 forward values for spot values/prices.
54
55 incomeDiscountCurve_, which for generality is not
56 automatically set to the discountCurve_, is the curve used to
57 discount future income/dividends/storage-costs etc back to the
58 evaluation date.
59
60 \todo Add preconditions and tests
61
62 \warning This class still needs to be rigorously tested
63
64 \ingroup instruments
65 */
66 class Forward : public Instrument {
67 public:
68 //! \name Inspectors
69 //@{
70 virtual Date settlementDate() const;
71 const Calendar& calendar() const;
72 BusinessDayConvention businessDayConvention() const;
73 const DayCounter& dayCounter() const;
74 //! term structure relevant to the contract (e.g. repo curve)
75 Handle<YieldTermStructure> discountCurve() const;
76 //! term structure that discounts the underlying's income cash flows
77 Handle<YieldTermStructure> incomeDiscountCurve() const;
78 //! returns whether the instrument is still tradable.
79 bool isExpired() const override;
80 //@}
81
82 //! returns spot value/price of an underlying financial instrument
83 virtual Real spotValue() const = 0;
84 //! NPV of income/dividends/storage-costs etc. of underlying instrument
85 virtual Real spotIncome(const Handle<YieldTermStructure>&
86 incomeDiscountCurve) const = 0;
87
88 //! \name Calculations
89 //@{
90 //! forward value/price of underlying, discounting income/dividends
91 /*! \note if this is a bond forward price, is must be a dirty
92 forward price.
93 */
94 virtual Real forwardValue() const;
95
96 /*! Simple yield calculation based on underlying spot and
97 forward values, taking into account underlying income.
98 When \f$ t>0 \f$, call with:
99 underlyingSpotValue=spotValue(t),
100 forwardValue=strikePrice, to get current yield. For a
101 repo, if \f$ t=0 \f$, impliedYield should reproduce the
102 spot repo rate. For FRA's, this should reproduce the
103 relevant zero rate at the FRA's maturityDate_;
104 */
105 InterestRate impliedYield(Real underlyingSpotValue,
106 Real forwardValue,
107 Date settlementDate,
108 Compounding compoundingConvention,
109 const DayCounter& dayCounter);
110 //@}
111 protected:
112 Forward(DayCounter dayCounter,
113 Calendar calendar,
114 BusinessDayConvention businessDayConvention,
115 Natural settlementDays,
116 ext::shared_ptr<Payoff> payoff,
117 const Date& valueDate,
118 const Date& maturityDate,
119 Handle<YieldTermStructure> discountCurve = Handle<YieldTermStructure>());
120
121 void performCalculations() const override;
122 /*! derived classes must set this, typically via spotIncome() */
123 mutable Real underlyingIncome_;
124 /*! derived classes must set this, typically via spotValue() */
125 mutable Real underlyingSpotValue_;
126
127 DayCounter dayCounter_;
128 Calendar calendar_;
129 BusinessDayConvention businessDayConvention_;
130 Natural settlementDays_;
131 ext::shared_ptr<Payoff> payoff_;
132 /*! valueDate = settlement date (date the fwd contract starts
133 accruing)
134 */
135 Date valueDate_;
136 //! maturityDate of the forward contract or delivery date of underlying
137 Date maturityDate_;
138 Handle<YieldTermStructure> discountCurve_;
139 /*! must set this in derived classes, based on particular underlying */
140 Handle<YieldTermStructure> incomeDiscountCurve_;
141 };
142
143
144 //! Class for forward type payoffs
145 class ForwardTypePayoff : public Payoff {
146 public:
147 ForwardTypePayoff(Position::Type type, Real strike)
148 : type_(type),strike_(strike) {
149 QL_REQUIRE(strike >= 0.0,"negative strike given");
150 }
151 Position::Type forwardType() const { return type_; };
152 Real strike() const { return strike_; };
153 //! \name Payoff interface
154 //@{
155 std::string name() const override { return "Forward"; }
156 std::string description() const override;
157 Real operator()(Real price) const override;
158 //@}
159 protected:
160 Position::Type type_;
161 Real strike_;
162 };
163
164
165
166 // inline definitions
167
168 inline const Calendar& Forward::calendar() const {
169 return calendar_;
170 }
171
172 inline BusinessDayConvention Forward::businessDayConvention() const {
173 return businessDayConvention_;
174 }
175
176 inline const DayCounter& Forward::dayCounter() const {
177 return dayCounter_;
178 }
179
180 inline Handle<YieldTermStructure> Forward::discountCurve() const {
181 return discountCurve_;
182 }
183
184 inline Handle<YieldTermStructure> Forward::incomeDiscountCurve() const {
185 return incomeDiscountCurve_;
186 }
187
188
189 inline std::string ForwardTypePayoff::description() const {
190 std::ostringstream result;
191 result << name() << ", " << strike() << " strike";
192 return result.str();
193 }
194
195 inline Real ForwardTypePayoff::operator()(Real price) const {
196 switch (type_) {
197 case Position::Long:
198 return (price-strike_);
199 case Position::Short:
200 return (strike_-price);
201 default:
202 QL_FAIL("unknown/illegal position type");
203 }
204 }
205
206}
207
208
209#endif
210
211

source code of quantlib/ql/instruments/forward.hpp