【C++】开源:量化金融计算库QuantLib配置与使用

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍量化交易库QuantLib配置与使用。
无专精则不能成,无涉猎则不能通。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • :smirk:1. 项目介绍
    • :blush:2. 环境配置
    • :satisfied:3. 使用说明

😏1. 项目介绍

官网:https://www.quantlib.org/

项目Github地址:https://github.com/lballabio/QuantLib

QuantLib(Quantitative Finance Library)是一个开源的跨平台软件框架,专为量化金融领域设计和开发。它提供了丰富的金融工具和计算功能,用于衍生品定价、风险管理、投资组合管理等多个领域。以下是关于QuantLib的一些主要特点和用途:

1.开源跨平台:QuantLib是完全开源的,可以在不同操作系统上运行,包括Windows、Linux和Mac OS X。这使得它成为量化金融研究和开发的理想工具,能够在不同的环境中使用和定制。

2.丰富的金融工具:QuantLib支持多种金融工具和衍生品的定价和分析,包括利率衍生品(如利率互换、利率期权)、股票衍生品(如期权)、信用衍生品(如信用违约掉期)、外汇衍生品等。

3.数值方法和模型支持:QuantLib提供了广泛的数值方法和模型,用于衍生品定价和风险管理,如蒙特卡洛模拟、有限差分法、解析方法等。它支持的模型包括Black-Scholes模型、Heston模型、Libor Market Model等。

4.投资组合和风险管理:QuantLib能够处理复杂的投资组合和风险管理需求,包括风险测度、对冲分析、压力测试等,为金融机构和量化交易员提供重要的决策支持工具。

5.易于集成和扩展:QuantLib的设计允许用户根据特定需求进行定制和扩展,通过C++编程接口提供了灵活的扩展性,同时也支持Python等编程语言的接口,使得QuantLib能够与其他系统和库集成使用。

😊2. 环境配置

Ubuntu环境安装QuantLib库:

git clone https://github.com/lballabio/QuantLib # 或者下载release版本 1.34
mkdir build && cd build
cmake ..
make
sudo make install

程序g++编译:g++ -o main main.cpp -lQuantLib

😆3. 使用说明

下面是一个简单示例,计算零息债券的定价:

#include <ql/quantlib.hpp>
#include <iostream>

using namespace QuantLib;

int main() {
    // 设置评估日期
    Date today = Date::todaysDate();
    Settings::instance().evaluationDate() = today;

    // 定义债券参数
    Real faceAmount = 1000.0; // 债券面值
    Rate couponRate = 0.05; // 年利率
    Date maturity = today + Period(1, Years); // 到期时间

    // 创建收益率曲线
    Rate marketRate = 0.03; // 市场利率
    Handle<YieldTermStructure> discountCurve(boost::shared_ptr<YieldTermStructure>(
        new FlatForward(today, marketRate, Actual360())));

    // 创建零息债券
    ZeroCouponBond bond(0, NullCalendar(), faceAmount, maturity, Following, 100.0, today);

    // 创建定价引擎并设置参数
    bond.setPricingEngine(boost::shared_ptr<PricingEngine>(
        new DiscountingBondEngine(discountCurve)));

    // 计算债券价格
    Real bondPrice = bond.NPV();
    std::cout << "Zero-coupon bond price: " << bondPrice << std::endl;

    return 0;
}

此外,还有官方示例里的BasketLosses 计算一组金融资产损失示例(看起来还是很复杂的):

/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*!
Copyright (C) 2009 Mark Joshi

