• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 20336169357

18 Dec 2025 11:58AM UTC coverage: 74.15% (-0.1%) from 74.295%
20336169357

Pull #2368

github

web-flow
Merge 57372ce41 into c15a6fecb
Pull Request #2368: Fx options utils - `BlackVolatilitySurfaceDelta` class

109 of 170 new or added lines in 5 files covered. (64.12%)

423 existing lines in 23 files now uncovered.

57618 of 77705 relevant lines covered (74.15%)

8750508.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.03
/ql/instruments/asianoption.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2003, 2004 Ferdinando Ametrano
5
 Copyright (C) 2007 StatPro Italia srl
6
 Copyright (C) 2025 Kareem Fareed
7

8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10

11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16

17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21

22
#include <ql/instruments/asianoption.hpp>
23
#include <ql/time/date.hpp>
24
#include <ql/settings.hpp>
25
#include <algorithm>
26
#include <utility>
27

28
namespace QuantLib {
29

30
    DiscreteAveragingAsianOption::DiscreteAveragingAsianOption(
192✔
31
        Average::Type averageType,
32
        Real runningAccumulator,
33
        Size pastFixings,
34
        std::vector<Date> fixingDates,
35
        const ext::shared_ptr<StrikedTypePayoff>& payoff,
36
        const ext::shared_ptr<Exercise>& exercise)
192✔
37
    : OneAssetOption(payoff, exercise), averageType_(averageType),
192✔
38
      runningAccumulator_(runningAccumulator), pastFixings_(pastFixings),
192✔
39
      fixingDates_(std::move(fixingDates)), allPastFixingsProvided_(false) {
384✔
40
        std::sort(fixingDates_.begin(), fixingDates_.end());
192✔
41

42
        // Add a hard override to the runningAccumulator if pastFixings is 0
43
        // (ie. the option is unseasoned)
44
        if (pastFixings_ == 0) {
192✔
45
            if (averageType == Average::Geometric) {
140✔
46
                runningAccumulator_ = 1.0;
42✔
47
            } else if (averageType == Average::Arithmetic) {
98✔
48
                runningAccumulator_ = 0.0;
98✔
49
            } else {
UNCOV
50
                QL_FAIL("Unrecognised average type, must be Average::Arithmetic or Average::Geometric");
×
51
            }
52
        }
53
    }
192✔
54

55
    DiscreteAveragingAsianOption::DiscreteAveragingAsianOption(
4✔
56
        Average::Type averageType,
57
        std::vector<Date> fixingDates,
58
        const ext::shared_ptr<StrikedTypePayoff>& payoff,
59
        const ext::shared_ptr<Exercise>& exercise,
60
        std::vector<Real> allPastFixings)
4✔
61
    : OneAssetOption(payoff, exercise), averageType_(averageType), runningAccumulator_(0.0),
4✔
62
      pastFixings_(0), fixingDates_(std::move(fixingDates)),
4✔
63
      allPastFixingsProvided_(true), allPastFixings_(std::move(allPastFixings)) {}
8✔
64

65
    void DiscreteAveragingAsianOption::setupArguments(
3,923✔
66
                                       PricingEngine::arguments* args) const {
67

68
        Real runningAccumulator = runningAccumulator_;
3,923✔
69
        Size pastFixings = pastFixings_;
3,923✔
70
        std::vector<Date> fixingDates = fixingDates_;
3,923✔
71

72
        // If the option was initialised with a list of fixings, before pricing we
73
        // compare the evaluation date to the fixing dates, and set up the pastFixings,
74
        // fixingDates, and runningAccumulator accordingly
75
        if (allPastFixingsProvided_) {
3,923✔
76
            std::vector<Date> futureFixingDates = std::vector<Date>();
77
            Date today = Settings::instance().evaluationDate();
8✔
78

79
            pastFixings = 0;
80
            for (auto fixingDate : fixingDates_) {
60✔
81
                if (fixingDate < today) {
52✔
82
                    pastFixings += 1;
14✔
83
                } else {
84
                    futureFixingDates.push_back(fixingDate);
38✔
85
                }
86
            }
87
            fixingDates = futureFixingDates;
8✔
88

89
            if (pastFixings > allPastFixings_.size())
8✔
UNCOV
90
                QL_FAIL("Not enough past fixings have been provided for the required historical fixing dates");
×
91

92
            if (averageType_ == Average::Geometric) {
8✔
93
                runningAccumulator = 1.0;
94
                for (Size i=0; i<pastFixings; i++)
×
UNCOV
95
                    runningAccumulator *= allPastFixings_[i];
×
96

97
            } else if (averageType_ == Average::Arithmetic) {
8✔
98
                runningAccumulator = 0.0;
99
                for (Size i=0; i<pastFixings; i++)
22✔
100
                    runningAccumulator += allPastFixings_[i];
14✔
101

102
            } else {
UNCOV
103
                QL_FAIL("Unrecognised average type, must be Average::Arithmetic or Average::Geometric");
×
104
            }
105

106
        }
107

108
        OneAssetOption::setupArguments(args);
3,923✔
109

110
        auto* moreArgs = dynamic_cast<DiscreteAveragingAsianOption::arguments*>(args);
3,923✔
111
        QL_REQUIRE(moreArgs != nullptr, "wrong argument type");
3,923✔
112
        moreArgs->averageType = averageType_;
3,923✔
113
        moreArgs->runningAccumulator = runningAccumulator;
3,923✔
114
        moreArgs->pastFixings = pastFixings;
3,923✔
115
        moreArgs->fixingDates = fixingDates;
3,923✔
116
    }
3,923✔
117

118
    void DiscreteAveragingAsianOption::arguments::validate() const {
3,923✔
119

120
        OneAssetOption::arguments::validate();
3,923✔
121

122
        QL_REQUIRE(Integer(averageType) != -1, "unspecified average type");
3,923✔
123
        QL_REQUIRE(pastFixings != Null<Size>(), "null past-fixing number");
3,923✔
124
        QL_REQUIRE(runningAccumulator != Null<Real>(), "null running product");
3,923✔
125
        switch (averageType) {
3,923✔
126
            case Average::Arithmetic:
259✔
127
                QL_REQUIRE(runningAccumulator >= 0.0,
259✔
128
                           "non negative running sum required: "
129
                           << runningAccumulator << " not allowed");
130
                break;
131
            case Average::Geometric:
3,664✔
132
                QL_REQUIRE(runningAccumulator > 0.0,
3,664✔
133
                           "positive running product required: "
134
                           << runningAccumulator << " not allowed");
135
                break;
136
            default:
×
UNCOV
137
                QL_FAIL("invalid average type");
×
138
        }
139

140
        // check fixingTimes_ here
141
    }
3,923✔
142

143

144

145

146
    ContinuousAveragingAsianOption::ContinuousAveragingAsianOption(
69✔
147
        Average::Type averageType,
148
        const ext::shared_ptr<StrikedTypePayoff>& payoff,
149
        const ext::shared_ptr<Exercise>& exercise)
69✔
150
    : OneAssetOption(payoff, exercise),
151
      averageType_(averageType)
138✔
152
      {}
69✔
153

154
    ContinuousAveragingAsianOption::ContinuousAveragingAsianOption(
25✔
155
        Average::Type averageType,
156
        Date startDate,
157
        const ext::shared_ptr<StrikedTypePayoff>& payoff,
158
        const ext::shared_ptr<Exercise>& exercise)
25✔
159
    : OneAssetOption(payoff, exercise),
160
      averageType_(averageType),
25✔
161
      startDate_(startDate) {}
50✔
162

163
    void ContinuousAveragingAsianOption::setupArguments(
3,648✔
164
                                       PricingEngine::arguments* args) const {
165

166
        OneAssetOption::setupArguments(args);
3,648✔
167

168
        auto* moreArgs = dynamic_cast<ContinuousAveragingAsianOption::arguments*>(args);
3,648✔
169
        QL_REQUIRE(moreArgs != nullptr, "wrong argument type");
3,648✔
170
        moreArgs->averageType = averageType_;
3,648✔
171
        moreArgs->startDate = startDate_;
3,648✔
172
    }
3,648✔
173

174
    void ContinuousAveragingAsianOption::arguments::validate() const {
3,648✔
175

176
        OneAssetOption::arguments::validate();
3,648✔
177

178
        QL_REQUIRE(Integer(averageType) != -1, "unspecified average type");
3,648✔
179
    }
3,648✔
180

181
}
182

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc