boost::shared_ptr<HazardRateStructure> qlHazardRateFactory::hazardRateTS(TiXmlNode* node)
{
    boost::shared_ptr<HazardRateStructure> hazardCurve;

    Date referenceDate = Settings::instance().evaluationDate();

    std::vector<boost::shared_ptr<DefaultProbabilityHelper> > instruments;

    qlCalendarFactory calFactory = qlCalendarFactory();
    qlTimeUnitFactory timeUnitFactory = qlTimeUnitFactory();
    qlYieldTermStructureFactory tsFactory = qlYieldTermStructureFactory();

    Calendar calendar = calFactory.calendar(node->FirstChildElement("calendar")->GetText());
    Real recoveryRate = strToDouble(node->FirstChildElement("recoveryRate")->GetText());

    TiXmlElement* rateNode = node->FirstChildElement("rateData");

    std::vector<Period> periods;
    std::vector<Real> spreadRates;

    if(rateNode)
    {
        for(rateNode; rateNode; rateNode = rateNode->NextSiblingElement("rateData"))
        {
            periods.push_back(timeUnitFactory.timeUnit(rateNode));
            spreadRates.push_back(strToDouble(rateNode->FirstChildElement("data")->GetText()));
        }
    }

    for (Size i=0; i<periods.size(); i++) {
        instruments.push_back(boost::shared_ptr<DefaultProbabilityHelper>(
                                  new SpreadCdsHelper(
                                      Handle<Quote>(boost::shared_ptr<Quote>(
                                              new SimpleQuote(spreadRates[i]))),
                                      periods[i],
                                      0,
                                      calendar,
                                      Quarterly,
                                      Following,
                                      DateGeneration::TwentiethIMM,
                                      Actual365Fixed(),
                                      recoveryRate,
                                      tsCurve_)));
    }

    // Bootstrap hazard rates

    std::string curveType = "HazardRate";
    std::string interpolationType = "BackwardFlat";

    boost::shared_ptr<PiecewiseDefaultCurve<HazardRate, BackwardFlat> >
    hazardRateStructure(
        new PiecewiseDefaultCurve<HazardRate, BackwardFlat>(
            referenceDate,
            instruments,
            Actual365Fixed()));

    return hazardCurve;
}
Exemple #2
0
 boost::shared_ptr<SmileSection>
 SwaptionVolCube2::smileSectionImpl(const Date& optionDate,
                                    const Period& swapTenor) const {
     calculate();
     Rate atmForward = atmStrike(optionDate, swapTenor);
     Volatility atmVol = atmVol_->volatility(optionDate,
                                             swapTenor,
                                             atmForward);
     Time optionTime = timeFromReference(optionDate);
     Real exerciseTimeSqrt = std::sqrt(optionTime);
     std::vector<Real> strikes, stdDevs;
     strikes.reserve(nStrikes_);
     stdDevs.reserve(nStrikes_);
     Time length = swapLength(swapTenor);
     for (Size i=0; i<nStrikes_; ++i) {
         strikes.push_back(atmForward + strikeSpreads_[i]);
         stdDevs.push_back(exerciseTimeSqrt*(
             atmVol + volSpreadsInterpolator_[i](length, optionTime)));
     }
     Real shift = atmVol_->shift(optionTime,length);
     return boost::shared_ptr<SmileSection>(new
         InterpolatedSmileSection<Linear>(optionTime,
                                          strikes,
                                          stdDevs,
                                          atmForward,
                                          Linear(),
                                          Actual365Fixed(),
                                          volatilityType(),
                                          shift));
 }
void SimpleRangeAccrualRateETI::initializeImpl(const TimeGrid& timeGrid,
				const boost::shared_ptr<YieldTermStructure>& discountCurve,
				const boost::shared_ptr<PathGeneratorFactory>& pathGenFactory)
{
	referenceCalculation_->initialize(timeGrid,discountCurve,pathGenFactory);
	this->payoffDateInfo_->initialize(timeGrid,discountCurve,pathGenFactory);

	this->rangeNum_ = simpleRangeRateList_.size();
	this->assetNum_ = pathGenFactory->numAssets();
	
	Date today = Settings::instance().evaluationDate();
	
	DayCounter dayCounter = Actual365Fixed();

	double fixingStartTime = dayCounter.yearFraction( today , calculationStartDate_ );
	Size fixingStartPosition = timeGrid.closestIndex(fixingStartTime);

	double fixingEndTime = dayCounter.yearFraction( today , calculationEndDate_ );
	Size fixingEndPosition = timeGrid.closestIndex(fixingEndTime);

	Size fixingSize = fixingEndPosition - fixingStartPosition;
	
	this->fixingDatePositions_ = std::valarray<Size>(fixingSize);

	for ( Size position = 0 ; fixingSize ; position++ )
	{
		fixingDatePositions_[position] = fixingStartPosition + position;
	}

	for ( Size rng = 0 ; this->rangeNum_ ; rng++ )
	{
		simpleRangeRateList_[rng]->initialize(timeGrid,discountCurve,pathGenFactory);
	}
	
}
DayCounter ComponentMust::eff_convert_basis(std::string basis) const
{
	//cette fonction fait la conversion 
	//de la convention de calcul (basis) de type string lue de XML de MUST

	// daycounter;
	if (basis == "A360")
		return Actual360();

	if (basis == "A365")
		return Actual365Fixed();

	if (basis == "Actual")
		return ActualActual();

	if (basis == "Daily Price")
		return OneDayCounter();

	if (basis == "Business 252")
		return Business252();

	if (basis == "JGB")
		return Actual365NoLeap();

	if (basis == "30/360")
		return Thirty360(Thirty360::EurobondBasis);


	return Thirty360();

}
void CompositeSumOptionPricer::initializeImpl(const TimeGrid& timeGrid,
							   const boost::shared_ptr<YieldTermStructure>& discountCurve,
							   const boost::shared_ptr<PathGeneratorFactory>& pathGenFactory)
{
	//this->referenceCal_->initialize(timeGrid,discountCurve);

	for (Size i=0 ; i < optionListNum_ ; i++)
	{
		optionList_[i]->initialize(timeGrid,discountCurve,pathGenFactory);
	}

	this->payoffDateInfo_->initialize(timeGrid,discountCurve,pathGenFactory);

	Date today = Settings::instance().evaluationDate();
	
	DayCounter dayCounter = Actual365Fixed();
	
	//this->discount_ = Array(1);

	//double payoffTime = dayCounter.yearFraction( today , payoffDateInfo_-> );
	//payoffDatePositions_[0] = timeGrid.closestIndex(payoffTime);

	//discount_[0] = discountCurve->discount(payoffTime);
	
}
 ScenarioGenerator(const Calendar &calendar = NullCalendar(),
                   const DayCounter &dc = Actual365Fixed())
     : calendar_(calendar), dc_(dc), pathNumber_(0), validPath_(true),
       validHorizonDate_(true) {
     resetHorizonDate();
     baseDate_ = horizonDate_;
 }