This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license.  You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev@lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#include <ql/qldefines.hpp>
#if !defined(BOOST_ALL_NO_LIB) && defined(BOOST_MSVC)
#  include <ql/auto_link.hpp>
#endif
#include <ql/models/marketmodels/marketmodel.hpp>
#include <ql/models/marketmodels/accountingengine.hpp>
#include <ql/models/marketmodels/pathwiseaccountingengine.hpp>
#include <ql/models/marketmodels/products/multiproductcomposite.hpp>
#include <ql/models/marketmodels/products/multistep/multistepswap.hpp>
#include <ql/models/marketmodels/products/multistep/callspecifiedmultiproduct.hpp>
#include <ql/models/marketmodels/products/multistep/exerciseadapter.hpp>
#include <ql/models/marketmodels/products/multistep/multistepnothing.hpp>
#include <ql/models/marketmodels/products/multistep/multistepinversefloater.hpp>
#include <ql/models/marketmodels/products/pathwise/pathwiseproductswap.hpp>
#include <ql/models/marketmodels/products/pathwise/pathwiseproductinversefloater.hpp>
#include <ql/models/marketmodels/products/pathwise/pathwiseproductcallspecified.hpp>
#include <ql/models/marketmodels/models/flatvol.hpp>
#include <ql/models/marketmodels/callability/swapratetrigger.hpp>
#include <ql/models/marketmodels/callability/swapbasissystem.hpp>
#include <ql/models/marketmodels/callability/swapforwardbasissystem.hpp>
#include <ql/models/marketmodels/callability/nothingexercisevalue.hpp>
#include <ql/models/marketmodels/callability/collectnodedata.hpp>
#include <ql/models/marketmodels/callability/lsstrategy.hpp>
#include <ql/models/marketmodels/callability/upperboundengine.hpp>
#include <ql/models/marketmodels/correlations/expcorrelations.hpp>
#include <ql/models/marketmodels/browniangenerators/mtbrowniangenerator.hpp>
#include <ql/models/marketmodels/browniangenerators/sobolbrowniangenerator.hpp>
#include <ql/models/marketmodels/evolvers/lognormalfwdratepc.hpp>
#include <ql/models/marketmodels/evolvers/lognormalfwdrateeuler.hpp>
#include <ql/models/marketmodels/pathwisegreeks/bumpinstrumentjacobian.hpp>
#include <ql/models/marketmodels/utilities.hpp>
#include <ql/methods/montecarlo/genericlsregression.hpp>
#include <ql/legacy/libormarketmodels/lmlinexpcorrmodel.hpp>
#include <ql/legacy/libormarketmodels/lmextlinexpvolmodel.hpp>
#include <ql/time/schedule.hpp>
#include <ql/time/calendars/nullcalendar.hpp>
#include <ql/time/daycounters/simpledaycounter.hpp>
#include <ql/pricingengines/blackformula.hpp>
#include <ql/pricingengines/blackcalculator.hpp>
#include <ql/utilities/dataformatters.hpp>
#include <ql/math/integrals/segmentintegral.hpp>
#include <ql/math/statistics/convergencestatistics.hpp>
#include <ql/termstructures/volatility/abcd.hpp>
#include <ql/termstructures/volatility/abcdcalibration.hpp>
#include <ql/math/optimization/simplex.hpp>
#include <ql/quotes/simplequote.hpp>
#include <sstream>
#include <iostream>
#include <ctime>

using namespace QuantLib;

std::vector<std::vector<Matrix>>
theVegaBumps(bool factorwiseBumping, const ext::shared_ptr<MarketModel>& marketModel, bool doCaps) {
    Real multiplierCutOff = 50.0;
    Real projectionTolerance = 1E-4;
    Size numberRates= marketModel->numberOfRates();

    std::vector<VolatilityBumpInstrumentJacobian::Cap> caps;

    if (doCaps)
    {

        Rate capStrike = marketModel->initialRates()[0];

        for (Size i=0; i< numberRates-1; i=i+1)
        {
            VolatilityBumpInstrumentJacobian::Cap nextCap;
            nextCap.startIndex_ = i;
            nextCap.endIndex_ = i+1;
            nextCap.strike_ = capStrike;
            caps.push_back(nextCap);
        }


    }

    std::vector<VolatilityBumpInstrumentJacobian::Swaption> swaptions(numberRates);

    for (Size i=0; i < numberRates; ++i)
    {
        swaptions[i].startIndex_ = i;
        swaptions[i].endIndex_ = numberRates;

    }

    VegaBumpCollection possibleBumps(marketModel,
        factorwiseBumping);

    OrthogonalizedBumpFinder  bumpFinder(possibleBumps,
        swaptions,
        caps,
        multiplierCutOff, // if vector length grows by more than this discard
        projectionTolerance);      // if vector projection before scaling less than this discard

    std::vector<std::vector<Matrix>> theBumps;

    bumpFinder.GetVegaBumps(theBumps);

    return theBumps;

}

