1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2005, 2006 Theo Boafo
5 Copyright (C) 2006, 2007 StatPro Italia srl
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 binomialconvertibleengine.hpp
22 \brief binomial engine for convertible bonds
23*/
24
25#ifndef quantlib_binomial_convertible_engine_hpp
26#define quantlib_binomial_convertible_engine_hpp
27
28#include <ql/instruments/bonds/convertiblebonds.hpp>
29#include <ql/pricingengines/bond/discretizedconvertible.hpp>
30#include <ql/methods/lattices/tflattice.hpp>
31#include <ql/instruments/payoffs.hpp>
32#include <ql/processes/blackscholesprocess.hpp>
33#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
34#include <ql/termstructures/yield/flatforward.hpp>
35#include <utility>
36
37namespace QuantLib {
38
39 //! Binomial Tsiveriotis-Fernandes engine for convertible bonds
40 /* \ingroup hybridengines
41
42 \test the correctness of the returned value is tested by
43 checking it against known results in a few corner cases.
44 */
45 template <class T>
46 class BinomialConvertibleEngine : public ConvertibleBond::engine {
47 public:
48 BinomialConvertibleEngine(ext::shared_ptr<GeneralizedBlackScholesProcess> process,
49 Size timeSteps,
50 const Handle<Quote>& creditSpread,
51 DividendSchedule dividends = DividendSchedule())
52 : process_(std::move(process)), timeSteps_(timeSteps),
53 dividends_(std::move(dividends)), creditSpread_(creditSpread)
54 {
55 QL_REQUIRE(timeSteps>0,
56 "timeSteps must be positive, " << timeSteps <<
57 " not allowed");
58
59 registerWith(h: process_);
60 registerWith(h: creditSpread);
61 }
62 void calculate() const override;
63 const Handle<Quote>& creditSpread() const { return creditSpread_; }
64 const DividendSchedule& dividends() const { return dividends_; }
65
66 private:
67 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
68 Size timeSteps_;
69 DividendSchedule dividends_;
70 Handle<Quote> creditSpread_;
71 };
72
73
74 template <class T>
75 void BinomialConvertibleEngine<T>::calculate() const {
76
77 DayCounter rfdc = process_->riskFreeRate()->dayCounter();
78 DayCounter divdc = process_->dividendYield()->dayCounter();
79 DayCounter voldc = process_->blackVolatility()->dayCounter();
80 Calendar volcal = process_->blackVolatility()->calendar();
81
82 Real s0 = process_->x0();
83 QL_REQUIRE(s0 > 0.0, "negative or null underlying");
84 Volatility v = process_->blackVolatility()->blackVol(
85 d: arguments_.exercise->lastDate(), strike: s0);
86 Date maturityDate = arguments_.exercise->lastDate();
87 Rate riskFreeRate = process_->riskFreeRate()->zeroRate(
88 d: maturityDate, resultDayCounter: rfdc, comp: Continuous, freq: NoFrequency);
89 Rate q = process_->dividendYield()->zeroRate(
90 d: maturityDate, resultDayCounter: divdc, comp: Continuous, freq: NoFrequency);
91 Date referenceDate = process_->riskFreeRate()->referenceDate();
92
93 // subtract dividends
94 Size i;
95 for (i=0; i<dividends_.size(); i++) {
96 if (dividends_[i]->date() >= referenceDate)
97 s0 -= dividends_[i]->amount() *
98 process_->riskFreeRate()->discount(d: dividends_[i]->date());
99 }
100 QL_REQUIRE(s0 > 0.0,
101 "negative value after subtracting dividends");
102
103 // binomial trees with constant coefficient
104 Handle<Quote> underlying(ext::shared_ptr<Quote>(new SimpleQuote(s0)));
105 Handle<YieldTermStructure> flatRiskFree(ext::shared_ptr<YieldTermStructure>(
106 new FlatForward(referenceDate, riskFreeRate, rfdc)));
107 Handle<YieldTermStructure> flatDividends(
108 ext::shared_ptr<YieldTermStructure>(new FlatForward(referenceDate, q, divdc)));
109 Handle<BlackVolTermStructure> flatVol(ext::shared_ptr<BlackVolTermStructure>(
110 new BlackConstantVol(referenceDate, volcal, v, voldc)));
111
112 Time maturity = rfdc.yearFraction(d1: arguments_.settlementDate, d2: maturityDate);
113 Real strike = arguments_.redemption / arguments_.conversionRatio ;
114
115 ext::shared_ptr<GeneralizedBlackScholesProcess> bs(
116 new GeneralizedBlackScholesProcess(underlying, flatDividends, flatRiskFree, flatVol));
117 ext::shared_ptr<T> tree(new T(bs, maturity, timeSteps_, strike));
118
119 Real creditSpread = creditSpread_->value();
120
121 ext::shared_ptr<Lattice> lattice(new TsiveriotisFernandesLattice<T>(
122 tree, riskFreeRate, maturity, timeSteps_, creditSpread, v, q));
123
124 DiscretizedConvertible convertible(arguments_, bs, dividends_, creditSpread_, TimeGrid(maturity, timeSteps_));
125
126 convertible.initialize(method: lattice, t: maturity);
127 convertible.rollback(to: 0.0);
128 results_.value = results_.settlementValue = convertible.presentValue();
129 QL_ENSURE(results_.value < std::numeric_limits<Real>::max(),
130 "floating-point overflow on tree grid");
131 }
132
133}
134
135
136#endif
137

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of quantlib/ql/pricingengines/bond/binomialconvertibleengine.hpp