Skip to content

Commit 991d07e

Browse files
committed
Merge branch 'feature/QPR-12959_output' into 'master'
QPR-12959 QPR-13690 QPR-13615 add SpreadedIndexYieldCurve to avoid double counting in fallback Closes QPR-12959 See merge request qs/oreplus!3076
2 parents 352cd1b + 72087c4 commit 991d07e

23 files changed

Lines changed: 180 additions & 277 deletions

Examples/conftest.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# conftest.py
2+
import pytest, os, sys
3+
from pathlib import Path
4+
script_dir = Path(__file__).parents[0]
5+
sys.path.append(os.path.join(script_dir, '../Tools/PythonTools'))
6+
from update_expected_output import copy_existing_files
7+
8+
9+
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
10+
def pytest_runtest_makereport(item, call):
11+
outcome = yield
12+
report = outcome.get_result()
13+
14+
# Only proceed during the "call" phase
15+
if report.when != "call":
16+
return
17+
18+
# Read environment variables
19+
copy_all_output = os.getenv("UPDATE_ALL_EXPECTED_OUTPUT", "").upper() == "TRUE"
20+
copy_failed_output = os.getenv("UPDATE_FAILED_EXPECTED_OUTPUT", "").upper() == "TRUE"
21+
22+
# Logic:
23+
# - UPDATE_ALL_EXPECTED_OUTPUT → always copy
24+
# - UPDATE_FAILED_EXPECTED_OUTPUT → copy only if test failed
25+
if copy_all_output or (copy_failed_output and report.failed):
26+
# Build test path
27+
test_name_props = item.name.split("_", 1)
28+
test_name = test_name_props[1]
29+
test_path = Path(item.config.rootdir) / test_name
30+
31+
copy_existing_files(test_path)
32+
33+
34+

Examples/ore_examples_helper.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,13 @@ def _locate_ore_exe(self):
9494
self.ore_exe = "..\\..\\..\\..\\build\\ore\\App\\RelWithDebInfo\\ore.exe"
9595
elif os.path.isfile("..\\..\\build\\App\\Release\\ore.exe"):
9696
self.ore_exe = "..\\..\\build\\App\\Release\\ore.exe"
97+
elif os.path.isfile("..\\..\\build\\ore\\App\\RelWithDebInfo\\ore.exe"):
98+
self.ore_exe = "..\\..\\build\\ore\\App\\RelWithDebInfo\\ore.exe"
9799
elif os.path.isfile("..\\..\\..\\build\\App\\Release\\ore.exe"):
98100
self.ore_exe = "..\\..\\..\\build\\App\\Release\\ore.exe"
99101
else:
100102
print_on_console("ORE executable not found.")
101-
quit()
103+
sys.exit(1)
102104
else:
103105
if os.path.isfile("..\\..\\App\\bin\\Win32\\Release\\ore.exe"):
104106
self.ore_exe = "..\\..\\App\\bin\\Win32\\Release\\ore.exe"
@@ -110,7 +112,7 @@ def _locate_ore_exe(self):
110112
self.ore_exe = "..\\..\\..\\build\\App\\ore.exe"
111113
else:
112114
print_on_console("ORE executable not found.")
113-
quit()
115+
sys.exit(1)
114116
else:
115117
if os.path.isfile("../../App/build/ore"):
116118
self.ore_exe = "../../App/build/ore"
@@ -138,7 +140,7 @@ def _locate_ore_exe(self):
138140
self.ore_exe = "/ore/App/ore"
139141
else:
140142
print_on_console("ORE executable not found.")
141-
quit()
143+
sys.exit(1)
142144
print_on_console("Using ORE executable " + (os.path.abspath(self.ore_exe)))
143145

144146
def print_headline(self, headline):