Exemple #7
0
 DailyTenorGBPLibor(Natural settlementDays,
                    const Handle<YieldTermStructure>& h =
                             Handle<YieldTermStructure>())
 : DailyTenorLibor("GBPLibor", settlementDays,
                   GBPCurrency(),
                   UnitedKingdom(UnitedKingdom::Exchange),
                   Actual365Fixed(), h) {}
Exemple #8
0
 GBPLibor(const Period& tenor,
          const Handle<YieldTermStructure>& h =
                             Handle<YieldTermStructure>())
 : Libor("GBPLibor", tenor,
         0,
         GBPCurrency(),
         UnitedKingdom(UnitedKingdom::Exchange),
         Actual365Fixed(), h) {}
Exemple #9
0
 Euribor365::Euribor365(const Period& tenor,
                        const Handle<YieldTermStructure>& h)
 : IborIndex("Euribor365", tenor,
             2, // settlement days
             EURCurrency(), TARGET(),
             euriborConvention(tenor), euriborEOM(tenor),
             Actual365Fixed(), h) {
     QL_REQUIRE(this->tenor().units()!=Days,
                "for daily tenors (" << this->tenor() <<
                ") dedicated DailyTenor constructor must be used");
 }
Exemple #10
0
 THBFIX(const Period& tenor,
        const Handle<YieldTermStructure>& h =
                             Handle<YieldTermStructure>())
 : IborIndex("THBFIX", tenor,
             2,
             THBCurrency(),
             JointCalendar(UnitedKingdom(UnitedKingdom::Exchange),
                           JointCalendar(UnitedStates(UnitedStates::LiborImpact),
                                         Thailand())),
             ModifiedFollowing, true,
             Actual365Fixed(), h) {}
Exemple #11
0
	boost::shared_ptr<BlackVolTermStructure> ProcessInfo::ProcessParser_Impl::
			make_vol_ts(const std::string& keyName,
								std::map<std::string, std::string>& variable_map,
								std::map<std::string, std::vector<std::string>>& variable_array_map,
								std::map<std::string, Matrix>& variable_matrix_map)
	{
		boost::shared_ptr<BlackVolTermStructure> vol_ts;

		Date refDate = Settings::instance().evaluationDate();

		const std::string& vol_type = "TYPE";

		if (variable_map.find(keyName) != variable_map.end())
		{
			double value = std::stod(variable_map[keyName]);
			vol_ts = boost::shared_ptr<BlackConstantVol>(
				new BlackConstantVol(refDate, NullCalendar(), value, Actual365Fixed()));

			return vol_ts;
		}

		vol_ts = boost::shared_ptr<BlackConstantVol>(
			new BlackConstantVol(refDate, NullCalendar(), 0.3, Actual365Fixed()));
		
		//if (vol_type == "CONSTANT")
		//{
		//	vol_ts = boost::shared_ptr<BlackConstantVol>(
		//		new BlackConstantVol(refDate, NullCalendar(), 0.3, Actual365Fixed()));
		//}
		//else if (vol_type == "CURVE")
		//{
		//}
		//else if (vol_type == "SURFACE")
		//{
		//}
		//else
		//{
		//}

		return vol_ts;
	}
Exemple #12
0
 MakeCapFloor::MakeCapFloor(CapFloor::Type capFloorType,
                            const Period& tenor,
                            const shared_ptr<IborIndex>& iborIndex,
                            Rate strike,
                            const Period& forwardStart)
 : capFloorType_(capFloorType), strike_(strike),
   firstCapletExcluded_(forwardStart==0*Days), asOptionlet_(false),
   // setting the fixed leg tenor avoids that MakeVanillaSwap throws
   // because of an unknown fixed leg default tenor for a currency,
   // notice that only the floating leg of the swap is used anyway
   makeVanillaSwap_(MakeVanillaSwap(tenor, iborIndex, 0.0, forwardStart)
                    .withFixedLegTenor(1*Years).withFixedLegDayCount(Actual365Fixed())) {}
Exemple #13
0
 Bbsw(const Period& tenor,
      const Handle<YieldTermStructure>& h =
          Handle<YieldTermStructure>())
     : IborIndex("Bbsw", tenor,
                 0, // settlement days
                 AUDCurrency(), Australia(),
                 HalfMonthModifiedFollowing, true,
                 Actual365Fixed(), h) {
     QL_REQUIRE(this->tenor().units() != Days,
                "for daily tenors (" << this->tenor() <<
                ") dedicated DailyTenor constructor must be used");
 }
 BlackScholesProcess::BlackScholesProcess(
                           const Handle<Quote>& x0,
                           const Handle<YieldTermStructure>& riskFreeTS,
                           const Handle<BlackVolTermStructure>& blackVolTS,
                           const boost::shared_ptr<discretization>& d)
 : GeneralizedBlackScholesProcess(
          x0,
          // no dividend yield
          Handle<YieldTermStructure>(boost::shared_ptr<YieldTermStructure>(
               new FlatForward(0, NullCalendar(), 0.0, Actual365Fixed()))),
          riskFreeTS,
          blackVolTS,
          d) {}
 Real SwaptionHelper::blackPrice(Volatility sigma) const {
     calculate();
     Handle<Quote> vol(boost::shared_ptr<Quote>(new SimpleQuote(sigma)));
     boost::shared_ptr<PricingEngine> engine;
     switch(volatilityType_) {
     case ShiftedLognormal:
         engine = boost::make_shared<BlackSwaptionEngine>(
             termStructure_, vol, Actual365Fixed(), shift_);
         break;
     case Normal:
         engine = boost::make_shared<BachelierSwaptionEngine>(
             termStructure_, vol, Actual365Fixed());
         break;
     default:
         QL_FAIL("can not construct engine: " << volatilityType_);
         break;
     }
     swaption_->setPricingEngine(engine);
     Real value = swaption_->NPV();
     swaption_->setPricingEngine(engine_);
     return value;
 }