int Bermudan()
{

    Size numberRates =20;
    Real accrual = 0.5;
    Real firstTime = 0.5;

    std::vector<Real> rateTimes(numberRates+1);
    for (Size i=0; i < rateTimes.size(); ++i)
        rateTimes[i] = firstTime + i*accrual;

    std::vector<Real> paymentTimes(numberRates);
    std::vector<Real> accruals(numberRates,accrual);
    for (Size i=0; i < paymentTimes.size(); ++i)
        paymentTimes[i] = firstTime + (i+1)*accrual;

    Real fixedRate = 0.05;
    std::vector<Real> strikes(numberRates,fixedRate);
    Real receive = -1.0;

    // 0. a payer swap
    MultiStepSwap payerSwap(rateTimes, accruals, accruals, paymentTimes,
        fixedRate, true);

    // 1. the equivalent receiver swap
    MultiStepSwap receiverSwap(rateTimes, accruals, accruals, paymentTimes,
        fixedRate, false);

    //exercise schedule, we can exercise on any rate time except the last one
    std::vector<Rate> exerciseTimes(rateTimes);
    exerciseTimes.pop_back();

    // naive exercise strategy, exercise above a trigger level
    std::vector<Rate> swapTriggers(exerciseTimes.size(), fixedRate);
    SwapRateTrigger naifStrategy(rateTimes, swapTriggers, exerciseTimes);

    // Longstaff-Schwartz exercise strategy
    std::vector<std::vector<NodeData>> collectedData;
    std::vector<std::vector<Real>> basisCoefficients;

    // control that does nothing, need it because some control is expected
    NothingExerciseValue control(rateTimes);

//    SwapForwardBasisSystem basisSystem(rateTimes,exerciseTimes);
    SwapBasisSystem basisSystem(rateTimes,exerciseTimes);

    // rebate that does nothing, need it because some rebate is expected
    // when you break a swap nothing happens.
    NothingExerciseValue nullRebate(rateTimes);

    CallSpecifiedMultiProduct dummyProduct =
        CallSpecifiedMultiProduct(receiverSwap, naifStrategy,
        ExerciseAdapter(nullRebate));

    const EvolutionDescription& evolution = dummyProduct.evolution();

    // parameters for models
    Size seed = 12332; // for Sobol generator
    Size trainingPaths = 65536;
    Size paths = 16384;
    Size vegaPaths = 16384*64;

    std::cout << "training paths, " << trainingPaths << "\n";
    std::cout << "paths, " << paths << "\n";
    std::cout << "vega Paths, " << vegaPaths << "\n";
#ifdef _DEBUG
   trainingPaths = 512;
  paths = 1024;
  vegaPaths = 1024;
#endif

    // set up a calibration, this would typically be done by using a calibrator

    Real rateLevel =0.05;

    Real initialNumeraireValue = 0.95;

    Real volLevel = 0.11;
    Real beta = 0.2;
    Real gamma = 1.0;
    Size numberOfFactors = std::min<Size>(5,numberRates);

    Spread displacementLevel =0.02;

    // set up vectors
    std::vector<Rate> initialRates(numberRates,rateLevel);
    std::vector<Volatility> volatilities(numberRates, volLevel);
    std::vector<Spread> displacements(numberRates, displacementLevel);

    ExponentialForwardCorrelation correlations(
        rateTimes,volLevel, beta,gamma);

    FlatVol  calibration(
        volatilities,
        ext::make_shared<ExponentialForwardCorrelation>(correlations),
        evolution,
        numberOfFactors,
        initialRates,
        displacements);

    auto marketModel = ext::make_shared<FlatVol>(calibration);

    // we use a factory since there is data that will only be known later
    SobolBrownianGeneratorFactory generatorFactory(
        SobolBrownianGenerator::Diagonal, seed);

    std::vector<Size> numeraires( moneyMarketMeasure(evolution));

    // the evolver will actually evolve the rates
    LogNormalFwdRatePc  evolver(marketModel,
        generatorFactory,
        numeraires   // numeraires for each step
        );

    auto evolverPtr = ext::make_shared<LogNormalFwdRatePc>(evolver);

    int t1= clock();

    // gather data before computing exercise strategy
    collectNodeData(evolver,
        receiverSwap,
        basisSystem,
        nullRebate,
        control,
        trainingPaths,
        collectedData);

    int t2 = clock();

    // calculate the exercise strategy's coefficients
    genericLongstaffSchwartzRegression(collectedData,
        basisCoefficients);

    // turn the coefficients into an exercise strategy
    LongstaffSchwartzExerciseStrategy exerciseStrategy(
        basisSystem, basisCoefficients,
        evolution, numeraires,
        nullRebate, control);

    //  bermudan swaption to enter into the payer swap
    CallSpecifiedMultiProduct bermudanProduct =
        CallSpecifiedMultiProduct(
        MultiStepNothing(evolution),
        exerciseStrategy, payerSwap);

    //  callable receiver swap
    CallSpecifiedMultiProduct callableProduct =
        CallSpecifiedMultiProduct(
        receiverSwap, exerciseStrategy,
        ExerciseAdapter(nullRebate));

    // lower bound: evolve all 4 products togheter
    MultiProductComposite allProducts;
    allProducts.add(payerSwap);
    allProducts.add(receiverSwap);
    allProducts.add(bermudanProduct);
    allProducts.add(callableProduct);
    allProducts.finalize();

    AccountingEngine accounter(evolverPtr,
        Clone<MarketModelMultiProduct>(allProducts),
        initialNumeraireValue);

    SequenceStatisticsInc stats;

    accounter.multiplePathValues (stats,paths);

    int t3 = clock();

    std::vector<Real> means(stats.mean());

    for (Real mean : means)
        std::cout << mean << "\n";

    std::cout << " time to build strategy, " << (t2-t1)/static_cast<Real>(CLOCKS_PER_SEC)<< ", seconds.\n";
    std::cout << " time to price, " << (t3-t2)/static_cast<Real>(CLOCKS_PER_SEC)<< ", seconds.\n";

    // vegas

    // do it twice once with factorwise bumping, once without
    Size pathsToDoVegas = vegaPaths;

    for (Size i=0; i < 4; ++i)
    {

        bool allowFactorwiseBumping = i % 2 > 0 ;

        bool doCaps = i / 2 > 0 ;





        LogNormalFwdRateEuler evolverEuler(marketModel,
            generatorFactory,
            numeraires
            ) ;

        MarketModelPathwiseSwap receiverPathwiseSwap(  rateTimes,
            accruals,
            strikes,
            receive);
        Clone<MarketModelPathwiseMultiProduct> receiverPathwiseSwapPtr(receiverPathwiseSwap.clone());

        //  callable receiver swap
        CallSpecifiedPathwiseMultiProduct callableProductPathwise(receiverPathwiseSwapPtr,
            exerciseStrategy);

        Clone<MarketModelPathwiseMultiProduct> callableProductPathwisePtr(callableProductPathwise.clone());


        std::vector<std::vector<Matrix>> theBumps(theVegaBumps(allowFactorwiseBumping,
            marketModel,
            doCaps));

        PathwiseVegasOuterAccountingEngine
            accountingEngineVegas(ext::make_shared<LogNormalFwdRateEuler>(evolverEuler),
            callableProductPathwisePtr,
            marketModel,
            theBumps,
            initialNumeraireValue);

        std::vector<Real> values,errors;

        accountingEngineVegas.multiplePathValues(values,errors,pathsToDoVegas);


        std::cout << "vega output \n";
        std::cout << " factorwise bumping " << allowFactorwiseBumping << "\n";
        std::cout << " doCaps " << doCaps << "\n";



        Size r=0;

        std::cout << " price estimate, " << values[r++] << "\n";

        for (Size i=0; i < numberRates; ++i, ++r)
            std::cout << " Delta, " << i << ", " << values[r] << ", " << errors[r] << "\n";

        Real totalVega = 0.0;

        for (; r < values.size(); ++r)
        {
            std::cout << " vega, " << r - 1 -  numberRates<< ", " << values[r] << " ," << errors[r] << "\n";
            totalVega +=  values[r];
        }

        std::cout << " total Vega, " << totalVega << "\n";
    }

    // upper bound

    MTBrownianGeneratorFactory uFactory(seed+142);

    auto upperEvolver = ext::make_shared<LogNormalFwdRatePc>(ext::make_shared<FlatVol>(calibration),
            uFactory,
            numeraires   // numeraires for each step
            );

    std::vector<ext::shared_ptr<MarketModelEvolver>> innerEvolvers;

    std::valarray<bool> isExerciseTime =   isInSubset(evolution.evolutionTimes(),    exerciseStrategy.exerciseTimes());

    for (Size s=0; s < isExerciseTime.size(); ++s)
    {
        if (isExerciseTime[s])
        {
            MTBrownianGeneratorFactory iFactory(seed+s);
            auto e = ext::make_shared<LogNormalFwdRatePc>(ext::make_shared<FlatVol>(calibration),
                    uFactory,
                    numeraires,  // numeraires for each step
                    s);

            innerEvolvers.push_back(e);
        }
    }

    UpperBoundEngine uEngine(upperEvolver,  // does outer paths
                             innerEvolvers, // for sub-simulations that do continuation values
                             receiverSwap,
                             nullRebate,
                             receiverSwap,
                             nullRebate,
                             exerciseStrategy,
                             initialNumeraireValue);

    Statistics uStats;
    Size innerPaths = 255;
    Size outerPaths =256;

    int t4 = clock();

    uEngine.multiplePathValues(uStats,outerPaths,innerPaths);
    Real upperBound = uStats.mean();
    Real upperSE = uStats.errorEstimate();

    int t5=clock();

    std::cout << " Upper - lower is, " << upperBound << ", with standard error " << upperSE << "\n";
    std::cout << " time to compute upper bound is,  " << (t5-t4)/static_cast<Real>(CLOCKS_PER_SEC) << ", seconds.\n";

    return 0;
}

