Esempio n. 1
0
RcppExport SEXP yearFraction(SEXP startDates, SEXP endDates, SEXP dayCounter){

    try {
        
        Rcpp::DateVector s = Rcpp::DateVector(startDates);
        Rcpp::DateVector e = Rcpp::DateVector(endDates);
        
		Rcpp::NumericVector dc(dayCounter);
        int n = dc.size();
        std::vector<double> result(n);
        for (int i=0; i< n; i++){
            QuantLib::Date d1( dateFromR(s[i]) );
            QuantLib::Date d2( dateFromR(e[i]) );            
            QuantLib::DayCounter counter = getDayCounter(dc[i]);
            result[i] = (double)counter.yearFraction(d1, d2);            
        }        
        return Rcpp::wrap(result);

    } catch(std::exception &ex) { 
        forward_exception_to_r(ex); 
    } catch(...) { 
        ::Rf_error("c++ exception (unknown reason)"); 
    }

    return R_NilValue;
}
Esempio n. 2
0
RcppExport SEXP cfamounts(SEXP params){
       
    SEXP rl=R_NilValue;
    char* exceptionMesg=NULL;
    try{
        RcppParams rparam(params); 

        QuantLib::Date maturity(dateFromR(rparam.getDateValue("Maturity")));
        QuantLib::Date settle(dateFromR(rparam.getDateValue("Settle")));
        QuantLib::Date issue(dateFromR(rparam.getDateValue("IssueDate")));

        double rate = rparam.getDoubleValue("CouponRate");
        std::vector<double> rateVec(1, rate);
        double faceAmount = rparam.getDoubleValue("Face");
        double period = rparam.getDoubleValue("Period");
        double basis = rparam.getDoubleValue("Basis");
        DayCounter dayCounter = getDayCounter(basis);
        Frequency freq = getFrequency(period);
        Period p(freq);
        double EMR = rparam.getDoubleValue("EMR");
        Calendar calendar=UnitedStates(UnitedStates::GovernmentBond);
        
        
        Schedule sch(settle, maturity, p, calendar, 
                     Unadjusted, Unadjusted, DateGeneration::Backward, 
                     (EMR == 1)? true : false);

        FixedRateBond bond(1, faceAmount, sch, rateVec, dayCounter, Following,
                           100, issue);

        //cashflow
        int numCol = 2;
        std::vector<std::string> colNames(numCol);
        colNames[0] = "Date";
        colNames[1] = "Amount";
        RcppFrame frame(colNames);
        
        Leg bondCashFlow = bond.cashflows();
        for (unsigned int i = 0; i< bondCashFlow.size(); i++){
            std::vector<ColDatum> row(numCol);
            Date d = bondCashFlow[i]->date();
            row[0].setDateValue(RcppDate(d.month(), d.dayOfMonth(), d.year()));
            row[1].setDoubleValue(bondCashFlow[i]->amount());
            frame.addRow(row);
        }
                     
        RcppResultSet rs;
        rs.add("cashFlow", frame);
        rl = rs.getReturnList();

    } catch(std::exception& ex) {
        exceptionMesg = copyMessageToR(ex.what());
    } catch(...) {
        exceptionMesg = copyMessageToR("unknown reason");
    }   
    if(exceptionMesg != NULL)
        Rf_error(exceptionMesg);    
    return rl;
}
Esempio n. 3
0
RcppExport SEXP cfdates(SEXP params){
    SEXP rl = R_NilValue;
    char* exceptionMesg = NULL;
    try {
        RcppParams rparam(params);
        
        double basis = rparam.getDoubleValue("dayCounter");
        DayCounter dayCounter = getDayCounter(basis);
        double p = rparam.getDoubleValue("period");        
        Frequency freq = getFrequency(p);
        Period period(freq);
        double emr = rparam.getDoubleValue("emr");

        bool endOfMonth = false;
        if (emr == 1) endOfMonth = true;

        QuantLib::Date d1(dateFromR(rparam.getDateValue("settle")));        
        QuantLib::Date d2(dateFromR(rparam.getDateValue("maturity")));
        Calendar calendar=UnitedStates(UnitedStates::GovernmentBond); 
        
        Schedule sch(d1, d2, period, calendar, Unadjusted,
                     Unadjusted, DateGeneration::Backward, endOfMonth);

        //cfdates
        int numCol = 1;
        std::vector<std::string> colNames(numCol);
        colNames[0] = "Date";        
        RcppFrame frame(colNames);
        
        std::vector<QuantLib::Date> dates = sch.dates();
        for (unsigned int i = 0; i< dates.size(); i++){
            std::vector<ColDatum> row(numCol);
            Date d = dates[i];
            row[0].setDateValue(RcppDate(d.month(), d.dayOfMonth(), d.year()));           
            frame.addRow(row);
        }
        RcppResultSet rs;
        rs.add("", frame);
        rl = rs.getReturnList();
    } 
    catch(std::exception& ex) {
        exceptionMesg = copyMessageToR(ex.what());
    } catch(...) {
        exceptionMesg = copyMessageToR("unknown reason");
    }
    if(exceptionMesg != NULL)
        Rf_error(exceptionMesg);
    
    return rl;
}
Esempio n. 4
0
// [[Rcpp::export]]
Rcpp::List calibrateHullWhiteUsingSwapsEngine(SEXP termStrcDateVec,
                                              SEXP termStrcZeroVec,
                                              SEXP swapDataDF,
                                              SEXP iborDateVec,
                                              SEXP iborZeroVec,
                                              std::string iborType,
                                              QuantLib::Date evalDate) {

    QuantLib::Settings::instance().evaluationDate() = evalDate;

    //set up the HullWhite model       
    QuantLib::Handle<QuantLib::YieldTermStructure> 
        term(rebuildCurveFromZeroRates(termStrcDateVec, termStrcZeroVec));
    boost::shared_ptr<QuantLib::HullWhite> model(new QuantLib::HullWhite(term));        
        
    //set up ibor index
    QuantLib::Handle<QuantLib::YieldTermStructure> 
        indexStrc(rebuildCurveFromZeroRates(iborDateVec, iborZeroVec));    
    boost::shared_ptr<QuantLib::IborIndex> index = buildIborIndex(iborType, indexStrc);
    //process capDataDF
    boost::shared_ptr<QuantLib::PricingEngine> 
        engine(new QuantLib::JamshidianSwaptionEngine(model));
    std::vector<boost::shared_ptr <QuantLib::CalibrationHelper> > swaps;

    Rcpp::DataFrame swapDF(swapDataDF);
    Rcpp::NumericVector i0v = swapDF[0];
    Rcpp::CharacterVector  s1v = swapDF[1];
    Rcpp::NumericVector i2v = swapDF[2];
    Rcpp::CharacterVector s3v = swapDF[3];
    Rcpp::NumericVector d4v = swapDF[4];
    Rcpp::NumericVector i5v = swapDF[5];
    Rcpp::CharacterVector s6v = swapDF[6];
    Rcpp::NumericVector i7v = swapDF[7];
    Rcpp::NumericVector i8v = swapDF[8];
    //std::vector<std::vector<ColDatum> > table = swapDF.getTableData();
    //int nrow = table.size();
    int nrow = i0v.size();
    for (int row=0; row<nrow;row++) {
        QuantLib::Period maturity = periodByTimeUnit(i0v[row], 
                                                     Rcpp::as<std::string>(s1v[row]));
        QuantLib::Period length = periodByTimeUnit(i0v[row], 
                                                   Rcpp::as<std::string>(s3v[row]));
        
        boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(d4v[row]));
        
        QuantLib::Period fixedLegTenor = periodByTimeUnit(i5v[row], 
                                                          Rcpp::as<std::string>(s6v[row]));
        QuantLib::DayCounter fixedLegDayCounter = getDayCounter(i7v[row]);
        QuantLib::DayCounter floatingLegDayCounter = getDayCounter(i8v[row]);

        boost::shared_ptr<QuantLib::CalibrationHelper> 
            helper(new QuantLib::SwaptionHelper(maturity, length, 
                                                QuantLib::Handle<QuantLib::Quote>(vol), 
                                                index, 
                                                fixedLegTenor, 
                                                fixedLegDayCounter,
                                                floatingLegDayCounter,
                                                term));
        helper->setPricingEngine(engine);                
        swaps.push_back(helper);
    }
        
    //calibrate the data
    QuantLib::LevenbergMarquardt optimizationMethod(1.0e-8,1.0e-8,1.0e-8);
    QuantLib::EndCriteria endCriteria(10000, 100, 1e-6, 1e-8, 1e-8);
    model->calibrate(swaps, optimizationMethod, endCriteria);
    //EndCriteria::Type ecType = model->endCriteria();
    //return the result
    QuantLib::Array xMinCalculated = model->params();

    return Rcpp::List::create(Rcpp::Named("alpha") = xMinCalculated[0],
                              Rcpp::Named("sigma") = xMinCalculated[1]);
}
Esempio n. 5
0
// [[Rcpp::export]]
Rcpp::List calibrateHullWhiteUsingCapsEngine(SEXP termStrcDateVec,
                                             SEXP termStrcZeroVec,
                                             SEXP capDataDF,
                                             SEXP iborDateVec,
                                             SEXP iborZeroVec,
                                             std::string iborType,
                                             QuantLib::Date evalDate) {
	
    QuantLib::Settings::instance().evaluationDate() = evalDate;

    QuantLib::Handle<QuantLib::YieldTermStructure> 
        term(rebuildCurveFromZeroRates(termStrcDateVec, termStrcZeroVec));
        
    //set up ibor index
    QuantLib::Handle<QuantLib::YieldTermStructure> 
        indexStrc(rebuildCurveFromZeroRates(iborDateVec, iborZeroVec));    
    boost::shared_ptr<QuantLib::IborIndex> index = buildIborIndex(iborType, indexStrc);
    //process capDataDF
    std::vector<boost::shared_ptr <QuantLib::CalibrationHelper> > caps;

    Rcpp::DataFrame capDF(capDataDF);
    Rcpp::NumericVector i0v = capDF[0];
    Rcpp::CharacterVector  s1v = capDF[1];
    Rcpp::NumericVector d2v = capDF[2];
    Rcpp::NumericVector i3v = capDF[3];
    Rcpp::NumericVector i4v = capDF[4];
    Rcpp::NumericVector i5v = capDF[5];
    //std::vector<std::vector<ColDatum> > table = capDF.getTableData();
    //int nrow = table.size();
    int nrow = i0v.size();
    for (int row=0; row<nrow;row++) {
        QuantLib::Period p = periodByTimeUnit(i0v[row], Rcpp::as<std::string>(s1v[row]));
        boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(d2v[row]));
        QuantLib::DayCounter dc = getDayCounter(i4v[row]);
        boost::shared_ptr<QuantLib::CalibrationHelper> 
            helper(new QuantLib::CapHelper(p, QuantLib::Handle<QuantLib::Quote>(vol), index, 
                                           getFrequency(i3v[row]),
                                           dc,
                                           (i5v[row]==1) ? true : false,
                                           term));
        boost::shared_ptr<QuantLib::BlackCapFloorEngine> 
            engine(new QuantLib::BlackCapFloorEngine(term, d2v[row]));
        
        helper->setPricingEngine(engine);                
        caps.push_back(helper);
    }
        
    //set up the HullWhite model
    boost::shared_ptr<QuantLib::HullWhite> model(new QuantLib::HullWhite(term));
        
    //calibrate the data
    QuantLib::LevenbergMarquardt optimizationMethod(1.0e-8,1.0e-8,1.0e-8);
    QuantLib::EndCriteria endCriteria(10000, 100, 1e-6, 1e-8, 1e-8);
    model->calibrate(caps, optimizationMethod, endCriteria);
    //EndCriteria::Type ecType = model->endCriteria();
    //return the result
    QuantLib::Array xMinCalculated = model->params();

    return Rcpp::List::create(Rcpp::Named("alpha") = xMinCalculated[0],
                              Rcpp::Named("sigma") = xMinCalculated[1]);
}
Esempio n. 6
0
// [[Rcpp::export]]
Rcpp::List affineWithRebuiltCurveEngine(Rcpp::List rparam,
                                        Rcpp::List legparams,
                                        std::vector<QuantLib::Date> dateVec, 
                                        std::vector<double> zeroVec,
                                        Rcpp::NumericVector swaptionMat,
                                        Rcpp::NumericVector swapLengths,
                                        Rcpp::NumericVector swaptionVols) {
    
    // std::vector<std::string> tsnames = tslist.names();

    
    QuantLib::Size i;
    //int *swaptionMat=0, *swapLengths=0;
    //double **swaptionVols=0;

    double notional = 10000; // prices in basis points

    QuantLib::Date todaysDate(Rcpp::as<QuantLib::Date>(rparam["tradeDate"])); 
    QuantLib::Date settlementDate(Rcpp::as<QuantLib::Date>(rparam["settleDate"])); 
    QuantLib::Date startDate(Rcpp::as<QuantLib::Date>(rparam["startDate"])); 
    QuantLib::Date maturity(Rcpp::as<QuantLib::Date>(rparam["maturity"])); 
    bool payfix = Rcpp::as<bool>(rparam["payFixed"]);
    bool european = Rcpp::as<bool>(rparam["european"]);
    
    
    //cout << "TradeDate: " << todaysDate << endl << "Settle: " << settlementDate << endl;
    
    RQLContext::instance().settleDate = settlementDate;
    QuantLib::Settings::instance().evaluationDate() = todaysDate;
    
    // initialise from the singleton instance
    QuantLib::Calendar calendar = RQLContext::instance().calendar;
    //Integer fixingDays = RQLContext::instance().fixingDays;
    
    double strike = Rcpp::as<double>(rparam["strike"]);
    std::string method = Rcpp::as<std::string>(rparam["method"]);

    QuantLib::Handle<QuantLib::YieldTermStructure> 
        rhTermStructure(rebuildCurveFromZeroRates(dateVec, zeroVec));
    
    // Get swaption maturities
    //Rcpp::NumericVector swaptionMat(maturities);
    int numRows = swaptionMat.size(); 

    // Create dummy swap to get schedules.
    QuantLib::Frequency fixedLegFrequency = getFrequency(Rcpp::as<double>(legparams["fixFreq"]));
    QuantLib::BusinessDayConvention fixedLegConvention = QuantLib::Unadjusted;
    QuantLib::BusinessDayConvention floatingLegConvention = QuantLib::ModifiedFollowing;
    QuantLib::DayCounter swFixedLegDayCounter = getDayCounter(Rcpp::as<double>(legparams["dayCounter"]));
    boost::shared_ptr<QuantLib::IborIndex> swFloatingLegIndex(new QuantLib::Euribor(QuantLib::Period(Rcpp::as<int>(legparams["floatFreq"]),QuantLib::Months),rhTermStructure));


    QuantLib::Rate dummyFixedRate = 0.03;

    QuantLib::Schedule fixedSchedule(startDate,maturity,
                                     QuantLib::Period(fixedLegFrequency),calendar,
                                     fixedLegConvention,fixedLegConvention,
                                     QuantLib::DateGeneration::Forward,false);
    QuantLib::Schedule floatSchedule(startDate,maturity,QuantLib::Period(Rcpp::as<int>(legparams["floatFreq"]),QuantLib::Months),
                                     calendar,
                                     floatingLegConvention,floatingLegConvention,
                                     QuantLib::DateGeneration::Forward,false);
    
    QuantLib::VanillaSwap::Type type;
    
    if(payfix){
        type = QuantLib::VanillaSwap::Payer;} 
    else{
        type = QuantLib::VanillaSwap::Receiver;    
    }
    boost::shared_ptr<QuantLib::VanillaSwap> 
        swap(new QuantLib::VanillaSwap(type, notional,
                                       fixedSchedule, dummyFixedRate, swFixedLegDayCounter,
                                       floatSchedule, swFloatingLegIndex, 0.0,
                                       swFloatingLegIndex->dayCounter()));
    swap->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::DiscountingSwapEngine(rhTermStructure)));

    // Find the ATM or break-even rate
    QuantLib::Rate fixedATMRate = swap->fairRate();

    QuantLib::Rate fixedRate;
    if(strike < 0) // factor instead of real strike
        fixedRate = fixedATMRate * (-strike);
    else
        fixedRate = strike;

    // The swap underlying the Affine swaption.
    boost::shared_ptr<QuantLib::VanillaSwap> 
        mySwap(new QuantLib::VanillaSwap(type, notional,
                                         fixedSchedule, fixedRate,swFixedLegDayCounter,
                                         floatSchedule, swFloatingLegIndex, 0.0,
                                         swFloatingLegIndex->dayCounter()));
    swap->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::DiscountingSwapEngine(rhTermStructure)));

    
    // Build swaptions that will be used to calibrate model to
    // the volatility matrix.
    std::vector<QuantLib::Period> swaptionMaturities;
    for(i = 0; i < (QuantLib::Size)numRows; i++)
        swaptionMaturities.push_back(QuantLib::Period(swaptionMat[i], QuantLib::Years));
    
    // Swaptions used for calibration
    std::vector<boost::shared_ptr<QuantLib::BlackCalibrationHelper> > swaptions;

    // List of times that have to be included in the timegrid
    std::list<QuantLib::Time> times;
    for (i=0; i<(QuantLib::Size)numRows; i++) {
        //boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(swaptionVols[i][numCols-i-1]));
        boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(swaptionVols(i)));
        swaptions.push_back(boost::shared_ptr<QuantLib::BlackCalibrationHelper>(new QuantLib::SwaptionHelper(swaptionMaturities[i],
                                                                                                             QuantLib::Period(swapLengths[i], QuantLib::Years),
                                                                                                             QuantLib::Handle<QuantLib::Quote>(vol),
                                                                                                             swFloatingLegIndex,
                                                                                                             swFloatingLegIndex->tenor(),
                                                                                                             swFloatingLegIndex->dayCounter(),
                                                                                                             swFloatingLegIndex->dayCounter(),
                                                                                                             rhTermStructure)));
        swaptions.back()->addTimesTo(times);
    }
    
    // Building time-grid
    QuantLib::TimeGrid grid(times.begin(), times.end(), 30);

    
    // Get Affine swaption exercise dates, single date if europen, coupon dates if bermudan
    std::vector<QuantLib::Date> affineDates;
    const std::vector<boost::shared_ptr<QuantLib::CashFlow> >& leg = swap->fixedLeg();
    if(european){
        boost::shared_ptr<QuantLib::Coupon> coupon = boost::dynamic_pointer_cast<QuantLib::Coupon>(leg[0]);
        affineDates.push_back(coupon->accrualStartDate());
    } else{
        for (i=0; i<leg.size(); i++) {
            boost::shared_ptr<QuantLib::Coupon> coupon = boost::dynamic_pointer_cast<QuantLib::Coupon>(leg[i]);
            affineDates.push_back(coupon->accrualStartDate());
        }

    }
    
    boost::shared_ptr<QuantLib::Exercise> affineExercise(new QuantLib::BermudanExercise(affineDates));
    
    // Price based on method selected.
    if (method.compare("G2Analytic") == 0) {
        boost::shared_ptr<QuantLib::G2> modelG2(new QuantLib::G2(rhTermStructure));
        Rprintf((char*)"G2/Jamshidian (analytic) calibration\n");
        for(i = 0; i < swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::G2SwaptionEngine(modelG2, 6.0, 16)));
        calibrateModel2(modelG2, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols); 
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelG2, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise); 
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a")         = modelG2->params()[0],
                                  Rcpp::Named("sigma")     = modelG2->params()[1],
                                  Rcpp::Named("b")         = modelG2->params()[2],
                                  Rcpp::Named("eta")       = modelG2->params()[3],
                                  Rcpp::Named("rho")       = modelG2->params()[4],
                                  Rcpp::Named("NPV")       = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params")    = params);
        
    } else if (method.compare("HWAnalytic") == 0) {
        boost::shared_ptr<QuantLib::HullWhite> modelHW(new QuantLib::HullWhite(rhTermStructure));
        Rprintf((char*)"Hull-White (analytic) calibration\n");
        for (i=0; i<swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::JamshidianSwaptionEngine(modelHW)));
        calibrateModel2(modelHW, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols);
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelHW, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise);
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a") = modelHW->params()[0],
                                  Rcpp::Named("sigma") = modelHW->params()[1],
                                  Rcpp::Named("NPV") = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params") = params);
        
    } else if (method.compare("HWTree") == 0) {
        boost::shared_ptr<QuantLib::HullWhite> modelHW2(new QuantLib::HullWhite(rhTermStructure));
        Rprintf((char*)"Hull-White (tree) calibration\n");
        for (i=0; i<swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::TreeSwaptionEngine(modelHW2,grid)));

        calibrateModel2(modelHW2, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols);
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelHW2, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise);
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a") = modelHW2->params()[0],
                                  Rcpp::Named("sigma") = modelHW2->params()[1],
                                  Rcpp::Named("NPV") = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params") = params);
        
            
    } else if (method.compare("BKTree") == 0) {
        boost::shared_ptr<QuantLib::BlackKarasinski> modelBK(new QuantLib::BlackKarasinski(rhTermStructure));
        Rprintf((char*)"Black-Karasinski (tree) calibration\n");
        for (i=0; i<swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::TreeSwaptionEngine(modelBK,grid)));
        calibrateModel2(modelBK, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols);
            
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelBK, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise);
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a") = modelBK->params()[0],
                                  Rcpp::Named("sigma") = modelBK->params()[1],
                                  Rcpp::Named("price") = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params") = params);
            
    } else {
        throw std::range_error("Unknown method in AffineSwaption\n");
    }
    
}