Exemple #16
0
	MurexCurve::MurexCurve(Date referenceDate,
				vector<Date> maturities,
				vector<double> discounts,
				long interpolationMode
				) :	refDate_(referenceDate),maturities_(maturities),discounts_(discounts),interpolationMode_(interpolationMode)
	{
		QL_REQUIRE(maturities.size()==discounts.size(),"Maturities size (" << maturities.size() << ") must match discounts size (" << discounts.size() << ")");
		QL_REQUIRE(interpolationMode_==0 || interpolationMode_==1,"Interpolation Mode (" << interpolationMode_ << ") must be 0 or 1.");
		dc_=Actual365Fixed();
		n_=maturities.size()+1;
		times_=vector<double>(n_);
		rates_=vector<double>(n_);
		calculate();
	}
Exemple #17
0
 GbpLiborSwapIsdaFix::GbpLiborSwapIsdaFix(
                         const Period& tenor,
                         const Handle<YieldTermStructure>& h)
 : SwapIndex("GbpLiborSwapIsdaFix", // familyName
             tenor,
             0, // settlementDays
             GBPCurrency(),
             UnitedKingdom(UnitedKingdom::Exchange),
             tenor > 1*Years ? // fixedLegTenor
                 6*Months : 1*Years,
             ModifiedFollowing, // fixedLegConvention
             Actual365Fixed(), // fixedLegDaycounter
             tenor > 1*Years ?
                 shared_ptr<IborIndex>(new GBPLibor(6*Months, h)) :
                 shared_ptr<IborIndex>(new GBPLibor(3*Months, h))) {}
Exemple #18
0
	boost::shared_ptr<YieldTermStructure> ProcessInfo::ProcessParser_Impl::make_yield_ts(
							const std::string& keyName,
							std::map<std::string, std::string>& variable_map,
							std::map<std::string, std::vector<std::string>>& variable_array_map,
							std::map<std::string, Matrix>& variable_matrix_map)
	{
		Date refDate = Settings::instance().evaluationDate();

		boost::shared_ptr<YieldTermStructure> yield_ts;

		if (variable_map.find(keyName) != variable_map.end())
		{
			double value = std::stod(variable_map[keyName]);
			yield_ts = boost::shared_ptr<YieldTermStructure>(new FlatForward(refDate, value, Actual365Fixed()));

			return yield_ts;
		}

		std::string tenor_key = keyName + "_CURVE_TENOR";
		std::string value_key = keyName + "_CURVE_VALUE";
		std::string interpolation_key = keyName + "_CURVE_INTERPOLATION";
		
		if (variable_array_map.find(tenor_key) == variable_array_map.end())
			QL_FAIL(tenor_key << " does not exist.");
		if (variable_array_map.find(value_key) == variable_array_map.end())
			QL_FAIL(value_key << " does not exist.");

		std::vector<std::string> periods = variable_array_map[tenor_key];
		std::vector<std::string> values = variable_array_map[value_key];
		std::vector<Real> data;

		// converting
		for (Size i = 0; i < values.size(); i++)
			data.push_back(std::stod(values[i]));

		QL_REQUIRE(periods.size() == data.size(), "tenor size must be same to value size");

		std::string interpolatedID = "LINEAR";

		if (variable_map.find(interpolation_key) != variable_map.end())
			interpolatedID = variable_map[interpolation_key];
			//QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used");

		yield_ts = CurveManager::instance().get_yield_curve(refDate, periods, data, interpolatedID);

		return yield_ts;

	}
	IBFRSwap::IBFRSwap(Type type,
					   Real nominal,
		               Date startDate,
		               Period swapTenor,
		               Period paymentTenor,
		               Rate fixedRate,
					   Rate rateSpread,
					   const boost::shared_ptr<RepoChina>& iborIndex)
					   :RepoCompoundingSwap(type, nominal,
					   Schedule(startDate, startDate + swapTenor, paymentTenor, China(), ModifiedFollowing, ModifiedFollowing, DateGeneration::Backward, false),
					   fixedRate,
					   Actual365Fixed(),
					   Schedule(startDate, startDate + swapTenor, paymentTenor, China(), ModifiedFollowing, ModifiedFollowing, DateGeneration::Backward, false),
					   iborIndex,
					   rateSpread,
					   0.0,
					   Actual360(),
					   Following) {}
    Real InterpolatedYoYOptionletStripper<Interpolator1D>::
    ObjectiveFunction::operator()(Volatility guess) const {

        vvec_[1] = guess;
        vvec_[0] = guess - slope_ * (tvec_[1] - tvec_[0]) * guess;
        // could have Interpolator1D instead of Linear
        boost::shared_ptr<InterpolatedYoYOptionletVolatilityCurve<Linear> >
        vCurve(
            new InterpolatedYoYOptionletVolatilityCurve<Linear>(
                                               0, TARGET(), ModifiedFollowing,
                                               Actual365Fixed(), lag_,
                                               frequency_, indexIsInterpolated_,
                                               dvec_, vvec_,
                                               -1.0, 3.0) ); // strike limits
        Handle<YoYOptionletVolatilitySurface> hCurve(vCurve);
        p_->setVolatility(hCurve);
        // hopefully this gets to the pricer ... then
        return priceToMatch_ - capfloor_.NPV();
    }
 boost::shared_ptr<SmileSection>
 StrippedOptionletAdapter::smileSectionImpl(Time t) const {
     std::vector< Rate > optionletStrikes =
         optionletStripper_->optionletStrikes(
             0); // strikes are the same for all times ?!
     std::vector< Real > stddevs;
     for (Size i = 0; i < optionletStrikes.size(); i++) {
         stddevs.push_back(volatilityImpl(t, optionletStrikes[i]) *
                           std::sqrt(t));
     }
     // Extrapolation may be a problem with splines, but since minStrike()
     // and maxStrike() are set, we assume that no one will use stddevs for
     // strikes outside these strikes
     CubicInterpolation::BoundaryCondition bc =
         optionletStrikes.size() >= 4 ? CubicInterpolation::Lagrange
                                      : CubicInterpolation::SecondDerivative;
     return boost::make_shared< InterpolatedSmileSection< Cubic > >(
         t, optionletStrikes, stddevs, Null< Real >(),
         Cubic(CubicInterpolation::Spline, false, bc, 0.0, bc, 0.0),
         Actual365Fixed(), volatilityType(), displacement());
 }
