void MainApplication::fetchSchedule(Schedule* toReplace, const QUrl& url, const QString& dateFormat)
{
    qDebug() << "fetch schedule url:" << url;

    QNetworkRequest request(url);

    QNetworkReply* reply = networkAccessManager_.get(request);
    connect(reply, &QNetworkReply::finished,
            [this, toReplace, reply, dateFormat]() {
                QByteArray data = reply->readAll();
                qDebug() << data;

                if (!data.isEmpty()) {
                    Schedule s = Schedule::fromOutlookCsvData(data, SF_TIME_ZONE, dateFormat);
                    qDebug() << "downloaded schedule:"
                        << s.size()
                        << s.getEventsByDate(QDate::currentDate());

                    // Sanity check.
                    if (s.size() > 0) {
                        qDebug() << "replacing schedule";
                        *toReplace = s;

                        this->updateEventTimes();
                    }
                }

                reply->deleteLater();
            });
}
Beispiel #2
0
void ScheduleToXML::OneWFScheduleToXML(ofstream&f, Schedule &currentSchedule, int currentWfNum){
	int currentWfPackage = 0;
	for (Schedule::size_type i = 0; i < currentSchedule.size(); i++){
		int packageNum = currentSchedule[i].get<0>();
		int tBegin = currentSchedule[i].get<1>() * data.context.GetDelta();
		int coresCount = currentSchedule[i].get<2>().size();
		vector <int> cores = currentSchedule[i].get<2>();
		int type = data.GetResourceType(cores[0]);
		int currBeginIndex = 0;
		// correct
		//cout << "type=" << type << " cores = " << coresCount << " package = " << packageNum << " ";
		double execTime = data.workflows[currentWfNum].GetExecTime(packageNum,type+1,coresCount);
		//cout << execTime << endl;
		int tEnd = tBegin + static_cast<int>(execTime);
		for (unsigned j = 0; j < cores.size(); j++){
			f << "\t\t<node_statistics>" << endl;
			f << "\t\t	<node_property name=\"id\" value=\"" << packageNum+1 <<"\"/>" << endl;
			f << "\t\t	<node_property name=\"type\" value=\"computation\"/>" << endl;
			f << "\t\t	<node_property name=\"start_time\" value=\"" << tBegin << "\"/>" << endl;
			f << "\t\t	<node_property name=\"end_time\" value=\"" << tEnd << "\"/>" << endl;
			f << "\t\t	<configuration>" << endl;
			f << "\t\t	  <conf_property name=\"cluster_id\" value=\"0\"/>" << endl;
			f << "\t\t	  <conf_property name=\"host_nb\" value=\"1\"/>" << endl;
			f << "\t\t	  <host_lists>" << endl;
			f << "\t\t	    <hosts start=\"" << cores[j] << "\" nb=\"1\"/>" << endl;
			f << "\t\t	  </host_lists>" << endl;
			f << "\t\t	</configuration>" << endl;
			f << "\t\t</node_statistics>" << endl;
		}
		currentWfPackage++;
	}
}
// get criteria value taling into account the average time of unscheduled tasks
double ReservedTimeCriteria::GetCriteria (const Schedule &in, const int &wfNum){
	double requiredDeadline = data.GetDeadline(wfNum);
	// max ending time
	double maxEndTime = 0;
	for (auto &sched: in){
		double currentEndTime = sched.get<1>() + sched.get<3>();
		if (maxEndTime < currentEndTime)
			maxEndTime = currentEndTime;
	}
	// if all tasks are unscheduled 
	if (maxEndTime == 0) return 0;
	double deadline = requiredDeadline - maxEndTime;
	// if there are some unscheduled tasks
	int pCount = data.Workflows(wfNum).GetPackageCount();
	if (in.size() != pCount){
		vector <int> scheduled;
		for (const auto &sched : in){
			scheduled.push_back(sched.get_head());
		}
		for (int pNum = 0; pNum < pCount; pNum++){
			// if package is unscheduled, add it avg exec time to deadline
			if (find(scheduled.begin(), scheduled.end(), pNum) == scheduled.end())
			// we suppose that all unscheduled packages execute sequentially
			deadline += data.Workflows(wfNum).GetAvgExecTime(pNum);
		}
	}
	return deadline;
}
Beispiel #4
0
const Real Gaussian1dModel::swapAnnuity(const Date &fixing, const Period &tenor,
                                        const Date &referenceDate, const Real y,
                                        boost::shared_ptr<SwapIndex> swapIdx) const {

    QL_REQUIRE(swapIdx != NULL, "no swap index given");

    calculate();

    Handle<YieldTermStructure> ytsd =
        swapIdx->discountingTermStructure(); // might be empty, then use
    // model curve

    boost::shared_ptr<VanillaSwap> underlying =
        underlyingSwap(swapIdx, fixing, tenor);

    Schedule sched = underlying->fixedSchedule();

    Real annuity = 0.0;
    for (unsigned int j = 1; j < sched.size(); j++) {
        annuity += zerobond(sched.calendar().adjust(
                                sched.date(j), underlying->paymentConvention()),
                            referenceDate, y, ytsd) *
                   swapIdx->dayCounter().yearFraction(sched.date(j - 1),
                           sched.date(j));
    }
    return annuity;
}
ELSStepDownMonthlyR::ELSStepDownMonthlyR(Real notional,
						const Date& issueDate,
						Natural settlementDays,
						//const std::vector<boost::shared_ptr<Index>>& refIndex,
						const std::vector<boost::shared_ptr<StockIndex>>& refIndex,
						const Schedule& schedule,
						std::vector<Real>& earlyExTriggers,
						std::vector<Real>& redemCoupon,
						Real KILossCoupon,
						const std::vector<Real>& KIbarrier,
						CheckKIType checkKIType,
						const DayCounter& daycount,
						const Calendar& calendar
						)
	:ELSStepDown(notional,issueDate,settlementDays,refIndex,schedule,earlyExTriggers,redemCoupon,
	KIbarrier,checkKIType,daycount,calendar),
	KILossCoupon_(KILossCoupon),checkKIType_(checkKIType)
	{
		pastKICount_=0;
		

		for(Size i=0;i<schedule.size();++i){
			if(earlyExTriggers[i]>0.0){
				fixingExDates_.push_back(schedule[i]);
			}
		}
		
	}
