C++:实现 VOL量化指标测试实例

#include "inflationvolatility.hpp"
#include "utilities.hpp"#include <ql/math/interpolations/cubicinterpolation.hpp>
#include <ql/math/interpolations/bicubicsplineinterpolation.hpp>
#include <ql/termstructures/yield/zerocurve.hpp>
#include <ql/termstructures/inflation/interpolatedyoyinflationcurve.hpp>#include <ql/cashflows/inflationcoupon.hpp>
#include <ql/cashflows/inflationcouponpricer.hpp>#include <ql/experimental/inflation/yoycapfloortermpricesurface.hpp>
#include <ql/pricingengines/inflation/inflationcapfloorengines.hpp>
#include <ql/experimental/inflation/yoyoptionletstripper.hpp>#include <ql/experimental/inflation/kinterpolatedyoyoptionletvolatilitysurface.hpp>
#include <ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp>#include <ql/cashflows/capflooredinflationcoupon.hpp>
#include <ql/indexes/inflation/euhicp.hpp>
#include <ql/indexes/inflation/ukrpi.hpp>#include <iostream>// local namespace for data
//*************************************************************************
namespace inflation_volatility_test {using namespace std;using namespace QuantLib;// local data globalsHandle<YieldTermStructure> nominalEUR;Handle<YieldTermStructure> nominalGBP;RelinkableHandle<YoYInflationTermStructure> yoyEU;RelinkableHandle<YoYInflationTermStructure> yoyUK;vector<Rate> cStrikesEU;vector<Rate> fStrikesEU;vector<Period> cfMaturitiesEU;ext::shared_ptr<Matrix> cPriceEU;ext::shared_ptr<Matrix> fPriceEU;ext::shared_ptr<YoYInflationIndex> yoyIndexUK;ext::shared_ptr<YoYInflationIndex> yoyIndexEU;vector<Rate> cStrikesUK;vector<Rate> fStrikesUK;vector<Period> cfMaturitiesUK;ext::shared_ptr<Matrix> cPriceUK;ext::shared_ptr<Matrix> fPriceUK;ext::shared_ptr<InterpolatedYoYCapFloorTermPriceSurface<Bicubic,Cubic> > priceSurfEU;void reset() {nominalEUR = Handle<YieldTermStructure>();nominalGBP = Handle<YieldTermStructure>();priceSurfEU.reset();yoyEU.linkTo(ext::shared_ptr<YoYInflationTermStructure>());yoyUK.linkTo(ext::shared_ptr<YoYInflationTermStructure>());yoyIndexUK.reset();yoyIndexEU.reset();cPriceEU.reset();fPriceEU.reset();cPriceUK.reset();fPriceUK.reset();yoyIndexUK.reset();cStrikesEU.clear();        fStrikesEU.clear();cStrikesUK.clear();        fStrikesUK.clear();cfMaturitiesEU.clear();cfMaturitiesUK.clear();}void setup() {// make sure of the evaluation dateDate eval = Date(Day(23), Month(11), Year(2007));Settings::instance().evaluationDate() = eval;yoyIndexUK = ext::shared_ptr<YoYInflationIndex>(new YYUKRPIr(true, yoyUK));yoyIndexEU = ext::shared_ptr<YoYInflationIndex>(new YYEUHICPr(true, yoyEU));// nominal yield curve (interpolated; times assume year parts have 365 days)Real timesEUR[] = {0.0109589, 0.0684932, 0.263014, 0.317808, 0.567123, 0.816438,1.06575, 1.31507, 1.56438, 2.0137, 3.01918, 4.01644,5.01644, 6.01644, 7.01644, 8.01644, 9.02192, 10.0192,12.0192, 15.0247, 20.0301, 25.0356, 30.0329, 40.0384,50.0466};Real ratesEUR[] = {0.0415600, 0.0426840, 0.0470980, 0.0458506, 0.0449550, 0.0439784,0.0431887, 0.0426604, 0.0422925, 0.0424591, 0.0421477, 0.0421853,0.0424016, 0.0426969, 0.0430804, 0.0435011, 0.0439368, 0.0443825,0.0452589, 0.0463389, 0.0472636, 0.0473401, 0.0470629, 0.0461092,0.0450794};Real timesGBP[] = {0.008219178, 0.010958904, 0.01369863,  0.019178082,  0.073972603,0.323287671, 0.57260274,  0.821917808, 1.071232877,  1.320547945,1.506849315, 2.002739726, 3.002739726, 4.002739726,  5.005479452,6.010958904, 7.008219178, 8.005479452, 9.008219178, 10.00821918,12.01369863, 15.0109589,  20.01369863, 25.01917808,  30.02191781,40.03287671, 50.03561644, 60.04109589, 70.04931507};Real ratesGBP[] = {0.0577363, 0.0582314, 0.0585265, 0.0587165, 0.0596598,0.0612506, 0.0589676, 0.0570512, 0.0556147, 0.0546082,0.0549492, 0.053801, 0.0529333, 0.0524068, 0.0519712,0.0516615, 0.0513711, 0.0510433, 0.0507974, 0.0504833,0.0498998, 0.0490464, 0.04768, 0.0464862, 0.045452,0.0437699, 0.0425311, 0.0420073, 0.041151};vector <Real> r;vector <Date> d;Size nTimesEUR = LENGTH(timesEUR);Size nTimesGBP = LENGTH(timesGBP);for (Size i = 0; i < nTimesEUR; i++) {r.push_back(ratesEUR[i]);Size ys = (Size)floor(timesEUR[i]);Size ds = (Size)((timesEUR[i]-(Real)ys)*365);Date dd = eval + Period(ys,Years) + Period(ds,Days);d.push_back( dd );}ext::shared_ptr<InterpolatedZeroCurve<Cubic> >euriborTS(new InterpolatedZeroCurve<Cubic>(d, r, Actual365Fixed()));Handle<YieldTermStructure> nominalHeur(euriborTS, false);nominalEUR = nominalHeur;   // copy to globald.clear();r.clear();for (Size i = 0; i < nTimesGBP; i++) {r.push_back(ratesGBP[i]);Size ys = (Size)floor(timesGBP[i]);Size ds = (Size)((timesGBP[i]-(Real)ys)*365);Date dd = eval + Period(ys,Years) + Period(ds,Days);d.push_back( dd );}ext::shared_ptr<InterpolatedZeroCurve<Cubic> >gbpLiborTS(new InterpolatedZeroCurve<Cubic>(d, r, Actual365Fixed()));Handle<YieldTermStructure> nominalHgbp(gbpLiborTS, false);nominalGBP = nominalHgbp;   // copy to global// times = years - lag, where the lag is 2 months or 2/12// because this data is derived from cap/floor data that// is based on a 2 month lag.// note that these are NOT swap rates// also not that the first value MUST be in the base period// i.e. the first rate is for a negative timeReal yoyEUrates[] = {0.0237951,0.0238749, 0.0240334, 0.0241934, 0.0243567, 0.0245323,0.0247213, 0.0249348, 0.0251768, 0.0254337, 0.0257258,0.0260217, 0.0263006, 0.0265538, 0.0267803, 0.0269378,0.0270608, 0.0271363, 0.0272, 0.0272512, 0.0272927,0.027317, 0.0273615, 0.0273811, 0.0274063, 0.0274307,0.0274625, 0.027527, 0.0275952, 0.0276734, 0.027794};d.clear();r.clear();Date baseDate = TARGET().advance(eval, -2, Months, ModifiedFollowing);for (Size i = 0; i < LENGTH(yoyEUrates); i++) {Date dd = TARGET().advance(baseDate, i, Years, ModifiedFollowing);d.push_back(dd);r.push_back(yoyEUrates[i]);}bool indexIsInterpolated = true;    // actually false for UKRPI but smooth surfaces are// better for finding intersections etcext::shared_ptr<InterpolatedYoYInflationCurve<Linear> >pYTSEU( new InterpolatedYoYInflationCurve<Linear>(eval, TARGET(), Actual365Fixed(), Period(2,Months), Monthly,indexIsInterpolated, d, r) );yoyEU.linkTo(pYTSEU);// price dataconst Size ncStrikesEU = 6;const Size nfStrikesEU = 6;const Size ncfMaturitiesEU = 7;Real capStrikesEU[ncStrikesEU] = {0.02, 0.025, 0.03, 0.035, 0.04, 0.05};Period capMaturitiesEU[ncfMaturitiesEU] = {3*Years, 5*Years, 7*Years,10*Years, 15*Years, 20*Years, 30*Years};Real capPricesEU[ncStrikesEU][ncfMaturitiesEU] ={{116.225, 204.945, 296.285, 434.29, 654.47, 844.775, 1132.33},{34.305, 71.575, 114.1, 184.33, 307.595, 421.395, 602.35},{6.37, 19.085, 35.635, 66.42, 127.69, 189.685, 296.195},{1.325, 5.745, 12.585, 26.945, 58.95, 94.08, 158.985},{0.501, 2.37, 5.38, 13.065, 31.91, 53.95, 96.97},{0.501, 0.695, 1.47, 4.415, 12.86, 23.75, 46.7}};Real floorStrikesEU[nfStrikesEU] = {-0.01, 0.00, 0.005, 0.01, 0.015, 0.02};Real floorPricesEU[nfStrikesEU][ncfMaturitiesEU] ={{0.501, 0.851, 2.44, 6.645, 16.23, 26.85, 46.365},{0.501, 2.236, 5.555, 13.075, 28.46, 44.525, 73.08},{1.025, 3.935, 9.095, 19.64, 39.93, 60.375, 96.02},{2.465, 7.885, 16.155, 31.6, 59.34, 86.21, 132.045},{6.9, 17.92, 32.085, 56.08, 95.95, 132.85, 194.18},{23.52, 47.625, 74.085, 114.355, 175.72, 229.565, 316.285}};// now load the data into vector and Matrix classescStrikesEU.clear();fStrikesEU.clear();cfMaturitiesEU.clear();for (Real& i : capStrikesEU)cStrikesEU.push_back(i);for (Real& i : floorStrikesEU)fStrikesEU.push_back(i);for (auto& i : capMaturitiesEU)cfMaturitiesEU.push_back(i);ext::shared_ptr<Matrix> tcPriceEU(new Matrix(ncStrikesEU, ncfMaturitiesEU));ext::shared_ptr<Matrix> tfPriceEU(new Matrix(nfStrikesEU, ncfMaturitiesEU));for(Size i = 0; i < ncStrikesEU; i++) {for(Size j = 0; j < ncfMaturitiesEU; j++) {(*tcPriceEU)[i][j] = capPricesEU[i][j];}}for(Size i = 0; i < nfStrikesEU; i++) {for(Size j = 0; j < ncfMaturitiesEU; j++) {(*tfPriceEU)[i][j] = floorPricesEU[i][j];}}cPriceEU = tcPriceEU;   // copy to globalfPriceEU = tfPriceEU;}void setupPriceSurface() {// construct://  calendar, business day convention, and day counter are//  taken from the nominal base give the reference date for//  the inflation options (generally 2 or 3 months before//  nominal reference date)Natural fixingDays = 0;Size lag = 3;// must be 3 because we use an interpolated index (EU)Period yyLag = Period(lag,Months);Rate baseRate = 1; // not really usedDayCounter dc = Actual365Fixed();TARGET cal;BusinessDayConvention bdc = ModifiedFollowing;const ext::shared_ptr<QuantLib::YieldTermStructure>& pn = nominalEUR.currentLink();Handle<QuantLib::YieldTermStructure> n(pn,false);ext::shared_ptr<InterpolatedYoYCapFloorTermPriceSurface<Bicubic,Cubic> >cfEUprices(new InterpolatedYoYCapFloorTermPriceSurface<Bicubic,Cubic>(fixingDays,yyLag, yoyIndexEU, baseRate,n, dc,cal,    bdc,cStrikesEU, fStrikesEU, cfMaturitiesEU,(*cPriceEU), (*fPriceEU)));priceSurfEU = cfEUprices;}}//***************************************************************************void InflationVolTest::testYoYPriceSurfaceToVol() {BOOST_TEST_MESSAGE("Testing conversion from YoY price surface ""to YoY volatility surface...");using namespace inflation_volatility_test;SavedSettings backup;setup();// first get the price surface set upsetupPriceSurface();// caplet pricer, recall that setCapletVolatility(Handle<YoYOptionletVolatilitySurface>)// exists ... we'll use it with the -Curve variant of the surface// test UNIT DISPLACED pricerext::shared_ptr<YoYOptionletVolatilitySurface> pVS;Handle<YoYOptionletVolatilitySurface> hVS(pVS, false); // pVS does NOT own whatever it points to later, hence the handle does not eitherext::shared_ptr<YoYInflationUnitDisplacedBlackCapFloorEngine>yoyPricerUD(new YoYInflationUnitDisplacedBlackCapFloorEngine(yoyIndexEU,hVS,nominalEUR)); //hVS// N.B. the vol gets set in the stripper ... else no point!// cap stripperext::shared_ptr<YoYOptionletStripper> yoyOptionletStripper(new InterpolatedYoYOptionletStripper<Linear>() );// now set up all the variables for the strippingNatural settlementDays = 0;TARGET cal;BusinessDayConvention bdc = ModifiedFollowing;DayCounter dc = Actual365Fixed();ext::shared_ptr<YoYCapFloorTermPriceSurface> capFloorPrices = priceSurfEU;Period lag = priceSurfEU->observationLag();Real slope = -0.5; //when you have bad data, i.e. very low/constant//prices for short dated extreem strikes//then you cannot assume constant caplet vol//(else arbitrage)// N.B. if this is too extreme then can't// get a no-arbitrage solution anyway// the way the slope is used means that the slope is// proportional to the level so higher slopes at// the edges when things are more volatile// Actually is doesn't matter what the interpolation is because we only// intend to use the K values that correspond to quotes ... for model fitting.ext::shared_ptr<KInterpolatedYoYOptionletVolatilitySurface<Linear> > yoySurf(newKInterpolatedYoYOptionletVolatilitySurface<Linear>(settlementDays,cal, bdc, dc, lag, capFloorPrices, yoyPricerUD, yoyOptionletStripper,slope) );// now use it for something ... like stating what the T=const lines look likeconst Real volATyear1[] = {0.0128, 0.0093, 0.0083, 0.0073, 0.0064,0.0058, 0.0042, 0.0046, 0.0053, 0.0064,0.0098};const Real volATyear3[] = {0.0079, 0.0058, 0.0051, 0.0045, 0.0039,0.0035, 0.0026, 0.0028, 0.0033, 0.0039,0.0060};Date d = yoySurf->baseDate() + Period(1,Years);pair<vector<Rate>, vector<Volatility> > someSlice;someSlice = yoySurf->Dslice(d);Size n = someSlice.first.size();Real eps = 0.0001;for(Size i = 0; i < n; i++){QL_REQUIRE( fabs(someSlice.second[i] - volATyear1[i]) < eps," could not recover 1yr vol: " << someSlice.second[i]<< " vs " << volATyear1[i] );}d = yoySurf->baseDate() + Period(3,Years);pair<vector<Rate>, vector<Volatility> >someOtherSlice = yoySurf->Dslice(d);n = someOtherSlice.first.size();for(Size i = 0; i < n; i++){QL_REQUIRE(fabs(someOtherSlice.second[i]-volATyear3[i]) < eps,"could not recover 3yr vol: "<< someOtherSlice.second[i]<< " vs " << volATyear3[i] );}reset();
}void InflationVolTest::testYoYPriceSurfaceToATM() {BOOST_TEST_MESSAGE("Testing conversion from YoY cap-floor surface ""to YoY inflation term structure...");using namespace inflation_volatility_test;SavedSettings backup;setup();setupPriceSurface();pair<vector<Time>, vector<Rate> > yyATMt = priceSurfEU->atmYoYSwapTimeRates();pair<vector<Date>, vector<Rate> > yyATMd = priceSurfEU->atmYoYSwapDateRates();// Real dy = (Real)lag / 12.0;const Real crv[] = {0.024586, 0.0247575, 0.0249396, 0.0252596,0.0258498, 0.0262883, 0.0267915};const Real swaps[] = {0.024586, 0.0247575, 0.0249396, 0.0252596,0.0258498, 0.0262883, 0.0267915};const Real ayoy[] = {0.0247659, 0.0251437, 0.0255945, 0.0265234,0.0280457, 0.0285534, 0.0295884};Real eps = 2e-5;for(Size i = 0; i < yyATMt.first.size(); i++) {QL_REQUIRE(fabs( yyATMt.second[i] - crv[i] ) < eps,"could not recover cached yoy swap curve "<< yyATMt.second[i]<< " vs " << crv[i]);}for(Size i = 0; i < yyATMd.first.size(); i++) {QL_REQUIRE(fabs( priceSurfEU->atmYoYSwapRate(yyATMd.first[i])  - swaps[i] ) < eps,"could not recover yoy swap curve "<< priceSurfEU->atmYoYSwapRate(yyATMd.first[i]) << " vs " << swaps[i]);}for(Size i = 0; i < yyATMd.first.size(); i++) {QL_REQUIRE(fabs( priceSurfEU->atmYoYRate(yyATMd.first[i])  - ayoy[i] ) < eps," could not recover cached yoy curve "<< priceSurfEU->atmYoYRate(yyATMd.first[i]) << " vs " << ayoy[i]<<" at "<<yyATMd.first[i]);}reset();
}boost::unit_test_framework::test_suite* InflationVolTest::suite() {auto* suite = BOOST_TEST_SUITE("yoyOptionletStripper (yoy inflation vol) tests");suite->add(QUANTLIB_TEST_CASE(&InflationVolTest::testYoYPriceSurfaceToATM));suite->add(QUANTLIB_TEST_CASE(&InflationVolTest::testYoYPriceSurfaceToVol));return suite;
}

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