int InverseFloater(Real rateLevel)
{

    Size numberRates =20;
    Real accrual = 0.5;
    Real firstTime = 0.5;

    Real strike =0.15;
    Real fixedMultiplier = 2.0;
    Real floatingSpread =0.0;
    bool payer = true;


    std::vector<Real> rateTimes(numberRates+1);
    for (Size i=0; i < rateTimes.size(); ++i)
        rateTimes[i] = firstTime + i*accrual;

    std::vector<Real> paymentTimes(numberRates);
    std::vector<Real> accruals(numberRates,accrual);
    std::vector<Real> fixedStrikes(numberRates,strike);
    std::vector<Real> floatingSpreads(numberRates,floatingSpread);
    std::vector<Real> fixedMultipliers(numberRates,fixedMultiplier);

    for (Size i=0; i < paymentTimes.size(); ++i)
        paymentTimes[i] = firstTime + (i+1)*accrual;

  MultiStepInverseFloater inverseFloater(
                                                        rateTimes,
                                                        accruals,
                                                         accruals,
                                                        fixedStrikes,
                                                        fixedMultipliers,
                                                        floatingSpreads,
                                                         paymentTimes,
                                                         payer);




    //exercise schedule, we can exercise on any rate time except the last one
    std::vector<Rate> exerciseTimes(rateTimes);
    exerciseTimes.pop_back();

    // naive exercise strategy, exercise above a trigger level
    Real trigger =0.05;
    std::vector<Rate> swapTriggers(exerciseTimes.size(), trigger);
    SwapRateTrigger naifStrategy(rateTimes, swapTriggers, exerciseTimes);

    // Longstaff-Schwartz exercise strategy
    std::vector<std::vector<NodeData>> collectedData;
    std::vector<std::vector<Real>> basisCoefficients;

    // control that does nothing, need it because some control is expected
    NothingExerciseValue control(rateTimes);

   SwapForwardBasisSystem basisSystem(rateTimes,exerciseTimes);
//    SwapBasisSystem basisSystem(rateTimes,exerciseTimes);



    // rebate that does nothing, need it because some rebate is expected
    // when you break a swap nothing happens.
    NothingExerciseValue nullRebate(rateTimes);

    CallSpecifiedMultiProduct dummyProduct =
        CallSpecifiedMultiProduct(inverseFloater, naifStrategy,
        ExerciseAdapter(nullRebate));

    const EvolutionDescription& evolution = dummyProduct.evolution();


    // parameters for models


    Size seed = 12332; // for Sobol generator
    Size trainingPaths = 65536;
    Size paths = 65536;
    Size vegaPaths =16384;

#ifdef _DEBUG
   trainingPaths = 8192;
  paths = 8192;
  vegaPaths = 1024;
#endif


    std::cout <<  " inverse floater \n";
    std::cout << " fixed strikes :  "  << strike << "\n";
    std::cout << " number rates :  " << numberRates << "\n";

    std::cout << "training paths, " << trainingPaths << "\n";
    std::cout << "paths, " << paths << "\n";
    std::cout << "vega Paths, " << vegaPaths << "\n";


    // set up a calibration, this would typically be done by using a calibrator



    //Real rateLevel =0.08;

    std::cout << " rate level " <<  rateLevel << "\n";

    Real initialNumeraireValue = 0.95;

    Real volLevel = 0.11;
    Real beta = 0.2;
    Real gamma = 1.0;
    Size numberOfFactors = std::min<Size>(5,numberRates);

    Spread displacementLevel =0.02;

    // set up vectors
    std::vector<Rate> initialRates(numberRates,rateLevel);
    std::vector<Volatility> volatilities(numberRates, volLevel);
    std::vector<Spread> displacements(numberRates, displacementLevel);

    ExponentialForwardCorrelation correlations(
        rateTimes,volLevel, beta,gamma);




    FlatVol  calibration(
        volatilities,
        ext::make_shared<ExponentialForwardCorrelation>(correlations),
        evolution,
        numberOfFactors,
        initialRates,
        displacements);

    auto marketModel = ext::make_shared<FlatVol>(calibration);

    // we use a factory since there is data that will only be known later
    SobolBrownianGeneratorFactory generatorFactory(
        SobolBrownianGenerator::Diagonal, seed);

    std::vector<Size> numeraires( moneyMarketMeasure(evolution));

    // the evolver will actually evolve the rates
    LogNormalFwdRatePc  evolver(marketModel,
        generatorFactory,
        numeraires   // numeraires for each step
        );

    auto evolverPtr = ext::make_shared<LogNormalFwdRatePc>(evolver);

    int t1= clock();

    // gather data before computing exercise strategy
    collectNodeData(evolver,
        inverseFloater,
        basisSystem,
        nullRebate,
        control,
        trainingPaths,
        collectedData);

    int t2 = clock();


    // calculate the exercise strategy's coefficients
    genericLongstaffSchwartzRegression(collectedData,
        basisCoefficients);


    // turn the coefficients into an exercise strategy
    LongstaffSchwartzExerciseStrategy exerciseStrategy(
        basisSystem, basisCoefficients,
        evolution, numeraires,
        nullRebate, control);


    //  callable receiver swap
    CallSpecifiedMultiProduct callableProduct =
        CallSpecifiedMultiProduct(
        inverseFloater, exerciseStrategy,
        ExerciseAdapter(nullRebate));

     MultiProductComposite allProducts;
    allProducts.add(inverseFloater);
    allProducts.add(callableProduct);
    allProducts.finalize();


    AccountingEngine accounter(evolverPtr,
        Clone<MarketModelMultiProduct>(allProducts),
        initialNumeraireValue);

    SequenceStatisticsInc stats;

    accounter.multiplePathValues (stats,paths);

    int t3 = clock();

    std::vector<Real> means(stats.mean());

    for (Real mean : means)
        std::cout << mean << "\n";

    std::cout << " time to build strategy, " << (t2-t1)/static_cast<Real>(CLOCKS_PER_SEC)<< ", seconds.\n";
    std::cout << " time to price, " << (t3-t2)/static_cast<Real>(CLOCKS_PER_SEC)<< ", seconds.\n";

    // vegas

    // do it twice once with factorwise bumping, once without
    Size pathsToDoVegas = vegaPaths;

    for (Size i=0; i < 4; ++i)
    {

        bool allowFactorwiseBumping = i % 2 > 0 ;

        bool doCaps = i / 2 > 0 ;


        LogNormalFwdRateEuler evolverEuler(marketModel,
            generatorFactory,
            numeraires
            ) ;

        MarketModelPathwiseInverseFloater pathwiseInverseFloater(
                                                         rateTimes,
                                                         accruals,
                                                         accruals,
                                                         fixedStrikes,
                                                         fixedMultipliers,
                                                         floatingSpreads,
                                                         paymentTimes,
                                                         payer);

        Clone<MarketModelPathwiseMultiProduct> pathwiseInverseFloaterPtr(pathwiseInverseFloater.clone());

        //  callable inverse floater
        CallSpecifiedPathwiseMultiProduct callableProductPathwise(pathwiseInverseFloaterPtr,
                                                                                                                                               exerciseStrategy);

        Clone<MarketModelPathwiseMultiProduct> callableProductPathwisePtr(callableProductPathwise.clone());


        std::vector<std::vector<Matrix>> theBumps(theVegaBumps(allowFactorwiseBumping,
            marketModel,
            doCaps));

        PathwiseVegasOuterAccountingEngine
            accountingEngineVegas(ext::make_shared<LogNormalFwdRateEuler>(evolverEuler),
   //         pathwiseInverseFloaterPtr,
            callableProductPathwisePtr,
            marketModel,
            theBumps,
            initialNumeraireValue);

        std::vector<Real> values,errors;

        accountingEngineVegas.multiplePathValues(values,errors,pathsToDoVegas);


        std::cout << "vega output \n";
        std::cout << " factorwise bumping " << allowFactorwiseBumping << "\n";
        std::cout << " doCaps " << doCaps << "\n";



        Size r=0;

        std::cout << " price estimate, " << values[r++] << "\n";

        for (Size i=0; i < numberRates; ++i, ++r)
            std::cout << " Delta, " << i << ", " << values[r] << ", " << errors[r] << "\n";

        Real totalVega = 0.0;

        for (; r < values.size(); ++r)
        {
            std::cout << " vega, " << r - 1 -  numberRates<< ", " << values[r] << " ," << errors[r] << "\n";
            totalVega +=  values[r];
        }

        std::cout << " total Vega, " << totalVega << "\n";
    }

    // upper bound

    MTBrownianGeneratorFactory uFactory(seed+142);


    auto upperEvolver = ext::make_shared<LogNormalFwdRatePc>(ext::make_shared<FlatVol>(calibration),
            uFactory,
            numeraires   // numeraires for each step
            );

    std::vector<ext::shared_ptr<MarketModelEvolver>> innerEvolvers;

    std::valarray<bool> isExerciseTime =   isInSubset(evolution.evolutionTimes(),    exerciseStrategy.exerciseTimes());

    for (Size s=0; s < isExerciseTime.size(); ++s)
    {
        if (isExerciseTime[s])
        {
            MTBrownianGeneratorFactory iFactory(seed+s);
            auto e = ext::make_shared<LogNormalFwdRatePc>(ext::make_shared<FlatVol>(calibration),
                    uFactory,
                    numeraires ,  // numeraires for each step
                    s);

            innerEvolvers.push_back(e);
        }
    }



    UpperBoundEngine uEngine(upperEvolver,  // does outer paths
                             innerEvolvers, // for sub-simulations that do continuation values
                             inverseFloater,
                             nullRebate,
                             inverseFloater,
                             nullRebate,
                             exerciseStrategy,
                             initialNumeraireValue);

    Statistics uStats;
    Size innerPaths = 255;
    Size outerPaths =256;

    int t4 = clock();

    uEngine.multiplePathValues(uStats,outerPaths,innerPaths);
    Real upperBound = uStats.mean();
    Real upperSE = uStats.errorEstimate();

    int t5=clock();

    std::cout << " Upper - lower is, " << upperBound << ", with standard error " << upperSE << "\n";
    std::cout << " time to compute upper bound is,  " << (t5-t4)/static_cast<Real>(CLOCKS_PER_SEC) << ", seconds.\n";

    return 0;
}