Beispiel #6
0
// implements staging scheme for finding the schedule for WFs set
// <PRE> 0 <= firstWfNum < data.workflows.size()
double Scheduler::StagedScheme(int firstWfNum){
   cout << "StagedScheme(int) was called\n";
   try{
      int wfCount = data.GetWFCount();
      if (firstWfNum < 0 || firstWfNum > wfCount) 
         throw UserException("Scheduler::StagedScheme(int) error. Wrong init workflow number");
      // creating XML with init time windows
      //xmlWriter->SetXMLBaseName("Init_");
      Schedule oneWFsched;
      //xmlWriter->CreateXML(oneWFsched, -1);
      // ??!! think about it !
      xmlWriter->SetXMLBaseName("Staged_");
      //double stagedT = clock();

      //string resFileName = "staged_scheme_" + to_string(firstWfNum) + ".txt";
      //ofstream res(resFileName);
      //if (res.fail()) 
      //	throw UserException("Scheduler::StagedScheme(int) error. Unable to create res file");
      //res << "Stage 1, workflow # " << firstWfNum << endl;
      //cout << "Stage 1, workflow # " << firstWfNum << endl;
      
      vector <double> eff;
      // applying settings of scheduling method for initial WF
      unique_ptr <SchedulingMethod> method = SchedulingFactory::GetMethod(data, methodsSet[firstWfNum], firstWfNum);
      // getting schedule for first WF
      double oneStepStart = clock();
      eff.push_back(method->GetWFSchedule(oneWFsched));

      // set local to global packages
      int initNum = data.GetInitPackageNumber(firstWfNum);
      for (int i = 0; i < oneWFsched.size(); i++)
         oneWFsched[i].get<0>() += initNum;


      fullSchedule = oneWFsched;
      
      //cout << "Elapsed time: " << (clock()-oneStepStart)/1000.0 << " sec" << endl;
      scheduledWFs.push_back(firstWfNum);	
      //xmlWriter->CreateXML(oneWFsched, firstWfNum);
      // write result to XML
      data.FixBusyIntervals();

      
      // write result to res file
      //PrintOneWFSched(res, oneWFsched, firstWfNum);
      
      
      // we need to store current busy intervals
      // of schedule that give the best efficiency
      // current best schedule is stored in oneWFsched
      vector<vector <BusyIntervals>> storedIntervals;
      Schedule storedSched;

      while (scheduledWFs.size() != wfCount ){
         //cout << "Stage " << scheduledWFs.size() + 1 << endl;
         double stageMaxEff = numeric_limits<double>::infinity();
         int bestWfNum = -1;
         for (int i = 0; i < wfCount; i++){
            // if this WF wasn't scheduled yet
            if (find(scheduledWFs.begin(), scheduledWFs.end(), i) == scheduledWFs.end()){
               //cout << "CurrentWfNum = " << i << " ";
               oneStepStart = clock();
               method = SchedulingFactory::GetMethod(data, methodsSet[i], i);
               oneWFsched.clear();
               double currentEff = method->GetWFSchedule(oneWFsched);
               //cout << "Elapsed time: " << (clock()-oneStepStart)/1000.0 << " sec" << endl;
               /*ReadData(i);
               directBellman = false;
               BackBellmanProcedure();
               directBellman = true;
               double currentEff = DirectBellman(i);*/
               if (stageMaxEff > currentEff){
                  stageMaxEff = currentEff;
                  bestWfNum = i;
                  storedSched = oneWFsched;
                  storedIntervals.clear();
                  data.GetCurrentIntervals(storedIntervals);
                  //GetBestBusyIntervals(bestBusyIntervals);
               }
               data.ResetBusyIntervals(); // newfag in my program
               //states.clear(); controls.clear(); nextStateNumbers.clear(); stagesCores.clear();
            }
         }
         // set local to global packages
         int initNum = data.GetInitPackageNumber(bestWfNum);
         for (int i = 0; i < storedSched.size(); i++)
            storedSched[i].get<0>() += initNum;

         copy(storedSched.begin(), storedSched.end(), back_inserter(fullSchedule));
         //copy(bestStagesCores.begin(), bestStagesCores.end(),back_inserter(allStagesCores));
         scheduledWFs.push_back(bestWfNum);
         //usedNums = scheduledWFs; ???
         //stagesCores = bestStagesCores;
         //currentWfNum = bestWfNum;
         eff.push_back(stageMaxEff);
         // set current intervals as stored intervals
         data.SetCurrentIntervals(storedIntervals);
         // write result to XML
         // xmlWriter->CreateXML(storedSched, bestWfNum);
         // write result to res file
      //	PrintOneWFSched(res, storedSched, bestWfNum);
           
         data.FixBusyIntervals();
         
         /*SetBestBusyIntervals(bestBusyIntervals);
         FixNewBusyIntervals();
         BellmanToXML(true);*/
         //std::system("pause");
      }
      /*usedNums = scheduledWFs; ???
      SetFirstBusyIntervals();
      stagesCores = allStagesCores;
      BellmanToXML(false);*/
      //PrintFooter(res, eff);
      double sumEff = 0.0;
      for (int i = 0; i < eff.size(); i++)
         sumEff += eff[i];
      
      data.SetInitBusyIntervals();
      //xmlWriter->CreateXML(fullSchedule, -1);
      //res.close();
      cout << "Max eff: " << sumEff/maxPossible << endl;
      //cout << "Elapsed time: " << (clock()-stagedT)/1000.0 << " sec" << endl;
      return sumEff/maxPossible ;
   }
   catch (UserException& e){
      cout<<"error : " << e.what() <<endl;
      std::system("pause");
      exit(EXIT_FAILURE);
   }
}
Beispiel #7
0
// scheduling ordered due to prioretization criteria
void Scheduler::OrderedScheme(int criteriaNumber){
   try{
      maxEff = 0.0;
      // get pointer to criteria 
      unique_ptr<CriteriaMethod> criteria = CriteriaFactory::GetMethod(data,criteriaNumber);
      bool tendsToMin = criteria->TendsToMin();
      // unscheduled WF numbers
      vector <int> unscheduled;
      for (int i = 0; i < data.GetWFCount(); i++)
         unscheduled.push_back(i);
      int stage = 0;
      // while we have unscheduled WFs
      while (unscheduled.size() != 0){
         //if (stage % 10 == 0) cout << "Stage " << stage << endl;
         stage++;
         // best schedule (from the prioretization criteria point of view)
         Schedule best;
         // and "best" wf number
         int bestWFNum = -1;
         // max eff (on this iteration)
         double currentBestEff = 0.0;
         // current best criteria value
         double bestCriteria = tendsToMin ? numeric_limits<double>::max() : 
            -1 * numeric_limits<double>::max();
         // busy intervals for best schedule

         vector<vector <BusyIntervals>> storedIntervals;
         // for each unscheduled WF
         for (auto &wfNum : unscheduled){
            Schedule current;
            unique_ptr <SchedulingMethod> method = 
               SchedulingFactory::GetMethod(data, methodsSet[wfNum], wfNum);
            // get current schedule in current variable
            double currentEff = method->GetWFSchedule(current);
            // get current criteria
            double currentCriteria = criteria->GetCriteria(current, wfNum);
            if (criteria->IsBetter(currentCriteria, bestCriteria)){
               best = current;
               bestWFNum = wfNum;
               currentBestEff = currentEff;
               bestCriteria = currentCriteria;
               storedIntervals.clear();
               data.GetCurrentIntervals(storedIntervals);
            }
            data.ResetBusyIntervals();
         }

         // set local to global packages
         int initNum = data.GetInitPackageNumber(bestWFNum);
         for (int i = 0; i < best.size(); i++)
            best[i].get<0>() += initNum;
         // add best schedule to full schedule
         copy(best.begin(), best.end(), back_inserter(fullSchedule));

         data.SetCurrentIntervals(storedIntervals);
         data.FixBusyIntervals();

         maxEff += currentBestEff;

         //cout << "Best wf num: " << bestWFNum << " bestCriteria: " << bestCriteria << endl;
         if (bestWFNum == -1) { 
            cout << "unscheduled.size() == " << unscheduled.size() << endl;
            break;
         }
         auto idx = find(unscheduled.begin(), unscheduled.end(), bestWFNum);
         if (idx == unscheduled.end()) 
            throw UserException("Scheduler::OrderedScheme(int) error. Best wf number was not found");
         unscheduled.erase(idx);
      }
      data.SetInitBusyIntervals();
      maxEff /= maxPossible;
      cout << "Ordered scheme eff: " << maxEff << endl;
      xmlWriter->SetXMLBaseName("Ordered_");
      // write result to XML
      xmlWriter->CreateXML(fullSchedule, -1);
      string resFileName = "ordered.txt";
      ofstream res(resFileName);
      if (res.fail()) 
         throw UserException("Scheduler::OrderedScheme error. Unable to create res file");
      PrintOneWFSched(res, fullSchedule, -1);
      res.close();
   }
   catch (UserException& e){
      cout<<"error : " << e.what() <<endl;
      std::system("pause");
      exit(EXIT_FAILURE);
   }
}
Beispiel #8
0
void InflationTest::testZeroIndex() {
    BOOST_MESSAGE("Testing zero inflation indices...");

    SavedSettings backup;

    EUHICP euhicp(true);
    if (euhicp.name() != "EU HICP"
        || euhicp.frequency() != Monthly
        || euhicp.revised()
        || !euhicp.interpolated()
        || euhicp.availabilityLag() != 1*Months) {
        BOOST_ERROR("wrong EU HICP data ("
                    << euhicp.name() << ", "
                    << euhicp.frequency() << ", "
                    << euhicp.revised() << ", "
                    << euhicp.interpolated() << ", "
                    << euhicp.availabilityLag() << ")");
    }

    UKRPI ukrpi(false);
    if (ukrpi.name() != "UK RPI"
        || ukrpi.frequency() != Monthly
        || ukrpi.revised()
        || ukrpi.interpolated()
        || ukrpi.availabilityLag() != 1*Months) {
        BOOST_ERROR("wrong UK RPI data ("
                    << ukrpi.name() << ", "
                    << ukrpi.frequency() << ", "
                    << ukrpi.revised() << ", "
                    << ukrpi.interpolated() << ", "
                    << ukrpi.availabilityLag() << ")");
    }

    // Retrieval test.
    //----------------
    // make sure of the evaluation date
    Date evaluationDate(13, August, 2007);
    evaluationDate = UnitedKingdom().adjust(evaluationDate);
    Settings::instance().evaluationDate() = evaluationDate;

    // fixing data
    Date from(1, January, 2005);
    Date to(13, August, 2007);
    Schedule rpiSchedule = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);

    Real fixData[] = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
        192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
        194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
        198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
        202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
        207.3, 206.1, -999.0 };

    bool interp = false;
    boost::shared_ptr<UKRPI> iir(new UKRPI(interp));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iir->addFixing(rpiSchedule[i], fixData[i]);
    }

    Date todayMinusLag = evaluationDate - iir->availabilityLag();
    std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, iir->frequency());
    todayMinusLag = lim.first;

    Real eps = 1.0e-8;

    // -1 because last value not yet available,
    // (no TS so can't forecast).
    for (Size i=0; i<rpiSchedule.size()-1;i++) {
        std::pair<Date,Date> lim = inflationPeriod(rpiSchedule[i],
                                                   iir->frequency());
        for (Date d=lim.first; d<=lim.second; d++) {
            if (d < inflationPeriod(todayMinusLag,iir->frequency()).first) {
                if (std::fabs(iir->fixing(d) - fixData[i]) > eps)
                    BOOST_ERROR("Fixings not constant within a period: "
                                << iir->fixing(d)
                                << ", should be " << fixData[i]);
            }
        }
    }
}
Beispiel #9
0
void InflationTest::testYYTermStructure() {
    BOOST_MESSAGE("Testing year-on-year inflation term structure...");

    SavedSettings backup;

    // try the YY UK
    Calendar calendar = UnitedKingdom();
    BusinessDayConvention bdc = ModifiedFollowing;
    Date evaluationDate(13, August, 2007);
    evaluationDate = calendar.adjust(evaluationDate);
    Settings::instance().evaluationDate() = evaluationDate;


    // fixing data
    Date from(1, January, 2005);
    Date to(13, August, 2007);
    Schedule rpiSchedule = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);
    Real fixData[] = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
        192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
        194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
        198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
        202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
        207.3, -999.0, -999 };

    RelinkableHandle<YoYInflationTermStructure> hy;
    bool interp = false;
    boost::shared_ptr<YYUKRPIr> iir(new YYUKRPIr(interp, hy));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iir->addFixing(rpiSchedule[i], fixData[i]);
    }



    boost::shared_ptr<YieldTermStructure> nominalTS = nominalTermStructure();

    // now build the YoY inflation curve
    Datum yyData[] = {
        { Date(13, August, 2008), 2.95 },
        { Date(13, August, 2009), 2.95 },
        { Date(13, August, 2010), 2.93 },
        { Date(15, August, 2011), 2.955 },
        { Date(13, August, 2012), 2.945 },
        { Date(13, August, 2013), 2.985 },
        { Date(13, August, 2014), 3.01 },
        { Date(13, August, 2015), 3.035 },
        { Date(13, August, 2016), 3.055 },  // note that
        { Date(13, August, 2017), 3.075 },  // some dates will be on
        { Date(13, August, 2019), 3.105 },  // holidays but the payment
        { Date(15, August, 2022), 3.135 },  // calendar will roll them
        { Date(13, August, 2027), 3.155 },
        { Date(13, August, 2032), 3.145 },
        { Date(13, August, 2037), 3.145 }
    };

    Period observationLag = Period(2,Months);
    DayCounter dc = Thirty360();

    // now build the helpers ...
    std::vector<boost::shared_ptr<BootstrapHelper<YoYInflationTermStructure> > > helpers =
    makeHelpers<YoYInflationTermStructure,YearOnYearInflationSwapHelper,
    YoYInflationIndex>(yyData, LENGTH(yyData), iir,
                        observationLag,
                        calendar, bdc, dc);

    Rate baseYYRate = yyData[0].rate/100.0;
    boost::shared_ptr<PiecewiseYoYInflationCurve<Linear> > pYYTS(
        new PiecewiseYoYInflationCurve<Linear>(
                evaluationDate, calendar, dc, observationLag,
                iir->frequency(),iir->interpolated(), baseYYRate,
                Handle<YieldTermStructure>(nominalTS), helpers));
    pYYTS->recalculate();

    // validation
    // yoy swaps should reprice to zero
    // yy rates should not equal yySwap rates
    Real eps = 0.000001;
    // usual swap engine
    Handle<YieldTermStructure> hTS(nominalTS);
    boost::shared_ptr<PricingEngine> sppe(new DiscountingSwapEngine(hTS));

    // make sure that the index has the latest yoy term structure
    hy.linkTo(pYYTS);

    for (Size j = 1; j < LENGTH(yyData); j++) {

        from = nominalTS->referenceDate();
        to = yyData[j].date;
        Schedule yoySchedule = MakeSchedule().from(from).to(to)
        .withConvention(Unadjusted) // fixed leg gets calendar from
        .withCalendar(calendar)     // schedule
        .withTenor(1*Years)
        .backwards()
        ;

        YearOnYearInflationSwap yyS2(YearOnYearInflationSwap::Payer,
                                        1000000.0,
                                        yoySchedule,//fixed schedule, but same as yoy
                                        yyData[j].rate/100.0,
                                        dc,
                                        yoySchedule,
                                        iir,
                                        observationLag,
                                        0.0,        //spread on index
                                        dc,
                                        UnitedKingdom());

        yyS2.setPricingEngine(sppe);



        BOOST_CHECK_MESSAGE(fabs(yyS2.NPV())<eps,"fresh yoy swap NPV!=0 from TS "
                <<"swap quote for pt " << j
                << ", is " << yyData[j].rate/100.0
                <<" vs YoY rate "<< pYYTS->yoyRate(yyData[j].date-observationLag)
                <<" at quote date "<<(yyData[j].date-observationLag)
                <<", NPV of a fresh yoy swap is " << yyS2.NPV()
                <<"\n      fair rate " << yyS2.fairRate()
                <<" payment "<<yyS2.paymentConvention());
    }

    Size jj=3;
    for (Size k = 0; k < 14; k++) {

        from = nominalTS->referenceDate() - k*Months;
        to = yyData[jj].date - k*Months;
        Schedule yoySchedule = MakeSchedule().from(from).to(to)
        .withConvention(Unadjusted) // fixed leg gets calendar from
        .withCalendar(calendar)     // schedule
        .withTenor(1*Years)
        .backwards()
        ;

        YearOnYearInflationSwap yyS3(YearOnYearInflationSwap::Payer,
                                    1000000.0,
                                    yoySchedule,//fixed schedule, but same as yoy
                                    yyData[jj].rate/100.0,
                                    dc,
                                    yoySchedule,
                                    iir,
                                    observationLag,
                                    0.0,        //spread on index
                                    dc,
                                    UnitedKingdom());

        yyS3.setPricingEngine(sppe);

        BOOST_CHECK_MESSAGE(fabs(yyS3.NPV())< 20000.0,
                            "unexpected size of aged YoY swap, aged "
                            <<k<<" months: YY aged NPV = " << yyS3.NPV()
                            <<", legs "<< yyS3.legNPV(0) << " and " << yyS3.legNPV(1)
                            );
    }

}
Beispiel #10
0
void InflationTest::testYYIndex() {
    BOOST_MESSAGE("Testing year-on-year inflation indices...");

    SavedSettings backup;

    YYEUHICP yyeuhicp(true);
    if (yyeuhicp.name() != "EU YY_HICP"
        || yyeuhicp.frequency() != Monthly
        || yyeuhicp.revised()
        || !yyeuhicp.interpolated()
        || yyeuhicp.ratio()
        || yyeuhicp.availabilityLag() != 1*Months) {
        BOOST_ERROR("wrong year-on-year EU HICP data ("
                    << yyeuhicp.name() << ", "
                    << yyeuhicp.frequency() << ", "
                    << yyeuhicp.revised() << ", "
                    << yyeuhicp.interpolated() << ", "
                    << yyeuhicp.ratio() << ", "
                    << yyeuhicp.availabilityLag() << ")");
    }

    YYEUHICPr yyeuhicpr(true);
    if (yyeuhicpr.name() != "EU YYR_HICP"
        || yyeuhicpr.frequency() != Monthly
        || yyeuhicpr.revised()
        || !yyeuhicpr.interpolated()
        || !yyeuhicpr.ratio()
        || yyeuhicpr.availabilityLag() != 1*Months) {
        BOOST_ERROR("wrong year-on-year EU HICPr data ("
                    << yyeuhicpr.name() << ", "
                    << yyeuhicpr.frequency() << ", "
                    << yyeuhicpr.revised() << ", "
                    << yyeuhicpr.interpolated() << ", "
                    << yyeuhicpr.ratio() << ", "
                    << yyeuhicpr.availabilityLag() << ")");
    }

    YYUKRPI yyukrpi(false);
    if (yyukrpi.name() != "UK YY_RPI"
        || yyukrpi.frequency() != Monthly
        || yyukrpi.revised()
        || yyukrpi.interpolated()
        || yyukrpi.ratio()
        || yyukrpi.availabilityLag() != 1*Months) {
        BOOST_ERROR("wrong year-on-year UK RPI data ("
                    << yyukrpi.name() << ", "
                    << yyukrpi.frequency() << ", "
                    << yyukrpi.revised() << ", "
                    << yyukrpi.interpolated() << ", "
                    << yyukrpi.ratio() << ", "
                    << yyukrpi.availabilityLag() << ")");
    }

    YYUKRPIr yyukrpir(false);
    if (yyukrpir.name() != "UK YYR_RPI"
        || yyukrpir.frequency() != Monthly
        || yyukrpir.revised()
        || yyukrpir.interpolated()
        || !yyukrpir.ratio()
        || yyukrpir.availabilityLag() != 1*Months) {
        BOOST_ERROR("wrong year-on-year UK RPIr data ("
                    << yyukrpir.name() << ", "
                    << yyukrpir.frequency() << ", "
                    << yyukrpir.revised() << ", "
                    << yyukrpir.interpolated() << ", "
                    << yyukrpir.ratio() << ", "
                    << yyukrpir.availabilityLag() << ")");
    }


    // Retrieval test.
    //----------------
    // make sure of the evaluation date
    Date evaluationDate(13, August, 2007);
    evaluationDate = UnitedKingdom().adjust(evaluationDate);
    Settings::instance().evaluationDate() = evaluationDate;

    // fixing data
    Date from(1, January, 2005);
    Date to(13, August, 2007);
    Schedule rpiSchedule = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);

    Real fixData[] = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
        192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
        194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
        198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
        202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
        207.3, -999.0, -999.0 };

    bool interp = false;
    boost::shared_ptr<YYUKRPIr> iir(new YYUKRPIr(interp));
    boost::shared_ptr<YYUKRPIr> iirYES(new YYUKRPIr(true));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iir->addFixing(rpiSchedule[i], fixData[i]);
        iirYES->addFixing(rpiSchedule[i], fixData[i]);
    }

    Date todayMinusLag = evaluationDate - iir->availabilityLag();
    std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, iir->frequency());
    todayMinusLag = lim.second + 1 - 2*Period(iir->frequency());

    Real eps = 1.0e-8;

    // Interpolation tests
    //--------------------
    // (no TS so can't forecast).
    for (Size i=13; i<rpiSchedule.size();i++) {
        std::pair<Date,Date> lim = inflationPeriod(rpiSchedule[i],
                                                   iir->frequency());
        std::pair<Date,Date> limBef = inflationPeriod(rpiSchedule[i-12],
                                                      iir->frequency());
        for (Date d=lim.first; d<=lim.second; d++) {
            if (d < todayMinusLag) {
                Rate expected = fixData[i]/fixData[i-12] - 1.0;
                Rate calculated = iir->fixing(d);
                BOOST_CHECK_MESSAGE(std::fabs(calculated - expected) < eps,
                                    "Non-interpolated fixings not constant within a period: "
                                    << calculated
                                    << ", should be "
                                    << expected);

                Real dp= lim.second + 1- lim.first;
                Real dpBef=limBef.second + 1 - limBef.first;
                Real dl = d-lim.first;
                // potentially does not work on 29th Feb
                Real dlBef = NullCalendar().advance(d, -1*Years, ModifiedFollowing)
                -limBef.first;

                Real linearNow = fixData[i] + (fixData[i+1]-fixData[i])*dl/dp;
                Real linearBef = fixData[i-12] + (fixData[i+1-12]-fixData[i-12])*dlBef/dpBef;
                Rate expectedYES = linearNow / linearBef - 1.0;
                Rate calculatedYES = iirYES->fixing(d);
                BOOST_CHECK_MESSAGE(fabs(expectedYES-calculatedYES)<eps,
                                    "Error in interpolated fixings: expect "<<expectedYES
                                    <<" see " << calculatedYES
                                    <<" flat " << calculated
                                    <<", data: "<< fixData[i-12] <<", "<< fixData[i+1-12]
                                    <<", "<<    fixData[i] <<", "<< fixData[i+1]
                                    <<", fac: "<< dp <<", "<< dl
                                    <<", "<< dpBef <<", "<< dlBef
                                    <<", to: "<<linearNow<<", "<<linearBef
                                    );
            }
        }
    }

}
Beispiel #11
0
void InflationTest::testZeroTermStructure() {
    BOOST_MESSAGE("Testing zero inflation term structure...");

    SavedSettings backup;

    // try the Zero UK
    Calendar calendar = UnitedKingdom();
    BusinessDayConvention bdc = ModifiedFollowing;
    Date evaluationDate(13, August, 2007);
    evaluationDate = calendar.adjust(evaluationDate);
    Settings::instance().evaluationDate() = evaluationDate;

    // fixing data
    Date from(1, January, 2005);
    Date to(13, August, 2007);
    Schedule rpiSchedule = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);

    Real fixData[] = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
        192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
        194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
        198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
        202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
        207.3, 206.1,  -999.0 };

    RelinkableHandle<ZeroInflationTermStructure> hz;
    bool interp = false;
    boost::shared_ptr<UKRPI> iiUKRPI(new UKRPI(interp, hz));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iiUKRPI->addFixing(rpiSchedule[i], fixData[i]);
    }

    boost::shared_ptr<ZeroInflationIndex> ii = boost::dynamic_pointer_cast<ZeroInflationIndex>(iiUKRPI);
    boost::shared_ptr<YieldTermStructure> nominalTS = nominalTermStructure();

    // now build the zero inflation curve
    Datum zcData[] = {
        { Date(13, August, 2008), 2.93 },
        { Date(13, August, 2009), 2.95 },
        { Date(13, August, 2010), 2.965 },
        { Date(15, August, 2011), 2.98 },
        { Date(13, August, 2012), 3.0 },
        { Date(13, August, 2014), 3.06 },
        { Date(13, August, 2017), 3.175 },
        { Date(13, August, 2019), 3.243 },
        { Date(15, August, 2022), 3.293 },
        { Date(14, August, 2027), 3.338 },
        { Date(13, August, 2032), 3.348 },
        { Date(15, August, 2037), 3.348 },
        { Date(13, August, 2047), 3.308 },
        { Date(13, August, 2057), 3.228 }
    };

    Period observationLag = Period(2,Months);
    DayCounter dc = Thirty360();
    Frequency frequency = Monthly;
    std::vector<boost::shared_ptr<BootstrapHelper<ZeroInflationTermStructure> > > helpers =
    makeHelpers<ZeroInflationTermStructure,ZeroCouponInflationSwapHelper,
                ZeroInflationIndex>(zcData, LENGTH(zcData), ii,
                                    observationLag,
                                    calendar, bdc, dc);

    Rate baseZeroRate = zcData[0].rate/100.0;
    boost::shared_ptr<PiecewiseZeroInflationCurve<Linear> > pZITS(
                        new PiecewiseZeroInflationCurve<Linear>(
                        evaluationDate, calendar, dc, observationLag,
                        frequency, ii->interpolated(), baseZeroRate,
                        Handle<YieldTermStructure>(nominalTS), helpers));
    pZITS->recalculate();

    // first check that the zero rates on the curve match the data
    // and that the helpers give the correct impled rates
    const Real eps = 0.00000001;
    bool forceLinearInterpolation = false;
    for (Size i=0; i<LENGTH(zcData); i++) {
        BOOST_REQUIRE_MESSAGE(std::fabs(zcData[i].rate/100.0
            - pZITS->zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)) < eps,
            "ZITS zeroRate != instrument "
            << pZITS->zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)
            << " vs " << zcData[i].rate/100.0
            << " interpolation: " << ii->interpolated()
            << " forceLinearInterpolation " << forceLinearInterpolation);
        BOOST_REQUIRE_MESSAGE(std::fabs(helpers[i]->impliedQuote()
            - zcData[i].rate/100.0) < eps,
            "ZITS implied quote != instrument "
            << helpers[i]->impliedQuote()
            << " vs " << zcData[i].rate/100.0);
    }


    // now test the forecasting capability of the index.
    hz.linkTo(pZITS);
    from = hz->baseDate();
    to = hz->maxDate()-1*Months; // a bit of margin for adjustments
    Schedule testIndex = MakeSchedule().from(from).to(to)
                            .withTenor(1*Months)
                            .withCalendar(UnitedKingdom())
                            .withConvention(ModifiedFollowing);


    // we are testing UKRPI which is not interpolated
    Date bd = hz->baseDate();
    Real bf = ii->fixing(bd);
    for (Size i=0; i<testIndex.size();i++) {
        Date d = testIndex[i];
        Real z = hz->zeroRate(d, Period(0,Days));
        Real t = hz->dayCounter().yearFraction(bd, d);
        if(!ii->interpolated()) // because fixing constant over period
            t = hz->dayCounter().yearFraction(bd,
                inflationPeriod(d, ii->frequency()).first);
        Real calc = bf * pow( 1+z, t);
        if (t<=0)
            calc = ii->fixing(d,false); // still historical
        if (std::fabs(calc - ii->fixing(d,true))/10000.0 > eps)
            BOOST_ERROR("ZC index does not forecast correctly for date " << d
                        << " from base date " << bd
                        << " with fixing " << bf
                        << ", correct:  " << calc
                        << ", fix: " << ii->fixing(d,true)
                        << ", t " << t);
    }


    //===========================================================================================
    // Test zero-inflation-indexed (i.e. cpi ratio) cashflow
    // just ordinary indexed cashflow with a zero inflation index

    Date baseDate(1, January, 2006);
    Date fixDate(1, August, 2014);
    Date payDate=UnitedKingdom().adjust(fixDate+Period(3,Months),ModifiedFollowing);
    boost::shared_ptr<Index> ind = boost::dynamic_pointer_cast<Index>(ii);
    BOOST_REQUIRE_MESSAGE(ind,"dynamic_pointer_cast to Index from InflationIndex failed");

    Real notional = 1000000.0;//1m
    IndexedCashFlow iicf(notional,ind,baseDate,fixDate,payDate);
    Real correctIndexed = ii->fixing(iicf.fixingDate())/ii->fixing(iicf.baseDate());
    Real calculatedIndexed = iicf.amount()/iicf.notional();
    BOOST_REQUIRE_MESSAGE(std::fabs(correctIndexed - calculatedIndexed) < eps,
               "IndexedCashFlow indexing wrong: " << calculatedIndexed << " vs correct = "
               << correctIndexed);


    //===========================================================================================
    // Test zero coupon swap

    // first make one ...

    boost::shared_ptr<ZeroInflationIndex> zii = boost::dynamic_pointer_cast<ZeroInflationIndex>(ii);
    BOOST_REQUIRE_MESSAGE(zii,"dynamic_pointer_cast to ZeroInflationIndex from UKRPI failed");
    ZeroCouponInflationSwap nzcis(ZeroCouponInflationSwap::Payer,
                                     1000000.0,
                                     evaluationDate,
                                     zcData[6].date,    // end date = maturity
                                     calendar, bdc, dc, zcData[6].rate/100.0, // fixed rate
                                     zii, observationLag);

    // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
    //      inflation curve attached to the inflation index.
    Handle<YieldTermStructure> hTS(nominalTS);
    boost::shared_ptr<PricingEngine> sppe(new DiscountingSwapEngine(hTS));
    nzcis.setPricingEngine(sppe);

    // ... and price it, should be zero
    BOOST_CHECK_MESSAGE(fabs(nzcis.NPV())<0.00001,"ZCIS does not reprice to zero "
                        << nzcis.NPV()
                        << evaluationDate << " to " << zcData[6].date << " becoming " << nzcis.maturityDate()
                        << " rate " << zcData[6].rate
                        << " fixed leg " << nzcis.legNPV(0)
                        << " indexed-predicted inflated leg " << nzcis.legNPV(1)
                        << " discount " << nominalTS->discount(nzcis.maturityDate())
                        );


    //===========================================================================================
    // Test multiplicative seasonality in price
    //

    //Seasonality factors NOT normalized
    //and UKRPI is not interpolated
    Date trueBaseDate = inflationPeriod(hz->baseDate(), ii->frequency()).second;
    Date seasonallityBaseDate(31,January,trueBaseDate.year());
    std::vector<Rate> seasonalityFactors(12);
    seasonalityFactors[0] = 1.003245;
    seasonalityFactors[1] = 1.000000;
    seasonalityFactors[2] = 0.999715;
    seasonalityFactors[3] = 1.000495;
    seasonalityFactors[4] = 1.000929;
    seasonalityFactors[5] = 0.998687;
    seasonalityFactors[6] = 0.995949;
    seasonalityFactors[7] = 0.994682;
    seasonalityFactors[8] = 0.995949;
    seasonalityFactors[9] = 1.000519;
    seasonalityFactors[10] = 1.003705;
    seasonalityFactors[11] = 1.004186;

    //Creating two different seasonality objects
    //
    boost::shared_ptr<MultiplicativePriceSeasonality> seasonality_1(new MultiplicativePriceSeasonality());
    std::vector<Rate> seasonalityFactors_1(12, 1.0);
    seasonality_1->set(seasonallityBaseDate,Monthly,seasonalityFactors_1);

    boost::shared_ptr<MultiplicativePriceSeasonality> seasonality_real(
        new MultiplicativePriceSeasonality(seasonallityBaseDate,Monthly,seasonalityFactors));
    //Testing seasonality correction when seasonality factors are = 1
    //
    Rate fixing[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)
    };

    hz->setSeasonality(seasonality_1);
    QL_REQUIRE(hz->hasSeasonality(),"[44] incorrectly believes NO seasonality correction");

    Rate seasonalityFixing_1[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)

    };

    for(int i=0;i<12;i++){
        if(std::fabs(fixing[i] - seasonalityFixing_1[i]) > eps) {
            BOOST_ERROR("Seasonality doesn't work correctly when seasonality factors are set = 1");
        }
    }

    //Testing seasonality correction when seasonality factors are different from 1
    //
    //0.998687 is the seasonality factor corresponding to June (the base CPI curve month)
    //
    Rate expectedFixing[] = {
        ii->fixing(Date(14,January  ,2013),true) * 1.003245/0.998687,
        ii->fixing(Date(14,February ,2013),true) * 1.000000/0.998687,
        ii->fixing(Date(14,March    ,2013),true) * 0.999715/0.998687,
        ii->fixing(Date(14,April    ,2013),true) * 1.000495/0.998687,
        ii->fixing(Date(14,May      ,2013),true) * 1.000929/0.998687,
        ii->fixing(Date(14,June     ,2013),true) * 0.998687/0.998687,
        ii->fixing(Date(14,July     ,2013),true) * 0.995949/0.998687,
        ii->fixing(Date(14,August   ,2013),true) * 0.994682/0.998687,
        ii->fixing(Date(14,September,2013),true) * 0.995949/0.998687,
        ii->fixing(Date(14,October  ,2013),true) * 1.000519/0.998687,
        ii->fixing(Date(14,November ,2013),true) * 1.003705/0.998687,
        ii->fixing(Date(14,December ,2013),true) * 1.004186/0.998687
    };

    hz->setSeasonality(seasonality_real);

    Rate seasonalityFixing_real[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)
    };

    for(int i=0;i<12;i++){
        if(std::fabs(expectedFixing[i] - seasonalityFixing_real[i]) > 0.01) {
            BOOST_ERROR("Seasonality doesn't work correctly when considering seasonality factors != 1 "
                        << expectedFixing[i] << " vs " << seasonalityFixing_real[i]);
        }
    }

    //Testing Unset function
    //
    QL_REQUIRE(hz->hasSeasonality(),"[4] incorrectly believes NO seasonality correction");
    hz->setSeasonality();
    QL_REQUIRE(!hz->hasSeasonality(),"[5] incorrectly believes HAS seasonality correction");

    Rate seasonalityFixing_unset[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)
    };

    for(int i=0;i<12;i++){
        if(std::fabs(seasonalityFixing_unset[i] - seasonalityFixing_1[i]) > eps) {
            BOOST_ERROR("UnsetSeasonality doesn't work correctly "
                        << seasonalityFixing_unset[i] << " vs " << seasonalityFixing_1[i]);
        }
    }



    //==============================================================================
    // now do an INTERPOLATED index, i.e. repeat everything on a fake version of
    // UKRPI (to save making another term structure)

    bool interpYES = true;
    boost::shared_ptr<UKRPI> iiUKRPIyes(new UKRPI(interpYES, hz));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iiUKRPIyes->addFixing(rpiSchedule[i], fixData[i]);
    }

    boost::shared_ptr<ZeroInflationIndex> iiyes
        = boost::dynamic_pointer_cast<ZeroInflationIndex>(iiUKRPIyes);

    // now build the zero inflation curve
    // same data, bigger lag or it will be a self-contradiction
    Period observationLagyes = Period(3,Months);
    std::vector<boost::shared_ptr<BootstrapHelper<ZeroInflationTermStructure> > > helpersyes =
    makeHelpers<ZeroInflationTermStructure,ZeroCouponInflationSwapHelper,
    ZeroInflationIndex>(zcData, LENGTH(zcData), iiyes,
                        observationLagyes,
                        calendar, bdc, dc);

    boost::shared_ptr<PiecewiseZeroInflationCurve<Linear> > pZITSyes(
            new PiecewiseZeroInflationCurve<Linear>(
            evaluationDate, calendar, dc, observationLagyes,
            frequency, iiyes->interpolated(), baseZeroRate,
            Handle<YieldTermStructure>(nominalTS), helpersyes));
    pZITSyes->recalculate();

    // first check that the zero rates on the curve match the data
    // and that the helpers give the correct impled rates
    forceLinearInterpolation = false;   // still
    for (Size i=0; i<LENGTH(zcData); i++) {
        BOOST_CHECK_MESSAGE(std::fabs(zcData[i].rate/100.0
                    - pZITSyes->zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)) < eps,
                    "ZITS INTERPOLATED zeroRate != instrument "
                    << pZITSyes->zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)
                    << " date " << zcData[i].date << " observationLagyes " << observationLagyes
                    << " vs " << zcData[i].rate/100.0
                    << " interpolation: " << iiyes->interpolated()
                    << " forceLinearInterpolation " << forceLinearInterpolation);
        BOOST_CHECK_MESSAGE(std::fabs(helpersyes[i]->impliedQuote()
                        - zcData[i].rate/100.0) < eps,
                    "ZITS INTERPOLATED implied quote != instrument "
                    << helpersyes[i]->impliedQuote()
                    << " vs " << zcData[i].rate/100.0);
    }


    //======================================================================================
    // now test the forecasting capability of the index.
    hz.linkTo(pZITSyes);
    from = hz->baseDate()+1*Months; // to avoid historical linear bit for rest of base month
    to = hz->maxDate()-1*Months; // a bit of margin for adjustments
    testIndex = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);

    // we are testing UKRPI which is FAKE interpolated for testing here
    bd = hz->baseDate();
    bf = iiyes->fixing(bd);
    for (Size i=0; i<testIndex.size();i++) {
        Date d = testIndex[i];
        Real z = hz->zeroRate(d, Period(0,Days));
        Real t = hz->dayCounter().yearFraction(bd, d);
        Real calc = bf * pow( 1+z, t);
        if (t<=0) calc = iiyes->fixing(d); // still historical
        if (std::fabs(calc - iiyes->fixing(d)) > eps)
            BOOST_ERROR("ZC INTERPOLATED index does not forecast correctly for date " << d
                        << " from base date " << bd
                        << " with fixing " << bf
                        << ", correct:  " << calc
                        << ", fix: " << iiyes->fixing(d)
                        << ", t " << t
                        << ", zero " << z);
    }



    //===========================================================================================
    // Test zero coupon swap

    boost::shared_ptr<ZeroInflationIndex> ziiyes = boost::dynamic_pointer_cast<ZeroInflationIndex>(iiyes);
    BOOST_REQUIRE_MESSAGE(ziiyes,"dynamic_pointer_cast to ZeroInflationIndex from UKRPI-I failed");
    ZeroCouponInflationSwap nzcisyes(ZeroCouponInflationSwap::Payer,
                                     1000000.0,
                                     evaluationDate,
                                     zcData[6].date,    // end date = maturity
                                     calendar, bdc, dc, zcData[6].rate/100.0, // fixed rate
                                     ziiyes, observationLagyes);

    // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
    //      inflation curve attached to the inflation index.
    nzcisyes.setPricingEngine(sppe);

    // ... and price it, should be zero
    BOOST_CHECK_MESSAGE(fabs(nzcisyes.NPV())<0.00001,"ZCIS-I does not reprice to zero "
                        << nzcisyes.NPV()
                        << evaluationDate << " to " << zcData[6].date << " becoming " << nzcisyes.maturityDate()
                        << " rate " << zcData[6].rate
                        << " fixed leg " << nzcisyes.legNPV(0)
                        << " indexed-predicted inflated leg " << nzcisyes.legNPV(1)
                        << " discount " << nominalTS->discount(nzcisyes.maturityDate())
                        );

}
Beispiel #12
0
void CPISwapTest::cpibondconsistency() {
    CommonVars common;

    // ZeroInflationSwap aka CPISwap

    CPISwap::Type type = CPISwap::Payer;
    Real nominal = 1000000.0;
    bool subtractInflationNominal = true;
    // float+spread leg
    Spread spread = 0.0;
    DayCounter floatDayCount = Actual365Fixed();
    BusinessDayConvention floatPaymentConvention = ModifiedFollowing;
    Natural fixingDays = 0;
    ext::shared_ptr<IborIndex> floatIndex(new GBPLibor(Period(6,Months),
                                                         common.nominalTS));

    // fixed x inflation leg
    Rate fixedRate = 0.1;//1% would be 0.01
    Real baseCPI = 206.1; // would be 206.13871 if we were interpolating
    DayCounter fixedDayCount = Actual365Fixed();
    BusinessDayConvention fixedPaymentConvention = ModifiedFollowing;
    Calendar fixedPaymentCalendar = UnitedKingdom();
    ext::shared_ptr<ZeroInflationIndex> fixedIndex = common.ii;
    Period contractObservationLag = common.contractObservationLag;
    CPI::InterpolationType observationInterpolation = common.contractObservationInterpolation;

    // set the schedules
    Date startDate(2, October, 2007);
    Date endDate(2, October, 2052);
    Schedule floatSchedule = MakeSchedule().from(startDate).to(endDate)
    .withTenor(Period(6,Months))
    .withCalendar(UnitedKingdom())
    .withConvention(floatPaymentConvention)
    .backwards()
    ;
    Schedule fixedSchedule = MakeSchedule().from(startDate).to(endDate)
    .withTenor(Period(6,Months))
    .withCalendar(UnitedKingdom())
    .withConvention(Unadjusted)
    .backwards()
    ;


    CPISwap zisV(type, nominal, subtractInflationNominal,
                 spread, floatDayCount, floatSchedule,
                 floatPaymentConvention, fixingDays, floatIndex,
                 fixedRate, baseCPI, fixedDayCount, fixedSchedule,
                 fixedPaymentConvention, contractObservationLag,
                 fixedIndex, observationInterpolation);

    Real floatFix[] = {0.06255,0.05975,0.0637,0.018425,0.0073438,-1,-1};
    Real cpiFix[] = {211.4,217.2,211.4,213.4,-2,-2};
    for(Size i=0;i<floatSchedule.size(); i++){
        if (floatSchedule[i] < common.evaluationDate) {
            floatIndex->addFixing(floatSchedule[i], floatFix[i],true);//true=overwrite
        }

        ext::shared_ptr<CPICoupon>
        zic = ext::dynamic_pointer_cast<CPICoupon>(zisV.cpiLeg()[i]);
        if (zic) {
            if (zic->fixingDate() < (common.evaluationDate - Period(1,Months))) {
                fixedIndex->addFixing(zic->fixingDate(), cpiFix[i],true);
            }
        }
    }


    // simple structure so simple pricing engine - most work done by index
    ext::shared_ptr<DiscountingSwapEngine>
    dse(new DiscountingSwapEngine(common.nominalTS));

    zisV.setPricingEngine(dse);

    // now do the bond equivalent
    std::vector<Rate> fixedRates(1,fixedRate);
    Natural settlementDays = 1;// cannot be zero!
    bool growthOnly = true;
    CPIBond cpiB(settlementDays, nominal, growthOnly,
                 baseCPI, contractObservationLag, fixedIndex,
                 observationInterpolation, fixedSchedule,
                 fixedRates, fixedDayCount, fixedPaymentConvention);

    ext::shared_ptr<DiscountingBondEngine>
    dbe(new DiscountingBondEngine(common.nominalTS));
    cpiB.setPricingEngine(dbe);

    QL_REQUIRE(fabs(cpiB.NPV() - zisV.legNPV(0))<1e-5,"cpi bond does not equal equivalent cpi swap leg");
    // remove circular refernce
    common.hcpi.linkTo(ext::shared_ptr<ZeroInflationTermStructure>());
}
Beispiel #13
0
void CPISwapTest::consistency() {

    // check inflation leg vs calculation directly from inflation TS
    CommonVars common;

    // ZeroInflationSwap aka CPISwap

    CPISwap::Type type = CPISwap::Payer;
    Real nominal = 1000000.0;
    bool subtractInflationNominal = true;
    // float+spread leg
    Spread spread = 0.0;
    DayCounter floatDayCount = Actual365Fixed();
    BusinessDayConvention floatPaymentConvention = ModifiedFollowing;
    Natural fixingDays = 0;
    ext::shared_ptr<IborIndex> floatIndex(new GBPLibor(Period(6,Months),
                                                         common.nominalTS));

    // fixed x inflation leg
    Rate fixedRate = 0.1;//1% would be 0.01
    Real baseCPI = 206.1; // would be 206.13871 if we were interpolating
    DayCounter fixedDayCount = Actual365Fixed();
    BusinessDayConvention fixedPaymentConvention = ModifiedFollowing;
    Calendar fixedPaymentCalendar = UnitedKingdom();
    ext::shared_ptr<ZeroInflationIndex> fixedIndex = common.ii;
    Period contractObservationLag = common.contractObservationLag;
    CPI::InterpolationType observationInterpolation = common.contractObservationInterpolation;

    // set the schedules
    Date startDate(2, October, 2007);
    Date endDate(2, October, 2052);
    Schedule floatSchedule = MakeSchedule().from(startDate).to(endDate)
    .withTenor(Period(6,Months))
    .withCalendar(UnitedKingdom())
    .withConvention(floatPaymentConvention)
    .backwards()
    ;
    Schedule fixedSchedule = MakeSchedule().from(startDate).to(endDate)
    .withTenor(Period(6,Months))
    .withCalendar(UnitedKingdom())
    .withConvention(Unadjusted)
    .backwards()
    ;


    CPISwap zisV(type, nominal, subtractInflationNominal,
                 spread, floatDayCount, floatSchedule,
                 floatPaymentConvention, fixingDays, floatIndex,
                 fixedRate, baseCPI, fixedDayCount, fixedSchedule,
                 fixedPaymentConvention, contractObservationLag,
                 fixedIndex, observationInterpolation);
    Date asofDate = Settings::instance().evaluationDate();

    Real floatFix[] = {0.06255,0.05975,0.0637,0.018425,0.0073438,-1,-1};
    Real cpiFix[] = {211.4,217.2,211.4,213.4,-2,-2};
    for(Size i=0;i<floatSchedule.size(); i++){
        if (floatSchedule[i] < common.evaluationDate) {
            floatIndex->addFixing(floatSchedule[i], floatFix[i],true);//true=overwrite
        }

        ext::shared_ptr<CPICoupon>
        zic = ext::dynamic_pointer_cast<CPICoupon>(zisV.cpiLeg()[i]);
        if (zic) {
            if (zic->fixingDate() < (common.evaluationDate - Period(1,Months))) {
                fixedIndex->addFixing(zic->fixingDate(), cpiFix[i],true);
            }
        }
    }


    // simple structure so simple pricing engine - most work done by index
    ext::shared_ptr<DiscountingSwapEngine>
        dse(new DiscountingSwapEngine(common.nominalTS));

    zisV.setPricingEngine(dse);

    // get float+spread & fixed*inflation leg prices separately
    Real testInfLegNPV = 0.0;
    for(Size i=0;i<zisV.leg(0).size(); i++){

        Date zicPayDate = (zisV.leg(0))[i]->date();
        if(zicPayDate > asofDate) {
            testInfLegNPV += (zisV.leg(0))[i]->amount()*common.nominalTS->discount(zicPayDate);
        }

        ext::shared_ptr<CPICoupon>
            zicV = ext::dynamic_pointer_cast<CPICoupon>(zisV.cpiLeg()[i]);
        if (zicV) {
            Real diff = fabs( zicV->rate() - (fixedRate*(zicV->indexFixing()/baseCPI)) );
            QL_REQUIRE(diff<1e-8,"failed "<<i<<"th coupon reconstruction as "
                       << (fixedRate*(zicV->indexFixing()/baseCPI)) << " vs rate = "
                       <<zicV->rate() << ", with difference: " << diff);
        }
    }

    Real error = fabs(testInfLegNPV - zisV.legNPV(0));
    QL_REQUIRE(error<1e-5,
               "failed manual inf leg NPV calc vs pricing engine: " <<
               testInfLegNPV << " vs " << zisV.legNPV(0));

    Real diff = fabs(1-zisV.NPV()/4191660.0);
    #ifndef QL_USE_INDEXED_COUPON
    Real max_diff = 1e-5;
    #else
    Real max_diff = 3e-5;
    #endif
    QL_REQUIRE(diff<max_diff,
               "failed stored consistency value test, ratio = " << diff);

    // remove circular refernce
    common.hcpi.linkTo(ext::shared_ptr<ZeroInflationTermStructure>());
}
void ConvertibleBondTest::testRegression() {

    BOOST_TEST_MESSAGE(
       "Testing fixed-coupon convertible bond in known regression case...");

    using namespace boost;

    SavedSettings backup;

    Date today = Date(23, December, 2008);
    Date tomorrow = today + 1;

    Settings::instance().evaluationDate() = tomorrow;

    Handle<Quote> u(shared_ptr<Quote>(new SimpleQuote(2.9084382818797443)));

    std::vector<Date> dates(25);
    std::vector<Rate> forwards(25);
    dates[0] = Date(29,December,2008);   forwards[0] = 0.0025999342800;
    dates[1] = Date(5,January,2009);     forwards[1] = 0.0025999342800;
    dates[2] = Date(29,January,2009);    forwards[2] = 0.0053123275500;
    dates[3] = Date(27,February,2009);   forwards[3] = 0.0197049598721;
    dates[4] = Date(30,March,2009);      forwards[4] = 0.0220524845296;
    dates[5] = Date(29,June,2009);       forwards[5] = 0.0217076395643;
    dates[6] = Date(29,December,2009);   forwards[6] = 0.0230349627478;
    dates[7] = Date(29,December,2010);   forwards[7] = 0.0087631647476;
    dates[8] = Date(29,December,2011);   forwards[8] = 0.0219084299499;
    dates[9] = Date(31,December,2012);   forwards[9] = 0.0244798766219;
    dates[10] = Date(30,December,2013);  forwards[10] = 0.0267885498456;
    dates[11] = Date(29,December,2014);  forwards[11] = 0.0266922867562;
    dates[12] = Date(29,December,2015);  forwards[12] = 0.0271052126386;
    dates[13] = Date(29,December,2016);  forwards[13] = 0.0268829891648;
    dates[14] = Date(29,December,2017);  forwards[14] = 0.0264594744498;
    dates[15] = Date(31,December,2018);  forwards[15] = 0.0273450367424;
    dates[16] = Date(30,December,2019);  forwards[16] = 0.0294852614749;
    dates[17] = Date(29,December,2020);  forwards[17] = 0.0285556119719;
    dates[18] = Date(29,December,2021);  forwards[18] = 0.0305557764659;
    dates[19] = Date(29,December,2022);  forwards[19] = 0.0292244738422;
    dates[20] = Date(29,December,2023);  forwards[20] = 0.0263917004194;
    dates[21] = Date(29,December,2028);  forwards[21] = 0.0239626970243;
    dates[22] = Date(29,December,2033);  forwards[22] = 0.0216417108090;
    dates[23] = Date(29,December,2038);  forwards[23] = 0.0228343838422;
    dates[24] = Date(31,December,2199);  forwards[24] = 0.0228343838422;

    Handle<YieldTermStructure> r(shared_ptr<YieldTermStructure>(
                             new ForwardCurve(dates, forwards, Actual360())));

    Handle<BlackVolTermStructure> sigma(shared_ptr<BlackVolTermStructure>(
            new BlackConstantVol(tomorrow, NullCalendar(), 21.685235548092248,
                                 Thirty360(Thirty360::BondBasis))));

    shared_ptr<BlackProcess> process(new BlackProcess(u,r,sigma));

    Handle<Quote> spread(shared_ptr<Quote>(
                                     new SimpleQuote(0.11498700678012874)));

    Date issueDate(23, July, 2008);
    Date maturityDate(1, August, 2013);
    Calendar calendar = UnitedStates();
    Schedule schedule = MakeSchedule().from(issueDate)
                                      .to(maturityDate)
                                      .withTenor(6*Months)
                                      .withCalendar(calendar)
                                      .withConvention(Unadjusted);
    Integer settlementDays = 3;
    shared_ptr<Exercise> exercise(new EuropeanExercise(maturityDate));
    Real conversionRatio = 100.0/20.3175;
    std::vector<Rate> coupons(schedule.size()-1, 0.05);
    DayCounter dayCounter = Thirty360(Thirty360::BondBasis);
    CallabilitySchedule no_callability;
    DividendSchedule no_dividends;
    Real redemption = 100.0;

    ConvertibleFixedCouponBond bond(exercise, conversionRatio,
                                    no_dividends, no_callability,
                                    spread, issueDate, settlementDays,
                                    coupons, dayCounter,
                                    schedule, redemption);
    bond.setPricingEngine(shared_ptr<PricingEngine>(
             new BinomialConvertibleEngine<CoxRossRubinstein>(process, 600)));

    try {
        Real x = bond.NPV();  // should throw; if not, an INF was not detected.
        BOOST_FAIL("INF result was not detected: " << x << " returned");
    } catch (Error&) {
        // as expected. Do nothing.

        // Note: we're expecting an Error we threw, not just any
        // exception.  If something else is thrown, then there's
        // another problem and the test must fail.
    }
}