C++:实现 VOL量化指标测试实例相关推荐

  1. C++:实现量化BlackDelta测试实例

    C++:实现量化BlackDelta测试实例 #include "blackdeltacalculator.hpp" #include "utilities.hpp&qu ...

  2. C++:实现量化OptionletStripper测试实例

    C++:实现量化OptionletStripper测试实例 #include "optionletstripper.hpp" #include "utilities.hp ...

  3. C++:实现量化可转换债券测试实例

    C++:实现量化可转换债券测试实例 #include "convertiblebonds.hpp" #include "utilities.hpp" #incl ...

  4. C++:实现量化相关的Interpolation插值测试实例

    C++:实现量化相关的Interpolation插值测试实例 #include "interpolations.hpp" #include "utilities.hpp& ...

  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++:实现量化Forward option远期合约期权测试实例

    C++:实现量化Forward option远期合约期权测试实例 #include "forwardoption.hpp" #include "utilities.hpp ...

  9. C++:实现量化dividend option股息期权 测试实例

    C++:实现量化dividend option股息期权 测试实例 #include "dividendoption.hpp" #include "utilities.hp ...

最新文章

  1. 迁移到MySQL的业务架构演进实战
  2. ssm jsp跳转jsp_去掉Shiro默认login.jsp跳转
  3. jQuery框架的简单使用(H5)
  4. 视觉硬件 - 相机 镜头 选型
  5. CCNA,CCNP资料
  6. [Java基础]异常概述与异常处理
  7. 华强北耳机版本太多,不知道如何选购?
  8. 七年级计算机室使用计划表,七年级信息技术教学工作计划
  9. 《Python Cookbook 3rd》笔记(1.12):序列中出现次数最多的元素
  10. 杭电oj1257最少拦截系统(贪心)
  11. git 创建远程仓库
  12. 使用easy_install安装BeautifulSoup——Python
  13. 量子统计中的涨落和时间关联函数的概念(谐振子例子)
  14. Java中 ? extends T 和 ? super T 的理解
  15. linux误删文件后恢复
  16. android webview 劫持,微信webview 及第三方浏览器劫持视频问题
  17. 社交媒体中有哪些有趣的数据?能挖掘出哪些价值?
  18. python面试常见问题汇总(1-30)
  19. 前程无忧简历泄露事件再被曝光,公司理念是“不赚钱的东西不做”
  20. 3D摄影机选择指南,你知道自己需要什么样的摄影机吗?

热门文章

  1. 做了一个收藏网页的东西
  2. python实现在一个画布绘制多张双y轴折线图,y轴数据大小不一样,怎么hua?
  3. D3D9学习笔记之纹理映射
  4. 反恐训练营(LCS)
  5. 前端自存文件到public文件夹中,点击实现下载
  6. 财务在线咨询平台,哪个机构可以提供财务顾问服务
  7. pygame机器人跳舞小动画_作者:李兴球
  8. zigbee(题型整理4)
  9. Java中pop和poll区别
  10. 如何使数据异常解决不那么卡通化