From 98822d7ba7c691f2972eb012d6e02b7b1516fc92 Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Sun, 17 Dec 2023 10:02:24 +0100 Subject: [PATCH] Remove unnecessary anonymous namespaces --- test-suite/americanoption.cpp | 414 ++++--- test-suite/andreasenhugevolatilityinterpl.cpp | 431 ++++--- test-suite/array.cpp | 10 +- test-suite/asianoptions.cpp | 117 +- test-suite/assetswap.cpp | 77 +- test-suite/barrieroption.cpp | 114 +- test-suite/basismodels.cpp | 318 +++--- test-suite/basisswapratehelpers.cpp | 305 +++-- test-suite/basketoption.cpp | 221 ++-- test-suite/batesmodel.cpp | 67 +- test-suite/bermudanswaption.cpp | 113 +- test-suite/binaryoption.cpp | 58 +- test-suite/blackdeltacalculator.cpp | 47 +- test-suite/bondforward.cpp | 64 +- test-suite/bonds.cpp | 49 +- test-suite/brownianbridge.cpp | 39 +- test-suite/businessdayconventions.cpp | 35 +- test-suite/callablebonds.cpp | 83 +- test-suite/capfloor.cpp | 163 ++- test-suite/capflooredcoupon.cpp | 248 ++-- test-suite/catbonds.cpp | 43 +- test-suite/cdo.cpp | 85 +- test-suite/cliquetoption.cpp | 245 ++-- test-suite/cms.cpp | 279 +++-- test-suite/cms_normal.cpp | 281 +++-- test-suite/cmsspread.cpp | 9 +- test-suite/compoundoption.cpp | 39 +- test-suite/convertiblebonds.cpp | 81 +- test-suite/covariance.cpp | 17 +- test-suite/crosscurrencyratehelpers.cpp | 324 +++--- test-suite/curvestates.cpp | 139 ++- test-suite/daycounters.cpp | 115 +- test-suite/defaultprobabilitycurves.cpp | 215 ++-- test-suite/digitalcoupon.cpp | 53 +- test-suite/digitaloption.cpp | 27 +- test-suite/distributions.cpp | 328 +++--- test-suite/dividendoption.cpp | 442 ++++--- test-suite/doublebarrieroption.cpp | 71 +- test-suite/doublebinaryoption.cpp | 30 +- test-suite/equitycashflow.cpp | 220 ++-- test-suite/equityindex.cpp | 54 +- test-suite/equitytotalreturnswap.cpp | 316 +++-- test-suite/europeanoption.cpp | 258 +++-- test-suite/extendedtrees.cpp | 272 +++-- test-suite/fdcev.cpp | 25 +- test-suite/fdheston.cpp | 98 +- test-suite/fdmlinearop.cpp | 238 ++-- test-suite/fdsabr.cpp | 153 ++- test-suite/forwardoption.cpp | 265 +++-- test-suite/garch.cpp | 80 +- test-suite/gaussianquadratures.cpp | 175 ++- test-suite/hestonmodel.cpp | 266 +++-- test-suite/hestonslvmodel.cpp | 779 +++++++------ test-suite/hybridhestonhullwhiteprocess.cpp | 200 ++-- test-suite/inflation.cpp | 294 +++-- test-suite/inflationcapfloor.cpp | 305 +++-- test-suite/inflationcapflooredcoupon.cpp | 430 ++++--- test-suite/inflationcpibond.cpp | 191 ++-- test-suite/inflationcpicapfloor.cpp | 454 ++++---- test-suite/inflationcpiswap.cpp | 344 +++--- test-suite/inflationvolatility.cpp | 414 ++++--- test-suite/integrals.cpp | 152 ++- test-suite/interestrates.cpp | 24 +- test-suite/interpolations.cpp | 307 +++-- test-suite/jumpdiffusion.cpp | 29 +- test-suite/lazyobject.cpp | 25 +- test-suite/libormarketmodel.cpp | 65 +- test-suite/libormarketmodelprocess.cpp | 79 +- test-suite/linearleastsquaresregression.cpp | 17 +- test-suite/lookbackoptions.cpp | 37 +- test-suite/lowdiscrepancysequences.cpp | 629 +++++----- test-suite/margrabeoption.cpp | 77 +- test-suite/marketmodel_cms.cpp | 631 +++++----- test-suite/marketmodel_smm.cpp | 617 +++++----- .../marketmodel_smmcapletalphacalibration.cpp | 277 +++-- .../marketmodel_smmcapletcalibration.cpp | 277 +++-- .../marketmodel_smmcaplethomocalibration.cpp | 277 +++-- test-suite/markovfunctional.cpp | 696 ++++++------ test-suite/matrices.cpp | 165 ++- test-suite/mclongstaffschwartzengine.cpp | 134 ++- test-suite/money.cpp | 21 +- test-suite/noarbsabr.cpp | 3 +- test-suite/normalclvmodel.cpp | 19 +- test-suite/nthorderderivativeop.cpp | 531 +++++---- test-suite/nthtodefault.cpp | 105 +- test-suite/numericaldifferentiation.cpp | 91 +- test-suite/observable.cpp | 148 ++- test-suite/ode.cpp | 67 +- test-suite/optimizers.cpp | 502 ++++---- test-suite/optionletstripper.cpp | 614 +++++----- test-suite/overnightindexedcoupon.cpp | 88 +- test-suite/overnightindexedswap.cpp | 333 +++--- test-suite/partialtimebarrieroption.cpp | 15 +- test-suite/pathgenerator.cpp | 179 ++- test-suite/piecewiseyieldcurve.cpp | 1012 ++++++++--------- .../piecewisezerospreadedtermstructure.cpp | 77 +- test-suite/quantooption.cpp | 136 ++- test-suite/quotes.cpp | 15 +- test-suite/rangeaccrual.cpp | 577 +++++----- test-suite/riskneutraldensitycalculator.cpp | 142 ++- test-suite/rounding.cpp | 69 +- test-suite/sampledcurve.cpp | 11 +- test-suite/schedule.cpp | 27 +- test-suite/shortratemodels.cpp | 13 +- test-suite/sofrfutures.cpp | 17 +- test-suite/solvers.cpp | 245 ++-- test-suite/squarerootclvmodel.cpp | 277 +++-- test-suite/stats.cpp | 452 ++++---- test-suite/subperiodcoupons.cpp | 236 ++-- test-suite/swap.cpp | 91 +- test-suite/swapforwardmappings.cpp | 217 ++-- test-suite/swaption.cpp | 126 +- test-suite/swaptionvolatilitycube.cpp | 159 ++- test-suite/swaptionvolatilitymatrix.cpp | 367 +++--- test-suite/swingoption.cpp | 75 +- test-suite/termstructures.cpp | 119 +- test-suite/tracing.cpp | 71 +- test-suite/twoassetbarrieroption.cpp | 33 +- test-suite/ultimateforwardtermstructure.cpp | 180 ++- test-suite/variancegamma.cpp | 32 +- test-suite/varianceswaps.cpp | 69 +- test-suite/vpp.cpp | 291 +++-- test-suite/zerocouponswap.cpp | 307 +++-- 123 files changed, 11946 insertions(+), 12355 deletions(-) diff --git a/test-suite/americanoption.cpp b/test-suite/americanoption.cpp index 2e65e532fdd..36c28ae33a2 100644 --- a/test-suite/americanoption.cpp +++ b/test-suite/americanoption.cpp @@ -72,20 +72,16 @@ BOOST_AUTO_TEST_SUITE(AmericanOptionTests) << " error: " << error << "\n" \ << " tolerance: " << tolerance); -namespace { - - struct AmericanOptionData { - Option::Type type; - Real strike; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time t; // time to maturity - Volatility v; // volatility - Real result; // expected result - }; - -} +struct AmericanOptionData { + Option::Type type; + Real strike; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time t; // time to maturity + Volatility v; // volatility + Real result; // expected result +}; BOOST_AUTO_TEST_CASE(testBaroneAdesiWhaleyValues) { @@ -255,82 +251,79 @@ BOOST_AUTO_TEST_CASE(testBjerksundStenslandValues) { } } -namespace { +/* The data below are from + An Approximate Formula for Pricing American Options + Journal of Derivatives Winter 1999 + Ju, N. +*/ +AmericanOptionData juValues[] = { + // type, strike, spot, q, r, t, vol, value, tol + // These values are from Exhibit 3 - Short dated Put Options + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.006 }, + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 0.201 }, + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 0.433 }, + + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.851 }, + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 1.576 }, + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 1.984 }, + + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 5.000 }, + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 5.084 }, + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 5.260 }, + + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 0.078 }, + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 0.697 }, + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 1.218 }, + + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 1.309 }, + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 2.477 }, + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 3.161 }, + + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 5.059 }, + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 5.699 }, + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 6.231 }, + + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 0.247 }, + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 1.344 }, + { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 2.150 }, + + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 1.767 }, + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 3.381 }, + { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 4.342 }, + + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 5.288 }, + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 6.501 }, + { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 7.367 }, + + // Type in Exhibits 4 and 5 if you have some spare time ;-) + + // type, strike, spot, q, r, t, vol, value, tol + // values from Exhibit 6 - Long dated Call Options with dividends + { Option::Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.2, 2.605 }, + { Option::Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.2, 5.182 }, + { Option::Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.2, 9.065 }, + { Option::Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.2, 14.430 }, + { Option::Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.2, 21.398 }, + + { Option::Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.4, 11.336 }, + { Option::Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.4, 15.711 }, + { Option::Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.4, 20.760 }, + { Option::Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.4, 26.440 }, + { Option::Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.4, 32.709 }, + + { Option::Call, 100.00, 80.00, 0.07, 0.00001, 3.0, 0.3, 5.552 }, + { Option::Call, 100.00, 90.00, 0.07, 0.00001, 3.0, 0.3, 8.868 }, + { Option::Call, 100.00, 100.00, 0.07, 0.00001, 3.0, 0.3, 13.158 }, + { Option::Call, 100.00, 110.00, 0.07, 0.00001, 3.0, 0.3, 18.458 }, + { Option::Call, 100.00, 120.00, 0.07, 0.00001, 3.0, 0.3, 24.786 }, + + { Option::Call, 100.00, 80.00, 0.03, 0.07, 3.0, 0.3, 12.177 }, + { Option::Call, 100.00, 90.00, 0.03, 0.07, 3.0, 0.3, 17.411 }, + { Option::Call, 100.00, 100.00, 0.03, 0.07, 3.0, 0.3, 23.402 }, + { Option::Call, 100.00, 110.00, 0.03, 0.07, 3.0, 0.3, 30.028 }, + { Option::Call, 100.00, 120.00, 0.03, 0.07, 3.0, 0.3, 37.177 } +}; - /* The data below are from - An Approximate Formula for Pricing American Options - Journal of Derivatives Winter 1999 - Ju, N. - */ - AmericanOptionData juValues[] = { - // type, strike, spot, q, r, t, vol, value, tol - // These values are from Exhibit 3 - Short dated Put Options - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.006 }, - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 0.201 }, - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 0.433 }, - - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 0.851 }, - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 1.576 }, - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 1.984 }, - - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.2, 5.000 }, - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.2, 5.084 }, - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.2, 5.260 }, - - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 0.078 }, - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 0.697 }, - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 1.218 }, - - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 1.309 }, - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 2.477 }, - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 3.161 }, - - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.3, 5.059 }, - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.3, 5.699 }, - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.3, 6.231 }, - - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 0.247 }, - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 1.344 }, - { Option::Put, 35.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 2.150 }, - - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 1.767 }, - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 3.381 }, - { Option::Put, 40.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 4.342 }, - - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.0833, 0.4, 5.288 }, - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.3333, 0.4, 6.501 }, - { Option::Put, 45.00, 40.00, 0.0, 0.0488, 0.5833, 0.4, 7.367 }, - - // Type in Exhibits 4 and 5 if you have some spare time ;-) - - // type, strike, spot, q, r, t, vol, value, tol - // values from Exhibit 6 - Long dated Call Options with dividends - { Option::Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.2, 2.605 }, - { Option::Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.2, 5.182 }, - { Option::Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.2, 9.065 }, - { Option::Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.2, 14.430 }, - { Option::Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.2, 21.398 }, - - { Option::Call, 100.00, 80.00, 0.07, 0.03, 3.0, 0.4, 11.336 }, - { Option::Call, 100.00, 90.00, 0.07, 0.03, 3.0, 0.4, 15.711 }, - { Option::Call, 100.00, 100.00, 0.07, 0.03, 3.0, 0.4, 20.760 }, - { Option::Call, 100.00, 110.00, 0.07, 0.03, 3.0, 0.4, 26.440 }, - { Option::Call, 100.00, 120.00, 0.07, 0.03, 3.0, 0.4, 32.709 }, - - { Option::Call, 100.00, 80.00, 0.07, 0.00001, 3.0, 0.3, 5.552 }, - { Option::Call, 100.00, 90.00, 0.07, 0.00001, 3.0, 0.3, 8.868 }, - { Option::Call, 100.00, 100.00, 0.07, 0.00001, 3.0, 0.3, 13.158 }, - { Option::Call, 100.00, 110.00, 0.07, 0.00001, 3.0, 0.3, 18.458 }, - { Option::Call, 100.00, 120.00, 0.07, 0.00001, 3.0, 0.3, 24.786 }, - - { Option::Call, 100.00, 80.00, 0.03, 0.07, 3.0, 0.3, 12.177 }, - { Option::Call, 100.00, 90.00, 0.03, 0.07, 3.0, 0.3, 17.411 }, - { Option::Call, 100.00, 100.00, 0.03, 0.07, 3.0, 0.3, 23.402 }, - { Option::Call, 100.00, 110.00, 0.03, 0.07, 3.0, 0.3, 30.028 }, - { Option::Call, 100.00, 120.00, 0.03, 0.07, 3.0, 0.3, 37.177 } - }; - -} BOOST_AUTO_TEST_CASE(testJuValues) { @@ -456,100 +449,97 @@ BOOST_AUTO_TEST_CASE(testFdValues) { } -namespace { - - template - void testFdGreeks() { - - std::map calculated, expected, tolerance; - tolerance["delta"] = 7.0e-4; - tolerance["gamma"] = 2.0e-4; - //tolerance["theta"] = 1.0e-4; - - Option::Type types[] = { Option::Call, Option::Put }; - Real strikes[] = { 50.0, 99.5, 100.0, 100.5, 150.0 }; - Real underlyings[] = { 100.0 }; - Rate qRates[] = { 0.04, 0.05, 0.06 }; - Rate rRates[] = { 0.01, 0.05, 0.15 }; - Integer years[] = { 1, 2 }; - Volatility vols[] = { 0.11, 0.50, 1.20 }; - - DayCounter dc = Actual360(); - Date today = Date::todaysDate(); - Settings::instance().evaluationDate() = today; - - ext::shared_ptr spot(new SimpleQuote(0.0)); - ext::shared_ptr qRate(new SimpleQuote(0.0)); - Handle qTS(flatRate(qRate, dc)); - ext::shared_ptr rRate(new SimpleQuote(0.0)); - Handle rTS(flatRate(rRate, dc)); - ext::shared_ptr vol(new SimpleQuote(0.0)); - Handle volTS(flatVol(vol, dc)); - - ext::shared_ptr payoff; - - for (auto& type : types) { - for (Real strike : strikes) { - for (int year : years) { - Date exDate = today + year * Years; - ext::shared_ptr exercise(new AmericanExercise(today, exDate)); - ext::shared_ptr payoff(new PlainVanillaPayoff(type, strike)); - ext::shared_ptr stochProcess( - new BlackScholesMertonProcess(Handle(spot), qTS, rTS, volTS)); - - ext::shared_ptr engine(new Engine(stochProcess, 50)); - - VanillaOption option(payoff, exercise); - option.setPricingEngine(engine); - - for (Real u : underlyings) { - for (Real m : qRates) { - for (Real n : rRates) { - for (Real v : vols) { - Rate q = m, r = n; +template +void testFdGreeks() { + + std::map calculated, expected, tolerance; + tolerance["delta"] = 7.0e-4; + tolerance["gamma"] = 2.0e-4; + //tolerance["theta"] = 1.0e-4; + + Option::Type types[] = { Option::Call, Option::Put }; + Real strikes[] = { 50.0, 99.5, 100.0, 100.5, 150.0 }; + Real underlyings[] = { 100.0 }; + Rate qRates[] = { 0.04, 0.05, 0.06 }; + Rate rRates[] = { 0.01, 0.05, 0.15 }; + Integer years[] = { 1, 2 }; + Volatility vols[] = { 0.11, 0.50, 1.20 }; + + DayCounter dc = Actual360(); + Date today = Date::todaysDate(); + Settings::instance().evaluationDate() = today; + + ext::shared_ptr spot(new SimpleQuote(0.0)); + ext::shared_ptr qRate(new SimpleQuote(0.0)); + Handle qTS(flatRate(qRate, dc)); + ext::shared_ptr rRate(new SimpleQuote(0.0)); + Handle rTS(flatRate(rRate, dc)); + ext::shared_ptr vol(new SimpleQuote(0.0)); + Handle volTS(flatVol(vol, dc)); + + ext::shared_ptr payoff; + + for (auto& type : types) { + for (Real strike : strikes) { + for (int year : years) { + Date exDate = today + year * Years; + ext::shared_ptr exercise(new AmericanExercise(today, exDate)); + ext::shared_ptr payoff(new PlainVanillaPayoff(type, strike)); + ext::shared_ptr stochProcess( + new BlackScholesMertonProcess(Handle(spot), qTS, rTS, volTS)); + + ext::shared_ptr engine(new Engine(stochProcess, 50)); + + VanillaOption option(payoff, exercise); + option.setPricingEngine(engine); + + for (Real u : underlyings) { + for (Real m : qRates) { + for (Real n : rRates) { + for (Real v : vols) { + Rate q = m, r = n; + spot->setValue(u); + qRate->setValue(q); + rRate->setValue(r); + vol->setValue(v); + Real value = option.NPV(); + calculated["delta"] = option.delta(); + calculated["gamma"] = option.gamma(); + // calculated["theta"] = option.theta(); + + if (value > spot->value() * 1.0e-5) { + // perturb spot and get delta and gamma + Real du = u * 1.0e-4; + spot->setValue(u + du); + Real value_p = option.NPV(), delta_p = option.delta(); + spot->setValue(u - du); + Real value_m = option.NPV(), delta_m = option.delta(); spot->setValue(u); - qRate->setValue(q); - rRate->setValue(r); - vol->setValue(v); - Real value = option.NPV(); - calculated["delta"] = option.delta(); - calculated["gamma"] = option.gamma(); - // calculated["theta"] = option.theta(); - - if (value > spot->value() * 1.0e-5) { - // perturb spot and get delta and gamma - Real du = u * 1.0e-4; - spot->setValue(u + du); - Real value_p = option.NPV(), delta_p = option.delta(); - spot->setValue(u - du); - Real value_m = option.NPV(), delta_m = option.delta(); - spot->setValue(u); - expected["delta"] = (value_p - value_m) / (2 * du); - expected["gamma"] = (delta_p - delta_m) / (2 * du); - - /* - // perturb date and get theta - Time dT = dc.yearFraction(today-1, today+1); - Settings::instance().setEvaluationDate(today-1); - value_m = option.NPV(); - Settings::instance().setEvaluationDate(today+1); - value_p = option.NPV(); - Settings::instance().setEvaluationDate(today); - expected["theta"] = (value_p - value_m)/dT; - */ - - // compare - std::map::iterator it; - for (it = calculated.begin(); it != calculated.end(); - ++it) { - std::string greek = it->first; - Real expct = expected[greek], calcl = calculated[greek], - tol = tolerance[greek]; - Real error = relativeError(expct, calcl, u); - if (error > tol) { - REPORT_FAILURE(greek, payoff, exercise, u, q, r, - today, v, expct, calcl, error, tol); - } + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); + + /* + // perturb date and get theta + Time dT = dc.yearFraction(today-1, today+1); + Settings::instance().setEvaluationDate(today-1); + value_m = option.NPV(); + Settings::instance().setEvaluationDate(today+1); + value_p = option.NPV(); + Settings::instance().setEvaluationDate(today); + expected["theta"] = (value_p - value_m)/dT; + */ + + // compare + std::map::iterator it; + for (it = calculated.begin(); it != calculated.end(); + ++it) { + std::string greek = it->first; + Real expct = expected[greek], calcl = calculated[greek], + tol = tolerance[greek]; + Real error = relativeError(expct, calcl, u); + if (error > tol) { + REPORT_FAILURE(greek, payoff, exercise, u, q, r, + today, v, expct, calcl, error, tol); } } } @@ -560,7 +550,6 @@ namespace { } } } - } BOOST_AUTO_TEST_CASE(testFdAmericanGreeks) { @@ -1612,37 +1601,36 @@ BOOST_AUTO_TEST_CASE(testQdEngineStandardExample) { } } -namespace { - class QdFpGaussLobattoScheme: public QdFpIterationScheme { - public: - QdFpGaussLobattoScheme(Size m, Size n, Real eps) - : m_(m), n_(n), - integrator_(ext::make_shared( - 100000, QL_MAX_REAL, 0.1*eps)) { - } - Size getNumberOfChebyshevInterpolationNodes() const override { - return n_; - } - Size getNumberOfNaiveFixedPointSteps() const override { - return m_-1; - } - Size getNumberOfJacobiNewtonFixedPointSteps() const override { - return Size(1); - } - ext::shared_ptr - getFixedPointIntegrator() const override { - return integrator_; - } - ext::shared_ptr - getExerciseBoundaryToPriceIntegrator() const override { - return integrator_; - } +class QdFpGaussLobattoScheme: public QdFpIterationScheme { + public: + QdFpGaussLobattoScheme(Size m, Size n, Real eps) + : m_(m), n_(n), + integrator_(ext::make_shared( + 100000, QL_MAX_REAL, 0.1*eps)) { + } + Size getNumberOfChebyshevInterpolationNodes() const override { + return n_; + } + Size getNumberOfNaiveFixedPointSteps() const override { + return m_-1; + } + Size getNumberOfJacobiNewtonFixedPointSteps() const override { + return Size(1); + } + ext::shared_ptr + getFixedPointIntegrator() const override { + return integrator_; + } + ext::shared_ptr + getExerciseBoundaryToPriceIntegrator() const override { + return integrator_; + } + + private: + const Size m_, n_; + const ext::shared_ptr integrator_; +}; - private: - const Size m_, n_; - const ext::shared_ptr integrator_; - }; -} BOOST_AUTO_TEST_CASE(testBulkQdFpAmericanEngine) { BOOST_TEST_MESSAGE("Testing Andersen, Lake and Offengenden " diff --git a/test-suite/andreasenhugevolatilityinterpl.cpp b/test-suite/andreasenhugevolatilityinterpl.cpp index 523c7b142c9..d05158d2cd9 100644 --- a/test-suite/andreasenhugevolatilityinterpl.cpp +++ b/test-suite/andreasenhugevolatilityinterpl.cpp @@ -49,94 +49,92 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(AndreasenHugeVolatilityInterplTests) -namespace { +struct CalibrationData { + const Handle spot; + Handle rTS, qTS; + AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; +}; - struct CalibrationData { - const Handle spot; - Handle rTS, qTS; - AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; - }; +struct CalibrationResults { + AndreasenHugeVolatilityInterpl::CalibrationType calibrationType; + AndreasenHugeVolatilityInterpl::InterpolationType interpolationType; + + Real maxError, avgError; + Real lvMaxError, lvAvgError; +}; + +CalibrationData AndreasenHugeExampleData() { + // This is the example market data from the original paper + // Andreasen J., Huge B., 2010. Volatility Interpolation + // https://ssrn.com/abstract=1694972 + + const Handle spot(ext::make_shared(2772.7)); - struct CalibrationResults { - AndreasenHugeVolatilityInterpl::CalibrationType calibrationType; - AndreasenHugeVolatilityInterpl::InterpolationType interpolationType; + const Time maturityTimes[] = { + 0.025, 0.101, 0.197, 0.274, 0.523, 0.772, + 1.769, 2.267, 2.784, 3.781, 4.778, 5.774 + }; - Real maxError, avgError; - Real lvMaxError, lvAvgError; + const Real raw[][13] = { + { 0.5131, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3366, 0.3291, 0.0000, 0.0000 }, + { 0.5864, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3178, 0.3129, 0.3008, 0.0000 }, + { 0.6597, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3019, 0.2976, 0.2975, 0.0000 }, + { 0.7330, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.2863, 0.2848, 0.2848, 0.0000 }, + { 0.7697, 0.0000, 0.0000, 0.0000, 0.3262, 0.3079, 0.3001, 0.2843, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.8063, 0.0000, 0.0000, 0.0000, 0.3058, 0.2936, 0.2876, 0.2753, 0.2713, 0.2711, 0.2711, 0.2722, 0.2809 }, + { 0.8430, 0.0000, 0.0000, 0.0000, 0.2887, 0.2798, 0.2750, 0.2666, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.8613, 0.3365, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.8796, 0.3216, 0.2906, 0.2764, 0.2717, 0.2663, 0.2637, 0.2575, 0.2555, 0.2580, 0.2585, 0.2611, 0.2693 }, + { 0.8979, 0.3043, 0.2797, 0.2672, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.9163, 0.2880, 0.2690, 0.2578, 0.2557, 0.2531, 0.2519, 0.2497, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.9346, 0.2724, 0.2590, 0.2489, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.9529, 0.2586, 0.2488, 0.2405, 0.2407, 0.2404, 0.2411, 0.2418, 0.2410, 0.2448, 0.2469, 0.2501, 0.2584 }, + { 0.9712, 0.2466, 0.2390, 0.2329, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 0.9896, 0.2358, 0.2300, 0.2253, 0.2269, 0.2284, 0.2299, 0.2347, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.0079, 0.2247, 0.2213, 0.2184, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.0262, 0.2159, 0.2140, 0.2123, 0.2142, 0.2173, 0.2198, 0.2283, 0.2275, 0.2322, 0.2384, 0.2392, 0.2486 }, + { 1.0445, 0.2091, 0.2076, 0.2069, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.0629, 0.2056, 0.2024, 0.2025, 0.2039, 0.2074, 0.2104, 0.2213, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.0812, 0.2045, 0.1982, 0.1984, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.0995, 0.2025, 0.1959, 0.1944, 0.1962, 0.1988, 0.2022, 0.2151, 0.2161, 0.2219, 0.2269, 0.2305, 0.2399 }, + { 1.1178, 0.1933, 0.1929, 0.1920, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.1362, 0.0000, 0.0000, 0.0000, 0.1902, 0.1914, 0.1950, 0.2091, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.1728, 0.0000, 0.0000, 0.0000, 0.1885, 0.1854, 0.1888, 0.2039, 0.2058, 0.2122, 0.2186, 0.2223, 0.2321 }, + { 1.2095, 0.0000, 0.0000, 0.0000, 0.1867, 0.1811, 0.1839, 0.1990, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, + { 1.2461, 0.0000, 0.0000, 0.0000, 0.1871, 0.1785, 0.1793, 0.1945, 0.0000, 0.2054, 0.2103, 0.2164, 0.2251 }, + { 1.3194, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1988, 0.2054, 0.2105, 0.2190 }, + { 1.3927, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1930, 0.2002, 0.2054, 0.2135 }, + { 1.4660, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1849, 0.1964, 0.2012, 0.0000 } }; - CalibrationData AndreasenHugeExampleData() { - // This is the example market data from the original paper - // Andreasen J., Huge B., 2010. Volatility Interpolation - // https://ssrn.com/abstract=1694972 - - const Handle spot(ext::make_shared(2772.7)); - - const Time maturityTimes[] = { - 0.025, 0.101, 0.197, 0.274, 0.523, 0.772, - 1.769, 2.267, 2.784, 3.781, 4.778, 5.774 - }; - - const Real raw[][13] = { - { 0.5131, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3366, 0.3291, 0.0000, 0.0000 }, - { 0.5864, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3178, 0.3129, 0.3008, 0.0000 }, - { 0.6597, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3019, 0.2976, 0.2975, 0.0000 }, - { 0.7330, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.2863, 0.2848, 0.2848, 0.0000 }, - { 0.7697, 0.0000, 0.0000, 0.0000, 0.3262, 0.3079, 0.3001, 0.2843, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.8063, 0.0000, 0.0000, 0.0000, 0.3058, 0.2936, 0.2876, 0.2753, 0.2713, 0.2711, 0.2711, 0.2722, 0.2809 }, - { 0.8430, 0.0000, 0.0000, 0.0000, 0.2887, 0.2798, 0.2750, 0.2666, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.8613, 0.3365, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.8796, 0.3216, 0.2906, 0.2764, 0.2717, 0.2663, 0.2637, 0.2575, 0.2555, 0.2580, 0.2585, 0.2611, 0.2693 }, - { 0.8979, 0.3043, 0.2797, 0.2672, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.9163, 0.2880, 0.2690, 0.2578, 0.2557, 0.2531, 0.2519, 0.2497, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.9346, 0.2724, 0.2590, 0.2489, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.9529, 0.2586, 0.2488, 0.2405, 0.2407, 0.2404, 0.2411, 0.2418, 0.2410, 0.2448, 0.2469, 0.2501, 0.2584 }, - { 0.9712, 0.2466, 0.2390, 0.2329, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 0.9896, 0.2358, 0.2300, 0.2253, 0.2269, 0.2284, 0.2299, 0.2347, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.0079, 0.2247, 0.2213, 0.2184, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.0262, 0.2159, 0.2140, 0.2123, 0.2142, 0.2173, 0.2198, 0.2283, 0.2275, 0.2322, 0.2384, 0.2392, 0.2486 }, - { 1.0445, 0.2091, 0.2076, 0.2069, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.0629, 0.2056, 0.2024, 0.2025, 0.2039, 0.2074, 0.2104, 0.2213, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.0812, 0.2045, 0.1982, 0.1984, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.0995, 0.2025, 0.1959, 0.1944, 0.1962, 0.1988, 0.2022, 0.2151, 0.2161, 0.2219, 0.2269, 0.2305, 0.2399 }, - { 1.1178, 0.1933, 0.1929, 0.1920, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.1362, 0.0000, 0.0000, 0.0000, 0.1902, 0.1914, 0.1950, 0.2091, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.1728, 0.0000, 0.0000, 0.0000, 0.1885, 0.1854, 0.1888, 0.2039, 0.2058, 0.2122, 0.2186, 0.2223, 0.2321 }, - { 1.2095, 0.0000, 0.0000, 0.0000, 0.1867, 0.1811, 0.1839, 0.1990, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 }, - { 1.2461, 0.0000, 0.0000, 0.0000, 0.1871, 0.1785, 0.1793, 0.1945, 0.0000, 0.2054, 0.2103, 0.2164, 0.2251 }, - { 1.3194, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1988, 0.2054, 0.2105, 0.2190 }, - { 1.3927, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1930, 0.2002, 0.2054, 0.2135 }, - { 1.4660, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1849, 0.1964, 0.2012, 0.0000 } - }; - - const DayCounter dc = Actual365Fixed(); - const Date today = Date(1, March, 2010); - - const Handle rTS(flatRate(today, 0.0, dc)); - const Handle qTS(flatRate(today, 0.0, dc)); - - const Size nStrikes = LENGTH(raw); - const Size nMaturities = LENGTH(maturityTimes); - - QL_REQUIRE(nMaturities == LENGTH(raw[1])-1, "check raw data"); - - AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; - - calibrationSet.reserve(std::count_if( + const DayCounter dc = Actual365Fixed(); + const Date today = Date(1, March, 2010); + + const Handle rTS(flatRate(today, 0.0, dc)); + const Handle qTS(flatRate(today, 0.0, dc)); + + const Size nStrikes = LENGTH(raw); + const Size nMaturities = LENGTH(maturityTimes); + + QL_REQUIRE(nMaturities == LENGTH(raw[1])-1, "check raw data"); + + AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; + + calibrationSet.reserve(std::count_if( &raw[0][0], &raw[nStrikes-1][nMaturities]+1, [](Real x) { return x != 0.0; }) - nStrikes); - for (const auto & i : raw) { - const Real strike = spot->value()*i[0]; + for (const auto & i : raw) { + const Real strike = spot->value()*i[0]; - for (Size j=1; j < LENGTH(i); ++j) { - if (i[j] > QL_EPSILON) { - const Date maturity - = today + Period(Size(365*maturityTimes[j-1]), Days); + for (Size j=1; j < LENGTH(i); ++j) { + if (i[j] > QL_EPSILON) { + const Date maturity + = today + Period(Size(365*maturityTimes[j-1]), Days); - const Volatility impliedVol = i[j]; + const Volatility impliedVol = i[j]; - calibrationSet.emplace_back( + calibrationSet.emplace_back( ext::make_shared( ext::make_shared( (strike < spot->value())? Option::Put @@ -144,250 +142,249 @@ namespace { strike), ext::make_shared(maturity)), ext::make_shared(impliedVol) - ); - } + ); } } - - return { spot, rTS, qTS, calibrationSet }; } - void testAndreasenHugeVolatilityInterpolation( - const CalibrationData& data, const CalibrationResults& expected) { + return { spot, rTS, qTS, calibrationSet }; +} - const Handle rTS = data.rTS; - const Handle qTS = data.qTS; +void testAndreasenHugeVolatilityInterpolation( + const CalibrationData& data, const CalibrationResults& expected) { - const DayCounter dc = rTS->dayCounter(); - const Date today = rTS->referenceDate(); - Settings::instance().evaluationDate() = today; + const Handle rTS = data.rTS; + const Handle qTS = data.qTS; - const Handle spot = data.spot; + const DayCounter dc = rTS->dayCounter(); + const Date today = rTS->referenceDate(); + Settings::instance().evaluationDate() = today; - AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet = - data.calibrationSet; + const Handle spot = data.spot; - const ext::shared_ptr - andreasenHugeVolInterplation( + AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet = + data.calibrationSet; + + const ext::shared_ptr + andreasenHugeVolInterplation( ext::make_shared( calibrationSet, spot, rTS, qTS, expected.interpolationType, expected.calibrationType)); - const ext::tuple error = - andreasenHugeVolInterplation->calibrationError(); + const ext::tuple error = + andreasenHugeVolInterplation->calibrationError(); - const Real maxError = ext::get<1>(error); - const Real avgError = ext::get<2>(error); + const Real maxError = ext::get<1>(error); + const Real avgError = ext::get<2>(error); - if (maxError > expected.maxError || avgError > expected.avgError) { - BOOST_FAIL("Failed to reproduce calibration error" - << "\n max calibration error: " << maxError - << "\n average calibration error: " << avgError - << "\n expected max error: " << expected.maxError - << "\n expected average error: " << expected.avgError); - } + if (maxError > expected.maxError || avgError > expected.avgError) { + BOOST_FAIL("Failed to reproduce calibration error" + << "\n max calibration error: " << maxError + << "\n average calibration error: " << avgError + << "\n expected max error: " << expected.maxError + << "\n expected average error: " << expected.avgError); + } - const ext::shared_ptr volatilityAdapter( + const ext::shared_ptr volatilityAdapter( ext::make_shared( andreasenHugeVolInterplation, 1e-12)); - const ext::shared_ptr localVolAdapter( + const ext::shared_ptr localVolAdapter( ext::make_shared( andreasenHugeVolInterplation)); - const ext::shared_ptr localVolProcess( + const ext::shared_ptr localVolProcess( ext::make_shared( spot, qTS, rTS, Handle(volatilityAdapter), Handle(localVolAdapter))); - Real lvAvgError = 0.0, lvMaxError = 0.0; - for (Size i=0, n=0; i < calibrationSet.size(); ++i) { + Real lvAvgError = 0.0, lvMaxError = 0.0; + for (Size i=0, n=0; i < calibrationSet.size(); ++i) { - const ext::shared_ptr option = - calibrationSet[i].first; + const ext::shared_ptr option = + calibrationSet[i].first; - const ext::shared_ptr payoff = - ext::dynamic_pointer_cast( + const ext::shared_ptr payoff = + ext::dynamic_pointer_cast( option->payoff()); - const Real strike = payoff->strike(); - const Option::Type optionType = payoff->optionType(); + const Real strike = payoff->strike(); + const Option::Type optionType = payoff->optionType(); - const Time t = dc.yearFraction(today, option->exercise()->lastDate()); + const Time t = dc.yearFraction(today, option->exercise()->lastDate()); - const Volatility expectedVol = calibrationSet[i].second->value(); - const Volatility calculatedVol = - volatilityAdapter->blackVol(t, strike, true); + const Volatility expectedVol = calibrationSet[i].second->value(); + const Volatility calculatedVol = + volatilityAdapter->blackVol(t, strike, true); - const Real diffVol = std::fabs(expectedVol - calculatedVol); - const Real tol = std::max(1e-10, 1.01*maxError); + const Real diffVol = std::fabs(expectedVol - calculatedVol); + const Real tol = std::max(1e-10, 1.01*maxError); - if (diffVol > tol) { - BOOST_FAIL("Failed to reproduce calibration option price" - << "\n calculated: " << calculatedVol - << "\n expected: " << expectedVol - << "\n difference: " << diffVol - << "\n tolerance: " << tol); - } + if (diffVol > tol) { + BOOST_FAIL("Failed to reproduce calibration option price" + << "\n calculated: " << calculatedVol + << "\n expected: " << expectedVol + << "\n difference: " << diffVol + << "\n tolerance: " << tol); + } - const ext::shared_ptr fdEngine( + const ext::shared_ptr fdEngine( ext::make_shared( localVolProcess, std::max(30, Size(100*t)), 200, 0, FdmSchemeDesc::Douglas(), true)); - option->setPricingEngine(fdEngine); + option->setPricingEngine(fdEngine); - const DiscountFactor discount = rTS->discount(t); - const Real fwd = spot->value()*qTS->discount(t)/discount; + const DiscountFactor discount = rTS->discount(t); + const Real fwd = spot->value()*qTS->discount(t)/discount; - const Volatility lvImpliedVol = blackFormulaImpliedStdDevLiRS( + const Volatility lvImpliedVol = blackFormulaImpliedStdDevLiRS( optionType, strike, fwd, option->NPV(), discount, 0.0, Null(), 1.0, 1e-12)/std::sqrt(t); - const Real lvError = std::fabs(lvImpliedVol - expectedVol); + const Real lvError = std::fabs(lvImpliedVol - expectedVol); - lvMaxError = std::max(lvError, lvMaxError); + lvMaxError = std::max(lvError, lvMaxError); - lvAvgError = (n*lvAvgError + lvError)/(n+1); + lvAvgError = (n*lvAvgError + lvError)/(n+1); - ++n; - } + ++n; + } - if (lvMaxError > expected.lvMaxError || avgError > expected.lvAvgError) { - BOOST_FAIL("Failed to reproduce local volatility calibration error" - << "\n max calibration error: " << lvMaxError - << "\n average calibration error: " << lvAvgError - << "\n expected max error: " << expected.lvMaxError - << "\n expected average error: " << expected.lvAvgError); - } + if (lvMaxError > expected.lvMaxError || avgError > expected.lvAvgError) { + BOOST_FAIL("Failed to reproduce local volatility calibration error" + << "\n max calibration error: " << lvMaxError + << "\n average calibration error: " << lvAvgError + << "\n expected max error: " << expected.lvMaxError + << "\n expected average error: " << expected.lvAvgError); } +} - CalibrationData BorovkovaExampleData() { - // see Svetlana Borovkova, Ferry J. Permana - // Implied volatility in oil markets - // http://www.researchgate.net/publication/46493859_Implied_volatility_in_oil_markets +CalibrationData BorovkovaExampleData() { + // see Svetlana Borovkova, Ferry J. Permana + // Implied volatility in oil markets + // http://www.researchgate.net/publication/46493859_Implied_volatility_in_oil_markets - const DayCounter dc = Actual365Fixed(); - const Date today = Date(4, January, 2018); + const DayCounter dc = Actual365Fixed(); + const Date today = Date(4, January, 2018); - const Handle rTS(flatRate(today, 0.025, dc)); - const Handle qTS(flatRate(today, 0.085, dc)); + const Handle rTS(flatRate(today, 0.025, dc)); + const Handle qTS(flatRate(today, 0.085, dc)); - Handle spot(ext::make_shared(100)); + Handle spot(ext::make_shared(100)); - const Real b1 = 0.35; - const Real b2 = 0.03; - const Real b3 = 0.005; - const Real b4 = -0.02; - const Real b5 = -0.005; + const Real b1 = 0.35; + const Real b2 = 0.03; + const Real b3 = 0.005; + const Real b4 = -0.02; + const Real b5 = -0.005; - const Real strikes[] = { 35, 50, 75, 100, 125, 150, 200, 300 }; - const Size maturityMonths[] = { 1, 3, 6, 9, 12, 15, 18, 24}; + const Real strikes[] = { 35, 50, 75, 100, 125, 150, 200, 300 }; + const Size maturityMonths[] = { 1, 3, 6, 9, 12, 15, 18, 24}; - AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; + AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; - for (Real strike : strikes) { - for (unsigned long maturityMonth : maturityMonths) { - const Date maturityDate = today + Period(maturityMonth, Months); - const Time t = dc.yearFraction(today, maturityDate); + for (Real strike : strikes) { + for (unsigned long maturityMonth : maturityMonths) { + const Date maturityDate = today + Period(maturityMonth, Months); + const Time t = dc.yearFraction(today, maturityDate); - const Real fwd = spot->value()*qTS->discount(t)/rTS->discount(t); - const Real mn = std::log(fwd/strike)/std::sqrt(t); + const Real fwd = spot->value()*qTS->discount(t)/rTS->discount(t); + const Real mn = std::log(fwd/strike)/std::sqrt(t); - const Volatility vol = b1 + b2*mn + b3*mn*mn + b4*t + b5*mn*t; + const Volatility vol = b1 + b2*mn + b3*mn*mn + b4*t + b5*mn*t; - if (std::fabs(mn) < 3.71*vol) { + if (std::fabs(mn) < 3.71*vol) { - calibrationSet.emplace_back( + calibrationSet.emplace_back( ext::make_shared( ext::make_shared( Option::Call, strike), ext::make_shared(maturityDate)), ext::make_shared(vol)); - } } } + } - CalibrationData data = { spot, rTS, qTS, calibrationSet }; + CalibrationData data = { spot, rTS, qTS, calibrationSet }; - return data; - } + return data; +} - CalibrationData arbitrageData() { +CalibrationData arbitrageData() { - const DayCounter dc = Actual365Fixed(); - const Date today = Date(4, January, 2018); + const DayCounter dc = Actual365Fixed(); + const Date today = Date(4, January, 2018); - const Handle rTS(flatRate(today, 0.13, dc)); - const Handle qTS(flatRate(today, 0.03, dc)); + const Handle rTS(flatRate(today, 0.13, dc)); + const Handle qTS(flatRate(today, 0.03, dc)); - Handle spot(ext::make_shared(100)); + Handle spot(ext::make_shared(100)); - const Real strikes[] = { 100, 100, 100, 150 }; - const Size maturities[] = { 1, 3, 6, 6 }; - const Volatility vols[] = { 0.25, 0.35, 0.05, 0.35 }; - AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; + const Real strikes[] = { 100, 100, 100, 150 }; + const Size maturities[] = { 1, 3, 6, 6 }; + const Volatility vols[] = { 0.25, 0.35, 0.05, 0.35 }; + AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; - for (Size i=0; i < LENGTH(strikes); ++i) { - const Real strike = strikes[i]; - const Date maturityDate = today + Period(maturities[i], Months); - const Volatility vol = vols[i]; + for (Size i=0; i < LENGTH(strikes); ++i) { + const Real strike = strikes[i]; + const Date maturityDate = today + Period(maturities[i], Months); + const Volatility vol = vols[i]; - calibrationSet.emplace_back( + calibrationSet.emplace_back( ext::make_shared( ext::make_shared( Option::Call, strike), ext::make_shared(maturityDate)), ext::make_shared(vol)); - } - - return { spot, rTS, qTS, calibrationSet }; } - std::pair > sabrData() { + return { spot, rTS, qTS, calibrationSet }; +} - const DayCounter dc = Actual365Fixed(); - const Date today = Date(4, January, 2018); +std::pair > sabrData() { - const Real alpha = 0.15; - const Real beta = 0.8; - const Real nu = 0.5; - const Real rho = -0.48; - const Real forward = 0.03; - const Size maturityInYears = 20; + const DayCounter dc = Actual365Fixed(); + const Date today = Date(4, January, 2018); - const Date maturityDate = today + Period(maturityInYears, Years); - const Time maturity = dc.yearFraction(today, maturityDate); + const Real alpha = 0.15; + const Real beta = 0.8; + const Real nu = 0.5; + const Real rho = -0.48; + const Real forward = 0.03; + const Size maturityInYears = 20; - AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; + const Date maturityDate = today + Period(maturityInYears, Years); + const Time maturity = dc.yearFraction(today, maturityDate); - const Real strikes[] = { 0.02, 0.025, 0.03, 0.035, 0.04, 0.05, 0.06 }; + AndreasenHugeVolatilityInterpl::CalibrationSet calibrationSet; - for (Real strike : strikes) { - const Volatility vol = sabrVolatility(strike, forward, maturity, alpha, beta, nu, rho); + const Real strikes[] = { 0.02, 0.025, 0.03, 0.035, 0.04, 0.05, 0.06 }; - calibrationSet.emplace_back( + for (Real strike : strikes) { + const Volatility vol = sabrVolatility(strike, forward, maturity, alpha, beta, nu, rho); + + calibrationSet.emplace_back( ext::make_shared( ext::make_shared( Option::Call, strike), ext::make_shared(maturityDate)), ext::make_shared(vol)); - } + } - const Handle rTS(flatRate(today, forward, dc)); - const Handle qTS(flatRate(today, forward, dc)); + const Handle rTS(flatRate(today, forward, dc)); + const Handle qTS(flatRate(today, forward, dc)); - Handle spot(ext::make_shared(forward)); + Handle spot(ext::make_shared(forward)); - const CalibrationData data = { spot, rTS, qTS, calibrationSet}; + const CalibrationData data = { spot, rTS, qTS, calibrationSet}; - std::vector parameter = { alpha, beta, nu, rho, forward, maturity }; + std::vector parameter = { alpha, beta, nu, rho, forward, maturity }; - return std::make_pair(data, parameter); - } + return std::make_pair(data, parameter); } diff --git a/test-suite/array.cpp b/test-suite/array.cpp index 493459b26ff..b1931cb1565 100644 --- a/test-suite/array.cpp +++ b/test-suite/array.cpp @@ -29,12 +29,10 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(ArrayTests) -namespace { - class FSquared { - public: - Real operator()(Real x) const { return x*x; } - }; -} +class FSquared { + public: + Real operator()(Real x) const { return x*x; } +}; BOOST_AUTO_TEST_CASE(testConstruction) { diff --git a/test-suite/asianoptions.cpp b/test-suite/asianoptions.cpp index 69b974be902..81522b54f5e 100644 --- a/test-suite/asianoptions.cpp +++ b/test-suite/asianoptions.cpp @@ -82,69 +82,68 @@ BOOST_AUTO_TEST_SUITE(AsianOptionTests) << "\n" \ << " tolerance: " << tolerance); -namespace { - std::string averageTypeToString(Average::Type averageType) { +std::string averageTypeToString(Average::Type averageType) { - if (averageType == Average::Geometric) - return "Geometric Averaging"; - else if (averageType == Average::Arithmetic) - return "Arithmetic Averaging"; - else - QL_FAIL("unknown averaging"); - } - - struct DiscreteAverageData { - Option::Type type; - Real underlying; - Real strike; - Rate dividendYield; - Rate riskFreeRate; - Time first; - Time length; - Size fixings; - Volatility volatility; - bool controlVariate; - Real result; - }; - - struct ContinuousAverageData { - Option::Type type; - Real spot; - Real currentAverage; - Real strike; - Rate dividendYield; - Rate riskFreeRate; - Volatility volatility; - Natural length; - Natural elapsed; - Real result; - }; + if (averageType == Average::Geometric) + return "Geometric Averaging"; + else if (averageType == Average::Arithmetic) + return "Arithmetic Averaging"; + else + QL_FAIL("unknown averaging"); +} - struct DiscreteAverageDataTermStructure { - Option::Type type; - Real underlying; - Real strike; - Rate b; - Rate riskFreeRate; - Time first; // t1 - Time expiry; - Size fixings; - Volatility volatility; - std::string slope; - Real result; - }; +struct DiscreteAverageData { + Option::Type type; + Real underlying; + Real strike; + Rate dividendYield; + Rate riskFreeRate; + Time first; + Time length; + Size fixings; + Volatility volatility; + bool controlVariate; + Real result; +}; + +struct ContinuousAverageData { + Option::Type type; + Real spot; + Real currentAverage; + Real strike; + Rate dividendYield; + Rate riskFreeRate; + Volatility volatility; + Natural length; + Natural elapsed; + Real result; +}; + +struct DiscreteAverageDataTermStructure { + Option::Type type; + Real underlying; + Real strike; + Rate b; + Rate riskFreeRate; + Time first; // t1 + Time expiry; + Size fixings; + Volatility volatility; + std::string slope; + Real result; +}; + +struct VecerData { + Real spot; + Rate riskFreeRate; + Volatility volatility; + Real strike; + Natural length; + Real result; + Real tolerance; +}; - struct VecerData { - Real spot; - Rate riskFreeRate; - Volatility volatility; - Real strike; - Natural length; - Real result; - Real tolerance; - }; -} BOOST_AUTO_TEST_CASE(testAnalyticContinuousGeometricAveragePrice) { diff --git a/test-suite/assetswap.cpp b/test-suite/assetswap.cpp index 3e4ad35a243..3fb04306af1 100644 --- a/test-suite/assetswap.cpp +++ b/test-suite/assetswap.cpp @@ -61,60 +61,53 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(AssetSwapTests) -namespace { - - struct CommonVars { - // common data - ext::shared_ptr iborIndex; - ext::shared_ptr swapIndex; - ext::shared_ptr pricer; - ext::shared_ptr cmspricer; - Spread spread; - Spread nonnullspread; - Real faceAmount; - Compounding compounding; - RelinkableHandle termStructure; - - // initial setup - CommonVars() { - Natural swapSettlementDays = 2; - faceAmount = 100.0; - BusinessDayConvention fixedConvention = Unadjusted; - compounding = Continuous; - Frequency fixedFrequency = Annual; - Frequency floatingFrequency = Semiannual; - iborIndex = ext::shared_ptr( +struct CommonVars { + // common data + ext::shared_ptr iborIndex; + ext::shared_ptr swapIndex; + ext::shared_ptr pricer; + ext::shared_ptr cmspricer; + Spread spread; + Spread nonnullspread; + Real faceAmount; + Compounding compounding; + RelinkableHandle termStructure; + + // initial setup + CommonVars() { + Natural swapSettlementDays = 2; + faceAmount = 100.0; + BusinessDayConvention fixedConvention = Unadjusted; + compounding = Continuous; + Frequency fixedFrequency = Annual; + Frequency floatingFrequency = Semiannual; + iborIndex = ext::shared_ptr( new Euribor(Period(floatingFrequency), termStructure)); - Calendar calendar = iborIndex->fixingCalendar(); - swapIndex= ext::make_shared( + Calendar calendar = iborIndex->fixingCalendar(); + swapIndex = ext::make_shared( "EuriborSwapIsdaFixA", 10*Years, swapSettlementDays, iborIndex->currency(), calendar, Period(fixedFrequency), fixedConvention, iborIndex->dayCounter(), iborIndex); - spread = 0.0; - nonnullspread = 0.003; - Date today(24,April,2007); - Settings::instance().evaluationDate() = today; - - //Date today = Settings::instance().evaluationDate(); - - termStructure.linkTo(flatRate(today, 0.05, Actual365Fixed())); - pricer = ext::shared_ptr(new - BlackIborCouponPricer); - Handle swaptionVolatilityStructure( + spread = 0.0; + nonnullspread = 0.003; + Date today(24,April,2007); + Settings::instance().evaluationDate() = today; + + termStructure.linkTo(flatRate(today, 0.05, Actual365Fixed())); + pricer = ext::shared_ptr(new BlackIborCouponPricer); + Handle swaptionVolatilityStructure( ext::shared_ptr(new ConstantSwaptionVolatility(today, NullCalendar(),Following, 0.2, Actual365Fixed()))); - Handle meanReversionQuote(ext::shared_ptr(new + Handle meanReversionQuote(ext::shared_ptr(new SimpleQuote(0.01))); - cmspricer = ext::shared_ptr(new + cmspricer = ext::shared_ptr(new AnalyticHaganPricer(swaptionVolatilityStructure, GFunctionFactory::Standard, meanReversionQuote)); - } - }; - -} + } +}; BOOST_AUTO_TEST_CASE(testConsistency) { diff --git a/test-suite/barrieroption.cpp b/test-suite/barrieroption.cpp index 65697fe673e..4ee971dcfe0 100644 --- a/test-suite/barrieroption.cpp +++ b/test-suite/barrieroption.cpp @@ -104,68 +104,64 @@ BOOST_AUTO_TEST_SUITE(BarrierOptionTests) << " tolerance: " << tolerance); -namespace { - - std::string barrierTypeToString(Barrier::Type type) { - switch(type){ - case Barrier::DownIn: - return std::string("Down-and-in"); - case Barrier::UpIn: - return std::string("Up-and-in"); - case Barrier::DownOut: - return std::string("Down-and-out"); - case Barrier::UpOut: - return std::string("Up-and-out"); - default: - QL_FAIL("unknown exercise type"); - } +std::string barrierTypeToString(Barrier::Type type) { + switch(type){ + case Barrier::DownIn: + return std::string("Down-and-in"); + case Barrier::UpIn: + return std::string("Up-and-in"); + case Barrier::DownOut: + return std::string("Down-and-out"); + case Barrier::UpOut: + return std::string("Up-and-out"); + default: + QL_FAIL("unknown exercise type"); } - - struct BarrierOptionData { - Barrier::Type type; - Volatility volatility; - Real strike; - Real barrier; - Real callValue; - Real putValue; - }; - - struct NewBarrierOptionData { - Barrier::Type barrierType; - Real barrier; - Real rebate; - Option::Type type; - Exercise::Type exType; - Real strike; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time t; // time to maturity - Volatility v; // volatility - Real result; // result - Real tol; // tolerance - }; - - struct BarrierFxOptionData { - Barrier::Type barrierType; - Real barrier; - Real rebate; - Option::Type type; - Real strike; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time t; // time to maturity - Volatility vol25Put; // 25 delta put vol - Volatility volAtm; // atm vol - Volatility vol25Call; // 25 delta call vol - Volatility v; // volatility at strike - Real result; // result - Real tol; // tolerance - }; - } +struct BarrierOptionData { + Barrier::Type type; + Volatility volatility; + Real strike; + Real barrier; + Real callValue; + Real putValue; +}; + +struct NewBarrierOptionData { + Barrier::Type barrierType; + Real barrier; + Real rebate; + Option::Type type; + Exercise::Type exType; + Real strike; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time t; // time to maturity + Volatility v; // volatility + Real result; // result + Real tol; // tolerance +}; + +struct BarrierFxOptionData { + Barrier::Type barrierType; + Real barrier; + Real rebate; + Option::Type type; + Real strike; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time t; // time to maturity + Volatility vol25Put; // 25 delta put vol + Volatility volAtm; // atm vol + Volatility vol25Call; // 25 delta call vol + Volatility v; // volatility at strike + Real result; // result + Real tol; // tolerance +}; + #define QL_ASSERT_EXCEPTION_THROWN(statement) \ auto exception_thrown = false; \ try { \ diff --git a/test-suite/basismodels.cpp b/test-suite/basismodels.cpp index 3808c0a0abb..3a85a06526e 100644 --- a/test-suite/basismodels.cpp +++ b/test-suite/basismodels.cpp @@ -43,191 +43,187 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BasisModelsTests) -namespace { +// auxiliary data +Period termsData[] = { + Period(0, Days), Period(1, Years), Period(2, Years), Period(3, Years), + Period(5, Years), Period(7, Years), Period(10, Years), Period(15, Years), + Period(20, Years), Period(61, Years) // avoid extrapolation issues with 30y caplets +}; +std::vector terms(termsData, termsData + 10); - // auxiliary data - Period termsData[] = { - Period(0, Days), Period(1, Years), Period(2, Years), Period(3, Years), - Period(5, Years), Period(7, Years), Period(10, Years), Period(15, Years), - Period(20, Years), Period(61, Years) // avoid extrapolation issues with 30y caplets - }; - std::vector terms(termsData, termsData + 10); +Real discRatesData[] = {-0.00147407, -0.001761684, -0.001736745, -0.00119244, 0.000896055, + 0.003537077, 0.007213824, 0.011391278, 0.013334611, 0.013982809}; +std::vector discRates(discRatesData, discRatesData + 10); - Real discRatesData[] = {-0.00147407, -0.001761684, -0.001736745, -0.00119244, 0.000896055, - 0.003537077, 0.007213824, 0.011391278, 0.013334611, 0.013982809}; - std::vector discRates(discRatesData, discRatesData + 10); +Real proj3mRatesData[] = {-0.000483439, -0.000578569, -0.000383832, 0.000272656, 0.002478699, + 0.005100113, 0.008750643, 0.012788095, 0.014534052, 0.014942896}; +std::vector proj3mRates(proj3mRatesData, proj3mRatesData + 10); - Real proj3mRatesData[] = {-0.000483439, -0.000578569, -0.000383832, 0.000272656, 0.002478699, - 0.005100113, 0.008750643, 0.012788095, 0.014534052, 0.014942896}; - std::vector proj3mRates(proj3mRatesData, proj3mRatesData + 10); +Real proj6mRatesData[] = {0.000233608, 0.000218862, 0.000504018, 0.001240556, 0.003554415, + 0.006153921, 0.009688264, 0.013521628, 0.015136391, 0.015377704}; +std::vector proj6mRates(proj6mRatesData, proj6mRatesData + 10); - Real proj6mRatesData[] = {0.000233608, 0.000218862, 0.000504018, 0.001240556, 0.003554415, - 0.006153921, 0.009688264, 0.013521628, 0.015136391, 0.015377704}; - std::vector proj6mRates(proj6mRatesData, proj6mRatesData + 10); - - Handle getYTS(const std::vector& terms, - const std::vector& rates, - const Real spread = 0.0) { - Date today = Settings::instance().evaluationDate(); - std::vector dates; - dates.reserve(terms.size()); - for (auto term : terms) - dates.push_back(NullCalendar().advance(today, term, Unadjusted)); - std::vector ratesPlusSpread(rates); - for (Real& k : ratesPlusSpread) - k += spread; - ext::shared_ptr ts = - ext::shared_ptr(new InterpolatedZeroCurve( +Handle getYTS(const std::vector& terms, + const std::vector& rates, + const Real spread = 0.0) { + Date today = Settings::instance().evaluationDate(); + std::vector dates; + dates.reserve(terms.size()); + for (auto term : terms) + dates.push_back(NullCalendar().advance(today, term, Unadjusted)); + std::vector ratesPlusSpread(rates); + for (Real& k : ratesPlusSpread) + k += spread; + ext::shared_ptr ts = + ext::shared_ptr(new InterpolatedZeroCurve( dates, ratesPlusSpread, Actual365Fixed(), NullCalendar())); - return RelinkableHandle(ts); - } + return RelinkableHandle(ts); +} - Period capletTermsData[] = {Period(1, Years), Period(2, Years), Period(3, Years), - Period(5, Years), Period(7, Years), Period(10, Years), - Period(15, Years), Period(20, Years), Period(25, Years), - Period(30, Years)}; - std::vector capletTerms(capletTermsData, capletTermsData + 10); +Period capletTermsData[] = {Period(1, Years), Period(2, Years), Period(3, Years), + Period(5, Years), Period(7, Years), Period(10, Years), + Period(15, Years), Period(20, Years), Period(25, Years), + Period(30, Years)}; +std::vector capletTerms(capletTermsData, capletTermsData + 10); - Real capletStrikesData[] = {-0.0050, 0.0000, 0.0050, 0.0100, 0.0150, 0.0200, 0.0300, 0.0500}; - std::vector capletStrikes(capletStrikesData, capletStrikesData + 8); +Real capletStrikesData[] = {-0.0050, 0.0000, 0.0050, 0.0100, 0.0150, 0.0200, 0.0300, 0.0500}; +std::vector capletStrikes(capletStrikesData, capletStrikesData + 8); - Handle getOptionletTS() { - Date today = Settings::instance().evaluationDate(); - std::vector dates; - dates.reserve(capletTerms.size()); - for (auto& capletTerm : capletTerms) - dates.push_back(TARGET().advance(today, capletTerm, Following)); - // set up vol data manually - std::vector > capletVols = +Handle getOptionletTS() { + Date today = Settings::instance().evaluationDate(); + std::vector dates; + dates.reserve(capletTerms.size()); + for (auto& capletTerm : capletTerms) + dates.push_back(TARGET().advance(today, capletTerm, Following)); + // set up vol data manually + std::vector > capletVols = { - {0.003010094, 0.002628065, 0.00456118, 0.006731268, 0.008678572, 0.010570881, 0.014149552, 0.021000638}, - {0.004173715, 0.003727039, 0.004180263, 0.005726083, 0.006905876, 0.008263514, 0.010555395, 0.014976523}, - {0.005870143, 0.005334526, 0.005599775, 0.006633987, 0.007773317, 0.009036581, 0.011474391, 0.016277549}, - {0.007458597, 0.007207522, 0.007263995, 0.007308727, 0.007813586, 0.008274858, 0.009743988, 0.012555171}, - {0.007711531, 0.007608826, 0.007572816, 0.007684107, 0.007971932, 0.008283118, 0.009268828, 0.011574083}, - {0.007619605, 0.007639059, 0.007719825, 0.007823373, 0.00800813, 0.008113384, 0.008616374, 0.009785436}, - {0.007312199, 0.007352993, 0.007369116, 0.007468333, 0.007515657, 0.00767695, 0.008020447, 0.009072769}, - {0.006905851, 0.006966315, 0.007056413, 0.007116494, 0.007259661, 0.00733308, 0.007667563, 0.008419696}, - {0.006529553, 0.006630731, 0.006749022, 0.006858027, 0.007001959, 0.007139097, 0.007390404, 0.008036255}, - {0.006225482, 0.006404012, 0.00651594, 0.006642273, 0.006640887, 0.006885713, 0.007093024, 0.00767373} + {0.003010094, 0.002628065, 0.00456118, 0.006731268, 0.008678572, 0.010570881, 0.014149552, 0.021000638}, + {0.004173715, 0.003727039, 0.004180263, 0.005726083, 0.006905876, 0.008263514, 0.010555395, 0.014976523}, + {0.005870143, 0.005334526, 0.005599775, 0.006633987, 0.007773317, 0.009036581, 0.011474391, 0.016277549}, + {0.007458597, 0.007207522, 0.007263995, 0.007308727, 0.007813586, 0.008274858, 0.009743988, 0.012555171}, + {0.007711531, 0.007608826, 0.007572816, 0.007684107, 0.007971932, 0.008283118, 0.009268828, 0.011574083}, + {0.007619605, 0.007639059, 0.007719825, 0.007823373, 0.00800813, 0.008113384, 0.008616374, 0.009785436}, + {0.007312199, 0.007352993, 0.007369116, 0.007468333, 0.007515657, 0.00767695, 0.008020447, 0.009072769}, + {0.006905851, 0.006966315, 0.007056413, 0.007116494, 0.007259661, 0.00733308, 0.007667563, 0.008419696}, + {0.006529553, 0.006630731, 0.006749022, 0.006858027, 0.007001959, 0.007139097, 0.007390404, 0.008036255}, + {0.006225482, 0.006404012, 0.00651594, 0.006642273, 0.006640887, 0.006885713, 0.007093024, 0.00767373} }; - // create quotes - std::vector > > capletVolQuotes; - for (auto& capletVol : capletVols) { - std::vector > row; - row.reserve(capletVol.size()); - for (Real j : capletVol) - row.push_back(RelinkableHandle(ext::shared_ptr(new SimpleQuote(j)))); - capletVolQuotes.push_back(row); - } - Handle curve3m = getYTS(terms, proj3mRates); - ext::shared_ptr index(new Euribor3M(curve3m)); - ext::shared_ptr tmp1( + // create quotes + std::vector > > capletVolQuotes; + for (auto& capletVol : capletVols) { + std::vector > row; + row.reserve(capletVol.size()); + for (Real j : capletVol) + row.push_back(RelinkableHandle(ext::shared_ptr(new SimpleQuote(j)))); + capletVolQuotes.push_back(row); + } + Handle curve3m = getYTS(terms, proj3mRates); + ext::shared_ptr index(new Euribor3M(curve3m)); + ext::shared_ptr tmp1( new StrippedOptionlet(2, TARGET(), Following, index, dates, capletStrikes, capletVolQuotes, Actual365Fixed(), Normal, 0.0)); - ext::shared_ptr tmp2(new StrippedOptionletAdapter(tmp1)); - return RelinkableHandle(tmp2); - } + ext::shared_ptr tmp2(new StrippedOptionletAdapter(tmp1)); + return RelinkableHandle(tmp2); +} - Period swaptionVTSTermsData[] = { - Period(1, Years), Period(5, Years), Period(10, Years), Period(20, Years), Period(30, Years), - }; - std::vector swaptionVTSTerms(swaptionVTSTermsData, swaptionVTSTermsData + 5); +Period swaptionVTSTermsData[] = { + Period(1, Years), Period(5, Years), Period(10, Years), Period(20, Years), Period(30, Years), +}; +std::vector swaptionVTSTerms(swaptionVTSTermsData, swaptionVTSTermsData + 5); - Handle getSwaptionVTS() { - std::vector > swaptionVols = - { - {0.002616, 0.00468, 0.0056, 0.005852, 0.005823}, - {0.006213, 0.00643, 0.006622, 0.006124, 0.005958}, - {0.006658, 0.006723, 0.006602, 0.005802, 0.005464}, - {0.005728, 0.005814, 0.005663, 0.004689, 0.004276}, - {0.005041, 0.005059, 0.004746, 0.003927, 0.003608} - }; - std::vector > > swaptionVolQuotes; - for (auto& swaptionVol : swaptionVols) { - std::vector > row; - row.reserve(swaptionVol.size()); - for (Real j : swaptionVol) - row.push_back(RelinkableHandle(ext::shared_ptr(new SimpleQuote(j)))); - swaptionVolQuotes.push_back(row); - } - ext::shared_ptr tmp( +Handle getSwaptionVTS() { + std::vector > swaptionVols = + { + {0.002616, 0.00468, 0.0056, 0.005852, 0.005823}, + {0.006213, 0.00643, 0.006622, 0.006124, 0.005958}, + {0.006658, 0.006723, 0.006602, 0.005802, 0.005464}, + {0.005728, 0.005814, 0.005663, 0.004689, 0.004276}, + {0.005041, 0.005059, 0.004746, 0.003927, 0.003608} + }; + std::vector > > swaptionVolQuotes; + for (auto& swaptionVol : swaptionVols) { + std::vector > row; + row.reserve(swaptionVol.size()); + for (Real j : swaptionVol) + row.push_back(RelinkableHandle(ext::shared_ptr(new SimpleQuote(j)))); + swaptionVolQuotes.push_back(row); + } + ext::shared_ptr tmp( new SwaptionVolatilityMatrix(TARGET(), Following, swaptionVTSTerms, swaptionVTSTerms, swaptionVolQuotes, Actual365Fixed(), true, Normal)); - return RelinkableHandle(tmp); - } + return RelinkableHandle(tmp); +} - void testSwaptioncfs(bool contTenorSpread) { - bool usingAtParCoupons = IborCoupon::Settings::instance().usingAtParCoupons(); - // market data and floating rate index - Handle discYTS = getYTS(terms, discRates); - Handle proj6mYTS = getYTS(terms, proj6mRates); - ext::shared_ptr euribor6m(new Euribor6M(proj6mYTS)); - // Vanilla swap details - Date today = Settings::instance().evaluationDate(); - Date swapStart = TARGET().advance(today, Period(5, Years), Following); - Date swapEnd = TARGET().advance(swapStart, Period(10, Years), Following); - Date exerciseDate = TARGET().advance(swapStart, Period(-2, Days), Preceding); - Schedule fixedSchedule(swapStart, swapEnd, Period(1, Years), TARGET(), ModifiedFollowing, - ModifiedFollowing, DateGeneration::Backward, false); - Schedule floatSchedule(swapStart, swapEnd, Period(6, Months), TARGET(), ModifiedFollowing, - ModifiedFollowing, DateGeneration::Backward, false); - ext::shared_ptr swap( +void testSwaptioncfs(bool contTenorSpread) { + bool usingAtParCoupons = IborCoupon::Settings::instance().usingAtParCoupons(); + // market data and floating rate index + Handle discYTS = getYTS(terms, discRates); + Handle proj6mYTS = getYTS(terms, proj6mRates); + ext::shared_ptr euribor6m(new Euribor6M(proj6mYTS)); + // Vanilla swap details + Date today = Settings::instance().evaluationDate(); + Date swapStart = TARGET().advance(today, Period(5, Years), Following); + Date swapEnd = TARGET().advance(swapStart, Period(10, Years), Following); + Date exerciseDate = TARGET().advance(swapStart, Period(-2, Days), Preceding); + Schedule fixedSchedule(swapStart, swapEnd, Period(1, Years), TARGET(), ModifiedFollowing, + ModifiedFollowing, DateGeneration::Backward, false); + Schedule floatSchedule(swapStart, swapEnd, Period(6, Months), TARGET(), ModifiedFollowing, + ModifiedFollowing, DateGeneration::Backward, false); + ext::shared_ptr swap( new VanillaSwap(Swap::Payer, 10000.0, fixedSchedule, 0.03, Thirty360(Thirty360::BondBasis), floatSchedule, euribor6m, 0.0, euribor6m->dayCounter())); - swap->setPricingEngine(ext::shared_ptr(new DiscountingSwapEngine(discYTS))); - // European exercise and swaption - ext::shared_ptr europeanExercise(new EuropeanExercise(exerciseDate)); - ext::shared_ptr swaption( - new Swaption(swap, europeanExercise, Settlement::Physical)); - // calculate basis model swaption cash flows, discount and conmpare with swap - SwaptionCashFlows cashFlows(swaption, discYTS, contTenorSpread); - // model time is always Act365Fixed - Time exerciseTime = Actual365Fixed().yearFraction(discYTS->referenceDate(), - swaption->exercise()->dates()[0]); - if (exerciseTime != cashFlows.exerciseTimes()[0]) - BOOST_ERROR( - "Swaption cash flow exercise time does not coincide with manual calculation"); - // there might be rounding errors - Real tol = 1.0e-8; - // (discounted) fixed leg coupons must match swap fixed leg NPV - Real fixedLeg = 0.0; - for (Size k = 0; k < cashFlows.fixedTimes().size(); ++k) - fixedLeg += cashFlows.fixedWeights()[k] * discYTS->discount(cashFlows.fixedTimes()[k]); - if (fabs(fixedLeg - (-swap->fixedLegNPV())) > tol) // note, '-1' because payer swap - BOOST_ERROR("Swaption cash flow fixed leg NPV does not match Vanillaswap fixed leg NPV" - << "SwaptionCashFlows: " << fixedLeg << "\n" - << "swap->fixedLegNPV: " << swap->fixedLegNPV() << "\n" - << "Variance: " << swap->fixedLegNPV() - fixedLeg << "\n"); - // (discounted) floating leg coupons must match swap floating leg NPV - Real floatLeg = 0.0; - for (Size k = 0; k < cashFlows.floatTimes().size(); ++k) - floatLeg += cashFlows.floatWeights()[k] * discYTS->discount(cashFlows.floatTimes()[k]); - if (fabs(floatLeg - swap->floatingLegNPV()) > tol) - BOOST_ERROR( - "Swaption cash flow floating leg NPV does not match Vanillaswap floating leg NPV.\n" - << "SwaptionCashFlows: " << floatLeg << "\n" - << "swap->floatingLegNPV: " << swap->floatingLegNPV() << "\n" - << "Variance: " << swap->floatingLegNPV() - floatLeg << "\n"); - // There should not be spread coupons in a single-curve setting. - // However, if indexed coupons are used the floating leg is not at par, - // so we need to relax the tolerance to a level at which it will only - // catch large errors. - Real tol2 = usingAtParCoupons ? tol : 0.02; + swap->setPricingEngine(ext::shared_ptr(new DiscountingSwapEngine(discYTS))); + // European exercise and swaption + ext::shared_ptr europeanExercise(new EuropeanExercise(exerciseDate)); + ext::shared_ptr swaption( + new Swaption(swap, europeanExercise, Settlement::Physical)); + // calculate basis model swaption cash flows, discount and conmpare with swap + SwaptionCashFlows cashFlows(swaption, discYTS, contTenorSpread); + // model time is always Act365Fixed + Time exerciseTime = Actual365Fixed().yearFraction(discYTS->referenceDate(), + swaption->exercise()->dates()[0]); + if (exerciseTime != cashFlows.exerciseTimes()[0]) + BOOST_ERROR("Swaption cash flow exercise time does not coincide with manual calculation"); + // there might be rounding errors + Real tol = 1.0e-8; + // (discounted) fixed leg coupons must match swap fixed leg NPV + Real fixedLeg = 0.0; + for (Size k = 0; k < cashFlows.fixedTimes().size(); ++k) + fixedLeg += cashFlows.fixedWeights()[k] * discYTS->discount(cashFlows.fixedTimes()[k]); + if (fabs(fixedLeg - (-swap->fixedLegNPV())) > tol) // note, '-1' because payer swap + BOOST_ERROR("Swaption cash flow fixed leg NPV does not match Vanillaswap fixed leg NPV" + << "SwaptionCashFlows: " << fixedLeg << "\n" + << "swap->fixedLegNPV: " << swap->fixedLegNPV() << "\n" + << "Variance: " << swap->fixedLegNPV() - fixedLeg << "\n"); + // (discounted) floating leg coupons must match swap floating leg NPV + Real floatLeg = 0.0; + for (Size k = 0; k < cashFlows.floatTimes().size(); ++k) + floatLeg += cashFlows.floatWeights()[k] * discYTS->discount(cashFlows.floatTimes()[k]); + if (fabs(floatLeg - swap->floatingLegNPV()) > tol) + BOOST_ERROR( + "Swaption cash flow floating leg NPV does not match Vanillaswap floating leg NPV.\n" + << "SwaptionCashFlows: " << floatLeg << "\n" + << "swap->floatingLegNPV: " << swap->floatingLegNPV() << "\n" + << "Variance: " << swap->floatingLegNPV() - floatLeg << "\n"); + // There should not be spread coupons in a single-curve setting. + // However, if indexed coupons are used the floating leg is not at par, + // so we need to relax the tolerance to a level at which it will only + // catch large errors. + Real tol2 = usingAtParCoupons ? tol : 0.02; - SwaptionCashFlows singleCurveCashFlows(swaption, proj6mYTS, contTenorSpread); - for (Size k = 1; k < singleCurveCashFlows.floatWeights().size() - 1; ++k) { - if (fabs(singleCurveCashFlows.floatWeights()[k]) > tol2) - BOOST_ERROR("Swaption cash flow floating leg spread does not vanish in " - "single-curve setting.\n" - << "Cash flow index k: " << k << ", floatWeights: " - << singleCurveCashFlows.floatWeights()[k] << "\n"); - } + SwaptionCashFlows singleCurveCashFlows(swaption, proj6mYTS, contTenorSpread); + for (Size k = 1; k < singleCurveCashFlows.floatWeights().size() - 1; ++k) { + if (fabs(singleCurveCashFlows.floatWeights()[k]) > tol2) + BOOST_ERROR("Swaption cash flow floating leg spread does not vanish in " + "single-curve setting.\n" + << "Cash flow index k: " << k << ", floatWeights: " + << singleCurveCashFlows.floatWeights()[k] << "\n"); } - } + BOOST_AUTO_TEST_CASE(testSwaptioncfsContCompSpread) { BOOST_TEST_MESSAGE( "Testing deterministic tenor basis model with continuous compounded spreads..."); diff --git a/test-suite/basisswapratehelpers.cpp b/test-suite/basisswapratehelpers.cpp index 0158e8a7c08..3c1921c4f9d 100644 --- a/test-suite/basisswapratehelpers.cpp +++ b/test-suite/basisswapratehelpers.cpp @@ -36,184 +36,181 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BasisSwapRateHelpersTests) -namespace { - - struct BasisSwapQuote { - Integer n; - TimeUnit units; - Spread basis; +struct BasisSwapQuote { + Integer n; + TimeUnit units; + Spread basis; +}; + +void testIborIborBootstrap(bool bootstrapBaseCurve) { + std::vector quotes = { + { 1, Years, 0.0010 }, + { 2, Years, 0.0012 }, + { 3, Years, 0.0015 }, + { 5, Years, 0.0015 }, + { 8, Years, 0.0018 }, + { 10, Years, 0.0020 }, + { 15, Years, 0.0021 }, + { 20, Years, 0.0021 }, }; - void testIborIborBootstrap(bool bootstrapBaseCurve) { - std::vector quotes = { - { 1, Years, 0.0010 }, - { 2, Years, 0.0012 }, - { 3, Years, 0.0015 }, - { 5, Years, 0.0015 }, - { 8, Years, 0.0018 }, - { 10, Years, 0.0020 }, - { 15, Years, 0.0021 }, - { 20, Years, 0.0021 }, - }; - - auto settlementDays = 2; - auto calendar = UnitedStates(UnitedStates::GovernmentBond); - auto convention = Following; - auto endOfMonth = false; - - Handle knownForecastCurve(flatRate(0.01, Actual365Fixed())); - Handle discountCurve(flatRate(0.005, Actual365Fixed())); - - ext::shared_ptr baseIndex, otherIndex; - - if (bootstrapBaseCurve) { - baseIndex = ext::make_shared(3 * Months); - otherIndex = ext::make_shared(6 * Months, knownForecastCurve); - } else { - baseIndex = ext::make_shared(3 * Months, knownForecastCurve); - otherIndex = ext::make_shared(6 * Months); - } + auto settlementDays = 2; + auto calendar = UnitedStates(UnitedStates::GovernmentBond); + auto convention = Following; + auto endOfMonth = false; + + Handle knownForecastCurve(flatRate(0.01, Actual365Fixed())); + Handle discountCurve(flatRate(0.005, Actual365Fixed())); + + ext::shared_ptr baseIndex, otherIndex; - std::vector> helpers; - for (auto q : quotes) { - auto h = ext::make_shared( + if (bootstrapBaseCurve) { + baseIndex = ext::make_shared(3 * Months); + otherIndex = ext::make_shared(6 * Months, knownForecastCurve); + } else { + baseIndex = ext::make_shared(3 * Months, knownForecastCurve); + otherIndex = ext::make_shared(6 * Months); + } + + std::vector> helpers; + for (auto q : quotes) { + auto h = ext::make_shared( Handle(ext::make_shared(q.basis)), Period(q.n, q.units), settlementDays, calendar, convention, endOfMonth, baseIndex, otherIndex, discountCurve, bootstrapBaseCurve); - helpers.push_back(h); - } - - auto bootstrappedCurve = ext::make_shared> - (0, calendar, helpers, Actual365Fixed()); + helpers.push_back(h); + } - Date today = Settings::instance().evaluationDate(); - Date spot = calendar.advance(today, settlementDays, Days); + auto bootstrappedCurve = ext::make_shared> + (0, calendar, helpers, Actual365Fixed()); - if (bootstrapBaseCurve) { - baseIndex = ext::make_shared(3 * Months, Handle(bootstrappedCurve)); - otherIndex = ext::make_shared(6 * Months, knownForecastCurve); - } else { - baseIndex = ext::make_shared(3 * Months, knownForecastCurve); - otherIndex = ext::make_shared(6 * Months, Handle(bootstrappedCurve)); - } + Date today = Settings::instance().evaluationDate(); + Date spot = calendar.advance(today, settlementDays, Days); - for (auto q : quotes) { - // create swaps and check they're fair - Date maturity = calendar.advance(spot, q.n, q.units, convention); - - Schedule s1 = - MakeSchedule() - .from(spot).to(maturity) - .withTenor(baseIndex->tenor()) - .withCalendar(calendar) - .withConvention(convention) - .withRule(DateGeneration::Forward); - Leg leg1 = IborLeg(s1, baseIndex) - .withSpreads(q.basis) - .withNotionals(100.0); - - Schedule s2 = - MakeSchedule() - .from(spot).to(maturity) - .withTenor(otherIndex->tenor()) - .withCalendar(calendar) - .withConvention(convention) - .withRule(DateGeneration::Forward); - Leg leg2 = IborLeg(s2, otherIndex) - .withNotionals(100.0); - - Swap swap(leg1, leg2); - swap.setPricingEngine(ext::make_shared(discountCurve)); + if (bootstrapBaseCurve) { + baseIndex = ext::make_shared(3 * Months, Handle(bootstrappedCurve)); + otherIndex = ext::make_shared(6 * Months, knownForecastCurve); + } else { + baseIndex = ext::make_shared(3 * Months, knownForecastCurve); + otherIndex = ext::make_shared(6 * Months, Handle(bootstrappedCurve)); + } - Real NPV = swap.NPV(); - Real tolerance = 1e-8; - if (std::fabs(NPV) > tolerance) { - BOOST_ERROR("Failed to price fair " << q.n << "-year(s) swap:" - << "\n calculated: " << NPV); - } + for (auto q : quotes) { + // create swaps and check they're fair + Date maturity = calendar.advance(spot, q.n, q.units, convention); + + Schedule s1 = + MakeSchedule() + .from(spot).to(maturity) + .withTenor(baseIndex->tenor()) + .withCalendar(calendar) + .withConvention(convention) + .withRule(DateGeneration::Forward); + Leg leg1 = IborLeg(s1, baseIndex) + .withSpreads(q.basis) + .withNotionals(100.0); + + Schedule s2 = + MakeSchedule() + .from(spot).to(maturity) + .withTenor(otherIndex->tenor()) + .withCalendar(calendar) + .withConvention(convention) + .withRule(DateGeneration::Forward); + Leg leg2 = IborLeg(s2, otherIndex) + .withNotionals(100.0); + + Swap swap(leg1, leg2); + swap.setPricingEngine(ext::make_shared(discountCurve)); + + Real NPV = swap.NPV(); + Real tolerance = 1e-8; + if (std::fabs(NPV) > tolerance) { + BOOST_ERROR("Failed to price fair " << q.n << "-year(s) swap:" + << "\n calculated: " << NPV); } } +} + +void testOvernightIborBootstrap(bool externalDiscountCurve) { + std::vector quotes = { + { 1, Years, 0.0010 }, + { 2, Years, 0.0012 }, + { 3, Years, 0.0015 }, + { 5, Years, 0.0015 }, + { 8, Years, 0.0018 }, + { 10, Years, 0.0020 }, + { 15, Years, 0.0021 }, + { 20, Years, 0.0021 }, + }; + + auto settlementDays = 2; + auto calendar = UnitedStates(UnitedStates::GovernmentBond); + auto convention = Following; + auto endOfMonth = false; + + Handle knownForecastCurve(flatRate(0.01, Actual365Fixed())); + + RelinkableHandle discountCurve; + if (externalDiscountCurve) + discountCurve.linkTo(flatRate(0.005, Actual365Fixed())); + + auto baseIndex = ext::make_shared(knownForecastCurve); + auto otherIndex = ext::make_shared(6 * Months); - void testOvernightIborBootstrap(bool externalDiscountCurve) { - std::vector quotes = { - { 1, Years, 0.0010 }, - { 2, Years, 0.0012 }, - { 3, Years, 0.0015 }, - { 5, Years, 0.0015 }, - { 8, Years, 0.0018 }, - { 10, Years, 0.0020 }, - { 15, Years, 0.0021 }, - { 20, Years, 0.0021 }, - }; - - auto settlementDays = 2; - auto calendar = UnitedStates(UnitedStates::GovernmentBond); - auto convention = Following; - auto endOfMonth = false; - - Handle knownForecastCurve(flatRate(0.01, Actual365Fixed())); - - RelinkableHandle discountCurve; - if (externalDiscountCurve) - discountCurve.linkTo(flatRate(0.005, Actual365Fixed())); - - auto baseIndex = ext::make_shared(knownForecastCurve); - auto otherIndex = ext::make_shared(6 * Months); - - std::vector> helpers; - for (auto q : quotes) { - auto h = ext::make_shared( + std::vector> helpers; + for (auto q : quotes) { + auto h = ext::make_shared( Handle(ext::make_shared(q.basis)), Period(q.n, q.units), settlementDays, calendar, convention, endOfMonth, baseIndex, otherIndex, discountCurve); - helpers.push_back(h); - } + helpers.push_back(h); + } - auto bootstrappedCurve = ext::make_shared> - (0, calendar, helpers, Actual365Fixed()); + auto bootstrappedCurve = ext::make_shared> + (0, calendar, helpers, Actual365Fixed()); - Date today = Settings::instance().evaluationDate(); - Date spot = calendar.advance(today, settlementDays, Days); + Date today = Settings::instance().evaluationDate(); + Date spot = calendar.advance(today, settlementDays, Days); - otherIndex = ext::make_shared(6 * Months, Handle(bootstrappedCurve)); + otherIndex = ext::make_shared(6 * Months, Handle(bootstrappedCurve)); + + for (auto q : quotes) { + // create swaps and check they're fair + Date maturity = calendar.advance(spot, q.n, q.units, convention); - for (auto q : quotes) { - // create swaps and check they're fair - Date maturity = calendar.advance(spot, q.n, q.units, convention); - - Schedule s = - MakeSchedule() - .from(spot).to(maturity) - .withTenor(otherIndex->tenor()) - .withCalendar(calendar) - .withConvention(convention) - .withRule(DateGeneration::Forward); - - Leg leg1 = OvernightLeg(s, baseIndex) - .withSpreads(q.basis) - .withNotionals(100.0); - Leg leg2 = IborLeg(s, otherIndex) - .withNotionals(100.0); - - Swap swap(leg1, leg2); - if (externalDiscountCurve) { - swap.setPricingEngine(ext::make_shared(discountCurve)); - } else { - swap.setPricingEngine(ext::make_shared( - Handle(bootstrappedCurve))); - } - - Real NPV = swap.NPV(); - Real tolerance = 1e-8; - if (std::fabs(NPV) > tolerance) { - BOOST_ERROR("Failed to price fair " << q.n << "-year(s) swap:" - << "\n calculated: " << NPV); - } + Schedule s = + MakeSchedule() + .from(spot).to(maturity) + .withTenor(otherIndex->tenor()) + .withCalendar(calendar) + .withConvention(convention) + .withRule(DateGeneration::Forward); + + Leg leg1 = OvernightLeg(s, baseIndex) + .withSpreads(q.basis) + .withNotionals(100.0); + Leg leg2 = IborLeg(s, otherIndex) + .withNotionals(100.0); + + Swap swap(leg1, leg2); + if (externalDiscountCurve) { + swap.setPricingEngine(ext::make_shared(discountCurve)); + } else { + swap.setPricingEngine(ext::make_shared( + Handle(bootstrappedCurve))); } - } + Real NPV = swap.NPV(); + Real tolerance = 1e-8; + if (std::fabs(NPV) > tolerance) { + BOOST_ERROR("Failed to price fair " << q.n << "-year(s) swap:" + << "\n calculated: " << NPV); + } + } } + BOOST_AUTO_TEST_CASE(testIborIborBaseCurveBootstrap) { BOOST_TEST_MESSAGE("Testing IBOR-IBOR basis-swap rate helpers (base curve bootstrap)..."); diff --git a/test-suite/basketoption.cpp b/test-suite/basketoption.cpp index bc23923d047..83b98e18185 100644 --- a/test-suite/basketoption.cpp +++ b/test-suite/basketoption.cpp @@ -96,123 +96,120 @@ BOOST_AUTO_TEST_SUITE(BasketOptionTests) << " tolerance: " << tolerance); -namespace { - - enum BasketType { MinBasket, MaxBasket, SpreadBasket }; - - std::string basketTypeToString(BasketType basketType) { - switch (basketType) { - case MinBasket: - return "MinBasket"; - case MaxBasket: - return "MaxBasket"; - case SpreadBasket: - return "Spread"; - } - QL_FAIL("unknown basket option type"); +enum BasketType { MinBasket, MaxBasket, SpreadBasket }; + +std::string basketTypeToString(BasketType basketType) { + switch (basketType) { + case MinBasket: + return "MinBasket"; + case MaxBasket: + return "MaxBasket"; + case SpreadBasket: + return "Spread"; } + QL_FAIL("unknown basket option type"); +} - ext::shared_ptr basketTypeToPayoff( - BasketType basketType, - const ext::shared_ptr &p) { - switch (basketType) { - case MinBasket: - return ext::shared_ptr(new MinBasketPayoff(p)); - case MaxBasket: - return ext::shared_ptr(new MaxBasketPayoff(p)); - case SpreadBasket: - return ext::shared_ptr(new SpreadBasketPayoff(p)); - } - QL_FAIL("unknown basket option type"); +ext::shared_ptr basketTypeToPayoff(BasketType basketType, + const ext::shared_ptr &p) { + switch (basketType) { + case MinBasket: + return ext::shared_ptr(new MinBasketPayoff(p)); + case MaxBasket: + return ext::shared_ptr(new MaxBasketPayoff(p)); + case SpreadBasket: + return ext::shared_ptr(new SpreadBasketPayoff(p)); } + QL_FAIL("unknown basket option type"); +} - struct BasketOptionOneData { - Option::Type type; - Real strike; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time t; // time to maturity - Volatility v; // volatility - Real result; // expected result - Real tol; // tolerance - }; - - struct BasketOptionTwoData { - BasketType basketType; - Option::Type type; - Real strike; - Real s1; - Real s2; - Rate q1; - Rate q2; - Rate r; - Time t; // years - Volatility v1; - Volatility v2; - Real rho; - Real result; - Real tol; - }; - - struct BasketOptionThreeData { - BasketType basketType; - Option::Type type; - Real strike; - Real s1; - Real s2; - Real s3; - Rate r; - Time t; // months - Volatility v1; - Volatility v2; - Volatility v3; - Real rho; - Real euroValue; - Real amValue; - }; +struct BasketOptionOneData { + Option::Type type; + Real strike; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time t; // time to maturity + Volatility v; // volatility + Real result; // expected result + Real tol; // tolerance +}; + +struct BasketOptionTwoData { + BasketType basketType; + Option::Type type; + Real strike; + Real s1; + Real s2; + Rate q1; + Rate q2; + Rate r; + Time t; // years + Volatility v1; + Volatility v2; + Real rho; + Real result; + Real tol; +}; + +struct BasketOptionThreeData { + BasketType basketType; + Option::Type type; + Real strike; + Real s1; + Real s2; + Real s3; + Rate r; + Time t; // months + Volatility v1; + Volatility v2; + Volatility v3; + Real rho; + Real euroValue; + Real amValue; +}; + +BasketOptionOneData oneDataValues[] = { + // type, strike, spot, q, r, t, vol, value, tol + { Option::Put, 100.00, 80.00, 0.0, 0.06, 0.5, 0.4, 21.6059, 1e-2 }, + { Option::Put, 100.00, 85.00, 0.0, 0.06, 0.5, 0.4, 18.0374, 1e-2 }, + { Option::Put, 100.00, 90.00, 0.0, 0.06, 0.5, 0.4, 14.9187, 1e-2 }, + { Option::Put, 100.00, 95.00, 0.0, 0.06, 0.5, 0.4, 12.2314, 1e-2 }, + { Option::Put, 100.00, 100.00, 0.0, 0.06, 0.5, 0.4, 9.9458, 1e-2 }, + { Option::Put, 100.00, 105.00, 0.0, 0.06, 0.5, 0.4, 8.0281, 1e-2 }, + { Option::Put, 100.00, 110.00, 0.0, 0.06, 0.5, 0.4, 6.4352, 1e-2 }, + { Option::Put, 100.00, 115.00, 0.0, 0.06, 0.5, 0.4, 5.1265, 1e-2 }, + { Option::Put, 100.00, 120.00, 0.0, 0.06, 0.5, 0.4, 4.0611, 1e-2 }, + + // Longstaff Schwartz 1D example + // use constant and three Laguerre polynomials + // 100,000 paths and 50 timesteps per year + { Option::Put, 40.00, 36.00, 0.0, 0.06, 1.0, 0.2, 4.478, 1e-2 }, + { Option::Put, 40.00, 36.00, 0.0, 0.06, 2.0, 0.2, 4.840, 1e-2 }, + { Option::Put, 40.00, 36.00, 0.0, 0.06, 1.0, 0.4, 7.101, 1e-2 }, + { Option::Put, 40.00, 36.00, 0.0, 0.06, 2.0, 0.4, 8.508, 1e-2 }, + + { Option::Put, 40.00, 38.00, 0.0, 0.06, 1.0, 0.2, 3.250, 1e-2 }, + { Option::Put, 40.00, 38.00, 0.0, 0.06, 2.0, 0.2, 3.745, 1e-2 }, + { Option::Put, 40.00, 38.00, 0.0, 0.06, 1.0, 0.4, 6.148, 1e-2 }, + { Option::Put, 40.00, 38.00, 0.0, 0.06, 2.0, 0.4, 7.670, 1e-2 }, + + { Option::Put, 40.00, 40.00, 0.0, 0.06, 1.0, 0.2, 2.314, 1e-2 }, + { Option::Put, 40.00, 40.00, 0.0, 0.06, 2.0, 0.2, 2.885, 1e-2 }, + { Option::Put, 40.00, 40.00, 0.0, 0.06, 1.0, 0.4, 5.312, 1e-2 }, + { Option::Put, 40.00, 40.00, 0.0, 0.06, 2.0, 0.4, 6.920, 1e-2 }, + + { Option::Put, 40.00, 42.00, 0.0, 0.06, 1.0, 0.2, 1.617, 1e-2 }, + { Option::Put, 40.00, 42.00, 0.0, 0.06, 2.0, 0.2, 2.212, 1e-2 }, + { Option::Put, 40.00, 42.00, 0.0, 0.06, 1.0, 0.4, 4.582, 1e-2 }, + { Option::Put, 40.00, 42.00, 0.0, 0.06, 2.0, 0.4, 6.248, 1e-2 }, + + { Option::Put, 40.00, 44.00, 0.0, 0.06, 1.0, 0.2, 1.110, 1e-2 }, + { Option::Put, 40.00, 44.00, 0.0, 0.06, 2.0, 0.2, 1.690, 1e-2 }, + { Option::Put, 40.00, 44.00, 0.0, 0.06, 1.0, 0.4, 3.948, 1e-2 }, + { Option::Put, 40.00, 44.00, 0.0, 0.06, 2.0, 0.4, 5.647, 1e-2 } +}; - BasketOptionOneData oneDataValues[] = { - // type, strike, spot, q, r, t, vol, value, tol - { Option::Put, 100.00, 80.00, 0.0, 0.06, 0.5, 0.4, 21.6059, 1e-2 }, - { Option::Put, 100.00, 85.00, 0.0, 0.06, 0.5, 0.4, 18.0374, 1e-2 }, - { Option::Put, 100.00, 90.00, 0.0, 0.06, 0.5, 0.4, 14.9187, 1e-2 }, - { Option::Put, 100.00, 95.00, 0.0, 0.06, 0.5, 0.4, 12.2314, 1e-2 }, - { Option::Put, 100.00, 100.00, 0.0, 0.06, 0.5, 0.4, 9.9458, 1e-2 }, - { Option::Put, 100.00, 105.00, 0.0, 0.06, 0.5, 0.4, 8.0281, 1e-2 }, - { Option::Put, 100.00, 110.00, 0.0, 0.06, 0.5, 0.4, 6.4352, 1e-2 }, - { Option::Put, 100.00, 115.00, 0.0, 0.06, 0.5, 0.4, 5.1265, 1e-2 }, - { Option::Put, 100.00, 120.00, 0.0, 0.06, 0.5, 0.4, 4.0611, 1e-2 }, - - // Longstaff Schwartz 1D example - // use constant and three Laguerre polynomials - // 100,000 paths and 50 timesteps per year - { Option::Put, 40.00, 36.00, 0.0, 0.06, 1.0, 0.2, 4.478, 1e-2 }, - { Option::Put, 40.00, 36.00, 0.0, 0.06, 2.0, 0.2, 4.840, 1e-2 }, - { Option::Put, 40.00, 36.00, 0.0, 0.06, 1.0, 0.4, 7.101, 1e-2 }, - { Option::Put, 40.00, 36.00, 0.0, 0.06, 2.0, 0.4, 8.508, 1e-2 }, - - { Option::Put, 40.00, 38.00, 0.0, 0.06, 1.0, 0.2, 3.250, 1e-2 }, - { Option::Put, 40.00, 38.00, 0.0, 0.06, 2.0, 0.2, 3.745, 1e-2 }, - { Option::Put, 40.00, 38.00, 0.0, 0.06, 1.0, 0.4, 6.148, 1e-2 }, - { Option::Put, 40.00, 38.00, 0.0, 0.06, 2.0, 0.4, 7.670, 1e-2 }, - - { Option::Put, 40.00, 40.00, 0.0, 0.06, 1.0, 0.2, 2.314, 1e-2 }, - { Option::Put, 40.00, 40.00, 0.0, 0.06, 2.0, 0.2, 2.885, 1e-2 }, - { Option::Put, 40.00, 40.00, 0.0, 0.06, 1.0, 0.4, 5.312, 1e-2 }, - { Option::Put, 40.00, 40.00, 0.0, 0.06, 2.0, 0.4, 6.920, 1e-2 }, - - { Option::Put, 40.00, 42.00, 0.0, 0.06, 1.0, 0.2, 1.617, 1e-2 }, - { Option::Put, 40.00, 42.00, 0.0, 0.06, 2.0, 0.2, 2.212, 1e-2 }, - { Option::Put, 40.00, 42.00, 0.0, 0.06, 1.0, 0.4, 4.582, 1e-2 }, - { Option::Put, 40.00, 42.00, 0.0, 0.06, 2.0, 0.4, 6.248, 1e-2 }, - - { Option::Put, 40.00, 44.00, 0.0, 0.06, 1.0, 0.2, 1.110, 1e-2 }, - { Option::Put, 40.00, 44.00, 0.0, 0.06, 2.0, 0.2, 1.690, 1e-2 }, - { Option::Put, 40.00, 44.00, 0.0, 0.06, 1.0, 0.4, 3.948, 1e-2 }, - { Option::Put, 40.00, 44.00, 0.0, 0.06, 2.0, 0.4, 5.647, 1e-2 } - }; -} BOOST_AUTO_TEST_CASE(testEuroTwoValues) { diff --git a/test-suite/batesmodel.cpp b/test-suite/batesmodel.cpp index 32a718250b6..bc88e35473c 100644 --- a/test-suite/batesmodel.cpp +++ b/test-suite/batesmodel.cpp @@ -46,44 +46,41 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BatesModelTests) -namespace { - - Real getCalibrationError( - std::vector > & options) { - Real sse = 0; - for (auto& option : options) { - const Real diff = option->calibrationError() * 100.0; - sse += diff*diff; - } - return sse; +Real getCalibrationError(std::vector > & options) { + Real sse = 0; + for (auto& option : options) { + const Real diff = option->calibrationError() * 100.0; + sse += diff*diff; } - - struct HestonModelData { - const char* const name; - Real v0; - Real kappa; - Real theta; - Real sigma; - Real rho; - Real r; - Real q; - }; - - HestonModelData hestonModels[] = { - // ADI finite difference schemes for option pricing in the - // Heston model with correlation, K.J. in t'Hout and S. Foulon, - {"'t Hout case 1", 0.04, 1.5, 0.04, 0.3, -0.9, 0.025, 0.0}, - // Efficient numerical methods for pricing American options under - // stochastic volatility, Samuli Ikonen and Jari Toivanen, - {"Ikonen-Toivanen", 0.0625, 5, 0.16, 0.9, 0.1, 0.1, 0.0}, - // Not-so-complex logarithms in the Heston model, - // Christian Kahl and Peter Jäckel - {"Kahl-Jaeckel", 0.16, 1.0, 0.16, 2.0, -0.8, 0.0, 0.0}, - // self defined test cases - {"Equity case", 0.07, 2.0, 0.04, 0.55, -0.8, 0.03, 0.035 }, - }; + return sse; } +struct HestonModelData { + const char* const name; + Real v0; + Real kappa; + Real theta; + Real sigma; + Real rho; + Real r; + Real q; +}; + +HestonModelData hestonModels[] = { + // ADI finite difference schemes for option pricing in the + // Heston model with correlation, K.J. in t'Hout and S. Foulon, + {"'t Hout case 1", 0.04, 1.5, 0.04, 0.3, -0.9, 0.025, 0.0}, + // Efficient numerical methods for pricing American options under + // stochastic volatility, Samuli Ikonen and Jari Toivanen, + {"Ikonen-Toivanen", 0.0625, 5, 0.16, 0.9, 0.1, 0.1, 0.0}, + // Not-so-complex logarithms in the Heston model, + // Christian Kahl and Peter Jäckel + {"Kahl-Jaeckel", 0.16, 1.0, 0.16, 2.0, -0.8, 0.0, 0.0}, + // self defined test cases + {"Equity case", 0.07, 2.0, 0.04, 0.55, -0.8, 0.03, 0.035 }, +}; + + BOOST_AUTO_TEST_CASE(testAnalyticVsBlack) { BOOST_TEST_MESSAGE("Testing analytic Bates engine against Black formula..."); diff --git a/test-suite/bermudanswaption.cpp b/test-suite/bermudanswaption.cpp index 5300b971298..9aaa64fb668 100644 --- a/test-suite/bermudanswaption.cpp +++ b/test-suite/bermudanswaption.cpp @@ -45,71 +45,68 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BermudanSwaptionTests) -namespace { - - struct CommonVars { - // global data - Date today, settlement; - Calendar calendar; - - // underlying swap parameters - Integer startYears, length; - Swap::Type type; - Real nominal; - BusinessDayConvention fixedConvention, floatingConvention; - Frequency fixedFrequency, floatingFrequency; - DayCounter fixedDayCount; - ext::shared_ptr index; - Natural settlementDays; - - RelinkableHandle termStructure; - - // setup - CommonVars() { - startYears = 1; - length = 5; - type = Swap::Payer; - nominal = 1000.0; - settlementDays = 2; - fixedConvention = Unadjusted; - floatingConvention = ModifiedFollowing; - fixedFrequency = Annual; - floatingFrequency = Semiannual; - fixedDayCount = Thirty360(Thirty360::BondBasis); - index = ext::shared_ptr(new Euribor6M(termStructure)); - calendar = index->fixingCalendar(); - today = calendar.adjust(Date::todaysDate()); - settlement = calendar.advance(today,settlementDays,Days); - } +struct CommonVars { + // global data + Date today, settlement; + Calendar calendar; + + // underlying swap parameters + Integer startYears, length; + Swap::Type type; + Real nominal; + BusinessDayConvention fixedConvention, floatingConvention; + Frequency fixedFrequency, floatingFrequency; + DayCounter fixedDayCount; + ext::shared_ptr index; + Natural settlementDays; + + RelinkableHandle termStructure; + + // setup + CommonVars() { + startYears = 1; + length = 5; + type = Swap::Payer; + nominal = 1000.0; + settlementDays = 2; + fixedConvention = Unadjusted; + floatingConvention = ModifiedFollowing; + fixedFrequency = Annual; + floatingFrequency = Semiannual; + fixedDayCount = Thirty360(Thirty360::BondBasis); + index = ext::shared_ptr(new Euribor6M(termStructure)); + calendar = index->fixingCalendar(); + today = calendar.adjust(Date::todaysDate()); + settlement = calendar.advance(today,settlementDays,Days); + } - // utilities - ext::shared_ptr makeSwap(Rate fixedRate) const { - Date start = calendar.advance(settlement, startYears, Years); - Date maturity = calendar.advance(start, length, Years); - Schedule fixedSchedule(start, maturity, - Period(fixedFrequency), - calendar, - fixedConvention, - fixedConvention, - DateGeneration::Forward, false); - Schedule floatSchedule(start, maturity, - Period(floatingFrequency), - calendar, - floatingConvention, - floatingConvention, - DateGeneration::Forward, false); - ext::shared_ptr swap( + // utilities + ext::shared_ptr makeSwap(Rate fixedRate) const { + Date start = calendar.advance(settlement, startYears, Years); + Date maturity = calendar.advance(start, length, Years); + Schedule fixedSchedule(start, maturity, + Period(fixedFrequency), + calendar, + fixedConvention, + fixedConvention, + DateGeneration::Forward, false); + Schedule floatSchedule(start, maturity, + Period(floatingFrequency), + calendar, + floatingConvention, + floatingConvention, + DateGeneration::Forward, false); + ext::shared_ptr swap( new VanillaSwap(type, nominal, fixedSchedule, fixedRate, fixedDayCount, floatSchedule, index, 0.0, index->dayCounter())); - swap->setPricingEngine(ext::shared_ptr( + swap->setPricingEngine(ext::shared_ptr( new DiscountingSwapEngine(termStructure))); - return swap; - } - }; + return swap; + } +}; -} BOOST_AUTO_TEST_CASE(testCachedValues) { diff --git a/test-suite/binaryoption.cpp b/test-suite/binaryoption.cpp index 3acdab84274..0079d2c242f 100644 --- a/test-suite/binaryoption.cpp +++ b/test-suite/binaryoption.cpp @@ -59,39 +59,37 @@ BOOST_AUTO_TEST_SUITE(BinaryOptionTests) << " error: " << error << "\n" \ << " tolerance: " << tolerance << "\n"); -namespace { - - std::string barrierTypeToString(Barrier::Type type) { - switch(type){ - case Barrier::DownIn: - return std::string("Down-and-in"); - case Barrier::UpIn: - return std::string("Up-and-in"); - case Barrier::DownOut: - return std::string("Down-and-out"); - case Barrier::UpOut: - return std::string("Up-and-out"); - default: - QL_FAIL("unknown exercise type"); - } +std::string barrierTypeToString(Barrier::Type type) { + switch(type){ + case Barrier::DownIn: + return std::string("Down-and-in"); + case Barrier::UpIn: + return std::string("Up-and-in"); + case Barrier::DownOut: + return std::string("Down-and-out"); + case Barrier::UpOut: + return std::string("Up-and-out"); + default: + QL_FAIL("unknown exercise type"); } - - struct BinaryOptionData { - Barrier::Type barrierType; - Real barrier; - Real cash; // cash payoff for cash-or-nothing - Option::Type type; - Real strike; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time t; // time to maturity - Volatility v; // volatility - Real result; // expected result - Real tol; // tolerance - }; } +struct BinaryOptionData { + Barrier::Type barrierType; + Real barrier; + Real cash; // cash payoff for cash-or-nothing + Option::Type type; + Real strike; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time t; // time to maturity + Volatility v; // volatility + Real result; // expected result + Real tol; // tolerance +}; + + BOOST_AUTO_TEST_CASE(testCashOrNothingHaugValues) { BOOST_TEST_MESSAGE("Testing cash-or-nothing barrier options against Haug's values..."); diff --git a/test-suite/blackdeltacalculator.cpp b/test-suite/blackdeltacalculator.cpp index 886f732e98e..629e74d65aa 100644 --- a/test-suite/blackdeltacalculator.cpp +++ b/test-suite/blackdeltacalculator.cpp @@ -38,32 +38,29 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BlackDeltaCalculatorTests) -namespace { - - struct DeltaData { - Option::Type ot; - DeltaVolQuote::DeltaType dt; - Real spot; - DiscountFactor dDf; // domestic discount - DiscountFactor fDf; // foreign discount - Real stdDev; - Real strike; - Real value; - }; - - struct EuropeanOptionData { - Option::Type type; - Real strike; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time t; // time to maturity - Volatility v; // volatility - Real result; // expected result - Real tol; // tolerance - }; +struct DeltaData { + Option::Type ot; + DeltaVolQuote::DeltaType dt; + Real spot; + DiscountFactor dDf; // domestic discount + DiscountFactor fDf; // foreign discount + Real stdDev; + Real strike; + Real value; +}; + +struct EuropeanOptionData { + Option::Type type; + Real strike; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time t; // time to maturity + Volatility v; // volatility + Real result; // expected result + Real tol; // tolerance +}; -} BOOST_AUTO_TEST_CASE(testDeltaValues){ diff --git a/test-suite/bondforward.cpp b/test-suite/bondforward.cpp index 9f248b5df89..aab43a249b6 100644 --- a/test-suite/bondforward.cpp +++ b/test-suite/bondforward.cpp @@ -31,43 +31,41 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BondForwardTests) -namespace { - - struct CommonVars { - // common data - Date today; - RelinkableHandle curveHandle; - - // setup - CommonVars() { - today = Date(7, March, 2022); - Settings::instance().evaluationDate() = today; - - curveHandle.linkTo(flatRate(today, 0.0004977, Actual365Fixed())); - } - }; - - ext::shared_ptr buildBond(const Date &issue, - const Date &maturity, - Rate cpn) { - Schedule sch(issue, maturity, Period(Annual), TARGET(), Following, Following, - DateGeneration::Backward, false); - - return ext::make_shared(2, 1.e5, sch, std::vector(1, cpn), - ActualActual(ActualActual::ISDA)); - } +struct CommonVars { + // common data + Date today; + RelinkableHandle curveHandle; + + // setup + CommonVars() { + today = Date(7, March, 2022); + Settings::instance().evaluationDate() = today; - ext::shared_ptr buildBondForward(const ext::shared_ptr& underlying, - const Handle &handle, - const Date& delivery, - Position::Type type) { - auto valueDt = handle->referenceDate(); - return ext::make_shared(valueDt, delivery, type, 0.0, 2, - ActualActual(ActualActual::ISDA), - TARGET(), Following, underlying, handle, handle); + curveHandle.linkTo(flatRate(today, 0.0004977, Actual365Fixed())); } +}; + +ext::shared_ptr buildBond(const Date &issue, + const Date &maturity, + Rate cpn) { + Schedule sch(issue, maturity, Period(Annual), TARGET(), Following, Following, + DateGeneration::Backward, false); + + return ext::make_shared(2, 1.e5, sch, std::vector(1, cpn), + ActualActual(ActualActual::ISDA)); } +ext::shared_ptr buildBondForward(const ext::shared_ptr& underlying, + const Handle &handle, + const Date& delivery, + Position::Type type) { + auto valueDt = handle->referenceDate(); + return ext::make_shared(valueDt, delivery, type, 0.0, 2, + ActualActual(ActualActual::ISDA), + TARGET(), Following, underlying, handle, handle); +} + + BOOST_AUTO_TEST_CASE(testFuturesPriceReplication) { BOOST_TEST_MESSAGE("Testing futures price replication..."); diff --git a/test-suite/bonds.cpp b/test-suite/bonds.cpp index 14384d3b900..b7760f1a6ee 100644 --- a/test-suite/bonds.cpp +++ b/test-suite/bonds.cpp @@ -65,32 +65,29 @@ BOOST_AUTO_TEST_SUITE(BondsTests) << "\n expected: " << std::setprecision(8) << expected); \ } -namespace { - - struct CommonVars { - // common data - Calendar calendar; - Date today; - Real faceAmount; - - // setup - CommonVars() { - calendar = TARGET(); - today = calendar.adjust(Date::todaysDate()); - Settings::instance().evaluationDate() = today; - faceAmount = 1000000.0; - } - }; - - void checkValue(Real value, Real expectedValue, Real tolerance, const std::string& msg) { - if (std::fabs(value - expectedValue) > tolerance) { - BOOST_ERROR(msg - << std::fixed - << "\n calculated: " << value - << "\n expected: " << expectedValue - << "\n tolerance: " << tolerance - << "\n error: " << value - expectedValue); - } +struct CommonVars { + // common data + Calendar calendar; + Date today; + Real faceAmount; + + // setup + CommonVars() { + calendar = TARGET(); + today = calendar.adjust(Date::todaysDate()); + Settings::instance().evaluationDate() = today; + faceAmount = 1000000.0; + } +}; + +void checkValue(Real value, Real expectedValue, Real tolerance, const std::string& msg) { + if (std::fabs(value - expectedValue) > tolerance) { + BOOST_ERROR(msg + << std::fixed + << "\n calculated: " << value + << "\n expected: " << expectedValue + << "\n tolerance: " << tolerance + << "\n error: " << value - expectedValue); } } diff --git a/test-suite/brownianbridge.cpp b/test-suite/brownianbridge.cpp index ea291230bec..d2947fa3d19 100644 --- a/test-suite/brownianbridge.cpp +++ b/test-suite/brownianbridge.cpp @@ -36,32 +36,29 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BrownianBridgeTests) -namespace { - - template - Real maxDiff(ForwardIterator1 begin1, ForwardIterator1 end1, - ForwardIterator2 begin2) { - Real diff = 0.0; - while (begin1 != end1) { - diff = std::max(diff, std::fabs(*begin1 - *begin2)); - ++begin1; ++begin2; - } - return diff; +template +Real maxDiff(ForwardIterator1 begin1, ForwardIterator1 end1, + ForwardIterator2 begin2) { + Real diff = 0.0; + while (begin1 != end1) { + diff = std::max(diff, std::fabs(*begin1 - *begin2)); + ++begin1; ++begin2; } + return diff; +} - template - Real maxRelDiff(ForwardIterator1 begin1, ForwardIterator1 end1, - ForwardIterator2 begin2) { - Real diff = 0.0; - while (begin1 != end1) { - diff = std::max(diff, std::fabs((*begin1 - *begin2)/(*begin2))); - ++begin1; ++begin2; - } - return diff; +template +Real maxRelDiff(ForwardIterator1 begin1, ForwardIterator1 end1, + ForwardIterator2 begin2) { + Real diff = 0.0; + while (begin1 != end1) { + diff = std::max(diff, std::fabs((*begin1 - *begin2)/(*begin2))); + ++begin1; ++begin2; } - + return diff; } + BOOST_AUTO_TEST_CASE(testVariates) { BOOST_TEST_MESSAGE("Testing Brownian-bridge variates..."); diff --git a/test-suite/businessdayconventions.cpp b/test-suite/businessdayconventions.cpp index 11888917695..3d0b8150b1f 100644 --- a/test-suite/businessdayconventions.cpp +++ b/test-suite/businessdayconventions.cpp @@ -30,26 +30,23 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(BusinessDayConventionTests) -namespace { - - struct SingleCase { - SingleCase(Calendar calendar, - const BusinessDayConvention& convention, - const Date& start, - const Period& period, - const bool endOfMonth, - Date result) - : calendar(std::move(calendar)), convention(convention), start(start), period(period), - endOfMonth(endOfMonth), result(result) {} - Calendar calendar; - BusinessDayConvention convention; - Date start; - Period period; - bool endOfMonth; - Date result; - }; +struct SingleCase { + SingleCase(Calendar calendar, + const BusinessDayConvention& convention, + const Date& start, + const Period& period, + const bool endOfMonth, + Date result) + : calendar(std::move(calendar)), convention(convention), start(start), period(period), + endOfMonth(endOfMonth), result(result) {} + Calendar calendar; + BusinessDayConvention convention; + Date start; + Period period; + bool endOfMonth; + Date result; +}; -} BOOST_AUTO_TEST_CASE(testConventions) { diff --git a/test-suite/callablebonds.cpp b/test-suite/callablebonds.cpp index 83fccf665e9..9166b782844 100644 --- a/test-suite/callablebonds.cpp +++ b/test-suite/callablebonds.cpp @@ -44,59 +44,56 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CallableBondTests) -namespace { +struct Globals { + // global data + Date today, settlement; + Calendar calendar; + DayCounter dayCounter; + BusinessDayConvention rollingConvention; - struct Globals { - // global data - Date today, settlement; - Calendar calendar; - DayCounter dayCounter; - BusinessDayConvention rollingConvention; - - RelinkableHandle termStructure; - RelinkableHandle model; + RelinkableHandle termStructure; + RelinkableHandle model; - Date issueDate() const { - // ensure that we're in mid-coupon - return calendar.adjust(today - 100*Days); - } + Date issueDate() const { + // ensure that we're in mid-coupon + return calendar.adjust(today - 100*Days); + } - Date maturityDate() const { - // ensure that we're in mid-coupon - return calendar.advance(issueDate(),10,Years); - } + Date maturityDate() const { + // ensure that we're in mid-coupon + return calendar.advance(issueDate(),10,Years); + } - std::vector evenYears() const { - std::vector dates; - for (Size i=2; i<10; i+=2) - dates.push_back(calendar.advance(issueDate(),i,Years)); - return dates; - } + std::vector evenYears() const { + std::vector dates; + for (Size i=2; i<10; i+=2) + dates.push_back(calendar.advance(issueDate(),i,Years)); + return dates; + } - std::vector oddYears() const { - std::vector dates; - for (Size i=1; i<10; i+=2) - dates.push_back(calendar.advance(issueDate(),i,Years)); - return dates; - } + std::vector oddYears() const { + std::vector dates; + for (Size i=1; i<10; i+=2) + dates.push_back(calendar.advance(issueDate(),i,Years)); + return dates; + } - template - ext::shared_ptr makeFlatCurve(const R& r) const { - return ext::shared_ptr( + template + ext::shared_ptr makeFlatCurve(const R& r) const { + return ext::shared_ptr( new FlatForward(settlement, r, dayCounter)); - } + } - Globals() { - calendar = TARGET(); - dayCounter = Actual365Fixed(); - rollingConvention = ModifiedFollowing; + Globals() { + calendar = TARGET(); + dayCounter = Actual365Fixed(); + rollingConvention = ModifiedFollowing; - today = Settings::instance().evaluationDate(); - settlement = calendar.advance(today,2,Days); - } - }; + today = Settings::instance().evaluationDate(); + settlement = calendar.advance(today,2,Days); + } +}; -} BOOST_AUTO_TEST_CASE(testInterplay) { diff --git a/test-suite/capfloor.cpp b/test-suite/capfloor.cpp index 19d41d335f7..74d026f22e9 100644 --- a/test-suite/capfloor.cpp +++ b/test-suite/capfloor.cpp @@ -48,107 +48,102 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CapFloorTests) -namespace { - - struct CommonVars { - // common data - Date settlement; - std::vector nominals; - BusinessDayConvention convention; - Frequency frequency; - ext::shared_ptr index; - Calendar calendar; - Natural fixingDays; - RelinkableHandle termStructure; - - // setup - CommonVars() - : nominals(1,100) { - frequency = Semiannual; - index = ext::shared_ptr(new Euribor6M(termStructure)); - calendar = index->fixingCalendar(); - convention = ModifiedFollowing; - Date today = Settings::instance().evaluationDate(); - Natural settlementDays = 2; - fixingDays = 2; - settlement = calendar.advance(today,settlementDays,Days); - termStructure.linkTo(flatRate(settlement,0.05, - ActualActual(ActualActual::ISDA))); - } +struct CommonVars { + // common data + Date settlement; + std::vector nominals; + BusinessDayConvention convention; + Frequency frequency; + ext::shared_ptr index; + Calendar calendar; + Natural fixingDays; + RelinkableHandle termStructure; + + // setup + CommonVars() + : nominals(1,100) { + frequency = Semiannual; + index = ext::shared_ptr(new Euribor6M(termStructure)); + calendar = index->fixingCalendar(); + convention = ModifiedFollowing; + Date today = Settings::instance().evaluationDate(); + Natural settlementDays = 2; + fixingDays = 2; + settlement = calendar.advance(today,settlementDays,Days); + termStructure.linkTo(flatRate(settlement,0.05, + ActualActual(ActualActual::ISDA))); + } - // utilities - Leg makeLeg(const Date& startDate, Integer length) const { - Date endDate = calendar.advance(startDate,length*Years,convention); - Schedule schedule(startDate, endDate, Period(frequency), calendar, - convention, convention, - DateGeneration::Forward, false); - return IborLeg(schedule, index) - .withNotionals(nominals) - .withPaymentDayCounter(index->dayCounter()) - .withPaymentAdjustment(convention) - .withFixingDays(fixingDays); - } + // utilities + Leg makeLeg(const Date& startDate, Integer length) const { + Date endDate = calendar.advance(startDate,length*Years,convention); + Schedule schedule(startDate, endDate, Period(frequency), calendar, + convention, convention, + DateGeneration::Forward, false); + return IborLeg(schedule, index) + .withNotionals(nominals) + .withPaymentDayCounter(index->dayCounter()) + .withPaymentAdjustment(convention) + .withFixingDays(fixingDays); + } - ext::shared_ptr makeEngine(Volatility volatility) const { - Handle vol(ext::shared_ptr( - new SimpleQuote(volatility))); - return ext::shared_ptr( + ext::shared_ptr makeEngine(Volatility volatility) const { + Handle vol(ext::shared_ptr(new SimpleQuote(volatility))); + return ext::shared_ptr( new BlackCapFloorEngine(termStructure, vol)); - } + } - ext::shared_ptr makeBachelierEngine(Volatility volatility) const { - Handle vol(ext::shared_ptr( - new SimpleQuote(volatility))); - return ext::shared_ptr( + ext::shared_ptr makeBachelierEngine(Volatility volatility) const { + Handle vol(ext::shared_ptr(new SimpleQuote(volatility))); + return ext::shared_ptr( new BachelierCapFloorEngine(termStructure, vol)); - } - - ext::shared_ptr makeCapFloor(CapFloor::Type type, - const Leg& leg, - Rate strike, - Volatility volatility, - bool isLogNormal = true) const { - ext::shared_ptr result; - switch (type) { - case CapFloor::Cap: - result = ext::shared_ptr( - new Cap(leg, std::vector(1, strike))); - break; - case CapFloor::Floor: - result = ext::shared_ptr( - new Floor(leg, std::vector(1, strike))); - break; - default: - QL_FAIL("unknown cap/floor type"); - } - if(isLogNormal){ - result->setPricingEngine(makeEngine(volatility)); - } else { - result->setPricingEngine(makeBachelierEngine(volatility)); - } - return result; - } - }; - - bool checkAbsError(Real x1, Real x2, Real tolerance){ - return std::fabs(x1 - x2) < tolerance; } - std::string typeToString(CapFloor::Type type) { + ext::shared_ptr makeCapFloor(CapFloor::Type type, + const Leg& leg, + Rate strike, + Volatility volatility, + bool isLogNormal = true) const { + ext::shared_ptr result; switch (type) { case CapFloor::Cap: - return "cap"; + result = ext::shared_ptr( + new Cap(leg, std::vector(1, strike))); + break; case CapFloor::Floor: - return "floor"; - case CapFloor::Collar: - return "collar"; + result = ext::shared_ptr( + new Floor(leg, std::vector(1, strike))); + break; default: QL_FAIL("unknown cap/floor type"); } + if(isLogNormal){ + result->setPricingEngine(makeEngine(volatility)); + } else { + result->setPricingEngine(makeBachelierEngine(volatility)); + } + return result; } +}; +bool checkAbsError(Real x1, Real x2, Real tolerance){ + return std::fabs(x1 - x2) < tolerance; } +std::string typeToString(CapFloor::Type type) { + switch (type) { + case CapFloor::Cap: + return "cap"; + case CapFloor::Floor: + return "floor"; + case CapFloor::Collar: + return "collar"; + default: + QL_FAIL("unknown cap/floor type"); + } +} + + BOOST_AUTO_TEST_CASE(testVega) { BOOST_TEST_MESSAGE("Testing cap/floor vega..."); diff --git a/test-suite/capflooredcoupon.cpp b/test-suite/capflooredcoupon.cpp index e155f36b631..2e8fb61fb52 100644 --- a/test-suite/capflooredcoupon.cpp +++ b/test-suite/capflooredcoupon.cpp @@ -44,150 +44,146 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CapFlooredCouponTests) -namespace { - - struct CommonVars { - // global data - Date today, settlement, startDate; - Calendar calendar; - Real nominal; - std::vector nominals; - BusinessDayConvention convention; - Frequency frequency; - ext::shared_ptr index; - Natural settlementDays, fixingDays; - RelinkableHandle termStructure; - std::vector caps; - std::vector floors; - Integer length; - Volatility volatility; - - // setup - CommonVars() { - length = 20; //years - volatility = 0.20; - nominal = 100.; - nominals = std::vector(length,nominal); - frequency = Annual; - index = ext::shared_ptr(new Euribor1Y(termStructure)); - calendar = index->fixingCalendar(); - convention = ModifiedFollowing; - today = calendar.adjust(Date::todaysDate()); - Settings::instance().evaluationDate() = today; - settlementDays = 2; - fixingDays = 2; - settlement = calendar.advance(today,settlementDays,Days); - startDate = settlement; - termStructure.linkTo(flatRate(settlement,0.05, - ActualActual(ActualActual::ISDA))); - } +struct CommonVars { + // global data + Date today, settlement, startDate; + Calendar calendar; + Real nominal; + std::vector nominals; + BusinessDayConvention convention; + Frequency frequency; + ext::shared_ptr index; + Natural settlementDays, fixingDays; + RelinkableHandle termStructure; + std::vector caps; + std::vector floors; + Integer length; + Volatility volatility; + + // setup + CommonVars() { + length = 20; //years + volatility = 0.20; + nominal = 100.; + nominals = std::vector(length,nominal); + frequency = Annual; + index = ext::shared_ptr(new Euribor1Y(termStructure)); + calendar = index->fixingCalendar(); + convention = ModifiedFollowing; + today = calendar.adjust(Date::todaysDate()); + Settings::instance().evaluationDate() = today; + settlementDays = 2; + fixingDays = 2; + settlement = calendar.advance(today,settlementDays,Days); + startDate = settlement; + termStructure.linkTo(flatRate(settlement,0.05, + ActualActual(ActualActual::ISDA))); + } - // utilities - Leg makeFixedLeg(const Date& startDate, Integer length) const { - - Date endDate = calendar.advance(startDate, length, Years, - convention); - Schedule schedule(startDate, endDate, Period(frequency), calendar, - convention, convention, - DateGeneration::Forward, false); - std::vector coupons(length, 0.0); - return FixedRateLeg(schedule) - .withNotionals(nominals) - .withCouponRates(coupons, Thirty360(Thirty360::BondBasis)); - } + // utilities + Leg makeFixedLeg(const Date& startDate, Integer length) const { + + Date endDate = calendar.advance(startDate, length, Years, + convention); + Schedule schedule(startDate, endDate, Period(frequency), calendar, + convention, convention, + DateGeneration::Forward, false); + std::vector coupons(length, 0.0); + return FixedRateLeg(schedule) + .withNotionals(nominals) + .withCouponRates(coupons, Thirty360(Thirty360::BondBasis)); + } - Leg makeFloatingLeg(const Date& startDate, - Integer length, - const Rate gearing = 1.0, - const Rate spread = 0.0) const { - - Date endDate = calendar.advance(startDate,length,Years,convention); - Schedule schedule(startDate,endDate,Period(frequency),calendar, - convention,convention, - DateGeneration::Forward,false); - std::vector gearingVector(length, gearing); - std::vector spreadVector(length, spread); - return IborLeg(schedule, index) - .withNotionals(nominals) - .withPaymentDayCounter(index->dayCounter()) - .withPaymentAdjustment(convention) - .withFixingDays(fixingDays) - .withGearings(gearingVector) - .withSpreads(spreadVector); - } + Leg makeFloatingLeg(const Date& startDate, + Integer length, + const Rate gearing = 1.0, + const Rate spread = 0.0) const { + + Date endDate = calendar.advance(startDate,length,Years,convention); + Schedule schedule(startDate,endDate,Period(frequency),calendar, + convention,convention, + DateGeneration::Forward,false); + std::vector gearingVector(length, gearing); + std::vector spreadVector(length, spread); + return IborLeg(schedule, index) + .withNotionals(nominals) + .withPaymentDayCounter(index->dayCounter()) + .withPaymentAdjustment(convention) + .withFixingDays(fixingDays) + .withGearings(gearingVector) + .withSpreads(spreadVector); + } - Leg makeCapFlooredLeg(const Date& startDate, - Integer length, - const std::vector& caps, - const std::vector& floors, - Volatility volatility, - const Rate gearing = 1.0, - const Rate spread = 0.0) const { - - Date endDate = calendar.advance(startDate,length,Years,convention); - Schedule schedule(startDate,endDate,Period(frequency),calendar, - convention,convention, - DateGeneration::Forward,false); - Handle vol( + Leg makeCapFlooredLeg(const Date& startDate, + Integer length, + const std::vector& caps, + const std::vector& floors, + Volatility volatility, + const Rate gearing = 1.0, + const Rate spread = 0.0) const { + + Date endDate = calendar.advance(startDate,length,Years,convention); + Schedule schedule(startDate,endDate,Period(frequency),calendar, + convention,convention, + DateGeneration::Forward,false); + Handle vol( ext::shared_ptr(new ConstantOptionletVolatility(0, calendar, Following, volatility,Actual365Fixed()))); - ext::shared_ptr pricer(new + ext::shared_ptr pricer(new BlackIborCouponPricer(vol)); - std::vector gearingVector(length, gearing); - std::vector spreadVector(length, spread); - - Leg iborLeg = IborLeg(schedule, index) - .withNotionals(nominals) - .withPaymentDayCounter(index->dayCounter()) - .withPaymentAdjustment(convention) - .withFixingDays(fixingDays) - .withGearings(gearingVector) - .withSpreads(spreadVector) - .withCaps(caps) - .withFloors(floors); - setCouponPricer(iborLeg, pricer); - return iborLeg; - } + std::vector gearingVector(length, gearing); + std::vector spreadVector(length, spread); + + Leg iborLeg = IborLeg(schedule, index) + .withNotionals(nominals) + .withPaymentDayCounter(index->dayCounter()) + .withPaymentAdjustment(convention) + .withFixingDays(fixingDays) + .withGearings(gearingVector) + .withSpreads(spreadVector) + .withCaps(caps) + .withFloors(floors); + setCouponPricer(iborLeg, pricer); + return iborLeg; + } - ext::shared_ptr makeEngine(Volatility volatility) const { - Handle vol(ext::shared_ptr( - new SimpleQuote(volatility))); - return ext::shared_ptr( + ext::shared_ptr makeEngine(Volatility volatility) const { + Handle vol(ext::shared_ptr(new SimpleQuote(volatility))); + return ext::shared_ptr( new BlackCapFloorEngine(termStructure, vol)); - } + } - ext::shared_ptr makeCapFloor(CapFloor::Type type, - const Leg& leg, - Rate capStrike, - Rate floorStrike, - Volatility volatility) const { - ext::shared_ptr result; - switch (type) { - case CapFloor::Cap: - result = ext::shared_ptr( + ext::shared_ptr makeCapFloor(CapFloor::Type type, + const Leg& leg, + Rate capStrike, + Rate floorStrike, + Volatility volatility) const { + ext::shared_ptr result; + switch (type) { + case CapFloor::Cap: + result = ext::shared_ptr( new Cap(leg, std::vector(1, capStrike))); - break; - case CapFloor::Floor: - result = ext::shared_ptr( + break; + case CapFloor::Floor: + result = ext::shared_ptr( new Floor(leg, std::vector(1, floorStrike))); - break; - case CapFloor::Collar: - result = ext::shared_ptr( + break; + case CapFloor::Collar: + result = ext::shared_ptr( new Collar(leg, std::vector(1, capStrike), std::vector(1, floorStrike))); - break; - default: - QL_FAIL("unknown cap/floor type"); - } - result->setPricingEngine(makeEngine(volatility)); - return result; + break; + default: + QL_FAIL("unknown cap/floor type"); } - }; + result->setPricingEngine(makeEngine(volatility)); + return result; + } +}; -} BOOST_AUTO_TEST_CASE(testLargeRates) { diff --git a/test-suite/catbonds.cpp b/test-suite/catbonds.cpp index 8b5a8b39b5b..3ccdbeb4b69 100644 --- a/test-suite/catbonds.cpp +++ b/test-suite/catbonds.cpp @@ -52,28 +52,27 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CatBondTests) -namespace { - std::pair data[] = {std::pair(Date(1, February, 2012), 100), std::pair(Date(1, July, 2013), 150), std::pair(Date(5, January, 2014), 50)}; - ext::shared_ptr > > sampleEvents(new std::vector >(data, data+3)); - - Date eventsStart(1, January, 2011); - Date eventsEnd(31, December, 2014); - - struct CommonVars { - // common data - Calendar calendar; - Date today; - Real faceAmount; - - // setup - CommonVars() { - calendar = TARGET(); - today = calendar.adjust(Date::todaysDate()); - Settings::instance().evaluationDate() = today; - faceAmount = 1000000.0; - } - }; -} +std::pair data[] = {std::pair(Date(1, February, 2012), 100), std::pair(Date(1, July, 2013), 150), std::pair(Date(5, January, 2014), 50)}; +ext::shared_ptr > > sampleEvents(new std::vector >(data, data+3)); + +Date eventsStart(1, January, 2011); +Date eventsEnd(31, December, 2014); + +struct CommonVars { + // common data + Calendar calendar; + Date today; + Real faceAmount; + + // setup + CommonVars() { + calendar = TARGET(); + today = calendar.adjust(Date::todaysDate()); + Settings::instance().evaluationDate() = today; + faceAmount = 1000000.0; + } +}; + BOOST_AUTO_TEST_CASE(testEventSetForWholeYears) { BOOST_TEST_MESSAGE("Testing that catastrophe events are split correctly for periods of whole years..."); diff --git a/test-suite/cdo.cpp b/test-suite/cdo.cpp index ae3ea564579..4a8b3999375 100644 --- a/test-suite/cdo.cpp +++ b/test-suite/cdo.cpp @@ -48,52 +48,49 @@ BOOST_AUTO_TEST_SUITE(CdoTests, *precondition(if_speed(Slow))) #ifndef QL_PATCH_SOLARIS -namespace { - - Real hwAttachment[] = { 0.00, 0.03, 0.06, 0.10 }; - Real hwDetachment[] = { 0.03, 0.06, 0.10, 1.00 }; - - struct hwDatum { - Real correlation; - Integer nm; - Integer nz; - Real trancheSpread[4]; - }; - - // HW Table 7 - // corr, Nm, Nz, 0-3, 3-6, 6-10, 10-100 - hwDatum hwData7[] = { - { 0.1, -1, -1, { 2279, 450, 89, 1 } }, - { 0.3, -1, -1, { 1487, 472, 203, 7 } }, - // Opening the T, T&G tests too. The convolution is analytical - // now so it runs it a time comparable to the gaussian tests and - // has enough precission to pass the tests. - // Below the T models are integrated with a quadrature, even if this - // is incorrect the test pass good enough, the quadrature gets to - // be worst as the kernel deviates from a normal, this is low - // orders of the T; here 5 is enough, 3 would not be. - { 0.3, -1, 5, { 1766, 420, 161, 6 } }, - { 0.3, 5, -1, { 1444, 408, 171, 10 } }, - { 0.3, 5, 5, { 1713, 359, 136, 9 } } - }; - - void check(int i, int j, const std::string& desc, Real found, Real expected, - Real bpTolerance, Real relativeTolerance) - { - /* Uncomment to display the full show if your debugging: - std::cout<< "Case: "<< i << " " << j << " " << found << " :: " - << expected << " ("<< desc << ") " << std::endl; - */ - Real absDiff = found - expected; - Real relDiff = absDiff / expected; - BOOST_CHECK_MESSAGE (fabs(relDiff) < relativeTolerance || - fabs(absDiff) < bpTolerance, - "case " << i << " " << j << " ("<< desc << "): " - << found << " vs. " << expected); - } - +Real hwAttachment[] = { 0.00, 0.03, 0.06, 0.10 }; +Real hwDetachment[] = { 0.03, 0.06, 0.10, 1.00 }; + +struct hwDatum { + Real correlation; + Integer nm; + Integer nz; + Real trancheSpread[4]; +}; + +// HW Table 7 +// corr, Nm, Nz, 0-3, 3-6, 6-10, 10-100 +hwDatum hwData7[] = { + { 0.1, -1, -1, { 2279, 450, 89, 1 } }, + { 0.3, -1, -1, { 1487, 472, 203, 7 } }, + // Opening the T, T&G tests too. The convolution is analytical + // now so it runs it a time comparable to the gaussian tests and + // has enough precission to pass the tests. + // Below the T models are integrated with a quadrature, even if this + // is incorrect the test pass good enough, the quadrature gets to + // be worst as the kernel deviates from a normal, this is low + // orders of the T; here 5 is enough, 3 would not be. + { 0.3, -1, 5, { 1766, 420, 161, 6 } }, + { 0.3, 5, -1, { 1444, 408, 171, 10 } }, + { 0.3, 5, 5, { 1713, 359, 136, 9 } } +}; + +void check(int i, int j, const std::string& desc, Real found, Real expected, + Real bpTolerance, Real relativeTolerance) +{ + /* Uncomment to display the full show if your debugging: + std::cout<< "Case: "<< i << " " << j << " " << found << " :: " + << expected << " ("<< desc << ") " << std::endl; + */ + Real absDiff = found - expected; + Real relDiff = absDiff / expected; + BOOST_CHECK_MESSAGE (fabs(relDiff) < relativeTolerance || + fabs(absDiff) < bpTolerance, + "case " << i << " " << j << " ("<< desc << "): " + << found << " vs. " << expected); } + struct dataSetOne { static const int dataset{0}; }; struct dataSetTwo { static const int dataset{1}; }; struct dataSetThree { static const int dataset{2}; }; diff --git a/test-suite/cliquetoption.cpp b/test-suite/cliquetoption.cpp index 9efd882b9d4..6fe965f89c6 100644 --- a/test-suite/cliquetoption.cpp +++ b/test-suite/cliquetoption.cpp @@ -103,144 +103,141 @@ BOOST_AUTO_TEST_CASE(testValues) { } -namespace { - - template - void testOptionGreeks() { - - std::map calculated, expected, tolerance; - tolerance["delta"] = 1.0e-5; - tolerance["gamma"] = 1.0e-5; - tolerance["theta"] = 1.0e-5; - tolerance["rho"] = 1.0e-5; - tolerance["divRho"] = 1.0e-5; - tolerance["vega"] = 1.0e-5; - - Option::Type types[] = { Option::Call, Option::Put }; - Real moneyness[] = { 0.9, 1.0, 1.1 }; - Real underlyings[] = { 100.0 }; - Rate qRates[] = { 0.04, 0.05, 0.06 }; - Rate rRates[] = { 0.01, 0.05, 0.15 }; - Integer lengths[] = { 1, 2 }; - Frequency frequencies[] = { Semiannual, Quarterly }; - Volatility vols[] = { 0.11, 0.50, 1.20 }; - - DayCounter dc = Actual360(); - Date today = Date::todaysDate(); - Settings::instance().evaluationDate() = today; - - ext::shared_ptr spot(new SimpleQuote(0.0)); - ext::shared_ptr qRate(new SimpleQuote(0.0)); - Handle qTS(flatRate(qRate, dc)); - ext::shared_ptr rRate(new SimpleQuote(0.0)); - Handle rTS(flatRate(rRate, dc)); - ext::shared_ptr vol(new SimpleQuote(0.0)); - Handle volTS(flatVol(vol, dc)); - - ext::shared_ptr process( +template +void testOptionGreeks() { + + std::map calculated, expected, tolerance; + tolerance["delta"] = 1.0e-5; + tolerance["gamma"] = 1.0e-5; + tolerance["theta"] = 1.0e-5; + tolerance["rho"] = 1.0e-5; + tolerance["divRho"] = 1.0e-5; + tolerance["vega"] = 1.0e-5; + + Option::Type types[] = { Option::Call, Option::Put }; + Real moneyness[] = { 0.9, 1.0, 1.1 }; + Real underlyings[] = { 100.0 }; + Rate qRates[] = { 0.04, 0.05, 0.06 }; + Rate rRates[] = { 0.01, 0.05, 0.15 }; + Integer lengths[] = { 1, 2 }; + Frequency frequencies[] = { Semiannual, Quarterly }; + Volatility vols[] = { 0.11, 0.50, 1.20 }; + + DayCounter dc = Actual360(); + Date today = Date::todaysDate(); + Settings::instance().evaluationDate() = today; + + ext::shared_ptr spot(new SimpleQuote(0.0)); + ext::shared_ptr qRate(new SimpleQuote(0.0)); + Handle qTS(flatRate(qRate, dc)); + ext::shared_ptr rRate(new SimpleQuote(0.0)); + Handle rTS(flatRate(rRate, dc)); + ext::shared_ptr vol(new SimpleQuote(0.0)); + Handle volTS(flatVol(vol, dc)); + + ext::shared_ptr process( new BlackScholesMertonProcess(Handle(spot), qTS, rTS, volTS)); - for (auto& type : types) { - for (Real moneynes : moneyness) { - for (int length : lengths) { - for (auto& frequencie : frequencies) { + for (auto& type : types) { + for (Real moneynes : moneyness) { + for (int length : lengths) { + for (auto& frequencie : frequencies) { - ext::shared_ptr maturity( + ext::shared_ptr maturity( new EuropeanExercise(today + length * Years)); - ext::shared_ptr payoff( + ext::shared_ptr payoff( new PercentageStrikePayoff(type, moneynes)); - std::vector reset; - for (Date d = today + Period(frequencie); d < maturity->lastDate(); - d += Period(frequencie)) - reset.push_back(d); + std::vector reset; + for (Date d = today + Period(frequencie); d < maturity->lastDate(); + d += Period(frequencie)) + reset.push_back(d); - ext::shared_ptr engine(new T(process)); + ext::shared_ptr engine(new T(process)); - CliquetOption option(payoff, maturity, reset); - option.setPricingEngine(engine); + CliquetOption option(payoff, maturity, reset); + option.setPricingEngine(engine); - for (Real u : underlyings) { - for (Real m : qRates) { - for (Real n : rRates) { - for (Real v : vols) { + for (Real u : underlyings) { + for (Real m : qRates) { + for (Real n : rRates) { + for (Real v : vols) { + + Rate q = m, r = n; + spot->setValue(u); + qRate->setValue(q); + rRate->setValue(r); + vol->setValue(v); - Rate q = m, r = n; + Real value = option.NPV(); + calculated["delta"] = option.delta(); + calculated["gamma"] = option.gamma(); + calculated["theta"] = option.theta(); + calculated["rho"] = option.rho(); + calculated["divRho"] = option.dividendRho(); + calculated["vega"] = option.vega(); + + if (value > spot->value() * 1.0e-5) { + // perturb spot and get delta and gamma + Real du = u * 1.0e-4; + spot->setValue(u + du); + Real value_p = option.NPV(), delta_p = option.delta(); + spot->setValue(u - du); + Real value_m = option.NPV(), delta_m = option.delta(); spot->setValue(u); - qRate->setValue(q); + expected["delta"] = (value_p - value_m) / (2 * du); + expected["gamma"] = (delta_p - delta_m) / (2 * du); + + // perturb rates and get rho and dividend rho + Spread dr = r * 1.0e-4; + rRate->setValue(r + dr); + value_p = option.NPV(); + rRate->setValue(r - dr); + value_m = option.NPV(); rRate->setValue(r); - vol->setValue(v); + expected["rho"] = (value_p - value_m) / (2 * dr); - Real value = option.NPV(); - calculated["delta"] = option.delta(); - calculated["gamma"] = option.gamma(); - calculated["theta"] = option.theta(); - calculated["rho"] = option.rho(); - calculated["divRho"] = option.dividendRho(); - calculated["vega"] = option.vega(); - - if (value > spot->value() * 1.0e-5) { - // perturb spot and get delta and gamma - Real du = u * 1.0e-4; - spot->setValue(u + du); - Real value_p = option.NPV(), delta_p = option.delta(); - spot->setValue(u - du); - Real value_m = option.NPV(), delta_m = option.delta(); - spot->setValue(u); - expected["delta"] = (value_p - value_m) / (2 * du); - expected["gamma"] = (delta_p - delta_m) / (2 * du); - - // perturb rates and get rho and dividend rho - Spread dr = r * 1.0e-4; - rRate->setValue(r + dr); - value_p = option.NPV(); - rRate->setValue(r - dr); - value_m = option.NPV(); - rRate->setValue(r); - expected["rho"] = (value_p - value_m) / (2 * dr); - - Spread dq = q * 1.0e-4; - qRate->setValue(q + dq); - value_p = option.NPV(); - qRate->setValue(q - dq); - value_m = option.NPV(); - qRate->setValue(q); - expected["divRho"] = (value_p - value_m) / (2 * dq); - - // perturb volatility and get vega - Volatility dv = v * 1.0e-4; - vol->setValue(v + dv); - value_p = option.NPV(); - vol->setValue(v - dv); - value_m = option.NPV(); - vol->setValue(v); - expected["vega"] = (value_p - value_m) / (2 * dv); - - // perturb date and get theta - Time dT = dc.yearFraction(today - 1, today + 1); - Settings::instance().evaluationDate() = today - 1; - value_m = option.NPV(); - Settings::instance().evaluationDate() = today + 1; - value_p = option.NPV(); - Settings::instance().evaluationDate() = today; - expected["theta"] = (value_p - value_m) / dT; - - // compare - std::map::iterator it; - for (it = calculated.begin(); it != calculated.end(); - ++it) { - std::string greek = it->first; - Real expct = expected[greek], - calcl = calculated[greek], - tol = tolerance[greek]; - Real error = relativeError(expct, calcl, u); - if (error > tol) { - REPORT_FAILURE(greek, payoff, maturity, u, q, r, - today, v, expct, calcl, error, - tol); - } + Spread dq = q * 1.0e-4; + qRate->setValue(q + dq); + value_p = option.NPV(); + qRate->setValue(q - dq); + value_m = option.NPV(); + qRate->setValue(q); + expected["divRho"] = (value_p - value_m) / (2 * dq); + + // perturb volatility and get vega + Volatility dv = v * 1.0e-4; + vol->setValue(v + dv); + value_p = option.NPV(); + vol->setValue(v - dv); + value_m = option.NPV(); + vol->setValue(v); + expected["vega"] = (value_p - value_m) / (2 * dv); + + // perturb date and get theta + Time dT = dc.yearFraction(today - 1, today + 1); + Settings::instance().evaluationDate() = today - 1; + value_m = option.NPV(); + Settings::instance().evaluationDate() = today + 1; + value_p = option.NPV(); + Settings::instance().evaluationDate() = today; + expected["theta"] = (value_p - value_m) / dT; + + // compare + std::map::iterator it; + for (it = calculated.begin(); it != calculated.end(); + ++it) { + std::string greek = it->first; + Real expct = expected[greek], + calcl = calculated[greek], + tol = tolerance[greek]; + Real error = relativeError(expct, calcl, u); + if (error > tol) { + REPORT_FAILURE(greek, payoff, maturity, u, q, r, + today, v, expct, calcl, error, + tol); } } } @@ -252,9 +249,9 @@ namespace { } } } - } + BOOST_AUTO_TEST_CASE(testGreeks) { BOOST_TEST_MESSAGE("Testing Cliquet option greeks..."); testOptionGreeks(); diff --git a/test-suite/cms.cpp b/test-suite/cms.cpp index 271d8a093df..8af2651596b 100644 --- a/test-suite/cms.cpp +++ b/test-suite/cms.cpp @@ -47,48 +47,46 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CmsTests) -namespace { +struct CommonVars { + // global data + RelinkableHandle termStructure; - struct CommonVars { - // global data - RelinkableHandle termStructure; + ext::shared_ptr iborIndex; - ext::shared_ptr iborIndex; + Handle atmVol; + Handle SabrVolCube1; + Handle SabrVolCube2; - Handle atmVol; - Handle SabrVolCube1; - Handle SabrVolCube2; + std::vector yieldCurveModels; + std::vector > numericalPricers; + std::vector > analyticPricers; - std::vector yieldCurveModels; - std::vector > numericalPricers; - std::vector > analyticPricers; + // setup + CommonVars() { - // setup - CommonVars() { + Calendar calendar = TARGET(); - Calendar calendar = TARGET(); + Date referenceDate = calendar.adjust(Date::todaysDate()); + Settings::instance().evaluationDate() = referenceDate; - Date referenceDate = calendar.adjust(Date::todaysDate()); - Settings::instance().evaluationDate() = referenceDate; + termStructure.linkTo(flatRate(referenceDate, 0.05, + Actual365Fixed())); - termStructure.linkTo(flatRate(referenceDate, 0.05, - Actual365Fixed())); + // ATM Volatility structure + std::vector atmOptionTenors = {1 * Months, 6 * Months, 1 * Years, + 5 * Years, 10 * Years, 30 * Years}; - // ATM Volatility structure - std::vector atmOptionTenors = {1 * Months, 6 * Months, 1 * Years, - 5 * Years, 10 * Years, 30 * Years}; + std::vector atmSwapTenors = {1 * Years, 5 * Years, 10 * Years, 30 * Years}; - std::vector atmSwapTenors = {1 * Years, 5 * Years, 10 * Years, 30 * Years}; + Matrix m(atmOptionTenors.size(), atmSwapTenors.size()); + m[0][0]=0.1300; m[0][1]=0.1560; m[0][2]=0.1390; m[0][3]=0.1220; + m[1][0]=0.1440; m[1][1]=0.1580; m[1][2]=0.1460; m[1][3]=0.1260; + m[2][0]=0.1600; m[2][1]=0.1590; m[2][2]=0.1470; m[2][3]=0.1290; + m[3][0]=0.1640; m[3][1]=0.1470; m[3][2]=0.1370; m[3][3]=0.1220; + m[4][0]=0.1400; m[4][1]=0.1300; m[4][2]=0.1250; m[4][3]=0.1100; + m[5][0]=0.1130; m[5][1]=0.1090; m[5][2]=0.1070; m[5][3]=0.0930; - Matrix m(atmOptionTenors.size(), atmSwapTenors.size()); - m[0][0]=0.1300; m[0][1]=0.1560; m[0][2]=0.1390; m[0][3]=0.1220; - m[1][0]=0.1440; m[1][1]=0.1580; m[1][2]=0.1460; m[1][3]=0.1260; - m[2][0]=0.1600; m[2][1]=0.1590; m[2][2]=0.1470; m[2][3]=0.1290; - m[3][0]=0.1640; m[3][1]=0.1470; m[3][2]=0.1370; m[3][3]=0.1220; - m[4][0]=0.1400; m[4][1]=0.1300; m[4][2]=0.1250; m[4][3]=0.1100; - m[5][0]=0.1130; m[5][1]=0.1090; m[5][2]=0.1070; m[5][3]=0.0930; - - atmVol = Handle( + atmVol = Handle( ext::shared_ptr(new SwaptionVolatilityMatrix(calendar, Following, @@ -97,86 +95,86 @@ namespace { m, Actual365Fixed()))); - // Vol cubes - std::vector optionTenors = {{1, Years}, {10, Years}, {30, Years}}; - std::vector swapTenors = {{2, Years}, {10, Years}, {30, Years}}; - std::vector strikeSpreads = {-0.020, -0.005, 0.000, 0.005, 0.020}; - - Size nRows = optionTenors.size()*swapTenors.size(); - Size nCols = strikeSpreads.size(); - Matrix volSpreadsMatrix(nRows, nCols); - volSpreadsMatrix[0][0] = 0.0599; - volSpreadsMatrix[0][1] = 0.0049; - volSpreadsMatrix[0][2] = 0.0000; - volSpreadsMatrix[0][3] = -0.0001; - volSpreadsMatrix[0][4] = 0.0127; - - volSpreadsMatrix[1][0] = 0.0729; - volSpreadsMatrix[1][1] = 0.0086; - volSpreadsMatrix[1][2] = 0.0000; - volSpreadsMatrix[1][3] = -0.0024; - volSpreadsMatrix[1][4] = 0.0098; - - volSpreadsMatrix[2][0] = 0.0738; - volSpreadsMatrix[2][1] = 0.0102; - volSpreadsMatrix[2][2] = 0.0000; - volSpreadsMatrix[2][3] = -0.0039; - volSpreadsMatrix[2][4] = 0.0065; - - volSpreadsMatrix[3][0] = 0.0465; - volSpreadsMatrix[3][1] = 0.0063; - volSpreadsMatrix[3][2] = 0.0000; - volSpreadsMatrix[3][3] = -0.0032; - volSpreadsMatrix[3][4] = -0.0010; - - volSpreadsMatrix[4][0] = 0.0558; - volSpreadsMatrix[4][1] = 0.0084; - volSpreadsMatrix[4][2] = 0.0000; - volSpreadsMatrix[4][3] = -0.0050; - volSpreadsMatrix[4][4] = -0.0057; - - volSpreadsMatrix[5][0] = 0.0576; - volSpreadsMatrix[5][1] = 0.0083; - volSpreadsMatrix[5][2] = 0.0000; - volSpreadsMatrix[5][3] = -0.0043; - volSpreadsMatrix[5][4] = -0.0014; - - volSpreadsMatrix[6][0] = 0.0437; - volSpreadsMatrix[6][1] = 0.0059; - volSpreadsMatrix[6][2] = 0.0000; - volSpreadsMatrix[6][3] = -0.0030; - volSpreadsMatrix[6][4] = -0.0006; - - volSpreadsMatrix[7][0] = 0.0533; - volSpreadsMatrix[7][1] = 0.0078; - volSpreadsMatrix[7][2] = 0.0000; - volSpreadsMatrix[7][3] = -0.0045; - volSpreadsMatrix[7][4] = -0.0046; - - volSpreadsMatrix[8][0] = 0.0545; - volSpreadsMatrix[8][1] = 0.0079; - volSpreadsMatrix[8][2] = 0.0000; - volSpreadsMatrix[8][3] = -0.0042; - volSpreadsMatrix[8][4] = -0.0020; - - std::vector > > volSpreads(nRows); - for (Size i=0; i >(nCols); - for (Size j=0; j(ext::shared_ptr( + // Vol cubes + std::vector optionTenors = {{1, Years}, {10, Years}, {30, Years}}; + std::vector swapTenors = {{2, Years}, {10, Years}, {30, Years}}; + std::vector strikeSpreads = {-0.020, -0.005, 0.000, 0.005, 0.020}; + + Size nRows = optionTenors.size()*swapTenors.size(); + Size nCols = strikeSpreads.size(); + Matrix volSpreadsMatrix(nRows, nCols); + volSpreadsMatrix[0][0] = 0.0599; + volSpreadsMatrix[0][1] = 0.0049; + volSpreadsMatrix[0][2] = 0.0000; + volSpreadsMatrix[0][3] = -0.0001; + volSpreadsMatrix[0][4] = 0.0127; + + volSpreadsMatrix[1][0] = 0.0729; + volSpreadsMatrix[1][1] = 0.0086; + volSpreadsMatrix[1][2] = 0.0000; + volSpreadsMatrix[1][3] = -0.0024; + volSpreadsMatrix[1][4] = 0.0098; + + volSpreadsMatrix[2][0] = 0.0738; + volSpreadsMatrix[2][1] = 0.0102; + volSpreadsMatrix[2][2] = 0.0000; + volSpreadsMatrix[2][3] = -0.0039; + volSpreadsMatrix[2][4] = 0.0065; + + volSpreadsMatrix[3][0] = 0.0465; + volSpreadsMatrix[3][1] = 0.0063; + volSpreadsMatrix[3][2] = 0.0000; + volSpreadsMatrix[3][3] = -0.0032; + volSpreadsMatrix[3][4] = -0.0010; + + volSpreadsMatrix[4][0] = 0.0558; + volSpreadsMatrix[4][1] = 0.0084; + volSpreadsMatrix[4][2] = 0.0000; + volSpreadsMatrix[4][3] = -0.0050; + volSpreadsMatrix[4][4] = -0.0057; + + volSpreadsMatrix[5][0] = 0.0576; + volSpreadsMatrix[5][1] = 0.0083; + volSpreadsMatrix[5][2] = 0.0000; + volSpreadsMatrix[5][3] = -0.0043; + volSpreadsMatrix[5][4] = -0.0014; + + volSpreadsMatrix[6][0] = 0.0437; + volSpreadsMatrix[6][1] = 0.0059; + volSpreadsMatrix[6][2] = 0.0000; + volSpreadsMatrix[6][3] = -0.0030; + volSpreadsMatrix[6][4] = -0.0006; + + volSpreadsMatrix[7][0] = 0.0533; + volSpreadsMatrix[7][1] = 0.0078; + volSpreadsMatrix[7][2] = 0.0000; + volSpreadsMatrix[7][3] = -0.0045; + volSpreadsMatrix[7][4] = -0.0046; + + volSpreadsMatrix[8][0] = 0.0545; + volSpreadsMatrix[8][1] = 0.0079; + volSpreadsMatrix[8][2] = 0.0000; + volSpreadsMatrix[8][3] = -0.0042; + volSpreadsMatrix[8][4] = -0.0020; + + std::vector > > volSpreads(nRows); + for (Size i=0; i >(nCols); + for (Size j=0; j(ext::shared_ptr( new SimpleQuote(volSpreadsMatrix[i][j]))); - } } + } - iborIndex = ext::shared_ptr(new Euribor6M(termStructure)); - ext::shared_ptr swapIndexBase(new + iborIndex = ext::shared_ptr(new Euribor6M(termStructure)); + ext::shared_ptr swapIndexBase(new EuriborSwapIsdaFixA(10*Years, termStructure)); - ext::shared_ptr shortSwapIndexBase(new + ext::shared_ptr shortSwapIndexBase(new EuriborSwapIsdaFixA(2*Years, termStructure)); - bool vegaWeightedSmileFit = false; + bool vegaWeightedSmileFit = false; - SabrVolCube2 = Handle( + SabrVolCube2 = Handle( ext::make_shared(atmVol, optionTenors, swapTenors, @@ -185,27 +183,27 @@ namespace { swapIndexBase, shortSwapIndexBase, vegaWeightedSmileFit)); - SabrVolCube2->enableExtrapolation(); - - std::vector > > guess(nRows); - for (Size i=0; i >(4); - guess[i][0] = - Handle(ext::shared_ptr(new SimpleQuote(0.2))); - guess[i][1] = - Handle(ext::shared_ptr(new SimpleQuote(0.5))); - guess[i][2] = - Handle(ext::shared_ptr(new SimpleQuote(0.4))); - guess[i][3] = - Handle(ext::shared_ptr(new SimpleQuote(0.0))); - } - std::vector isParameterFixed(4, false); - isParameterFixed[1] = true; + SabrVolCube2->enableExtrapolation(); + + std::vector > > guess(nRows); + for (Size i=0; i >(4); + guess[i][0] = + Handle(ext::shared_ptr(new SimpleQuote(0.2))); + guess[i][1] = + Handle(ext::shared_ptr(new SimpleQuote(0.5))); + guess[i][2] = + Handle(ext::shared_ptr(new SimpleQuote(0.4))); + guess[i][3] = + Handle(ext::shared_ptr(new SimpleQuote(0.0))); + } + std::vector isParameterFixed(4, false); + isParameterFixed[1] = true; - // FIXME - bool isAtmCalibrated = false; + // FIXME + bool isAtmCalibrated = false; - SabrVolCube1 = Handle( + SabrVolCube1 = Handle( ext::make_shared(atmVol, optionTenors, swapTenors, @@ -217,35 +215,34 @@ namespace { guess, isParameterFixed, isAtmCalibrated)); - SabrVolCube1->enableExtrapolation(); + SabrVolCube1->enableExtrapolation(); - yieldCurveModels = {GFunctionFactory::Standard, - GFunctionFactory::ExactYield, - GFunctionFactory::ParallelShifts, - GFunctionFactory::NonParallelShifts, - GFunctionFactory::NonParallelShifts}; + yieldCurveModels = {GFunctionFactory::Standard, + GFunctionFactory::ExactYield, + GFunctionFactory::ParallelShifts, + GFunctionFactory::NonParallelShifts, + GFunctionFactory::NonParallelShifts}; - Handle zeroMeanRev(ext::make_shared(0.0)); + Handle zeroMeanRev(ext::make_shared(0.0)); - numericalPricers.clear(); - analyticPricers.clear(); - for (Size j = 0; j < yieldCurveModels.size(); ++j) { - if (j < yieldCurveModels.size() - 1) - numericalPricers.push_back( + numericalPricers.clear(); + analyticPricers.clear(); + for (Size j = 0; j < yieldCurveModels.size(); ++j) { + if (j < yieldCurveModels.size() - 1) + numericalPricers.push_back( ext::shared_ptr(new NumericHaganPricer( atmVol, yieldCurveModels[j], zeroMeanRev))); - else - numericalPricers.push_back(ext::shared_ptr( + else + numericalPricers.push_back(ext::shared_ptr( new LinearTsrPricer(atmVol, zeroMeanRev))); - analyticPricers.push_back(ext::shared_ptr(new + analyticPricers.push_back(ext::shared_ptr(new AnalyticHaganPricer(atmVol, yieldCurveModels[j], zeroMeanRev))); - } } - }; + } +}; -} BOOST_AUTO_TEST_CASE(testFairRate) { diff --git a/test-suite/cms_normal.cpp b/test-suite/cms_normal.cpp index b2cd7bfab1d..efdcf3b7ed0 100644 --- a/test-suite/cms_normal.cpp +++ b/test-suite/cms_normal.cpp @@ -48,50 +48,48 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CmsNormalTests) -namespace { +struct CommonVars { + // global data + RelinkableHandle termStructure; - struct CommonVars { - // global data - RelinkableHandle termStructure; + ext::shared_ptr iborIndex; - ext::shared_ptr iborIndex; + Handle atmVol; + Handle SabrVolCube1; + Handle SabrVolCube2; - Handle atmVol; - Handle SabrVolCube1; - Handle SabrVolCube2; + std::vector yieldCurveModels; + std::vector > numericalPricers; + std::vector > analyticPricers; - std::vector yieldCurveModels; - std::vector > numericalPricers; - std::vector > analyticPricers; + // setup + CommonVars() { - // setup - CommonVars() { + Calendar calendar = TARGET(); - Calendar calendar = TARGET(); + Date referenceDate = calendar.adjust(Date::todaysDate()); + Settings::instance().evaluationDate() = referenceDate; - Date referenceDate = calendar.adjust(Date::todaysDate()); - Settings::instance().evaluationDate() = referenceDate; + termStructure.linkTo(flatRate(referenceDate, 0.02, + Actual365Fixed())); - termStructure.linkTo(flatRate(referenceDate, 0.02, - Actual365Fixed())); + // ATM Volatility structure + std::vector atmOptionTenors = {1 * Months, 6 * Months, 1 * Years, + 5 * Years, 10 * Years, 30 * Years}; - // ATM Volatility structure - std::vector atmOptionTenors = {1 * Months, 6 * Months, 1 * Years, - 5 * Years, 10 * Years, 30 * Years}; + std::vector atmSwapTenors = {1 * Years, 5 * Years, 10 * Years, 30 * Years}; - std::vector atmSwapTenors = {1 * Years, 5 * Years, 10 * Years, 30 * Years}; + Matrix m(atmOptionTenors.size(), atmSwapTenors.size()); + m[0][0]=0.0085; m[0][1]=0.0120; m[0][2]=0.0102; m[0][3]=0.0095; + m[1][0]=0.0106; m[1][1]=0.0104; m[1][2]=0.0095; m[1][3]=0.0092; + m[2][0]=0.0104; m[2][1]=0.0099; m[2][2]=0.0092; m[2][3]=0.0088; + m[3][0]=0.0091; m[3][1]=0.0086; m[3][2]=0.0080; m[3][3]=0.0070; + m[4][0]=0.0077; m[4][1]=0.0073; m[4][2]=0.0068; m[4][3]=0.0060; + m[5][0]=0.0057; m[5][1]=0.0055; m[5][2]=0.0050; m[5][3]=0.0039; - Matrix m(atmOptionTenors.size(), atmSwapTenors.size()); - m[0][0]=0.0085; m[0][1]=0.0120; m[0][2]=0.0102; m[0][3]=0.0095; - m[1][0]=0.0106; m[1][1]=0.0104; m[1][2]=0.0095; m[1][3]=0.0092; - m[2][0]=0.0104; m[2][1]=0.0099; m[2][2]=0.0092; m[2][3]=0.0088; - m[3][0]=0.0091; m[3][1]=0.0086; m[3][2]=0.0080; m[3][3]=0.0070; - m[4][0]=0.0077; m[4][1]=0.0073; m[4][2]=0.0068; m[4][3]=0.0060; - m[5][0]=0.0057; m[5][1]=0.0055; m[5][2]=0.0050; m[5][3]=0.0039; - - atmVol = Handle( + atmVol = Handle( ext::shared_ptr(new SwaptionVolatilityMatrix(calendar, Following, @@ -103,89 +101,89 @@ namespace { QuantLib::VolatilityType::Normal))); - // Vol cubes - std::vector optionTenors = {{1, Years}, {10, Years}, {30, Years}}; - std::vector swapTenors = {{2, Years}, {10, Years}, {30, Years}}; - std::vector strikeSpreads = {-0.020, -0.005, 0.000, 0.005, 0.020}; + // Vol cubes + std::vector optionTenors = {{1, Years}, {10, Years}, {30, Years}}; + std::vector swapTenors = {{2, Years}, {10, Years}, {30, Years}}; + std::vector strikeSpreads = {-0.020, -0.005, 0.000, 0.005, 0.020}; - Size nRows = optionTenors.size()*swapTenors.size(); - Size nCols = strikeSpreads.size(); - Matrix volSpreadsMatrix(nRows, nCols); + Size nRows = optionTenors.size()*swapTenors.size(); + Size nCols = strikeSpreads.size(); + Matrix volSpreadsMatrix(nRows, nCols); - volSpreadsMatrix[0][0] = -0.0016; - volSpreadsMatrix[0][1] = -0.0008; - volSpreadsMatrix[0][2] = 0.0000; - volSpreadsMatrix[0][3] = 0.0009; - volSpreadsMatrix[0][4] = 0.0038; - - volSpreadsMatrix[1][0] = 0.0009; - volSpreadsMatrix[1][1] = -0.0003; - volSpreadsMatrix[1][2] = 0.0000; - volSpreadsMatrix[1][3] = 0.0007; - volSpreadsMatrix[1][4] = 0.0035; - - volSpreadsMatrix[2][0] = 0.0025; - volSpreadsMatrix[2][1] = 0.0002; - volSpreadsMatrix[2][2] = 0.0000; - volSpreadsMatrix[2][3] = 0.0002; - volSpreadsMatrix[2][4] = 0.0024; - - volSpreadsMatrix[3][0] = -0.0009; - volSpreadsMatrix[3][1] = -0.0003; - volSpreadsMatrix[3][2] = 0.0000; - volSpreadsMatrix[3][3] = 0.0003; - volSpreadsMatrix[3][4] = 0.0013; - - volSpreadsMatrix[4][0] = -0.0001; - volSpreadsMatrix[4][1] = -0.0001; - volSpreadsMatrix[4][2] = 0.0000; - volSpreadsMatrix[4][3] = 0.0001; - volSpreadsMatrix[4][4] = 0.0007; - - volSpreadsMatrix[5][0] = 0.0003; - volSpreadsMatrix[5][1] = 0.0000; - volSpreadsMatrix[5][2] = 0.0000; - volSpreadsMatrix[5][3] = 0.0001; - volSpreadsMatrix[5][4] = 0.0005; - - volSpreadsMatrix[6][0] = -0.0004; - volSpreadsMatrix[6][1] = -0.0001; - volSpreadsMatrix[6][2] = 0.0000; - volSpreadsMatrix[6][3] = 0.0001; - volSpreadsMatrix[6][4] = 0.0006; - - volSpreadsMatrix[7][0] = -0.0001; - volSpreadsMatrix[7][1] = 0.0000; - volSpreadsMatrix[7][2] = 0.0000; - volSpreadsMatrix[7][3] = 0.0000; - volSpreadsMatrix[7][4] = 0.0002; - - - volSpreadsMatrix[8][0] = -0.0002; - volSpreadsMatrix[8][1] = -0.0001; - volSpreadsMatrix[8][2] = 0.0000; - volSpreadsMatrix[8][3] = 0.0001; - volSpreadsMatrix[8][4] = 0.0002; - - - std::vector > > volSpreads(nRows); - for (Size i=0; i >(nCols); - for (Size j=0; j(ext::shared_ptr( + volSpreadsMatrix[0][0] = -0.0016; + volSpreadsMatrix[0][1] = -0.0008; + volSpreadsMatrix[0][2] = 0.0000; + volSpreadsMatrix[0][3] = 0.0009; + volSpreadsMatrix[0][4] = 0.0038; + + volSpreadsMatrix[1][0] = 0.0009; + volSpreadsMatrix[1][1] = -0.0003; + volSpreadsMatrix[1][2] = 0.0000; + volSpreadsMatrix[1][3] = 0.0007; + volSpreadsMatrix[1][4] = 0.0035; + + volSpreadsMatrix[2][0] = 0.0025; + volSpreadsMatrix[2][1] = 0.0002; + volSpreadsMatrix[2][2] = 0.0000; + volSpreadsMatrix[2][3] = 0.0002; + volSpreadsMatrix[2][4] = 0.0024; + + volSpreadsMatrix[3][0] = -0.0009; + volSpreadsMatrix[3][1] = -0.0003; + volSpreadsMatrix[3][2] = 0.0000; + volSpreadsMatrix[3][3] = 0.0003; + volSpreadsMatrix[3][4] = 0.0013; + + volSpreadsMatrix[4][0] = -0.0001; + volSpreadsMatrix[4][1] = -0.0001; + volSpreadsMatrix[4][2] = 0.0000; + volSpreadsMatrix[4][3] = 0.0001; + volSpreadsMatrix[4][4] = 0.0007; + + volSpreadsMatrix[5][0] = 0.0003; + volSpreadsMatrix[5][1] = 0.0000; + volSpreadsMatrix[5][2] = 0.0000; + volSpreadsMatrix[5][3] = 0.0001; + volSpreadsMatrix[5][4] = 0.0005; + + volSpreadsMatrix[6][0] = -0.0004; + volSpreadsMatrix[6][1] = -0.0001; + volSpreadsMatrix[6][2] = 0.0000; + volSpreadsMatrix[6][3] = 0.0001; + volSpreadsMatrix[6][4] = 0.0006; + + volSpreadsMatrix[7][0] = -0.0001; + volSpreadsMatrix[7][1] = 0.0000; + volSpreadsMatrix[7][2] = 0.0000; + volSpreadsMatrix[7][3] = 0.0000; + volSpreadsMatrix[7][4] = 0.0002; + + + volSpreadsMatrix[8][0] = -0.0002; + volSpreadsMatrix[8][1] = -0.0001; + volSpreadsMatrix[8][2] = 0.0000; + volSpreadsMatrix[8][3] = 0.0001; + volSpreadsMatrix[8][4] = 0.0002; + + + std::vector > > volSpreads(nRows); + for (Size i=0; i >(nCols); + for (Size j=0; j(ext::shared_ptr( new SimpleQuote(volSpreadsMatrix[i][j]))); - } } + } - iborIndex = ext::shared_ptr(new Euribor6M(termStructure)); - /* - ext::shared_ptr swapIndexBase(new + iborIndex = ext::shared_ptr(new Euribor6M(termStructure)); + /* + ext::shared_ptr swapIndexBase(new EuriborSwapIsdaFixA(10*Years, termStructure,termStructure)); - ext::shared_ptr shortSwapIndexBase(new + ext::shared_ptr shortSwapIndexBase(new EuriborSwapIsdaFixA(2*Years, termStructure,termStructure)); - */ + */ - ext::shared_ptr swapIndexBase(new SwapIndex("swapIndexBase", + ext::shared_ptr swapIndexBase(new SwapIndex("swapIndexBase", 2*Years, iborIndex->fixingDays(), iborIndex->currency(), @@ -195,7 +193,7 @@ namespace { Thirty360(Thirty360::EurobondBasis),//EUR iborIndex, termStructure)); - ext::shared_ptr shortSwapIndexBase(new SwapIndex("shortSwapIndexBase", + ext::shared_ptr shortSwapIndexBase(new SwapIndex("shortSwapIndexBase", 1*Years, iborIndex->fixingDays(), iborIndex->currency(), @@ -206,9 +204,9 @@ namespace { iborIndex, termStructure)); - bool vegaWeightedSmileFit = false; + bool vegaWeightedSmileFit = false; - SabrVolCube2 = Handle( + SabrVolCube2 = Handle( ext::make_shared(atmVol, optionTenors, swapTenors, @@ -217,27 +215,27 @@ namespace { swapIndexBase, shortSwapIndexBase, vegaWeightedSmileFit)); - SabrVolCube2->enableExtrapolation(); - - std::vector > > guess(nRows); - for (Size i=0; i >(4); - guess[i][0] = - Handle(ext::shared_ptr(new SimpleQuote(0.01))); - guess[i][1] = - Handle(ext::shared_ptr(new SimpleQuote(0.0))); - guess[i][2] = - Handle(ext::shared_ptr(new SimpleQuote(0.3))); - guess[i][3] = - Handle(ext::shared_ptr(new SimpleQuote(0.5))); - } - std::vector isParameterFixed(4, false); - isParameterFixed[1] = true; + SabrVolCube2->enableExtrapolation(); + + std::vector > > guess(nRows); + for (Size i=0; i >(4); + guess[i][0] = + Handle(ext::shared_ptr(new SimpleQuote(0.01))); + guess[i][1] = + Handle(ext::shared_ptr(new SimpleQuote(0.0))); + guess[i][2] = + Handle(ext::shared_ptr(new SimpleQuote(0.3))); + guess[i][3] = + Handle(ext::shared_ptr(new SimpleQuote(0.5))); + } + std::vector isParameterFixed(4, false); + isParameterFixed[1] = true; - // FIXME - bool isAtmCalibrated = false; + // FIXME + bool isAtmCalibrated = false; - SabrVolCube1 = Handle( + SabrVolCube1 = Handle( ext::make_shared(atmVol, optionTenors, swapTenors, @@ -249,30 +247,29 @@ namespace { guess, isParameterFixed, isAtmCalibrated)); - SabrVolCube1->enableExtrapolation(); + SabrVolCube1->enableExtrapolation(); - yieldCurveModels = {GFunctionFactory::Standard, - GFunctionFactory::ExactYield, - GFunctionFactory::ParallelShifts, - GFunctionFactory::NonParallelShifts}; + yieldCurveModels = {GFunctionFactory::Standard, + GFunctionFactory::ExactYield, + GFunctionFactory::ParallelShifts, + GFunctionFactory::NonParallelShifts}; - Handle zeroMeanRev(ext::make_shared(0.0)); + Handle zeroMeanRev(ext::make_shared(0.0)); - numericalPricers.clear(); - analyticPricers.clear(); - for (auto& yieldCurveModel : yieldCurveModels) { - numericalPricers.push_back(ext::shared_ptr( + numericalPricers.clear(); + analyticPricers.clear(); + for (auto& yieldCurveModel : yieldCurveModels) { + numericalPricers.push_back(ext::shared_ptr( new NumericHaganPricer(atmVol, yieldCurveModel, zeroMeanRev))); - analyticPricers.push_back(ext::shared_ptr( + analyticPricers.push_back(ext::shared_ptr( new AnalyticHaganPricer(atmVol, yieldCurveModel, zeroMeanRev))); - } } - }; + } +}; -} BOOST_AUTO_TEST_CASE(testFairRate) { diff --git a/test-suite/cmsspread.cpp b/test-suite/cmsspread.cpp index c8024dc2943..f7bd36410d0 100644 --- a/test-suite/cmsspread.cpp +++ b/test-suite/cmsspread.cpp @@ -47,7 +47,6 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CmsSpreadTests) -namespace { struct TestData { TestData() { refDate = Date(23, February, 2018); @@ -93,7 +92,7 @@ struct TestData { ext::shared_ptr cmsspPricerLn, cmsspPricerSln, cmsspPricerN; }; -} // namespace + BOOST_AUTO_TEST_CASE(testFixings) { BOOST_TEST_MESSAGE("Testing fixings of cms spread indices..."); @@ -134,7 +133,7 @@ BOOST_AUTO_TEST_CASE(testFixings) { cms10y->fixing(d.refDate) - cms2y->fixing(d.refDate)); } -namespace { + Real mcReferenceValue(const ext::shared_ptr& cpn1, const ext::shared_ptr& cpn2, const Real cap, const Real floor, @@ -185,8 +184,8 @@ Real mcReferenceValue(const ext::shared_ptr& cpn1, acc(std::min(std::max(z[0] - z[1], floor), cap)); } return mean(acc); -} // mcReferenceValue -} // namespace +} + BOOST_AUTO_TEST_CASE(testCouponPricing) { BOOST_TEST_MESSAGE("Testing pricing of cms spread coupons..."); diff --git a/test-suite/compoundoption.cpp b/test-suite/compoundoption.cpp index d2c260b34a0..ea678e97d92 100644 --- a/test-suite/compoundoption.cpp +++ b/test-suite/compoundoption.cpp @@ -59,28 +59,25 @@ BOOST_AUTO_TEST_SUITE(CompoundOptionTests) "\nerror: " << error << \ "\ntolerance: " << tolerance); -namespace { - - struct CompoundOptionData { - Option::Type typeMother; - Option::Type typeDaughter; - Real strikeMother; - Real strikeDaughter; - Real s; // spot - Rate q; // dividend - Rate r; // risk-free rate - Time tMother; // time to maturity - Time tDaughter;// time to maturity - Volatility v; // volatility - Real npv; // expected result - Real tol; // tolerance - Real delta; - Real gamma; - Real vega; - Real theta; - }; +struct CompoundOptionData { + Option::Type typeMother; + Option::Type typeDaughter; + Real strikeMother; + Real strikeDaughter; + Real s; // spot + Rate q; // dividend + Rate r; // risk-free rate + Time tMother; // time to maturity + Time tDaughter;// time to maturity + Volatility v; // volatility + Real npv; // expected result + Real tol; // tolerance + Real delta; + Real gamma; + Real vega; + Real theta; +}; -} BOOST_AUTO_TEST_CASE(testPutCallParity){ diff --git a/test-suite/convertiblebonds.cpp b/test-suite/convertiblebonds.cpp index d6c24d43ab9..0e508640c03 100644 --- a/test-suite/convertiblebonds.cpp +++ b/test-suite/convertiblebonds.cpp @@ -49,62 +49,59 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(ConvertibleBondTests) -namespace { +struct CommonVars { + // global data + Date today, issueDate, maturityDate; + Calendar calendar; + DayCounter dayCounter; + Frequency frequency; + Natural settlementDays; - struct CommonVars { - // global data - Date today, issueDate, maturityDate; - Calendar calendar; - DayCounter dayCounter; - Frequency frequency; - Natural settlementDays; + RelinkableHandle underlying; + RelinkableHandle dividendYield, riskFreeRate; + RelinkableHandle volatility; + ext::shared_ptr process; - RelinkableHandle underlying; - RelinkableHandle dividendYield, riskFreeRate; - RelinkableHandle volatility; - ext::shared_ptr process; + RelinkableHandle creditSpread; - RelinkableHandle creditSpread; - - CallabilitySchedule no_callability; + CallabilitySchedule no_callability; - Real faceAmount, redemption, conversionRatio; + Real faceAmount, redemption, conversionRatio; - // setup - CommonVars() { - calendar = TARGET(); + // setup + CommonVars() { + calendar = TARGET(); - today = calendar.adjust(Date::todaysDate()); - Settings::instance().evaluationDate() = today; + today = calendar.adjust(Date::todaysDate()); + Settings::instance().evaluationDate() = today; - dayCounter = Actual360(); - frequency = Annual; - settlementDays = 3; + dayCounter = Actual360(); + frequency = Annual; + settlementDays = 3; - issueDate = calendar.advance(today,2,Days); - maturityDate = calendar.advance(issueDate, 10, Years); - // reset to avoid inconsistencies as the schedule is backwards - issueDate = calendar.advance(maturityDate, -10, Years); + issueDate = calendar.advance(today,2,Days); + maturityDate = calendar.advance(issueDate, 10, Years); + // reset to avoid inconsistencies as the schedule is backwards + issueDate = calendar.advance(maturityDate, -10, Years); - underlying.linkTo(ext::make_shared(50.0)); - dividendYield.linkTo(flatRate(today, 0.02, dayCounter)); - riskFreeRate.linkTo(flatRate(today, 0.05, dayCounter)); - volatility.linkTo(flatVol(today, 0.15, dayCounter)); + underlying.linkTo(ext::make_shared(50.0)); + dividendYield.linkTo(flatRate(today, 0.02, dayCounter)); + riskFreeRate.linkTo(flatRate(today, 0.05, dayCounter)); + volatility.linkTo(flatVol(today, 0.15, dayCounter)); - process = ext::make_shared( + process = ext::make_shared( underlying, dividendYield, riskFreeRate, volatility); - creditSpread.linkTo(ext::make_shared(0.005)); + creditSpread.linkTo(ext::make_shared(0.005)); - // it fails with 1000000 - // faceAmount = 1000000.0; - faceAmount = 100.0; - redemption = 100.0; - conversionRatio = redemption/underlying->value(); - } - }; + // it fails with 1000000 + // faceAmount = 1000000.0; + faceAmount = 100.0; + redemption = 100.0; + conversionRatio = redemption/underlying->value(); + } +}; -} BOOST_AUTO_TEST_CASE(testBond) { diff --git a/test-suite/covariance.cpp b/test-suite/covariance.cpp index 049ca5feaba..bcb598ab087 100644 --- a/test-suite/covariance.cpp +++ b/test-suite/covariance.cpp @@ -31,18 +31,15 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CovarianceTests) -namespace { - - Real norm(const Matrix& m) { - Real sum = 0.0; - for (Size i=0; i baseCcyIdx; - ext::shared_ptr quoteCcyIdx; - - RelinkableHandle baseCcyIdxHandle; - RelinkableHandle quoteCcyIdxHandle; - - std::vector basisData; - - // utilities - - ext::shared_ptr - constantNotionalXccyRateHelper(const XccyTestDatum& q, - const Handle& collateralHandle, - bool isFxBaseCurrencyCollateralCurrency, - bool isBasisOnFxBaseCurrencyLeg) const { - Handle quoteHandle(ext::make_shared(q.basis * basisPoint)); - Period tenor(q.n, q.units); - return ext::shared_ptr(new ConstNotionalCrossCurrencyBasisSwapRateHelper( +struct XccyTestDatum { + Integer n; + TimeUnit units; + Spread basis; + + XccyTestDatum(Integer n, TimeUnit units, Spread basis) : n(n), units(units), basis(basis) {} +}; + +struct CommonVars { + Real basisPoint; + Real fxSpot; + + Date today, settlement; + Calendar calendar; + Natural settlementDays; + Currency ccy; + BusinessDayConvention businessConvention; + DayCounter dayCount; + bool endOfMonth; + + ext::shared_ptr baseCcyIdx; + ext::shared_ptr quoteCcyIdx; + + RelinkableHandle baseCcyIdxHandle; + RelinkableHandle quoteCcyIdxHandle; + + std::vector basisData; + + // utilities + + ext::shared_ptr + constantNotionalXccyRateHelper(const XccyTestDatum& q, + const Handle& collateralHandle, + bool isFxBaseCurrencyCollateralCurrency, + bool isBasisOnFxBaseCurrencyLeg) const { + Handle quoteHandle(ext::make_shared(q.basis * basisPoint)); + Period tenor(q.n, q.units); + return ext::shared_ptr(new ConstNotionalCrossCurrencyBasisSwapRateHelper( quoteHandle, tenor, settlementDays, calendar, businessConvention, endOfMonth, baseCcyIdx, quoteCcyIdx, collateralHandle, isFxBaseCurrencyCollateralCurrency, isBasisOnFxBaseCurrencyLeg)); - } + } - std::vector > - buildConstantNotionalXccyRateHelpers(const std::vector& xccyData, - const Handle& collateralHandle, - bool isFxBaseCurrencyCollateralCurrency, - bool isBasisOnFxBaseCurrencyLeg) const { - std::vector > instruments; - instruments.reserve(xccyData.size()); - for (const auto& i : xccyData) { - instruments.push_back(constantNotionalXccyRateHelper( + std::vector > + buildConstantNotionalXccyRateHelpers(const std::vector& xccyData, + const Handle& collateralHandle, + bool isFxBaseCurrencyCollateralCurrency, + bool isBasisOnFxBaseCurrencyLeg) const { + std::vector > instruments; + instruments.reserve(xccyData.size()); + for (const auto& i : xccyData) { + instruments.push_back(constantNotionalXccyRateHelper( i, collateralHandle, isFxBaseCurrencyCollateralCurrency, isBasisOnFxBaseCurrencyLeg)); - } - - return instruments; } - ext::shared_ptr - resettingXccyRateHelper(const XccyTestDatum& q, - const Handle& collateralHandle, - bool isFxBaseCurrencyCollateralCurrency, - bool isBasisOnFxBaseCurrencyLeg, - bool isFxBaseCurrencyLegResettable) const { - Handle quoteHandle(ext::make_shared(q.basis * basisPoint)); - Period tenor(q.n, q.units); - return ext::shared_ptr(new MtMCrossCurrencyBasisSwapRateHelper( + return instruments; + } + + ext::shared_ptr + resettingXccyRateHelper(const XccyTestDatum& q, + const Handle& collateralHandle, + bool isFxBaseCurrencyCollateralCurrency, + bool isBasisOnFxBaseCurrencyLeg, + bool isFxBaseCurrencyLegResettable) const { + Handle quoteHandle(ext::make_shared(q.basis * basisPoint)); + Period tenor(q.n, q.units); + return ext::shared_ptr(new MtMCrossCurrencyBasisSwapRateHelper( quoteHandle, tenor, settlementDays, calendar, businessConvention, endOfMonth, baseCcyIdx, quoteCcyIdx, collateralHandle, isFxBaseCurrencyCollateralCurrency, isBasisOnFxBaseCurrencyLeg, isFxBaseCurrencyLegResettable)); - } + } - std::vector > - buildResettingXccyRateHelpers(const std::vector& xccyData, - const Handle& collateralHandle, - bool isFxBaseCurrencyCollateralCurrency, - bool isBasisOnFxBaseCurrencyLeg, - bool isFxBaseCurrencyLegResettable) const { - std::vector > instruments; - instruments.reserve(xccyData.size()); - for (const auto& i : xccyData) { - instruments.push_back(resettingXccyRateHelper( + std::vector > + buildResettingXccyRateHelpers(const std::vector& xccyData, + const Handle& collateralHandle, + bool isFxBaseCurrencyCollateralCurrency, + bool isBasisOnFxBaseCurrencyLeg, + bool isFxBaseCurrencyLegResettable) const { + std::vector > instruments; + instruments.reserve(xccyData.size()); + for (const auto& i : xccyData) { + instruments.push_back(resettingXccyRateHelper( i, collateralHandle, isFxBaseCurrencyCollateralCurrency, isBasisOnFxBaseCurrencyLeg, isFxBaseCurrencyLegResettable)); - } - - return instruments; } - Schedule legSchedule(const Period& tenor, - const ext::shared_ptr& idx) const { - return MakeSchedule() - .from(settlement) - .to(settlement + tenor) - .withTenor(idx->tenor()) - .withCalendar(calendar) - .withConvention(businessConvention) - .endOfMonth(endOfMonth) - .backwards(); - } + return instruments; + } - Leg constantNotionalLeg(const Schedule& schedule, - const ext::shared_ptr& idx, - Real notional, - Spread basis) const { - Leg leg = IborLeg(schedule, idx).withNotionals(notional).withSpreads(basis); - Date lastPaymentDate = leg.back()->date(); - leg.push_back(ext::make_shared(notional, lastPaymentDate)); - return leg; - } + Schedule legSchedule(const Period& tenor, + const ext::shared_ptr& idx) const { + return MakeSchedule() + .from(settlement) + .to(settlement + tenor) + .withTenor(idx->tenor()) + .withCalendar(calendar) + .withConvention(businessConvention) + .endOfMonth(endOfMonth) + .backwards(); + } - std::vector > - buildXccyBasisSwap(const XccyTestDatum& q, - Real fxSpot, - bool isFxBaseCurrencyCollateralCurrency, - bool isBasisOnFxBaseCurrencyLeg) const { - const Real baseCcyLegNotional = 1.0; - Real quoteCcyLegNotional = baseCcyLegNotional * fxSpot; - - Spread baseCcyLegBasis = isBasisOnFxBaseCurrencyLeg ? Real(q.basis * basisPoint) : 0.0; - Spread quoteCcyLegBasis = isBasisOnFxBaseCurrencyLeg ? 0.0 : Real(q.basis * basisPoint); - - std::vector > legs; - bool payer = true; - - Leg baseCcyLeg = constantNotionalLeg(legSchedule(Period(q.n, q.units), baseCcyIdx), - baseCcyIdx, baseCcyLegNotional, baseCcyLegBasis); - legs.push_back(ext::make_shared(std::vector(1, baseCcyLeg), - std::vector(1, !payer))); - - Leg quoteCcyLeg = - constantNotionalLeg(legSchedule(Period(q.n, q.units), quoteCcyIdx), quoteCcyIdx, - quoteCcyLegNotional, quoteCcyLegBasis); - legs.push_back(ext::make_shared(std::vector(1, quoteCcyLeg), - std::vector(1, payer))); - return legs; - } + Leg constantNotionalLeg(const Schedule& schedule, + const ext::shared_ptr& idx, + Real notional, + Spread basis) const { + Leg leg = IborLeg(schedule, idx).withNotionals(notional).withSpreads(basis); + Date lastPaymentDate = leg.back()->date(); + leg.push_back(ext::make_shared(notional, lastPaymentDate)); + return leg; + } + + std::vector > + buildXccyBasisSwap(const XccyTestDatum& q, + Real fxSpot, + bool isFxBaseCurrencyCollateralCurrency, + bool isBasisOnFxBaseCurrencyLeg) const { + const Real baseCcyLegNotional = 1.0; + Real quoteCcyLegNotional = baseCcyLegNotional * fxSpot; + + Spread baseCcyLegBasis = isBasisOnFxBaseCurrencyLeg ? Real(q.basis * basisPoint) : 0.0; + Spread quoteCcyLegBasis = isBasisOnFxBaseCurrencyLeg ? 0.0 : Real(q.basis * basisPoint); + + std::vector > legs; + bool payer = true; + + Leg baseCcyLeg = constantNotionalLeg(legSchedule(Period(q.n, q.units), baseCcyIdx), + baseCcyIdx, baseCcyLegNotional, baseCcyLegBasis); + legs.push_back(ext::make_shared(std::vector(1, baseCcyLeg), + std::vector(1, !payer))); + + Leg quoteCcyLeg = + constantNotionalLeg(legSchedule(Period(q.n, q.units), quoteCcyIdx), quoteCcyIdx, + quoteCcyLegNotional, quoteCcyLegBasis); + legs.push_back(ext::make_shared(std::vector(1, quoteCcyLeg), + std::vector(1, payer))); + return legs; + } + + CommonVars() { + settlementDays = 2; + businessConvention = Following; + calendar = TARGET(); + dayCount = Actual365Fixed(); + endOfMonth = false; + + basisPoint = 1.0e-4; + fxSpot = 1.25; + + baseCcyIdx = ext::shared_ptr(new Euribor3M(baseCcyIdxHandle)); + quoteCcyIdx = ext::shared_ptr(new USDLibor(3 * Months, quoteCcyIdxHandle)); + + /* Data source: + N. Moreni, A. Pallavicini (2015) + FX Modelling in Collateralized Markets: foreign measures, basis curves + and pricing formulae. + + section 4.2.1, Table 2. + */ + basisData.emplace_back(1, Years, -14.5); + basisData.emplace_back(18, Months, -18.5); + basisData.emplace_back(2, Years, -20.5); + basisData.emplace_back(3, Years, -23.75); + basisData.emplace_back(4, Years, -25.5); + basisData.emplace_back(5, Years, -26.5); + basisData.emplace_back(7, Years, -26.75); + basisData.emplace_back(10, Years, -26.25); + basisData.emplace_back(15, Years, -24.75); + basisData.emplace_back(20, Years, -23.25); + basisData.emplace_back(30, Years, -20.50); + + today = calendar.adjust(Date(6, September, 2013)); + Settings::instance().evaluationDate() = today; + settlement = calendar.advance(today, settlementDays, Days); + + baseCcyIdxHandle.linkTo(flatRate(settlement, 0.007, dayCount)); + quoteCcyIdxHandle.linkTo(flatRate(settlement, 0.015, dayCount)); + } +}; - CommonVars() { - settlementDays = 2; - businessConvention = Following; - calendar = TARGET(); - dayCount = Actual365Fixed(); - endOfMonth = false; - - basisPoint = 1.0e-4; - fxSpot = 1.25; - - baseCcyIdx = ext::shared_ptr(new Euribor3M(baseCcyIdxHandle)); - quoteCcyIdx = ext::shared_ptr(new USDLibor(3 * Months, quoteCcyIdxHandle)); - - /* Data source: - N. Moreni, A. Pallavicini (2015) - FX Modelling in Collateralized Markets: foreign measures, basis curves - and pricing formulae. - - section 4.2.1, Table 2. - */ - basisData.emplace_back(1, Years, -14.5); - basisData.emplace_back(18, Months, -18.5); - basisData.emplace_back(2, Years, -20.5); - basisData.emplace_back(3, Years, -23.75); - basisData.emplace_back(4, Years, -25.5); - basisData.emplace_back(5, Years, -26.5); - basisData.emplace_back(7, Years, -26.75); - basisData.emplace_back(10, Years, -26.25); - basisData.emplace_back(15, Years, -24.75); - basisData.emplace_back(20, Years, -23.25); - basisData.emplace_back(30, Years, -20.50); - - today = calendar.adjust(Date(6, September, 2013)); - Settings::instance().evaluationDate() = today; - settlement = calendar.advance(today, settlementDays, Days); - - baseCcyIdxHandle.linkTo(flatRate(settlement, 0.007, dayCount)); - quoteCcyIdxHandle.linkTo(flatRate(settlement, 0.015, dayCount)); - } - }; -} void testConstantNotionalCrossCurrencySwapsNPV(bool isFxBaseCurrencyCollateralCurrency, bool isBasisOnFxBaseCurrencyLeg) { diff --git a/test-suite/curvestates.cpp b/test-suite/curvestates.cpp index 7b7a4c6f403..493bf61713b 100644 --- a/test-suite/curvestates.cpp +++ b/test-suite/curvestates.cpp @@ -41,80 +41,77 @@ BOOST_FIXTURE_TEST_SUITE(QuantLibTests, TopLevelFixture) BOOST_AUTO_TEST_SUITE(CurveStatesTests) -namespace { - - struct CommonVars { - // global data - Date todaysDate, startDate, endDate; - std::vector