C++:实现量化Libor市场模型流程测试实例

#include "libormarketmodelprocess.hpp"
#include "utilities.hpp"
#include <ql/timegrid.hpp>
#include <ql/math/randomnumbers/rngtraits.hpp>
#include <ql/methods/montecarlo/multipathgenerator.hpp>
#include <ql/indexes/ibor/euribor.hpp>
#include <ql/math/statistics/generalstatistics.hpp>
#include <ql/termstructures/yield/zerocurve.hpp>
#include <ql/time/daycounters/actualactual.hpp>
#include <ql/time/daycounters/actual360.hpp>
#include <ql/termstructures/volatility/optionlet/constantoptionletvol.hpp>
#include <ql/termstructures/volatility/optionlet/capletvariancecurve.hpp>
#include <ql/legacy/libormarketmodels/lfmhullwhiteparam.hpp>using namespace QuantLib;
using namespace boost::unit_test_framework;namespace libor_market_model_process_test {Size len = 10;ext::shared_ptr<IborIndex> makeIndex() {DayCounter dayCounter = Actual360();std::vector<Date> dates = {{4,September,2005}, {4,September,2018}};std::vector<Rate> rates = {0.01, 0.08};RelinkableHandle<YieldTermStructure> termStructure(ext::shared_ptr<YieldTermStructure>(new ZeroCurve(dates,rates,dayCounter)));ext::shared_ptr<IborIndex> index(new Euribor1Y(termStructure));Date todaysDate =index->fixingCalendar().adjust(Date(4,September,2005));Settings::instance().evaluationDate() = todaysDate;dates[0] = index->fixingCalendar().advance(todaysDate,index->fixingDays(), Days);termStructure.linkTo(ext::shared_ptr<YieldTermStructure>(new ZeroCurve(dates, rates, dayCounter)));return index;}ext::shared_ptr<CapletVarianceCurve>makeCapVolCurve(const Date& todaysDate) {Volatility vols[] = {14.40, 17.15, 16.81, 16.64, 16.17,15.78, 15.40, 15.21, 14.86, 14.54};std::vector<Date> dates;std::vector<Volatility> capletVols;ext::shared_ptr<LiborForwardModelProcess> process(new LiborForwardModelProcess(len+1, makeIndex()));for (Size i=0; i < len; ++i) {capletVols.push_back(vols[i]/100);dates.push_back(process->fixingDates()[i+1]);}return ext::make_shared<CapletVarianceCurve>(todaysDate, dates, capletVols,ActualActual(ActualActual::ISDA));}ext::shared_ptr<LiborForwardModelProcess>makeProcess(const Matrix& volaComp = Matrix()) {Size factors = (volaComp.empty() ? 1 : volaComp.columns());ext::shared_ptr<IborIndex> index = makeIndex();ext::shared_ptr<LiborForwardModelProcess> process(new LiborForwardModelProcess(len, index));ext::shared_ptr<LfmCovarianceParameterization> fct(new LfmHullWhiteParameterization(process,makeCapVolCurve(Settings::instance().evaluationDate()),volaComp * transpose(volaComp), factors));process->setCovarParam(fct);return process;}}void LiborMarketModelProcessTest::testInitialisation() {BOOST_TEST_MESSAGE("Testing caplet LMM process initialisation...");SavedSettings backup;DayCounter dayCounter = Actual360();RelinkableHandle<YieldTermStructure> termStructure(flatRate(Date::todaysDate(), 0.04, dayCounter));ext::shared_ptr<IborIndex> index(new Euribor6M(termStructure));ext::shared_ptr<OptionletVolatilityStructure> capletVol(newConstantOptionletVolatility(termStructure->referenceDate(),termStructure->calendar(),Following,0.2,termStructure->dayCounter()));Calendar calendar = index->fixingCalendar();for (Integer daysOffset=0; daysOffset < 1825 /* 5 year*/; daysOffset+=8) {Date todaysDate = calendar.adjust(Date::todaysDate()+daysOffset);Settings::instance().evaluationDate() = todaysDate;Date settlementDate =calendar.advance(todaysDate, index->fixingDays(), Days);termStructure.linkTo(flatRate(settlementDate, 0.04, dayCounter));LiborForwardModelProcess process(60, index);std::vector<Time> fixings = process.fixingTimes();for (Size i=1; i < fixings.size()-1; ++i) {Size ileft  = process.nextIndexReset(fixings[i]-0.000001);Size iright = process.nextIndexReset(fixings[i]+0.000001);Size ii     = process.nextIndexReset(fixings[i]);if ((ileft != i) || (iright != i+1) || (ii != i+1)) {BOOST_ERROR("Failed to next index resets");}}}
}void LiborMarketModelProcessTest::testLambdaBootstrapping() {BOOST_TEST_MESSAGE("Testing caplet LMM lambda bootstrapping...");using namespace libor_market_model_process_test;SavedSettings backup;Real tolerance = 1e-10;Volatility lambdaExpected[]= {14.3010297550, 19.3821411939, 15.9816590141,15.9953118303, 14.0570815635, 13.5687599894,12.7477197786, 13.7056638165, 11.6191989567};ext::shared_ptr<LiborForwardModelProcess> process = makeProcess();Matrix covar = process->covariance(0.0, Null<Array>(), 1.0);for (Size i=0; i<9; ++i) {const Real calculated = std::sqrt(covar[i+1][i+1]);const Real expected   = lambdaExpected[i]/100;if (std::fabs(calculated - expected) > tolerance)BOOST_ERROR("Failed to reproduce expected lambda values"<< "\n    calculated: " << calculated<< "\n    expected:   " << expected);}ext::shared_ptr<LfmCovarianceParameterization> param =process->covarParam();std::vector<Time> tmp = process->fixingTimes();TimeGrid grid(tmp.begin(), tmp.end(), 14);for (Real t : grid) {Matrix diff = (param->integratedCovariance(t) -param->LfmCovarianceParameterization::integratedCovariance(t));for (Size i=0; i<diff.rows(); ++i) {for (Size j=0; j<diff.columns(); ++j) {if (std::fabs(diff[i][j]) > tolerance) {BOOST_FAIL("Failed to reproduce integrated covariance" <<"\n    i: " << i <<"\n    j: " << j <<"\nerror: " << diff[i][j]);}}}}
}void LiborMarketModelProcessTest::testMonteCarloCapletPricing() {BOOST_TEST_MESSAGE("Testing caplet LMM Monte-Carlo caplet pricing...");using namespace libor_market_model_process_test;SavedSettings backup;/* factor loadings are taken from Hull & White articleplus extra normalisation to get orthogonal eigenvectorshttp://www.rotman.utoronto.ca/~amackay/fin/libormktmodel2.pdf */Real compValues[] = {0.85549771, 0.46707264, 0.22353259,0.91915359, 0.37716089, 0.11360610,0.96438280, 0.26413316,-0.01412414,0.97939148, 0.13492952,-0.15028753,0.95970595,-0.00000000,-0.28100621,0.97939148,-0.13492952,-0.15028753,0.96438280,-0.26413316,-0.01412414,0.91915359,-0.37716089, 0.11360610,0.85549771,-0.46707264, 0.22353259};Matrix volaComp(9,3);std::copy(compValues, compValues+9*3, volaComp.begin());ext::shared_ptr<LiborForwardModelProcess> process1 = makeProcess();ext::shared_ptr<LiborForwardModelProcess> process2 = makeProcess(volaComp);std::vector<Time> tmp = process1->fixingTimes();TimeGrid grid(tmp.begin(), tmp.end(),12);Size i;std::vector<Size> location;for (i=0; i < tmp.size(); ++i) {location.push_back(std::find(grid.begin(),grid.end(),tmp[i])-grid.begin());}// set-up a small Monte-Carlo simulation to price caplets// and ratchet caps using a one- and a three factor libor market modeltypedef LowDiscrepancy::rsg_type rsg_type;typedef MultiPathGenerator<rsg_type>::sample_type sample_type;BigNatural seed = 42;rsg_type rsg1 = LowDiscrepancy::make_sequence_generator(process1->factors()*(grid.size()-1), seed);rsg_type rsg2 = LowDiscrepancy::make_sequence_generator(process2->factors()*(grid.size()-1), seed);MultiPathGenerator<rsg_type> generator1(process1, grid, rsg1, false);MultiPathGenerator<rsg_type> generator2(process2, grid, rsg2, false);const Size nrTrails = 250000;std::vector<GeneralStatistics> stat1(process1->size());std::vector<GeneralStatistics> stat2(process2->size());std::vector<GeneralStatistics> stat3(process2->size()-1);for (i=0; i<nrTrails; ++i) {sample_type path1 = generator1.next();sample_type path2 = generator2.next();std::vector<Rate> rates1(len);std::vector<Rate> rates2(len);for (Size j=0; j<process1->size(); ++j) {rates1[j] = path1.value[j][location[j]];rates2[j] = path2.value[j][location[j]];}std::vector<DiscountFactor> dis1 = process1->discountBond(rates1);std::vector<DiscountFactor> dis2 = process2->discountBond(rates2);for (Size k=0; k<process1->size(); ++k) {Real accrualPeriod =  process1->accrualEndTimes()[k]- process1->accrualStartTimes()[k];// caplet payoff function, cap rate at 4%Real payoff1 = std::max(rates1[k] - 0.04, 0.0) * accrualPeriod;Real payoff2 = std::max(rates2[k] - 0.04, 0.0) * accrualPeriod;stat1[k].add(dis1[k] * payoff1);stat2[k].add(dis2[k] * payoff2);if (k != 0) {// ratchet cap payoff functionReal payoff3 =  std::max(rates2[k] - (rates2[k-1]+0.0025), 0.0)* accrualPeriod;stat3[k-1].add(dis2[k] * payoff3);}}}Real capletNpv[] = {0.000000000000, 0.000002841629, 0.002533279333,0.009577143571, 0.017746502618, 0.025216116835,0.031608230268, 0.036645683881, 0.039792254012,0.041829864365};Real ratchetNpv[] = {0.0082644895, 0.0082754754, 0.0082159966,0.0082982822, 0.0083803357, 0.0084366961,0.0084173270, 0.0081803406, 0.0079533814};for (Size k=0; k < process1->size(); ++k) {Real calculated1 = stat1[k].mean();Real tolerance1  = stat1[k].errorEstimate();Real expected    = capletNpv[k];if (std::fabs(calculated1 - expected) > tolerance1) {BOOST_ERROR("Failed to reproduce expected caplet NPV"<< "\n    calculated: " << calculated1<< "\n    error int:  " << tolerance1<< "\n    expected:   " << expected);}Real calculated2 = stat2[k].mean();Real tolerance2  = stat2[k].errorEstimate();if (std::fabs(calculated2 - expected) > tolerance2) {BOOST_ERROR("Failed to reproduce expected caplet NPV"<< "\n    calculated: " << calculated2<< "\n    error int:  " << tolerance2<< "\n    expected:   " << expected);}if (k != 0) {Real calculated3 = stat3[k-1].mean();Real tolerance3  = stat3[k-1].errorEstimate();expected    = ratchetNpv[k-1];Real refError = 1e-5; // 1e-5. error bars of the reference valuesif (std::fabs(calculated3 - expected) > tolerance3 + refError) {BOOST_ERROR("Failed to reproduce expected caplet NPV"<< "\n    calculated: " << calculated3<< "\n    error int:  " << tolerance3 + refError<< "\n    expected:   " << expected);}}}
}test_suite* LiborMarketModelProcessTest::suite(SpeedLevel speed) {auto* suite = BOOST_TEST_SUITE("Libor market model process tests");suite->add(QUANTLIB_TEST_CASE(&LiborMarketModelProcessTest::testInitialisation));suite->add(QUANTLIB_TEST_CASE(&LiborMarketModelProcessTest::testLambdaBootstrapping));if (speed <= Fast) {suite->add(QUANTLIB_TEST_CASE(&LiborMarketModelProcessTest::testMonteCarloCapletPricing));}return suite;
}