int main()
{
    try {
        for (Size i=5; i < 10; ++i)
            InverseFloater(i/100.0);

        return 0;
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "unknown error" << std::endl;
        return 1;
    }
}

在这里插入图片描述

以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/767343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux模拟aix盘19c单机asm安装补丁

linux模拟盘aix盘vi /etc/rc.d/rc.local/bin/ln /dev/sda /dev/rhdisk2/bin/ln /dev/sdb /dev/rhdisk3 /bin/chown grid:oinstall /dev/rhdisk*chmod 660 /dev/rhdisk* 一、19c安装GI&#xff08;Standalone Oracle Restart&#xff09; su - grid配置环境变量vi .profileex…

红酒与摄影:捕捉酒香与光影的交融

在摄影的世界里&#xff0c;每一个画面都是一段故事&#xff0c;每一束光线都是情感的载体。当红酒遇上摄影&#xff0c;两者之间的交融&#xff0c;仿佛开启了一场关于色彩、光影与情感的视觉盛宴。今天&#xff0c;就让我们一起探索红酒与摄影的奇妙结合&#xff0c;感受雷盛…

为什么我感觉 C 语言在 Linux 下执行效率比 Windows 快得多?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;Windows的终端或者叫控制台…

反射--通俗易懂

一、反射(Reflection) 反射就是:加载类&#xff0c;并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等) 动态语言&#xff0c;是一类在运行时可以改变其结构的语言&#xff1a;例如新的函数、对象、甚至代码可以被引进&#xff0c;已有的函数可以被删除或是其他…