void SimpleRangeRateETI::initializeImpl(const TimeGrid& timeGrid,
				const boost::shared_ptr<YieldTermStructure>& discountCurve,
				const boost::shared_ptr<PathGeneratorFactory>& pathGenFactory)
{
	this->payoffDateInfo_->initialize(timeGrid,discountCurve,pathGenFactory);
	
	for ( Size i=0 ; i < simpleRangeEventList_.size() ; i++ )
	{
		simpleRangeEventList_[i]->initialize(timeGrid,discountCurve,pathGenFactory);
	}

	this->rangeNum_ = simpleRangeEventList_.size();
	this->assetNum_ = pathGenFactory->numAssets();

	Date today = Settings::instance().evaluationDate();
	
	DayCounter dayCounter = Actual365Fixed();

	double calculationYearFrac = 0.0;

	if ( today < calculationEndDate_ )
	{
		calculationYearFrac = dayCounter.yearFraction( calculationStartDate_ , calculationEndDate_ );
	}

	//if ( today < calculationStart_ )
	//{
	//	calculationYearFrac = dayCounter.yearFraction( calculationStart_ , calculationEnd_ );
	//}
	//else if ( today > calculationEnd_ )
	//{
	//	calculationYearFrac = 0.0;//dayCounter.yearFraction( today , calculationEnd_ );
	//}
	//else {}

	this->yearFrac_ = calculationYearFrac;

}
ClonedYieldTermStructure::ClonedYieldTermStructure(
    const boost::shared_ptr<YieldTermStructure> &source,
    const ReactionToTimeDecay reactionToTimeDecay, const Processing processing,
    const Calendar calendar)
    : YieldTermStructure(source->dayCounter()),
      reactionToTimeDecay_(reactionToTimeDecay), processing_(processing),
      originalEvalDate_(Settings::instance().evaluationDate()),
      originalReferenceDate_(Date(source->referenceDate())),
      originalMaxDate_(source->maxDate()) {

    calendar_ = calendar.empty() ? source->calendar() : calendar;
    QL_REQUIRE(!calendar_.empty() || reactionToTimeDecay_ == FixedReferenceDate,
               "a floating termstructure needs a calendar, none given and "
               "source termstructures' calendar is empty, too");

    referenceDate_ = originalReferenceDate_;
    maxDate_ = originalMaxDate_;
    offset_ = 0.0;
    valid_ = true;

    instFwdMax_ =
        source->forwardRate(maxDate_, maxDate_, Actual365Fixed(), Continuous)
            .rate();

    if (reactionToTimeDecay != FixedReferenceDate) {
        QL_REQUIRE(originalReferenceDate_ >= originalEvalDate_,
                   "to construct a moving term structure the source term "
                   "structure must have a reference date ("
                       << originalReferenceDate_
                       << ") after the evaluation date ("
                       << originalEvalDate_
                       << ")");
        try {
            impliedSettlementDays_ = source->settlementDays();
        } catch (...) {
            // if the source ts has no settlement days we imply
            // them from the difference of the original reference
            // date and the original evaluation date
            impliedSettlementDays_ = this->calendar().businessDaysBetween(
                originalEvalDate_, originalReferenceDate_);
        }
    }

    logDiscounts_.resize(originalMaxDate_.serialNumber() -
                      originalReferenceDate_.serialNumber() + 1);
    times_.resize(logDiscounts_.size());

    for (BigInteger i = 0; i <= originalMaxDate_.serialNumber() -
                                    originalReferenceDate_.serialNumber();
         ++i) {
        Date d = Date(originalReferenceDate_.serialNumber() + i);
        logDiscounts_[i] = std::log(source->discount(d));
        times_[i] = timeFromReference(d);
        if (processing == PositiveYieldsAndForwards) {
            logDiscounts_[i] = std::min(0.0, logDiscounts_[i]);
        }
        if (processing == PositiveForwards ||
            processing == PositiveYieldsAndForwards) {
            if (i > 0)
                logDiscounts_[i] = std::min(logDiscounts_[i - 1], logDiscounts_[i]);
        }
    }

    if (reactionToTimeDecay_ != FixedReferenceDate) {
        registerWith(Settings::instance().evaluationDate());
    }
}
Exemple #24
0
 Jibar(const Period& tenor,
       const Handle<YieldTermStructure>& h =
                             Handle<YieldTermStructure>())
 : IborIndex("Jibar", tenor, 0, ZARCurrency(),
         SouthAfrica(), ModifiedFollowing, false,
         Actual365Fixed(), h) {}
