1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2007 Cristina Duminuco 5 Copyright (C) 2007 Giorgio Facchinetti 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 21 /*! \file digitalcoupon.hpp 22 \brief Floating-rate coupon with digital call/put option 23 */ 24 25 #ifndef quantlib_digital_coupon_hpp 26 #define quantlib_digital_coupon_hpp 27 28 #include <ql/cashflows/floatingratecoupon.hpp> 29 #include <ql/cashflows/couponpricer.hpp> 30 #include <ql/cashflows/replication.hpp> 31 #include <ql/position.hpp> 32 #include <ql/utilities/null.hpp> 33 34 namespace QuantLib { 35 36 //! Digital-payoff coupon 37 /*! Implementation of a floating-rate coupon with digital call/put option. 38 Payoffs: 39 - Coupon with cash-or-nothing Digital Call 40 rate + csi * payoffRate * Heaviside(rate-strike) 41 - Coupon with cash-or-nothing Digital Put 42 rate + csi * payoffRate * Heaviside(strike-rate) 43 where csi=+1 or csi=-1. 44 - Coupon with asset-or-nothing Digital Call 45 rate + csi * rate * Heaviside(rate-strike) 46 - Coupon with asset-or-nothing Digital Put 47 rate + csi * rate * Heaviside(strike-rate) 48 where csi=+1 or csi=-1. If nakedOption is true, the rate in the 49 payoffs is set to zero. 50 The evaluation of the coupon is made using the call/put spread 51 replication method. 52 */ 53 /*! \ingroup instruments 54 55 \test 56 - the correctness of the returned value in case of Asset-or-nothing 57 embedded option is tested by pricing the digital option with 58 Cox-Rubinstein formula. 59 - the correctness of the returned value in case of deep-in-the-money 60 Asset-or-nothing embedded option is tested vs the expected values of 61 coupon and option. 62 - the correctness of the returned value in case of deep-out-of-the-money 63 Asset-or-nothing embedded option is tested vs the expected values of 64 coupon and option. 65 - the correctness of the returned value in case of Cash-or-nothing 66 embedded option is tested by pricing the digital option with 67 Reiner-Rubinstein formula. 68 - the correctness of the returned value in case of deep-in-the-money 69 Cash-or-nothing embedded option is tested vs the expected values of 70 coupon and option. 71 - the correctness of the returned value in case of deep-out-of-the-money 72 Cash-or-nothing embedded option is tested vs the expected values of 73 coupon and option. 74 - the correctness of the returned value is tested checking the correctness 75 of the call-put parity relation. 76 - the correctness of the returned value is tested by the relationship 77 between prices in case of different replication types. 78 */ 79 class DigitalCoupon : public FloatingRateCoupon { 80 public: 81 //! \name Constructors 82 //@{ 83 //! general constructor 84 DigitalCoupon(const ext::shared_ptr<FloatingRateCoupon>& underlying, 85 Rate callStrike = Null<Rate>(), 86 Position::Type callPosition = Position::Long, 87 bool isCallITMIncluded = false, 88 Rate callDigitalPayoff = Null<Rate>(), 89 Rate putStrike = Null<Rate>(), 90 Position::Type putPosition = Position::Long, 91 bool isPutITMIncluded = false, 92 Rate putDigitalPayoff = Null<Rate>(), 93 const ext::shared_ptr<DigitalReplication>& replication = 94 ext::shared_ptr<DigitalReplication>(), 95 bool nakedOption = false); 96 97 //@} 98 //! \name Coupon interface 99 //@{ 100 Rate rate() const; 101 Rate convexityAdjustment() const; 102 //@} 103 //@} 104 //! \name Digital inspectors 105 //@{ 106 Rate callStrike() const; 107 Rate putStrike() const; 108 Rate callDigitalPayoff() const; 109 Rate putDigitalPayoff() const; hasPut() const110 bool hasPut() const { return hasPutStrike_; } hasCall() const111 bool hasCall() const {return hasCallStrike_; } hasCollar() const112 bool hasCollar() const {return (hasCallStrike_ && hasPutStrike_); } isLongPut() const113 bool isLongPut() const { return (putCsi_==1.); } isLongCall() const114 bool isLongCall() const { return (callCsi_==1.); } underlying() const115 ext::shared_ptr<FloatingRateCoupon> underlying() const { return underlying_; } 116 /*! Returns the call option rate 117 (multiplied by: nominal*accrualperiod*discount is the NPV of the option) 118 */ 119 Rate callOptionRate() const; 120 /*! Returns the put option rate 121 (multiplied by: nominal*accrualperiod*discount is the NPV of the option) 122 */ 123 Rate putOptionRate() const; 124 //@} 125 //! \name Observer interface 126 //@{ 127 void update(); 128 //@} 129 //! \name Visitability 130 //@{ 131 virtual void accept(AcyclicVisitor&); 132 setPricer(const ext::shared_ptr<FloatingRateCouponPricer> & pricer)133 void setPricer( 134 const ext::shared_ptr<FloatingRateCouponPricer>& pricer) { 135 if (pricer_ != 0) 136 unregisterWith(pricer_); 137 pricer_ = pricer; 138 if (pricer_ != 0) 139 registerWith(pricer_); 140 update(); 141 underlying_->setPricer(pricer); 142 } 143 144 protected: 145 //! \name Data members 146 //@{ 147 //! 148 ext::shared_ptr<FloatingRateCoupon> underlying_; 149 //! strike rate for the the call option 150 Rate callStrike_; 151 //! strike rate for the the put option 152 Rate putStrike_; 153 //! multiplicative factor of call payoff 154 Real callCsi_; 155 //! multiplicative factor of put payoff 156 Real putCsi_; 157 //! inclusion flag og the call payoff if the call option ends at-the-money 158 bool isCallATMIncluded_; 159 //! inclusion flag og the put payoff if the put option ends at-the-money 160 bool isPutATMIncluded_; 161 //! digital call option type: if true, cash-or-nothing, if false asset-or-nothing 162 bool isCallCashOrNothing_; 163 //! digital put option type: if true, cash-or-nothing, if false asset-or-nothing 164 bool isPutCashOrNothing_; 165 //! digital call option payoff rate, if any 166 Rate callDigitalPayoff_; 167 //! digital put option payoff rate, if any 168 Rate putDigitalPayoff_; 169 //! the left and right gaps applied in payoff replication for call 170 Real callLeftEps_, callRightEps_; 171 //! the left and right gaps applied in payoff replication for put 172 Real putLeftEps_, putRightEps_; 173 //! 174 bool hasPutStrike_, hasCallStrike_; 175 //! Type of replication 176 Replication::Type replicationType_; 177 //! underlying excluded from the payoff 178 bool nakedOption_; 179 180 //@} 181 private: 182 Rate callPayoff() const; 183 Rate putPayoff() const; 184 185 }; 186 187 } 188 189 #endif 190