聊聊Redis持久化策略RDB

写在文章开头 为避免服务器宕机着情况导致redis内存数据库数据丢失&#xff0c;redis默认出通过rdb保证可靠性&#xff0c;本文将从源码的角度带读者了解rdb读写时机和写入流程。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核技术上作死的 java coder &#xff…

【D3.js in Action 3 精译】1.1.3 D3.js 的工作原理

译者注 上一节我们探讨了 D3.js 的适用场景——需要高度定制化、可以尽情释放想象力的复杂图表。这一节我们再跟随作者的视角&#xff0c;看看 D3.js 的工作原理究竟是怎样的。 1.1.3 D3.js 的工作原理 您可能已经体验过 D3 并且发现它不太容易上手。这也许是因为您把它当成了…

c++边界处理机制

1.vector std::vector&#xff1a;std::vector 是动态数组&#xff0c;它会在运行时动态地调整存储空间大小&#xff0c;因此当访问超出边界时&#xff0c;会触发运行时异常 std::out_of_range。可以通过try-catch块来捕获这种异常来处理越界访问。 #include <iostream>…

Mybatis数据封装

目录 解决方案&#xff1a; 1.起别名&#xff1a; 2.手动结果映射&#xff1a; 3.开启驼峰命名(推荐)&#xff1a; 我们看到查询返回的结果中大部分字段是有值的&#xff0c;但是deptId&#xff0c;createTime&#xff0c;updateTime这几个字段是没有值的&#xff0c;而数据…

