Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/instruments/forwardrateagreement.cpp
Line
Count
Source
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
 <https://www.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
#include <ql/event.hpp>
21
#include <ql/indexes/iborindex.hpp>
22
#include <ql/instruments/forwardrateagreement.hpp>
23
#include <utility>
24
#include <iostream>
25
26
namespace QuantLib {
27
28
    ForwardRateAgreement::ForwardRateAgreement(const ext::shared_ptr<IborIndex>& index,
29
                                               const Date& valueDate,
30
                                               Position::Type type,
31
                                               Rate strikeForwardRate,
32
                                               Real notionalAmount,
33
                                               Handle<YieldTermStructure> discountCurve)
34
0
    : ForwardRateAgreement(index, valueDate, index->maturityDate(valueDate), type,
35
0
                           strikeForwardRate, notionalAmount, std::move(discountCurve)) {
36
0
        useIndexedCoupon_ = true;
37
0
    }
Unexecuted instantiation: QuantLib::ForwardRateAgreement::ForwardRateAgreement(boost::shared_ptr<QuantLib::IborIndex> const&, QuantLib::Date const&, QuantLib::Position::Type, double, double, QuantLib::Handle<QuantLib::YieldTermStructure>)
Unexecuted instantiation: QuantLib::ForwardRateAgreement::ForwardRateAgreement(boost::shared_ptr<QuantLib::IborIndex> const&, QuantLib::Date const&, QuantLib::Position::Type, double, double, QuantLib::Handle<QuantLib::YieldTermStructure>)
38
39
    ForwardRateAgreement::ForwardRateAgreement(const ext::shared_ptr<IborIndex>& index,
40
                                               const Date& valueDate,
41
                                               const Date& maturityDate,
42
                                               Position::Type type,
43
                                               Rate strikeForwardRate,
44
                                               Real notionalAmount,
45
                                               Handle<YieldTermStructure> discountCurve)
46
0
    : fraType_(type), notionalAmount_(notionalAmount), index_(index),
47
0
      useIndexedCoupon_(false), dayCounter_(index->dayCounter()),
48
0
      calendar_(index->fixingCalendar()), businessDayConvention_(index->businessDayConvention()),
49
0
      valueDate_(valueDate), maturityDate_(maturityDate),
50
0
      discountCurve_(std::move(discountCurve)) {
51
52
0
        maturityDate_ = calendar_.adjust(maturityDate_, businessDayConvention_);
53
54
0
        registerWith(Settings::instance().evaluationDate());
55
0
        registerWith(discountCurve_);
56
57
0
        QL_REQUIRE(notionalAmount > 0.0, "notionalAmount must be positive");
58
0
        QL_REQUIRE(valueDate_ < maturityDate_, "valueDate must be earlier than maturityDate");
59
60
0
        strikeForwardRate_ = InterestRate(strikeForwardRate,
61
0
                                          index->dayCounter(),
62
0
                                          Simple, Once);
63
0
        registerWith(index_);
64
0
    }
Unexecuted instantiation: QuantLib::ForwardRateAgreement::ForwardRateAgreement(boost::shared_ptr<QuantLib::IborIndex> const&, QuantLib::Date const&, QuantLib::Date const&, QuantLib::Position::Type, double, double, QuantLib::Handle<QuantLib::YieldTermStructure>)
Unexecuted instantiation: QuantLib::ForwardRateAgreement::ForwardRateAgreement(boost::shared_ptr<QuantLib::IborIndex> const&, QuantLib::Date const&, QuantLib::Date const&, QuantLib::Position::Type, double, double, QuantLib::Handle<QuantLib::YieldTermStructure>)
65
66
0
    Date ForwardRateAgreement::fixingDate() const {
67
0
        return index_->fixingDate(valueDate_);
68
0
    }
69
70
0
    bool ForwardRateAgreement::isExpired() const {
71
0
        return detail::simple_event(valueDate_).hasOccurred();
72
0
    }
73
74
0
    Real ForwardRateAgreement::amount() const {
75
0
        calculate();
76
0
        return amount_;
77
0
    }
78
79
0
    InterestRate ForwardRateAgreement::forwardRate() const {
80
0
        calculate();
81
0
        return forwardRate_;
82
0
    }
83
84
0
    void ForwardRateAgreement::setupExpired() const {
85
0
        Instrument::setupExpired();
86
0
        calculateForwardRate();
87
0
    }
88
89
0
    void ForwardRateAgreement::performCalculations() const {
90
0
        calculateAmount();
91
0
        Handle<YieldTermStructure> discount =
92
0
            discountCurve_.empty() ? index_->forwardingTermStructure() : discountCurve_;
93
0
        NPV_ = amount_ * discount->discount(valueDate_);
94
0
    }
95
96
0
    void ForwardRateAgreement::calculateForwardRate() const {
97
0
        if (useIndexedCoupon_)
98
0
            forwardRate_ =
99
0
                InterestRate(index_->fixing(fixingDate()), index_->dayCounter(), Simple, Once);
100
0
        else
101
            // par coupon approximation
102
0
            forwardRate_ =
103
0
                InterestRate((index_->forwardingTermStructure()->discount(valueDate_) /
104
0
                                  index_->forwardingTermStructure()->discount(maturityDate_) -
105
0
                              1.0) /
106
0
                                 index_->dayCounter().yearFraction(valueDate_, maturityDate_),
107
0
                             index_->dayCounter(), Simple, Once);
108
0
    }
109
110
0
    void ForwardRateAgreement::calculateAmount() const {
111
0
        calculateForwardRate();
112
0
        Integer sign = fraType_ == Position::Long? 1 : -1;
113
0
        Rate F = forwardRate_.rate();
114
0
        Rate K = strikeForwardRate_.rate();
115
0
        Time T = forwardRate_.dayCounter().yearFraction(valueDate_, maturityDate_);
116
0
        amount_ = notionalAmount_ * sign * (F - K) * T / (1.0 + F * T);
117
0
    }
118
119
}