Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ql/math/ode/fractionalkernelapproximation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ namespace QuantLib {

// (exp(y) - 1) / y, continuous at the origin
inline Real expm1OverX(Real y) {
return (std::fabs(y) < 1e-8) ? 1.0 + 0.5 * y : std::expm1(y) / y;
if (std::fabs(y) < 1e-8)
return 1.0 + 0.5 * y;
return std::expm1(y) / y;
}

/* sin(pi b) / (pi b), the reflection-formula rewriting of
Expand All @@ -47,7 +49,9 @@ namespace QuantLib {
inline Real fractionalKernelNorm(Real b) {
const Real y{M_PI * b};

return (std::fabs(y) < 1e-8) ? 1.0 - y * y / 6.0 : std::sin(y) / y;
if (std::fabs(y) < 1e-8)
return 1.0 - y * y / 6.0;
return std::sin(y) / y;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ namespace QuantLib {
Array result(size);

auto previous = index(0);
auto beta = a*dptr[previous] + b;
Real beta = a*dptr[previous] + b;
QL_REQUIRE(beta != 0.0, "division by zero");
beta = 1.0 / beta;
result[previous] = r[previous] * beta;
Expand Down
2 changes: 1 addition & 1 deletion ql/pricingengines/vanilla/analyticroughhestonengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ namespace QuantLib {
const Real v0 = model_->v0();
const Real a = model_->hurst() + 0.5;

const std::vector<std::complex<Real>> h{solveAdamsRiccati(z, t)};
const std::vector<std::complex<Real>> h = solveAdamsRiccati(z, t);

const Real dt{t / timeSteps_};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -968,9 +968,11 @@ namespace QuantLib {
Matrix spreadVols(2,2,0.);
for (Size i=0; i<2; i++){
for (Size j=0; j<2; j++){
strikes[i][j] = volatilityType_ == VolatilityType::Normal ?
atmForwards[i][j] + strike - atmForward :
(atmForwards[i][j]+atmShifts[i][j])/moneyness - atmShifts[i][j];
if (volatilityType_ == VolatilityType::Normal)
strikes[i][j] = atmForwards[i][j] + strike - atmForward;
else
strikes[i][j] =
(atmForwards[i][j]+atmShifts[i][j])/moneyness - atmShifts[i][j];
if (marketSpreads) {
const Size section =
(optionTimesPreviousIndex+i)*nSwapTenors_ +
Expand Down
6 changes: 3 additions & 3 deletions test-suite/basisswapratehelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,8 @@ void testOvernightOvernightBootstrap(bool externalDiscountCurve,
externalDiscountCurve ? discountCurve : bootstrappedCurveHandle));

Real tolerance = 1e-8;
BOOST_CHECK_SMALL(swap.NPV(), tolerance);
BOOST_CHECK_SMALL(basisHelpers[i]->impliedQuote() - q.basis, tolerance);
QL_CHECK_SMALL(swap.NPV(), tolerance);
QL_CHECK_SMALL(basisHelpers[i]->impliedQuote() - q.basis, tolerance);
}
}

Expand Down Expand Up @@ -789,7 +789,7 @@ BOOST_AUTO_TEST_CASE(testOvernightOvernightTelescopicValueDatesWithSimpleAveragi
fullSimpleCoupon->valueDates().size());
BOOST_CHECK_LT(telescopicCompoundedCoupon->valueDates().size(),
fullCompoundedCoupon->valueDates().size());
BOOST_CHECK_SMALL(telescopicSimpleCoupon->rate() - fullSimpleCoupon->rate(), 1.0e-14);
QL_CHECK_SMALL(telescopicSimpleCoupon->rate() - fullSimpleCoupon->rate(), 1.0e-14);
}

BOOST_AUTO_TEST_CASE(testOvernightIborMarginOnIborLeg) {
Expand Down
10 changes: 5 additions & 5 deletions test-suite/crosscurrencyratehelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,10 +780,10 @@ BOOST_AUTO_TEST_CASE(testMtMHelperMatchesStandaloneWithAsymmetricFxHolidays) {
BOOST_REQUIRE(firstHelperCoupon != nullptr);
BOOST_CHECK_EQUAL(firstHelperCoupon->fxResetDate(), expectedFxFixingDate);
BOOST_CHECK_EQUAL(firstHelperCoupon->fxResetValueDate(), start);
BOOST_CHECK_SMALL(helperSwap->NPV() - standalone->NPV(), 1.0e-12);
BOOST_CHECK_SMALL(helperSwap->fairFxQuoteSpread() - standalone->fairFxQuoteSpread(),
QL_CHECK_SMALL(helperSwap->NPV() - standalone->NPV(), 1.0e-12);
QL_CHECK_SMALL(helperSwap->fairFxQuoteSpread() - standalone->fairFxQuoteSpread(),
1.0e-12);
BOOST_CHECK_SMALL(helperSwap->fairFxQuoteSpread() - basis, 1.0e-10);
QL_CHECK_SMALL(helperSwap->fairFxQuoteSpread() - basis, 1.0e-10);

// Under the previous zero-day convention the first reset is still in the
// future and is projected instead of using today's observed fixing.
Expand Down Expand Up @@ -1058,7 +1058,7 @@ BOOST_AUTO_TEST_CASE(testBasisHelpersWithPaymentLagMatchUnderlyingSwaps) {
collateralCurve, false, true, std::nullopt, 2);
constantHelper.setTermStructure(bootstrappedCurve.get());

BOOST_CHECK_SMALL(constantHelper.impliedQuote() - constantHelper.swap()->fairPaySpread(),
QL_CHECK_SMALL(constantHelper.impliedQuote() - constantHelper.swap()->fairPaySpread(),
1.0e-12);

MtMCrossCurrencyBasisSwapRateHelper resettingHelper(
Expand All @@ -1067,7 +1067,7 @@ BOOST_AUTO_TEST_CASE(testBasisHelpersWithPaymentLagMatchUnderlyingSwaps) {
collateralCurve, false, true, false, std::nullopt, 2);
resettingHelper.setTermStructure(bootstrappedCurve.get());

BOOST_CHECK_SMALL(resettingHelper.impliedQuote() -
QL_CHECK_SMALL(resettingHelper.impliedQuote() -
resettingHelper.swap()->fairFxBaseSpread(),
1.0e-12);
}
Expand Down
2 changes: 1 addition & 1 deletion test-suite/distributions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ BOOST_AUTO_TEST_CASE(testInverseCumulativeStudent) {
Real upper = inv(1.0 - p);
Real error = std::fabs(lower + upper);
Real tolerance = 1.0e-8 *
std::max({1.0, std::fabs(lower), std::fabs(upper)});
std::max<Real>({1.0, std::fabs(lower), std::fabs(upper)});
if (error > tolerance)
BOOST_ERROR("Inverse cumulative Student t distribution "
"symmetry failure:"
Expand Down
10 changes: 5 additions & 5 deletions test-suite/gsr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ BOOST_AUTO_TEST_CASE(testSofrSwaptionPaymentLag) {
Swap::Payer, 1.0, schedule, probe->fairRate(), dc, sofr, 0.0, 2,
Following, calendar);
swap->setPricingEngine(discountingEngine);
BOOST_CHECK_SMALL(swap->NPV(), 1.0e-12);
QL_CHECK_SMALL(swap->NPV(), 1.0e-12);

for (const auto& cashflow : swap->overnightLeg()) {
auto coupon = ext::dynamic_pointer_cast<OvernightIndexedCoupon>(cashflow);
Expand All @@ -1064,19 +1064,19 @@ BOOST_AUTO_TEST_CASE(testSofrSwaptionPaymentLag) {
ext::make_shared<Gaussian1dJamshidianSwaptionEngine>(gsr));
Real gaussianJamshidian = swaption->NPV();

BOOST_CHECK_CLOSE(gaussianJamshidian, gaussian, 0.2);
QL_CHECK_CLOSE(gaussianJamshidian, gaussian, 0.2);
// Conversion to a NonstandardSwap must preserve the payment lag, and the
// nonstandard Gaussian engine must reproduce the standard engine.
auto nonstandardSwap = ext::make_shared<NonstandardSwap>(*swap);
nonstandardSwap->setPricingEngine(discountingEngine);
BOOST_CHECK_EQUAL(nonstandardSwap->paymentLag(), 2);
BOOST_CHECK_SMALL(nonstandardSwap->NPV() - swap->NPV(), 1.0e-12);
QL_CHECK_SMALL(nonstandardSwap->NPV() - swap->NPV(), 1.0e-12);
auto nonstandardSwaption =
ext::make_shared<NonstandardSwaption>(nonstandardSwap, exercise);
nonstandardSwaption->setPricingEngine(
ext::make_shared<Gaussian1dNonstandardSwaptionEngine>(
gsr, 128, 8.0, true, false, Handle<Quote>(), curve));
BOOST_CHECK_CLOSE(nonstandardSwaption->NPV(), gaussian, 0.2);
QL_CHECK_CLOSE(nonstandardSwaption->NPV(), gaussian, 0.2);

// Exercise the same path with variable notionals and margins.
Size coupons = schedule.size() - 1;
Expand Down Expand Up @@ -1129,7 +1129,7 @@ BOOST_AUTO_TEST_CASE(testSofrSwaptionPaymentLag) {
// the variable-notional, variable-margin and payment-lag path. The two
// prices come from separate integrations, so the check is relative but not
// at roundoff level (BOOST_CHECK_CLOSE takes a percentage).
BOOST_CHECK_CLOSE(scaledSwaption->NPV(), 2.0 * payerValue, 1.0e-6);
QL_CHECK_CLOSE(scaledSwaption->NPV(), 2.0 * payerValue, 1.0e-6);
}

BOOST_AUTO_TEST_SUITE_END()
Expand Down
40 changes: 20 additions & 20 deletions test-suite/mtmcrosscurrencybasisswap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,32 +341,32 @@ BOOST_AUTO_TEST_CASE(testFxResetObservationDatesAndProjection) {
if (auto coupon = ext::dynamic_pointer_cast<FxResetCoupon>(cf)) {
BOOST_REQUIRE(resetNo < fxResetRates.size());
Real expectedRate = fxResetPricer->fxRate(coupon->fxReset());
BOOST_CHECK_CLOSE(fxResetRates[resetNo], expectedRate, 1.0e-10);
BOOST_CHECK_CLOSE(fxResetNotionals[resetNo], eurNominal * expectedRate, 1.0e-10);
QL_CHECK_CLOSE(fxResetRates[resetNo], expectedRate, 1.0e-10);
QL_CHECK_CLOSE(fxResetNotionals[resetNo], eurNominal * expectedRate, 1.0e-10);
++resetNo;
}
}
BOOST_CHECK_EQUAL(resetNo, fxResetRates.size());
BOOST_CHECK_CLOSE(fxResetRates.front(), expectedForward, 1.0e-10);
QL_CHECK_CLOSE(fxResetRates.front(), expectedForward, 1.0e-10);

spotQuote->setValue(1.20);
std::vector<Real> bumpedFxResetRates = swap->fxResetRates();
std::vector<Real> bumpedFxResetNotionals = swap->fxResetNotionals();
BOOST_CHECK_CLOSE(bumpedFxResetRates.front(), fxResetRates.front() * 1.20 / spotFx,
QL_CHECK_CLOSE(bumpedFxResetRates.front(), fxResetRates.front() * 1.20 / spotFx,
1.0e-10);
BOOST_CHECK_CLOSE(bumpedFxResetNotionals.front(),
QL_CHECK_CLOSE(bumpedFxResetNotionals.front(),
fxResetNotionals.front() * 1.20 / spotFx, 1.0e-10);
spotQuote->setValue(spotFx);

setFxResetPricer(swap->resettingLeg(), fxResetPricer);
BOOST_CHECK_CLOSE(firstCoupon->nominal(), eurNominal * expectedForward, 1.0e-10);
QL_CHECK_CLOSE(firstCoupon->nominal(), eurNominal * expectedForward, 1.0e-10);

// Omitting the engine's explicit spot settlement date must derive the same
// date from the swap's reset convention.
swap->setPricingEngine(ext::make_shared<DiscountingMtMCrossCurrencyBasisSwapEngine>(
USDCurrency(), usdCurve, EURCurrency(), eurCurve, makeQuoteHandle(spotFx),
std::nullopt, Date(), Date(), spotFxSettleDate));
BOOST_CHECK_SMALL(swap->NPV() - automaticallyDatedNpv, 1.0e-10 * eurNominal);
QL_CHECK_SMALL(swap->NPV() - automaticallyDatedNpv, 1.0e-10 * eurNominal);

// The equivalent reference-date FX quote must give the same result when an
// explicit reference-date settlement overrides the convention.
Expand All @@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE(testFxResetObservationDatesAndProjection) {
swap->setPricingEngine(ext::make_shared<DiscountingMtMCrossCurrencyBasisSwapEngine>(
USDCurrency(), usdCurve, EURCurrency(), eurCurve, makeQuoteHandle(referenceDateFx),
std::nullopt, Date(), Date(), today));
BOOST_CHECK_SMALL(swap->NPV() - automaticallyDatedNpv, 1.0e-10 * eurNominal);
QL_CHECK_SMALL(swap->NPV() - automaticallyDatedNpv, 1.0e-10 * eurNominal);
}

BOOST_AUTO_TEST_CASE(testResetFixingStateUsesEvaluationDate) {
Expand All @@ -397,12 +397,12 @@ BOOST_AUTO_TEST_CASE(testResetFixingStateUsesEvaluationDate) {

// Although today's fixing precedes the curves' spot-date reference, it is
// forecast when no fixing has been published yet.
BOOST_CHECK_CLOSE(pricer.fxRate(reset), spotFx, 1.0e-12);
QL_CHECK_CLOSE(pricer.fxRate(reset), spotFx, 1.0e-12);

Real publishedFixing = 1.25;
ExchangeRateManager::instance().add(
ExchangeRate(EURCurrency(), USDCurrency(), publishedFixing), today, today);
BOOST_CHECK_CLOSE(pricer.fxRate(reset), publishedFixing, 1.0e-12);
QL_CHECK_CLOSE(pricer.fxRate(reset), publishedFixing, 1.0e-12);

ExchangeRateManager::instance().clear();
Settings::instance().enforcesTodaysHistoricFixings() = true;
Expand Down Expand Up @@ -512,7 +512,7 @@ BOOST_AUTO_TEST_CASE(testKnownFxResetBeforeAccrualStart) {
swap->resettingLeg(),
ext::make_shared<DiscountingFxResetPricer>(
EURCurrency(), USDCurrency(), eurCurve, usdCurve, makeQuoteHandle(1.10), true));
BOOST_CHECK_CLOSE(firstCoupon->nominal(), eurNominal * fixedFx, 1.0e-10);
QL_CHECK_CLOSE(firstCoupon->nominal(), eurNominal * fixedFx, 1.0e-10);
}

BOOST_AUTO_TEST_CASE(testResettableLegCashFlowsMatchLegResults) {
Expand Down Expand Up @@ -566,7 +566,7 @@ BOOST_AUTO_TEST_CASE(testResettableLegCashFlowsMatchLegResults) {
Date reset = coupon->fxResetDate();
Real expected = usdNominal * (1.0 / spotFx) * usdCurve->discount(reset) /
eurCurve->discount(reset);
BOOST_CHECK_CLOSE(coupon->nominal(), expected, 1.0e-8);
QL_CHECK_CLOSE(coupon->nominal(), expected, 1.0e-8);
} else if (ext::dynamic_pointer_cast<FxResetNotionalExchange>(cf)) {
++exchangeCount;
} else {
Expand All @@ -575,7 +575,7 @@ BOOST_AUTO_TEST_CASE(testResettableLegCashFlowsMatchLegResults) {
}

BOOST_CHECK_EQUAL(exchangeCount, couponCount + 1);
BOOST_CHECK_SMALL(npv - legNpv, 1.0e-8 * usdNominal);
QL_CHECK_SMALL(npv - legNpv, 1.0e-8 * usdNominal);
}

BOOST_AUTO_TEST_CASE(testSameDayResetUsesSpot) {
Expand Down Expand Up @@ -655,7 +655,7 @@ BOOST_AUTO_TEST_CASE(testFxSettlementAndNpvDateConsistency) {
std::nullopt, Date(), Date(), fxSettlementDate));

Real tolerance = 1.0e-10 * usdNominal;
BOOST_CHECK_SMALL(settlementSwap->NPV() - referenceNpv, tolerance);
QL_CHECK_SMALL(settlementSwap->NPV() - referenceNpv, tolerance);

Date npvDate = cal.advance(today, 9 * Months);
auto forwardNpvSwap = makeSwap();
Expand All @@ -664,9 +664,9 @@ BOOST_AUTO_TEST_CASE(testFxSettlementAndNpvDateConsistency) {
USDCurrency(), usdCurve, EURCurrency(), eurCurve, makeQuoteHandle(referenceSpot),
std::nullopt, Date(), npvDate));
DiscountFactor domesticNpvDateDiscount = usdCurve->discount(npvDate);
BOOST_CHECK_SMALL(forwardNpvSwap->NPV() * domesticNpvDateDiscount - referenceNpv,
QL_CHECK_SMALL(forwardNpvSwap->NPV() * domesticNpvDateDiscount - referenceNpv,
tolerance);
BOOST_CHECK_CLOSE(forwardNpvSwap->npvDateDiscount(), domesticNpvDateDiscount, 1.0e-10);
QL_CHECK_CLOSE(forwardNpvSwap->npvDateDiscount(), domesticNpvDateDiscount, 1.0e-10);
}

BOOST_AUTO_TEST_CASE(testSeasonedResetPeriodNeedsExchangeRate) {
Expand Down Expand Up @@ -963,7 +963,7 @@ BOOST_AUTO_TEST_CASE(testSeasonedOvernightLegsMatchConstantNotional) {
USDCurrency(), usdCurve, EURCurrency(), eurCurve, spot));

Real tol = 1.0e-6 * usdNominal;
BOOST_CHECK_SMALL(mtm->NPV() - ref->NPV(), tol);
QL_CHECK_SMALL(mtm->NPV() - ref->NPV(), tol);

// The FX-resetting coupon must accrue like the reference constant-notional
// coupon built on the realised reset notional: only the overnight fixings
Expand All @@ -981,9 +981,9 @@ BOOST_AUTO_TEST_CASE(testSeasonedOvernightLegsMatchConstantNotional) {
mtm->resettingLeg(),
ext::make_shared<DiscountingFxResetPricer>(
USDCurrency(), EURCurrency(), usdCurve, eurCurve, spot, false));
BOOST_CHECK_CLOSE(mtmCoupon->nominal(), refCoupon->nominal(), 1.0e-8);
BOOST_CHECK_CLOSE(mtmCoupon->accruedAmount(today), refCoupon->accruedAmount(today), 1.0e-8);
BOOST_CHECK_CLOSE(mtmCoupon->amount(), refCoupon->amount(), 1.0e-8);
QL_CHECK_CLOSE(mtmCoupon->nominal(), refCoupon->nominal(), 1.0e-8);
QL_CHECK_CLOSE(mtmCoupon->accruedAmount(today), refCoupon->accruedAmount(today), 1.0e-8);
QL_CHECK_CLOSE(mtmCoupon->amount(), refCoupon->amount(), 1.0e-8);
}

BOOST_AUTO_TEST_CASE(testResetExchangePaymentDates) {
Expand Down
8 changes: 4 additions & 4 deletions test-suite/optionletstripper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ namespace {
// The flat ATM curve and flat surface imply an exact zero adjustment;
// the tight price tolerance below therefore isolates leg conventions.
for (Volatility spread : stripper2->spreadsVol())
BOOST_CHECK_SMALL(spread, 1.0e-12);
QL_CHECK_SMALL(spread, 1.0e-12);

Handle<OptionletVolatilityStructure> vol(
ext::make_shared<StrippedOptionletAdapter>(stripper2));
Expand Down Expand Up @@ -1245,7 +1245,7 @@ namespace {
MakeCapFloor(CapFloor::Cap, tenors.front(), iborIndex,
strikes.front(), 0 * Days)
.withPricingEngine(engine);
BOOST_CHECK_SMALL(cap->NPV() - targetPrices.front(), vars.tolerance);
QL_CHECK_SMALL(cap->NPV() - targetPrices.front(), vars.tolerance);
}

}
Expand Down Expand Up @@ -1311,7 +1311,7 @@ BOOST_AUTO_TEST_CASE(testIborReferenceDateCompatibility) {
ext::shared_ptr<CapFloor> legacyCap =
MakeCapFloor(type, capFloorLength, iborIndex, vars.strikes[j], 0 * Days)
.withPricingEngine(legacyEngine);
BOOST_CHECK_SMALL(
QL_CHECK_SMALL(
capFloorPrices[i][j] - legacyCap->NPV(), 1.0e-12);
}
capFloorLength += iborIndex->tenor();
Expand All @@ -1333,7 +1333,7 @@ BOOST_AUTO_TEST_CASE(testIborReferenceDateCompatibility) {
MakeCapFloor(CapFloor::Cap, vars.optionTenors[i], iborIndex,
atmStrikes[i], 0 * Days)
.withPricingEngine(legacyEngine);
BOOST_CHECK_SMALL(atmPrices[i] - legacyCap->NPV(), 1.0e-12);
QL_CHECK_SMALL(atmPrices[i] - legacyCap->NPV(), 1.0e-12);
}
}

Expand Down
4 changes: 2 additions & 2 deletions test-suite/overnightindexedswap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,8 +1108,8 @@ BOOST_AUTO_TEST_CASE(testNonstandardSwapConversionPreservesObservationConvention
converted->setPricingEngine(engine);
simpleSource->setPricingEngine(engine);
simpleConverted->setPricingEngine(engine);
BOOST_CHECK_SMALL(converted->NPV() - source->NPV(), 1.0e-12);
BOOST_CHECK_SMALL(simpleConverted->NPV() - simpleSource->NPV(), 1.0e-12);
QL_CHECK_SMALL(converted->NPV() - source->NPV(), 1.0e-12);
QL_CHECK_SMALL(simpleConverted->NPV() - simpleSource->NPV(), 1.0e-12);
}

BOOST_AUTO_TEST_CASE(testSettlementDaysEffectiveDateConflict) {
Expand Down
4 changes: 2 additions & 2 deletions test-suite/roughhestonmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ BOOST_AUTO_TEST_CASE(testFractionalAdamsScheme) {
return sum;
}();

const std::vector<std::complex<Real>> wc{
const std::vector<std::complex<Real>> wc =
FractionalAdams<std::complex<Real>>(alpha).solve(
[lambda](Real, const std::complex<Real>& x) { return lambda * x; },
std::complex<Real>(1.0), 1.0, 400)};
std::complex<Real>(1.0), 1.0, 400);

if (std::abs(wc.back() - mittagLefflerComplexRef) > mlTol)
BOOST_ERROR("failed to reproduce complex Mittag-Leffler solution of "
Expand Down
Loading
Loading