Coverage Report

Created: 2026-08-14 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/instruments/bmaswap.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2007 Roland Lichters
5
 Copyright (C) 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
 <https://www.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
#include <ql/instruments/bmaswap.hpp>
22
#include <ql/cashflows/iborcoupon.hpp>
23
#include <ql/cashflows/averagebmacoupon.hpp>
24
25
namespace QuantLib {
26
27
    BMASwap::BMASwap(Type type,
28
                     Real nominal,
29
                     // Libor leg
30
                     Schedule liborSchedule,
31
                     Real liborFraction,
32
                     Spread liborSpread,
33
                     const ext::shared_ptr<IborIndex>& liborIndex,
34
                     const DayCounter& liborDayCount,
35
                     // BMA leg
36
                     Schedule bmaSchedule,
37
                     const ext::shared_ptr<BMAIndex>& bmaIndex,
38
                     const DayCounter& bmaDayCount)
39
0
    : Swap(2), type_(type), nominal_(nominal),
40
0
      liborFraction_(liborFraction), liborSpread_(liborSpread)  {
41
42
0
        BusinessDayConvention convention =
43
0
            liborSchedule.businessDayConvention();
44
45
0
        legs_[0] = IborLeg(std::move(liborSchedule), liborIndex)
46
0
            .withNotionals(nominal)
47
0
            .withPaymentDayCounter(liborDayCount)
48
0
            .withPaymentAdjustment(convention)
49
0
            .withFixingDays(liborIndex->fixingDays())
50
0
            .withGearings(liborFraction)
51
0
            .withSpreads(liborSpread);
52
53
0
        auto bmaConvention = bmaSchedule.businessDayConvention();
54
55
0
        legs_[1] = AverageBMALeg(std::move(bmaSchedule), bmaIndex)
56
0
            .withNotionals(nominal)
57
0
            .withPaymentDayCounter(bmaDayCount)
58
0
            .withPaymentAdjustment(bmaConvention);
59
60
0
        for (Size j=0; j<2; ++j) {
61
0
            for (auto& i : legs_[j])
62
0
                registerWith(i);
63
0
        }
64
65
0
        switch (type_) {
66
0
          case Payer:
67
0
            payer_[0] = +1.0;
68
0
            payer_[1] = -1.0;
69
0
            break;
70
0
          case Receiver:
71
0
            payer_[0] = -1.0;
72
0
            payer_[1] = +1.0;
73
0
            break;
74
0
          default:
75
0
            QL_FAIL("Unknown BMA-swap type");
76
0
        }
77
0
    }
Unexecuted instantiation: QuantLib::BMASwap::BMASwap(QuantLib::Swap::Type, double, QuantLib::Schedule, double, double, boost::shared_ptr<QuantLib::IborIndex> const&, QuantLib::DayCounter const&, QuantLib::Schedule, boost::shared_ptr<QuantLib::BMAIndex> const&, QuantLib::DayCounter const&)
Unexecuted instantiation: QuantLib::BMASwap::BMASwap(QuantLib::Swap::Type, double, QuantLib::Schedule, double, double, boost::shared_ptr<QuantLib::IborIndex> const&, QuantLib::DayCounter const&, QuantLib::Schedule, boost::shared_ptr<QuantLib::BMAIndex> const&, QuantLib::DayCounter const&)
78
79
0
    Real BMASwap::liborFraction() const {
80
0
        return liborFraction_;
81
0
    }
82
83
0
    Spread BMASwap::liborSpread() const {
84
0
        return liborSpread_;
85
0
    }
86
87
0
    Real BMASwap::nominal() const {
88
0
        return nominal_;
89
0
    }
90
91
0
    Swap::Type BMASwap::type() const {
92
0
        return type_;
93
0
    }
94
95
0
    const Leg& BMASwap::liborLeg() const {
96
0
        return legs_[0];
97
0
    }
98
99
0
    const Leg& BMASwap::bmaLeg() const {
100
0
        return legs_[1];
101
0
    }
102
103
104
0
    Real BMASwap::liborLegBPS() const {
105
0
        calculate();
106
0
        QL_REQUIRE(legBPS_[0] != Null<Real>(), "result not available");
107
0
        return legBPS_[0];
108
0
    }
109
110
0
    Real BMASwap::liborLegNPV() const {
111
0
        calculate();
112
0
        QL_REQUIRE(legNPV_[0] != Null<Real>(), "result not available");
113
0
        return legNPV_[0];
114
0
    }
115
116
0
    Real BMASwap::fairLiborFraction() const {
117
0
        static Spread basisPoint = 1.0e-4;
118
119
0
        Real spreadNPV = (liborSpread_/basisPoint)*liborLegBPS();
120
0
        Real pureLiborNPV = liborLegNPV() - spreadNPV;
121
0
        QL_REQUIRE(pureLiborNPV != 0.0,
122
0
                   "result not available (null libor NPV)");
123
0
        return -liborFraction_ * (bmaLegNPV() + spreadNPV) / pureLiborNPV;
124
0
    }
125
126
0
    Spread BMASwap::fairLiborSpread() const {
127
0
        static Spread basisPoint = 1.0e-4;
128
129
0
        return liborSpread_ - NPV()/(liborLegBPS()/basisPoint);
130
0
    }
131
132
0
    Real BMASwap::bmaLegBPS() const {
133
0
        calculate();
134
0
        QL_REQUIRE(legBPS_[1] != Null<Real>(), "result not available");
135
0
        return legBPS_[1];
136
0
    }
137
138
0
    Real BMASwap::bmaLegNPV() const {
139
0
        calculate();
140
0
        QL_REQUIRE(legNPV_[1] != Null<Real>(), "result not available");
141
0
        return legNPV_[1];
142
0
    }
143
144
}