项目管理系统厂商:奥博思发布《项目管理系统助力 IPD 高效落地》演讲

一场题为&#xff1a;“标准为基&#xff0c;项目之上 &#xff0c;持续提升 PMO 卓越中心”的全国 PMO 专业人士年度盛会在京召开。会议围绕 PMO 卓越中心能力提升、项目管理标准化、项目管理体系建设等核心话题力邀业界专家、卓有建树的 PMO 实践精英来演讲、交流、分享。 奥…

无人机在航拍领域有哪些独特优势?

那肯定是便宜啊&#xff0c;相比传统的飞机或直升机航拍作业&#xff0c;无人机航拍具有更快的响应速度和更低的成本。无人机可以随时随地进行起降&#xff0c;并在短时间内完成航拍任务&#xff0c;极大地提高了作业效率。同时&#xff0c;无人机的运营成本相对较低&#xff0…

C语言快速学习笔记

学习网站&#xff1a;C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com) 这个网站知识完整&#xff0c;讲解清晰。 在线C语言编程工具&#xff1a;菜鸟教程在线编辑器 (runoob.com) 国外学习网站&#xff1a;C语言介…

nanodiffusion代码逐行理解之time embedding

目录 一、time embedding调用过程二、time embedding定义过程三、PositionalEmbedding定义过程 time embedding本质上就是把时间步t转换为指定维度的嵌入向量&#xff0c;这个向量由时间步 &#xff0c;向量维度&#xff0c;周期等参数决定&#xff0c;可以简单理解为根据时间步…