void qlMultiAssetCompositeOptionFactory::factoryMultiAssetCompositeOption()
{
	//TiXmlText* rootNode = new TiXmlText(instInfo_.c_str());
	TiXmlDocument document;
	document.Parse(instInfo_.c_str(), 0, TIXML_ENCODING_UTF8);

	//rootNode.SetValue;

	TiXmlNode* instNode = document.FirstChild("instrument");
	std::string code = instNode->FirstChild("code")->ToElement()->GetText();

	FpmlSerialized::Instrument xml_instrument = FpmlSerialized::Instrument(instNode);
	//boost::shared_ptr<FpmlSerialized::InstPositionInfo> xml_positionInfo = xml_instrument.getInstPositionInfo();
	//this->krCode_ = xml_positionInfo->getKrCode()->SValue();

	boost::shared_ptr<FpmlSerialized::Excel_interface> xml_interface = xml_instrument.getExcel_interface();

	boost::shared_ptr<FpmlSerialized::Excel_multiAssetCompositeOption> xml_multiAssetCompOption = xml_interface->getExcel_multiAssetCompositeOption();

	DayCounter daycounter = Actual365Fixed();
	Calendar calendar = SouthKorea(); // ?

	boost::shared_ptr<FpmlSerialized::Excel_noteInfo> xml_noteInfo = xml_multiAssetCompOption->getExcel_issueInfo()->getExcel_noteInfo();

	//Date tradeDate = xml_noteInfo->getTradeDate()->dateValue();
	Date effectiveDate = xml_noteInfo->getEffectiveDate()->dateValue();
	Date maturityDate = xml_noteInfo->getMaturityDate()->dateValue();
	notional_ = xml_noteInfo->getNotional()->DValue();

	std::vector<boost::shared_ptr<FpmlSerialized::Excel_multiAsset_compositeOption_subtype>> xml_multiAssetCompOptionSubList = xml_multiAssetCompOption->getExcel_multiAsset_compositeOption_subtype();
	std::vector<boost::shared_ptr<QuantLib::EventTriggerInfo>> ql_etiList;

	qlEventTriggerInfoFactory qetif = qlEventTriggerInfoFactory();

	for(Size i = 0 ; i<xml_multiAssetCompOptionSubList.size(); ++i )
	{
		const boost::shared_ptr<EventTriggerInfo>& ql_eti
			= qetif.multiAssetCompOptionSubType(xml_multiAssetCompOptionSubList[i]);

		ql_etiList.push_back(ql_eti);

	}

	qlFixingDateInfoFactory ql_fdf = qlFixingDateInfoFactory();

	Real notionalPayment = xml_multiAssetCompOption->getNotionalMaturityPayment()->DValue();

	Date notionalPayment_PayoffDate = xml_multiAssetCompOption->getPayoffDate()->dateValue();

	const boost::shared_ptr<QuantLib::FixingDateInfo>& ql_fdi = ql_fdf.fixingDateInfo(notionalPayment_PayoffDate);

	/*const boost::shared_ptr<MCPricer>& pricer*/
	this->pricer_ = boost::shared_ptr<CompositeSumOptionPricer>( 
								new CompositeSumOptionPricer(notionalPayment,
															ql_fdi,
															ql_etiList));

	// --------------------------------- Engine ---------------------------------------------

	//boost::shared_ptr<FpmlSerialized::Excel_underlyingCalcInfo_para> xml_underlyingCalcInfo_para = xml_hifive->getExcel_underlyingCalcInfo();

	const boost::shared_ptr<NoteInst>& noteInst
			= boost::shared_ptr<NoteInst>(
						new NoteInst(code,notional_,
									effectiveDate,
									maturityDate,
									daycounter,
									calendar));

	this->engine_ = engine();

	noteInst->setPricingEngine(this->engine_);

	this->instrument_ = noteInst;

	//std::cout << "Start" << std::endl;
	//inst_->setPricingEngine(elsEngine);
	//std::cout << "Eu price                    : " << els100.NPV() << std::endl;

	//std::cout << "Calculation End" << std::endl;
}
Exemple #26
0
	boost::shared_ptr<SwaptionVolatilityStructure> ProcessInfo::ProcessParser_Impl::
			make_swaption_vol_ts(std::map<std::string, std::string>& variable_map,
								std::map<std::string, std::vector<std::string>>& variable_array_map,
								std::map<std::string, Matrix>& variable_matrix_map)
	{
		boost::shared_ptr<SwaptionVolatilityStructure> swaption_vol_ts;

		Date refDate = Settings::instance().evaluationDate();

		const Calendar& calendar = NullCalendar();
		BusinessDayConvention bdc = BusinessDayConvention::ModifiedFollowing;
		DayCounter daycounter = Actual365Fixed();

		std::string type_key = "SWAPTION_TYPE";

		if (variable_map.find(type_key) == variable_map.end())
			QL_FAIL(type_key << " does not exist.");

		std::string vol_type = variable_map[type_key];

		if (vol_type == "CONSTANT")
		{
			std::string swaption_flat_vol_key = "SWAP_VOL_CONSTANT";

			if (variable_array_map.find(swaption_flat_vol_key) == variable_array_map.end())
				QL_FAIL(swaption_flat_vol_key << " does not exist.");

			Real flatVol = 0.0;

			swaption_vol_ts = boost::shared_ptr<SwaptionVolatilityStructure>(
				new ConstantSwaptionVolatility(refDate, calendar, bdc, flatVol, daycounter));

		}
		else if (vol_type == "SURFACE")
		{
			std::string optionTenor_key = "SWAPTION_VOL_SURFACE_OPTIONTENOR";
			std::string swapTenor_key = "SWAPTION_VOL_SURFACE_SWAPTENOR";
			std::string value_key = "SWAPTION_VOL_SURFACE_VALUE";

			if (variable_array_map.find(optionTenor_key) == variable_array_map.end())
				QL_FAIL(optionTenor_key << " does not exist.");
			if (variable_array_map.find(swapTenor_key) == variable_array_map.end())
				QL_FAIL(swapTenor_key << " does not exist.");
			if (variable_matrix_map.find(value_key) == variable_matrix_map.end())
				QL_FAIL(value_key << " does not exist.");

			std::vector<std::string> optionTenors = variable_array_map[optionTenor_key];
			std::vector<std::string> swapTenors = variable_array_map[swapTenor_key];

			Matrix value_matrix = variable_matrix_map[value_key];

			std::vector<Period> optionPeriod_data;
			std::vector<Period> swapPeriod_data;

			for (Size i = 0; i < optionTenors.size(); i++)
				optionPeriod_data.push_back(PeriodParser::parse(optionTenors[i]));

			for (Size i = 0; i < swapTenors.size(); i++)
				swapPeriod_data.push_back(PeriodParser::parse(swapTenors[i]));

			// converting
			QL_REQUIRE(optionTenors.size() * swapTenors.size() == value_matrix.rows() * value_matrix.columns(), "tenor * strike must be same to value matrix size");

			//std::string interpolatedID = "LINEAR";

			//if (variable_map.find(interpolation_key) != variable_map.end())
			//	interpolatedID = variable_map[interpolation_key];
			//QL_DEBUG(tenor_key << " does not exist. Linear interpolation is used");
			swaption_vol_ts = boost::shared_ptr<SwaptionVolatilityStructure>(
				new SwaptionVolatilityMatrix(refDate, calendar, bdc, 
											optionPeriod_data, 
											swapPeriod_data, 
											value_matrix, 
											daycounter));

		
		}
		else if (vol_type == "CUBE")
		{
			QL_FAIL("not implemeted");
		}
		else
		{

		}

		return swaption_vol_ts;
	}
