1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2008 Mark Joshi
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 #include <ql/models/marketmodels/pathwisediscounter.hpp>
20 #include <ql/models/marketmodels/utilities.hpp>
21 #include <algorithm>
22 
23 namespace QuantLib
24 {
25 
MarketModelPathwiseDiscounter(Time paymentTime,const std::vector<Time> & rateTimes)26 MarketModelPathwiseDiscounter::MarketModelPathwiseDiscounter(Time paymentTime,
27                               const std::vector<Time>& rateTimes)
28 {
29     checkIncreasingTimes(rateTimes);
30 
31     numberRates_ = rateTimes.size()-1;
32         before_ = std::lower_bound(rateTimes.begin(), rateTimes.end(),
33                                    paymentTime) - rateTimes.begin();
34 
35         // handle the case where the payment is in the last
36         // period or after the last period
37         if (before_ > rateTimes.size()-2)
38             before_ =  rateTimes.size()-2;
39 
40         beforeWeight_=1.0-(paymentTime-rateTimes[before_])/
41             (rateTimes[before_+1]-rateTimes[before_]);
42 
43         postWeight_  = 1.0 - beforeWeight_;
44         taus_.resize(numberRates_);
45 
46         for (Size i=0; i < numberRates_; ++i)
47             taus_[i] = rateTimes[i+1] - rateTimes[i];
48 
49 }
50 
getFactors(const Matrix &,const Matrix & Discounts,Size currentStep,std::vector<Real> & factors) const51 void MarketModelPathwiseDiscounter::getFactors(
52             const Matrix& , // LIBORRates, for all steps
53             const Matrix& Discounts, // P(t_0, t_j) for j=0,...n for each step
54             Size currentStep,
55             std::vector<Real>& factors) const
56 {
57     Real preDF = Discounts[currentStep][before_];
58     Real postDF = Discounts[currentStep][before_+1];
59 
60     for (Size i=before_+1; i<numberRates_; ++i)
61         factors[i+1] =0.0;
62 
63     if (postWeight_==0.0)
64     {
65         factors[0] = preDF;
66 
67         for (Size i=0; i<before_; ++i)
68             factors[i+1] = -preDF*taus_[i]*Discounts[currentStep][i+1]/Discounts[currentStep][i];
69 
70         factors[before_+1]=0.0;
71 
72         return;
73     }
74 
75     Real df = preDF * std::pow(postDF/preDF, postWeight_);
76 
77     factors[0] = df;
78 
79     for (Size i=0; i<=before_; ++i)
80        factors[i+1] = -df*taus_[i]*Discounts[currentStep][i+1]/Discounts[currentStep][i];
81 
82     factors[before_+1] *= postWeight_;
83 }
84 }
85