OREAnalytics/orea/app/inputparameters.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ void InputParameters::setScenarioReader(const std::string& fileName) {
743743
scenarioReader_ = QuantLib::ext::make_shared<ScenarioFileReader>(
744744
fileName, QuantLib::ext::make_shared<SimpleScenarioFactory>(false));
745745
}
746-
} catch (const std::exception& e) {
746+
} catch (const std::exception&) {
747747
// If the file does not exist or fails, assume it is a scenario string
748748
scenarioReader_ = QuantLib::ext::make_shared<ScenarioBufferReader>(
749749
fileName, QuantLib::ext::make_shared<SimpleScenarioFactory>(true));

OREAnalytics/orea/engine/dependencymarket.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ Handle<IborIndex> DependencyMarket::iborIndex(const string& name, const string&
222222
<< rfrName << "' to OvernightIndex, this is unexpected.");
223223
auto fallbackData = iborFallbackConfig_->fallbackData(name);
224224
if (auto original = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(iip))
225-
ii = Handle<IborIndex>(QuantLib::ext::make_shared<QuantExt::FallbackOvernightIndex>(original, oi, fallbackData.spread,
225+
ii = Handle<IborIndex>(QuantLib::ext::make_shared<QuantExt::FallbackOvernightIndex>(
226+
original, oi, fallbackData.spread,
226227
fallbackData.switchDate, false));
227228
else
228229
ii = Handle<IborIndex>(QuantLib::ext::make_shared<QuantExt::FallbackIborIndex>(*ii, oi, fallbackData.spread,

OREAnalytics/orea/scenario/scenariosimmarket.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ ScenarioSimMarket::ScenarioSimMarket(
510510
i = QuantLib::ext::make_shared<QuantExt::FallbackOvernightIndex>(
511511
original, rfrInd, fallbackData.spread, fallbackData.switchDate,
512512
iborFallbackConfig_->useRfrCurveInSimulationMarket());
513-
else
513+
else
514514
i = QuantLib::ext::make_shared<QuantExt::FallbackIborIndex>(
515515
i, rfrInd, fallbackData.spread, fallbackData.switchDate,
516516
iborFallbackConfig_->useRfrCurveInSimulationMarket());

OREData/ored/marketdata/yieldcurve.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@
4747
#include <qle/termstructures/iborfallbackcurve.hpp>
4848
#include <qle/termstructures/immfraratehelper.hpp>
4949
#include <qle/termstructures/iterativebootstrap.hpp>
50-
#include <qle/termstructures/oisratehelper.hpp>
51-
#include <qle/termstructures/overnightfallbackcurve.hpp>
5250
#include <qle/termstructures/pillaronlyyieldcurve.hpp>
51+
#include <qle/termstructures/oisratehelper.hpp>
5352
#include <qle/termstructures/subperiodsswaphelper.hpp>
5453
#include <qle/termstructures/tenorbasisswaphelper.hpp>
5554
#include <qle/termstructures/weightedyieldtermstructure.hpp>
@@ -1274,7 +1273,7 @@ void YieldCurve::buildIborFallbackCurve(const std::size_t index) {
12741273
DLOG("building ibor fallback curve for '" << segment->iborIndex() << "' with rfrIndex='" << rfrIndexName
12751274
<< "' and spread=" << spread);
12761275
if (auto on = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(originalIndex)) {
1277-
p_[index] = QuantLib::ext::make_shared<OvernightFallbackCurve>(on, rfrIndex, spread, Date::minDate());
1276+
p_[index] = QuantLib::ext::make_shared<IborFallbackCurve>(on, rfrIndex, spread, Date::minDate());
12781277
} else {
12791278
p_[index] = QuantLib::ext::make_shared<IborFallbackCurve>(originalIndex, rfrIndex, spread, Date::minDate());
12801279
}

OREData/ored/portfolio/builders/scriptedtrade.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,6 @@ void ScriptedTradeEngineBuilder::populateFixingsMap(
684684
// all other indices can be handled generically, notice for inf we include the scripting specific
685685
// suffixes #L, #F in the index name, this is handled in the scripted trade builder when populating the
686686
// required fixings
687-
688687
if (i.irIborFallback(iborFallbackConfig)) {
689688
// well, except ibor fallback indices that we handle here...
690689
Size nIbor = 0, nRfr = 0;

OREData/ored/scripting/utilities.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ QuantLib::ext::shared_ptr<FallbackIborIndex> IndexInfo::irIborFallback(const Qua
504504
auto on = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(parseIborIndex(data.rfrIndex));
505505
QL_REQUIRE(on, "IndexInfo::irIborFallback(): could not cast rfr index '"
506506
<< data.rfrIndex << "' for ibor fallback index '" << name_ << "' to an overnight index");
507-
return QuantLib::ext::make_shared<FallbackIborIndex>(irIbor_, on, data.spread, data.switchDate, false);
507+
return QuantLib::ext::make_shared<FallbackIborIndex>(irIbor_, on, data.spread, data.switchDate, irIbor_->forwardingTermStructure());
508508
}
509509
return nullptr;
510510
}
@@ -519,7 +519,8 @@ IndexInfo::irOvernightFallback(const QuantLib::ext::shared_ptr<IborFallbackConfi
519519
QL_REQUIRE(on, "IndexInfo::irIborFallback(): could not cast rfr index '"
520520
<< data.rfrIndex << "' for ibor fallback index '" << name_ << "' to an overnight index");
521521
if (auto original = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(irIbor_))
522-
return QuantLib::ext::make_shared<FallbackOvernightIndex>(original, on, data.spread, data.switchDate, false);
522+
return QuantLib::ext::make_shared<FallbackOvernightIndex>(original, on, data.spread, data.switchDate,
523+
original->forwardingTermStructure());
523524
else
524525
return nullptr;
525526
}

OREData/ored/scripting/utilities.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ class IndexInfo {
117117
QuantLib::ext::shared_ptr<FallbackIborIndex> irIborFallback(const QuantLib::ext::shared_ptr<IborFallbackConfig>& iborFallbackConfig,
118118
const Date& asof = QuantLib::Date::maxDate()) const;
119119
// nullptr if it is no overnight fallback index
120-
QuantLib::ext::shared_ptr<FallbackOvernightIndex> irOvernightFallback(const QuantLib::ext::shared_ptr<IborFallbackConfig>& iborFallbackConfig,
120+
QuantLib::ext::shared_ptr<FallbackOvernightIndex>
121+
irOvernightFallback(const QuantLib::ext::shared_ptr<IborFallbackConfig>& iborFallbackConfig,
121122
const Date& asof = QuantLib::Date::maxDate()) const;
122123
QuantLib::ext::shared_ptr<SwapIndex> irSwap() const { return irSwap_; }
123124
QuantLib::ext::shared_ptr<ZeroInflationIndex> inf() const { return inf_; }

QuantExt/qle/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,6 @@ termstructures/oisratehelper.cpp
401401
termstructures/optionletstripper.cpp
402402
termstructures/optionletstripper1.cpp
403403
termstructures/optionletstripper2.cpp
404-
termstructures/overnightfallbackcurve.cpp
405404
termstructures/parametricvolatility.cpp
406405
termstructures/parametricvolatilitysmilesection.cpp
407406
termstructures/pricetermstructure.cpp
@@ -1010,7 +1009,6 @@ termstructures/optionletstripper1.hpp
10101009
termstructures/optionletstripper2.hpp
10111010
termstructures/optionletstripperwithatm.hpp
10121011
termstructures/optionpricesurface.hpp
1013-
termstructures/overnightfallbackcurve.hpp
10141012
termstructures/parametricvolatility.hpp
10151013
termstructures/parametricvolatilitysmilesection.hpp
10161014
termstructures/piecewiseatmoptionletcurve.hpp

0 commit comments

Comments
 (0)