说说硬件调试中发现的那些低级错误

高速先生成员--周伟 最近遇到很多debug相关的咨询&#xff0c;曾经我们说过&#xff0c;我们做过的板子越多&#xff0c;遇到问题的概率也越多&#xff0c;很多别人没遇到过的问题&#xff0c;说不定我们早就触过雷&#xff0c;从而类似的问题形成经验总结&#xff0c;就不会再…

Python知识点背诵手册,超详细知识梳理

一、手册介绍 《Python知识点背诵手册》是一份详尽的Python学习资料&#xff0c;旨在帮助学习者系统地掌握Python语言的基础知识和进阶技能。该手册将Python的所有关键语法和概念进行了精炼的总结&#xff0c;并以易于理解和记忆的方式呈现。以下是手册的主要特点和内容概述&a…

石墨烯分散液制备方法众多 应用领域广泛

石墨烯分散液制备方法众多 应用领域广泛 石墨烯分散液指将石墨烯纳米片均匀分散在特定溶剂中制成的溶液。石墨烯分散液具有化学稳定性好、生物相容性好、热稳定性好等优势&#xff0c;未来有望在涂料、纤维制品、电池制造、油墨等领域获得广泛应用。 石墨烯分散液以石墨…

AWS云创建EC2与所需要注意事项

AWS云&#xff08;Amazon Web Services&#xff09;作为全球领先的云计算服务提供商&#xff0c;为用户提供了丰富的云计算服务。其中&#xff0c;EC2&#xff08;Elastic Compute Cloud&#xff09;是AWS云中的一项重要服务&#xff0c;可以帮助用户轻松创建和管理虚拟服务器实…

从0开始搭建vue项目

#先查下电脑有没有安装过node和npm node -v npm -v #安装vue npm install -g vue #安装webpack npm install webpack -g 都安装好后&#xff0c;进入你想创建的文件夹内 创建名字&#xff1a;vue init webpack <project_name> 就默认回车 然后根据项目需求Y/n 比如…

提升学历的最佳选择:深职训学校的成人大专远程教育

你有没有想过&#xff0c;一边工作一边提升自己的学历&#xff1f;很多人都觉得这是一件不可能完成的任务&#xff0c;但今天我要告诉你&#xff0c;其实有一个不错的选择&#xff0c;那就是深职训学校的成人大专远程教育。 深圳提升学历www.shenzhixun.com 为什么要选择成人大…

难道 Java 已经过时了?

当一门技术已经存在许多年了&#xff0c;它可能会失去竞争力&#xff0c;而后黯然退场&#xff0c;默默地离开&#xff0c;这对大部分的人来说就已经算是过时了。 Java 于 1995 年正式上线&#xff0c;至今已经走过了 27 个年头&#xff0c;在众多编程技术里算是年龄比较大的语…

开箱机视觉系统大揭秘:如何轻松辨别千差万别的包装?

在现代物流仓储领域&#xff0c;开箱机作为提升作业效率的关键设备&#xff0c;正日益受到行业的重视。而开箱机的视觉系统更是其十分强大&#xff0c;能够准确辨认不同包装&#xff0c;确保物流作业的高效与准确。与星派深入探究一下开箱机视觉系统是如何工作的&#xff0c;以…