Exemple #27
0
 explicit Aonia(const Handle<YieldTermStructure>& h =
                       Handle<YieldTermStructure>())
 : OvernightIndex("Aonia", 0, AUDCurrency(),
                  Australia(),
                  Actual365Fixed(), h) {}
void VannaVolgaDoubleBarrierEngine::calculate() const {

    const Real sigmaShift_vega = 0.001;
    const Real sigmaShift_volga = 0.0001;
    const Real spotShift_delta = 0.0001 * spotFX_->value();
    const Real sigmaShift_vanna = 0.0001;

    Handle<Quote> x0Quote(  //used for shift
        boost::make_shared<SimpleQuote>(spotFX_->value()));
    Handle<Quote> atmVolQuote( //used for shift
        boost::make_shared<SimpleQuote>(atmVol_->value()));

    boost::shared_ptr<BlackVolTermStructure> blackVolTS =
        boost::make_shared<BlackConstantVol>(
            Settings::instance().evaluationDate(),
            NullCalendar(), atmVolQuote, Actual365Fixed());
    boost::shared_ptr<BlackScholesMertonProcess> stochProcess =
        boost::make_shared<BlackScholesMertonProcess>(
            x0Quote,
            foreignTS_,
            domesticTS_,
            Handle<BlackVolTermStructure>(blackVolTS));

    boost::shared_ptr<PricingEngine> engineBS =
        boost::make_shared<AnalyticDoubleBarrierEngine>(stochProcess,
                series_);

    BlackDeltaCalculator blackDeltaCalculatorAtm(
        Option::Call, atmVol_->deltaType(), x0Quote->value(),
        domesticTS_->discount(T_), foreignTS_->discount(T_),
        atmVol_->value() * sqrt(T_));
    Real atmStrike = blackDeltaCalculatorAtm.atmStrike(atmVol_->atmType());

    Real call25Vol = vol25Call_->value();
    Real put25Vol = vol25Put_->value();
    BlackDeltaCalculator blackDeltaCalculatorPut25(
        Option::Put, vol25Put_->deltaType(), x0Quote->value(),
        domesticTS_->discount(T_), foreignTS_->discount(T_),
        put25Vol * sqrt(T_));
    Real put25Strike = blackDeltaCalculatorPut25.strikeFromDelta(-0.25);
    BlackDeltaCalculator blackDeltaCalculatorCall25(
        Option::Call, vol25Call_->deltaType(), x0Quote->value(),
        domesticTS_->discount(T_), foreignTS_->discount(T_),
        call25Vol * sqrt(T_));
    Real call25Strike = blackDeltaCalculatorCall25.strikeFromDelta(0.25);

    //here use vanna volga interpolated smile to price vanilla
    std::vector<Real> strikes;
    std::vector<Real> vols;
    strikes.push_back(put25Strike);
    vols.push_back(put25Vol);
    strikes.push_back(atmStrike);
    vols.push_back(atmVol_->value());
    strikes.push_back(call25Strike);
    vols.push_back(call25Vol);
    VannaVolga vannaVolga(x0Quote->value(), foreignTS_->discount(T_), foreignTS_->discount(T_), T_);
    Interpolation interpolation = vannaVolga.interpolate(strikes.begin(), strikes.end(), vols.begin());
    interpolation.enableExtrapolation();
    const boost::shared_ptr<StrikedTypePayoff> payoff =
        boost::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
    Real strikeVol = interpolation(payoff->strike());
    //vannila option price
    Real vanillaOption = blackFormula(payoff->optionType(), payoff->strike(),
                                      x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                      strikeVol * sqrt(T_),
                                      domesticTS_->discount(T_));

    //already out
    if((x0Quote->value() > arguments_.barrier[1] || x0Quote->value() < arguments_.barrier[0])
            && arguments_.barrierType[0] == Barrier::DownOut) {
        results_.value = 0.0;
        results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierOutPrice"] = 0.0;
    }
    //already in
    else if((x0Quote->value() > arguments_.barrier[1] || x0Quote->value() < arguments_.barrier[0])
            && arguments_.barrierType[0] == Barrier::DownIn) {
        results_.value = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["VanillaPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierInPrice"] = adaptVanDelta_? bsPriceWithSmile_ : vanillaOption;
        results_.additionalResults["BarrierOutPrice"] = 0.0;
    }
    else {

        //set up BS barrier option pricing
        //only calculate out barrier option price
        // in barrier price = vanilla - out barrier
        boost::shared_ptr<StrikedTypePayoff> payoff
            = boost::static_pointer_cast<StrikedTypePayoff> (arguments_.payoff);
        DoubleBarrierOption doubleBarrierOption(arguments_.barrierType,
                                                arguments_.barrier,
                                                arguments_.rebate,
                                                payoff,
                                                arguments_.exercise);

        doubleBarrierOption.setPricingEngine(engineBS);

        //BS price
        Real priceBS = doubleBarrierOption.NPV();

        Real priceAtmCallBS = blackFormula(Option::Call,atmStrike,
                                           x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                           atmVol_->value() * sqrt(T_),
                                           domesticTS_->discount(T_));
        Real price25CallBS = blackFormula(Option::Call,call25Strike,
                                          x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                          atmVol_->value() * sqrt(T_),
                                          domesticTS_->discount(T_));
        Real price25PutBS = blackFormula(Option::Put,put25Strike,
                                         x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                         atmVol_->value() * sqrt(T_),
                                         domesticTS_->discount(T_));

        //market price
        Real priceAtmCallMkt = blackFormula(Option::Call,atmStrike,
                                            x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                            atmVol_->value() * sqrt(T_),
                                            domesticTS_->discount(T_));
        Real price25CallMkt = blackFormula(Option::Call,call25Strike,
                                           x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                           call25Vol * sqrt(T_),
                                           domesticTS_->discount(T_));
        Real price25PutMkt = blackFormula(Option::Put,put25Strike,
                                          x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_),
                                          put25Vol * sqrt(T_),
                                          domesticTS_->discount(T_));

        //Analytical Black Scholes formula
        NormalDistribution norm;
        Real d1atm = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/atmStrike)
                      + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_));
        Real vegaAtm_Analytical = x0Quote->value() * norm(d1atm) * sqrt(T_) * foreignTS_->discount(T_);
        Real vannaAtm_Analytical = vegaAtm_Analytical/x0Quote->value() *(1.0 - d1atm/(atmVolQuote->value()*sqrt(T_)));
        Real volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value();

        Real d125call = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/call25Strike)
                         + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_));
        Real vega25Call_Analytical = x0Quote->value() * norm(d125call) * sqrt(T_) * foreignTS_->discount(T_);
        Real vanna25Call_Analytical = vega25Call_Analytical/x0Quote->value() *(1.0 - d125call/(atmVolQuote->value()*sqrt(T_)));
        Real volga25Call_Analytical = vega25Call_Analytical * d125call * (d125call - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value();

        Real d125Put = (std::log(x0Quote->value()* foreignTS_->discount(T_)/ domesticTS_->discount(T_)/put25Strike)
                        + 0.5*std::pow(atmVolQuote->value(),2.0) * T_)/(atmVolQuote->value() * sqrt(T_));
        Real vega25Put_Analytical = x0Quote->value() * norm(d125Put) * sqrt(T_) * foreignTS_->discount(T_);
        Real vanna25Put_Analytical = vega25Put_Analytical/x0Quote->value() *(1.0 - d125Put/(atmVolQuote->value()*sqrt(T_)));
        Real volga25Put_Analytical = vega25Put_Analytical * d125Put * (d125Put - atmVolQuote->value() * sqrt(T_))/atmVolQuote->value();


        //BS vega
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega);
        doubleBarrierOption.recalculate();
        Real vegaBarBS = (doubleBarrierOption.NPV() - priceBS)/sigmaShift_vega;
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_vega);//setback

        //BS volga

        //vegaBar2
        //base NPV
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_volga);
        doubleBarrierOption.recalculate();
        Real priceBS2 = doubleBarrierOption.NPV();

        //shifted npv
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega);
        doubleBarrierOption.recalculate();
        Real vegaBarBS2 = (doubleBarrierOption.NPV() - priceBS2)/sigmaShift_vega;
        Real volgaBarBS = (vegaBarBS2 - vegaBarBS)/sigmaShift_volga;
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value()
                - sigmaShift_volga
                - sigmaShift_vega);//setback

        //BS Delta
        //base delta
        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//shift forth
        doubleBarrierOption.recalculate();
        Real priceBS_delta1 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);//shift back
        doubleBarrierOption.recalculate();
        Real priceBS_delta2 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() +  spotShift_delta);//set back
        Real deltaBar1 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta);

        //shifted vanna
        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() + sigmaShift_vanna);//shift sigma
        //shifted delta
        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() + spotShift_delta);//shift forth
        doubleBarrierOption.recalculate();
        priceBS_delta1 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);//shift back
        doubleBarrierOption.recalculate();
        priceBS_delta2 = doubleBarrierOption.NPV();

        boost::static_pointer_cast<SimpleQuote> (x0Quote.currentLink())->setValue(x0Quote->value() +  spotShift_delta);//set back
        Real deltaBar2 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta);

        Real vannaBarBS = (deltaBar2 - deltaBar1)/sigmaShift_vanna;

        boost::static_pointer_cast<SimpleQuote> (atmVolQuote.currentLink())->setValue(atmVolQuote->value() - sigmaShift_vanna);//set back

        //Matrix
        Matrix A(3,3,0.0);

        //analytical
        A[0][0] = vegaAtm_Analytical;
        A[0][1] = vega25Call_Analytical;
        A[0][2] = vega25Put_Analytical;
        A[1][0] = vannaAtm_Analytical;
        A[1][1] = vanna25Call_Analytical;
        A[1][2] = vanna25Put_Analytical;
        A[2][0] = volgaAtm_Analytical;
        A[2][1] = volga25Call_Analytical;
        A[2][2] = volga25Put_Analytical;

        Array b(3,0.0);
        b[0] = vegaBarBS;
        b[1] = vannaBarBS;
        b[2] = volgaBarBS;
        Array q = inverse(A) * b;

        Real H = arguments_.barrier[1];
        Real L = arguments_.barrier[0];
        Real theta_tilt_minus = ((domesticTS_->zeroRate(T_, Continuous) - foreignTS_->zeroRate(T_, Continuous))/atmVol_->value() - atmVol_->value()/2.0)*std::sqrt(T_);
        Real h = 1.0/atmVol_->value() * std::log(H/x0Quote->value())/std::sqrt(T_);
        Real l = 1.0/atmVol_->value() * std::log(L/x0Quote->value())/std::sqrt(T_);
        CumulativeNormalDistribution cnd;

        Real doubleNoTouch = 0.0;
        for(int j = -series_; j< series_; j++ ) {
            Real e_minus = 2*j*(h-l) - theta_tilt_minus;
            doubleNoTouch += std::exp(-2.0*j*theta_tilt_minus*(h-l))*(cnd(h+e_minus) - cnd(l+e_minus))
                             - std::exp(-2.0*j*theta_tilt_minus*(h-l)+2.0*theta_tilt_minus*h)*(cnd(h-2.0*h+e_minus) - cnd(l-2.0*h+e_minus));
        }

        Real p_survival = doubleNoTouch;

        Real lambda = p_survival ;
        Real adjust = q[0]*(priceAtmCallMkt - priceAtmCallBS)
                      + q[1]*(price25CallMkt - price25CallBS)
                      + q[2]*(price25PutMkt - price25PutBS);
        Real outPrice = priceBS + lambda*adjust;//
        Real inPrice;

        //adapt Vanilla delta
        if(adaptVanDelta_ == true) {
            outPrice += lambda*(bsPriceWithSmile_ - vanillaOption);
            //capfloored by (0, vanilla)
            outPrice = std::max(0.0, std::min(bsPriceWithSmile_, outPrice));
            inPrice = bsPriceWithSmile_ - outPrice;
        }
        else {
            //capfloored by (0, vanilla)
            outPrice = std::max(0.0, std::min(vanillaOption , outPrice));
            inPrice = vanillaOption - outPrice;
        }

        if(arguments_.barrierType[0] == Barrier::DownOut)
            results_.value = outPrice;
        else
            results_.value = inPrice;
        results_.additionalResults["VanillaPrice"] = vanillaOption;
        results_.additionalResults["BarrierInPrice"] = inPrice;
        results_.additionalResults["BarrierOutPrice"] = outPrice;
        results_.additionalResults["lambda"] = lambda;
    }
}
 void setConventions() {
     calendar = TARGET();
     optionBdc = ModifiedFollowing;
     dayCounter = Actual365Fixed();
 }
    MakeVanillaSwap::operator ext::shared_ptr<VanillaSwap>() const {

        Date startDate;
        if (effectiveDate_ != Date())
            startDate = effectiveDate_;
        else {
            Date refDate = Settings::instance().evaluationDate();
            // if the evaluation date is not a business day
            // then move to the next business day
            refDate = floatCalendar_.adjust(refDate);
            Date spotDate = floatCalendar_.advance(refDate,
                                                   settlementDays_*Days);
            startDate = spotDate+forwardStart_;
            if (forwardStart_.length()<0)
                startDate = floatCalendar_.adjust(startDate,
                                                  Preceding);
            else
                startDate = floatCalendar_.adjust(startDate,
                                                  Following);
        }

        Date endDate = terminationDate_;
        if (endDate == Date()) {
            if (floatEndOfMonth_)
                endDate = floatCalendar_.advance(startDate,
                                                 swapTenor_,
                                                 ModifiedFollowing,
                                                 floatEndOfMonth_);
            else
                endDate = startDate + swapTenor_;
        }

        const Currency& curr = iborIndex_->currency();
        Period fixedTenor;
        if (fixedTenor_ != Period())
            fixedTenor = fixedTenor_;
        else {
            if ((curr == EURCurrency()) ||
                (curr == USDCurrency()) ||
                (curr == CHFCurrency()) ||
                (curr == SEKCurrency()) ||
                (curr == GBPCurrency() && swapTenor_ <= 1 * Years))
                fixedTenor = Period(1, Years);
            else if ((curr == GBPCurrency() && swapTenor_ > 1 * Years) ||
                (curr == JPYCurrency()) ||
                (curr == AUDCurrency() && swapTenor_ >= 4 * Years))
                fixedTenor = Period(6, Months);
            else if ((curr == HKDCurrency() ||
                     (curr == AUDCurrency() && swapTenor_ < 4 * Years)))
                fixedTenor = Period(3, Months);
            else
                QL_FAIL("unknown fixed leg default tenor for " << curr);
        }

        Schedule fixedSchedule(startDate, endDate,
                               fixedTenor, fixedCalendar_,
                               fixedConvention_,
                               fixedTerminationDateConvention_,
                               fixedRule_, fixedEndOfMonth_,
                               fixedFirstDate_, fixedNextToLastDate_);

        Schedule floatSchedule(startDate, endDate,
                               floatTenor_, floatCalendar_,
                               floatConvention_,
                               floatTerminationDateConvention_,
                               floatRule_, floatEndOfMonth_,
                               floatFirstDate_, floatNextToLastDate_);

        DayCounter fixedDayCount;
        if (fixedDayCount_ != DayCounter())
            fixedDayCount = fixedDayCount_;
        else {
            if (curr == USDCurrency())
                fixedDayCount = Actual360();
            else if (curr == EURCurrency() || curr == CHFCurrency() ||
                     curr == SEKCurrency())
                fixedDayCount = Thirty360(Thirty360::BondBasis);
            else if (curr == GBPCurrency() || curr == JPYCurrency() ||
                     curr == AUDCurrency() || curr == HKDCurrency())
                fixedDayCount = Actual365Fixed();
            else
                QL_FAIL("unknown fixed leg day counter for " << curr);
        }

        Rate usedFixedRate = fixedRate_;
        if (fixedRate_ == Null<Rate>()) {
            VanillaSwap temp(type_, nominal_,
                             fixedSchedule,
                             0.0, // fixed rate
                             fixedDayCount,
                             floatSchedule, iborIndex_,
                             floatSpread_, floatDayCount_);
            if (engine_ == 0) {
                Handle<YieldTermStructure> disc =
                                        iborIndex_->forwardingTermStructure();
                QL_REQUIRE(!disc.empty(),
                           "null term structure set to this instance of " <<
                           iborIndex_->name());
                bool includeSettlementDateFlows = false;
                ext::shared_ptr<PricingEngine> engine(new
                    DiscountingSwapEngine(disc, includeSettlementDateFlows));
                temp.setPricingEngine(engine);
            } else
                temp.setPricingEngine(engine_);

            usedFixedRate = temp.fairRate();
        }

        ext::shared_ptr<VanillaSwap> swap(new
            VanillaSwap(type_, nominal_,
                        fixedSchedule,
                        usedFixedRate, fixedDayCount,
                        floatSchedule,
                        iborIndex_, floatSpread_, floatDayCount_));

        if (engine_ == 0) {
            Handle<YieldTermStructure> disc =
                                    iborIndex_->forwardingTermStructure();
            bool includeSettlementDateFlows = false;
            ext::shared_ptr<PricingEngine> engine(new
                DiscountingSwapEngine(disc, includeSettlementDateFlows));
            swap->setPricingEngine(engine);
        } else
            swap->setPricingEngine(engine_);

        return swap;
    }