该博文为原创文章,未经博主同意不得转。
本文章博客地址:https://cplusplus.blog.csdn.net/article/details/128364315

C++:实现量化Libor市场模型流程测试实例相关推荐

  1. C++:实现量化Libor市场模型测试实例

    C++:实现量化Libor市场模型测试实例 #include "libormarketmodel.hpp" #include "utilities.hpp"#i ...

  2. C++:实现量化Piecewise yield曲线测试实例

    C++:实现量化Piecewise yield曲线测试实例 #include "piecewiseyieldcurve.hpp" #include "utilities. ...

  3. C++:实现量化daycounters 日计数器测试实例

    C++:实现量化daycounters 日计数器测试实例 #include "daycounters.hpp" #include "utilities.hpp" ...

  4. C++:实现量化CPI债券交换测试实例

    C++:实现量化CPI债券交换测试实例 #include "utilities.hpp" #include "inflationcpiswap.hpp" #in ...

  5. C++:实现量化N阶导数运算测试实例

    C++:实现量化N阶导数运算测试实例 #include "nthorderderivativeop.hpp" #include "utilities.hpp"# ...

  6. C++:实现量化SMM Caplet校准测试实例

    C++:实现量化SMM Caplet校准测试实例 #include "marketmodel_smmcapletcalibration.hpp" #include "ut ...

  7. C++:实现量化SMM Caplet α 校准测试实例

    C++:实现量化SMM Caplet α 校准测试实例 #include "marketmodel_smmcapletalphacalibration.hpp" #include ...

  8. C++:实现量化Jump-diffusion跳跃扩散过程测试实例

    C++:实现量化Jump-diffusion跳跃扩散过程测试实例 #include "jumpdiffusion.hpp" #include "utilities.hpp ...

  9. C++:实现量化投资组合孤注一掷BasketLosses测试实例

    C++:实现量化投资组合孤注一掷BasketLosses测试实例 #include <ql/qldefines.hpp> #if !defined(BOOST_ALL_NO_LIB) &a ...

