Coverage Report

Created: 2025-10-14 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/commodities/energyfuture.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2008 J. Erik Radmall
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/experimental/commodities/commoditysettings.hpp>
21
#include <ql/experimental/commodities/energyfuture.hpp>
22
#include <ql/settings.hpp>
23
#include <utility>
24
25
namespace QuantLib {
26
27
    EnergyFuture::EnergyFuture(Integer buySell,
28
                               Quantity quantity,
29
                               CommodityUnitCost tradePrice,
30
                               ext::shared_ptr<CommodityIndex> index,
31
                               const CommodityType& commodityType,
32
                               const ext::shared_ptr<SecondaryCosts>& secondaryCosts)
33
0
    : EnergyCommodity(commodityType, secondaryCosts), buySell_(buySell),
34
0
      quantity_(std::move(quantity)), tradePrice_(std::move(tradePrice)), index_(std::move(index)) {
35
0
        registerWith(Settings::instance().evaluationDate());
36
0
        registerWith(index_);
37
0
    }
Unexecuted instantiation: QuantLib::EnergyFuture::EnergyFuture(int, QuantLib::Quantity, QuantLib::CommodityUnitCost, boost::shared_ptr<QuantLib::CommodityIndex>, QuantLib::CommodityType const&, boost::shared_ptr<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::any, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::any> > > > const&)
Unexecuted instantiation: QuantLib::EnergyFuture::EnergyFuture(int, QuantLib::Quantity, QuantLib::CommodityUnitCost, boost::shared_ptr<QuantLib::CommodityIndex>, QuantLib::CommodityType const&, boost::shared_ptr<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::any, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::any> > > > const&)
38
39
0
    bool EnergyFuture::isExpired() const {
40
0
        return false;
41
0
    }
42
43
0
    void EnergyFuture::performCalculations() const {
44
45
0
        NPV_ = 0.0;
46
0
        additionalResults_.clear();
47
48
0
        Date evaluationDate = Settings::instance().evaluationDate();
49
0
        const Currency& baseCurrency =
50
0
            CommoditySettings::instance().currency();
51
0
        const UnitOfMeasure baseUnitOfMeasure =
52
0
            CommoditySettings::instance().unitOfMeasure();
53
54
0
        Real quantityUomConversionFactor =
55
0
            calculateUomConversionFactor(
56
0
                           quantity_.commodityType(),
57
0
                           baseUnitOfMeasure,
58
0
                           quantity_.unitOfMeasure()) * index_->lotQuantity();
59
0
        Real indexUomConversionFactor =
60
0
            calculateUomConversionFactor(index_->commodityType(),
61
0
                                         index_->unitOfMeasure(),
62
0
                                         baseUnitOfMeasure);
63
0
        Real tradePriceUomConversionFactor =
64
0
            calculateUomConversionFactor(quantity_.commodityType(),
65
0
                                         tradePrice_.unitOfMeasure(),
66
0
                                         baseUnitOfMeasure);
67
68
0
        Real tradePriceFxConversionFactor =
69
0
            calculateFxConversionFactor(tradePrice_.amount().currency(),
70
0
                                        baseCurrency, evaluationDate);
71
0
        Real indexPriceFxConversionFactor =
72
0
            calculateFxConversionFactor(index_->currency(), baseCurrency,
73
0
                                        evaluationDate);
74
75
0
        Real quoteValue = 0;
76
77
0
        Date lastQuoteDate = index_->lastQuoteDate();
78
0
        if (lastQuoteDate >= evaluationDate - 1) {
79
0
            quoteValue = index_->fixing(evaluationDate);
80
0
        } else {
81
0
            quoteValue = index_->forwardPrice(evaluationDate);
82
0
            std::ostringstream message;
83
0
            message << "curve [" << index_->name()
84
0
                    << "] has last quote date of "
85
0
                    << io::iso_date(lastQuoteDate)
86
0
                    << " using forward price from ["
87
0
                    << index_->forwardCurve()->name() << "]";
88
0
            addPricingError(PricingError::Warning, message.str());
89
0
        }
90
91
0
        QL_REQUIRE(quoteValue != Null<Real>(),
92
0
                   "missing quote for [" << index_->name() << "]");
93
94
0
        Real tradePriceValue =
95
0
            tradePrice_.amount().value() * tradePriceUomConversionFactor
96
0
            * tradePriceFxConversionFactor;
97
0
        Real quotePriceValue = quoteValue * indexUomConversionFactor
98
0
            * indexPriceFxConversionFactor;
99
100
0
        Real quantityAmount = quantity_.amount() * quantityUomConversionFactor;
101
102
0
        Real delta = (((quotePriceValue - tradePriceValue) * quantityAmount)
103
0
                      * index_->lotQuantity()) * buySell_;
104
105
0
        NPV_ = delta;
106
107
0
        calculateSecondaryCostAmounts(quantity_.commodityType(),
108
0
                                      quantity_.amount(), evaluationDate);
109
0
        for (auto & secondaryCostAmount : secondaryCostAmounts_) {
110
0
            Real amount = secondaryCostAmount.second.value();
111
0
            NPV_ -= amount;
112
0
        }
113
114
        // additionalResults_["brokerCommission"] =
115
        //     -(brokerCommissionValue * quantityAmount);
116
0
    }
117
118
}
119