最新文章

  1. Python中可以使用静态类变量吗?
  2. 【机器学习PAI实践四】如何实现金融风控
  3. JAVA程序设计----多线程(下)
  4. 头像星球html,HTML5 Canvas 星球大战黑武士头像
  5. mybatis学习笔记-02-第一个mybatis程序
  6. dscms源码分析笔记
  7. python 英语分词_python 英文分词
  8. 2021SC@SDUSC Zxing开源代码(十)Data Matrix二维码(三)
  9. cosh和acosh--双曲余弦和反双曲余弦函数
  10. 《霍比特人2》:我靠,洞里有条好大的龙!!!
  11. vsphere client下载地址
  12. 《割绳子》《蜡笔物理学》《Contre Jour》《顽皮鳄鱼爱洗澡》等游戏用Box2D引擎实现物理部分的方法(转)...
  13. 文本相似度计算——Simhash算法(python实现)
  14. linux 重定向 21
  15. 使用Foxmail设置Gmail以及Hotmail
  16. 【赠书】熊德意老师的一部不止于技术的神经机器翻译“百科全书”
  17. 在Exchange Server 2007中限制部分用户只能收发内部邮件 1
  18. python基础编程:基于Python对象引用、可变性和垃圾回收详解
  19. java中的repo什么意思_java – Spring数据jpa repo,为什么需要接口服务和服务实现
  20. 和程序员约会的十个理由

热门文章

  1. anemometer mysql5.6_slowlog分析anemometer平台搭建
  2. CC2530关于端口中断常用的寄存器
  3. 托管调试助手“LoaderLock”在XXX中检测到故障。其他信息:正尝试在OS加载程序锁内执行托管代码。不要尝试在DllMain或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
  4. Pool thread stack traces: Thread[C3P0PooledConnectionPoolManager[identityToken-原因解决办法
  5. 真正拖垮年轻人认知水平的,是幸存者偏差!
  6. 抖音、快手、脸书陷舆论漩涡,CEO纷纷致歉,AI算法不灵了?
  7. 学习笔记:SKU组件(React版)
  8. html 点击选择变色,css实现选中后变色并且效果不消失
  9. 用FDM打印会遇到的3D打印常见问题详解
  10. 卸载Photoshop