Exemplo n.º 1
0
    shared_ptr<VanillaSwap>
    SwapIndex::underlyingSwap(const Date& fixingDate) const {

        QL_REQUIRE(fixingDate!=Date(), "null fixing date");

        // caching mechanism
        if (lastFixingDate_!=fixingDate) {
            Rate fixedRate = 0.0;
            if (exogenousDiscount_)
                lastSwap_ = MakeVanillaSwap(tenor_, iborIndex_, fixedRate)
                    .withEffectiveDate(valueDate(fixingDate))
                    .withFixedLegCalendar(fixingCalendar())
                    .withFixedLegDayCount(dayCounter_)
                    .withFixedLegTenor(fixedLegTenor_)
                    .withFixedLegConvention(fixedLegConvention_)
                    .withFixedLegTerminationDateConvention(fixedLegConvention_)
                    .withDiscountingTermStructure(discount_);
            else
                lastSwap_ = MakeVanillaSwap(tenor_, iborIndex_, fixedRate)
                    .withEffectiveDate(valueDate(fixingDate))
                    .withFixedLegCalendar(fixingCalendar())
                    .withFixedLegDayCount(dayCounter_)
                    .withFixedLegTenor(fixedLegTenor_)
                    .withFixedLegConvention(fixedLegConvention_)
                    .withFixedLegTerminationDateConvention(fixedLegConvention_);
            lastFixingDate_ = fixingDate;
        }
        return lastSwap_;
    }
Exemplo n.º 2
0
    VanillaSwap::VanillaSwap(
            const shared_ptr<ObjectHandler::ValueObject>& properties,
            const QuantLib::Period& swapTenor, 
            const shared_ptr<QuantLib::IborIndex>& index,
            QuantLib::Rate fixedRate,
            const QuantLib::Date& immDate,
            const QuantLib::DayCounter& fixDayCounter,
            QuantLib::Spread floatingLegSpread,
            bool permanent)
    : Swap(properties, permanent)
    {
        QuantLib::Date effectiveDate = immDate;
        if (effectiveDate==QuantLib::Date())
            effectiveDate = QuantLib::IMM::nextDate();

        QuantLib::Date terminationDate = effectiveDate+swapTenor;
        terminationDate = QuantLib::Date::nthWeekday(3,
                                                     QuantLib::Wednesday,
                                                     terminationDate.month(),
                                                     terminationDate.year());

        libraryObject_ = MakeVanillaSwap(swapTenor, index,
                                                   fixedRate)
                         .withEffectiveDate(effectiveDate)
                         .withTerminationDate(terminationDate)
                         .withRule(QuantLib::DateGeneration::ThirdWednesday)
                         .withFixedLegDayCount(fixDayCounter)
                         .withFloatingLegSpread(floatingLegSpread)
                         .operator shared_ptr<QuantLib::VanillaSwap>();
    }
Exemplo n.º 3
0
    void SwapRateHelper::initializeDates() {

        // 1. do not pass the spread here, as it might be a Quote
        //    i.e. it can dinamically change
        // 2. input discount curve Handle might be empty now but it could
        //    be assigned a curve later; use a RelinkableHandle here
        swap_ = MakeVanillaSwap(tenor_, iborIndex_, 0.0, fwdStart_)
            .withSettlementDays(settlementDays_)
            .withDiscountingTermStructure(discountRelinkableHandle_)
            .withFixedLegDayCount(fixedDayCount_)
            .withFixedLegTenor(Period(fixedFrequency_))
            .withFixedLegConvention(fixedConvention_)
            .withFixedLegTerminationDateConvention(fixedConvention_)
            .withFixedLegCalendar(calendar_)
            .withFloatingLegCalendar(calendar_);

        earliestDate_ = swap_->startDate();

        // Usually...
        latestDate_ = swap_->maturityDate();
        // ...but due to adjustments, the last floating coupon might
        // need a later date for fixing
        #ifdef QL_USE_INDEXED_COUPON
        shared_ptr<FloatingRateCoupon> lastFloating =
            boost::dynamic_pointer_cast<FloatingRateCoupon>(
                                                 swap_->floatingLeg().back());
        Date fixingValueDate =
            iborIndex_->valueDate(lastFloating->fixingDate());
        Date endValueDate = iborIndex_->maturityDate(fixingValueDate);
        latestDate_ = std::max(latestDate_, endValueDate);
        #endif
    }
     Real HullWhiteSmileSection::volatilityImpl(Rate strike) const {
		
		boost::shared_ptr<VanillaSwap> underlying = MakeVanillaSwap(swapLength_,swapIndex_->iborIndex(),strike)
																	.withEffectiveDate(swapIndex_->valueDate(optionDate_))  
																	.withFixedLegCalendar(swapIndex_->fixingCalendar())
													                .withFixedLegDayCount(swapIndex_->dayCounter())
													                .withFixedLegTenor(swapIndex_->fixedLegTenor())
													                .withFixedLegConvention(swapIndex_->fixedLegConvention())
													                .withFixedLegTerminationDateConvention(swapIndex_->fixedLegConvention())
																	.withType(VanillaSwap::Payer);
		underlying->setPricingEngine(discountingEngine_);
		boost::shared_ptr<Exercise> exercise(new EuropeanExercise(optionDate_));
		Swaption swaption(underlying,exercise);
		swaption.setPricingEngine(jamshidianEngine_);
		Real npv = swaption.NPV();
		Real annuity = fabs(underlying->fixedLegBPS() * 10000.0);

		//Real blackNpv=blackFormula(Option::Call,strike,atm,0.30*sqrt(exerciseTime()));
		//std::cout << std::setprecision(8) << "SECTION atm=" << atm_ << " annuity=" << annuity << " npv=" << npv << " strike= " << strike << std::endl;

		Real vol=0.0;
		try {
			vol=blackFormulaImpliedStdDev(Option::Call,strike,atm_,npv,annuity) / sqrt(exerciseTime());
		} catch(QuantLib::Error) {
			//std::cout << " can not imply vol for npv " << npv << " black(300%)=" << blackFormula(Option::Call,strike,atm_,sqrt(exerciseTime())*3.00,annuity) << 
			//	" black(1%)=" << blackFormula(Option::Call,strike,atm_,sqrt(exerciseTime())*0.01,annuity) << std::endl;
			if(npv>blackFormula(Option::Call,strike,atm_,3.00,annuity)) vol =3.0/sqrt(exerciseTime());
			else vol=0.0;
		}
		return vol;

     }
Exemplo n.º 5
0
    MakeSwaption::operator ext::shared_ptr<Swaption>() const {

        const Calendar& fixingCalendar = swapIndex_->fixingCalendar();
        Date refDate = Settings::instance().evaluationDate();
        // if the evaluation date is not a business day
        // then move to the next business day
        refDate = fixingCalendar.adjust(refDate);
        if (fixingDate_ == Null<Date>())
            fixingDate_ = fixingCalendar.advance(refDate, optionTenor_,
                                                 optionConvention_);
        if (exerciseDate_ == Null<Date>()) {
            exercise_ = ext::shared_ptr<Exercise>(new
                EuropeanExercise(fixingDate_));
        } else {
            QL_REQUIRE(exerciseDate_ <= fixingDate_,
                       "exercise date (" << exerciseDate_ << ") must be less "
                       "than or equal to fixing date (" << fixingDate_ << ")");
            exercise_ = ext::shared_ptr<Exercise>(new
                EuropeanExercise(exerciseDate_));
        }

        Rate usedStrike = strike_;
        if (strike_ == Null<Rate>()) {
            // ATM on curve(s) attached to index
            QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(),
                       "null term structure set to this instance of " <<
                       swapIndex_->name());
            ext::shared_ptr<VanillaSwap> temp =
                swapIndex_->underlyingSwap(fixingDate_);
            temp->setPricingEngine(
                ext::shared_ptr<PricingEngine>(new DiscountingSwapEngine(
                    swapIndex_->exogenousDiscount()
                        ? swapIndex_->discountingTermStructure()
                        : swapIndex_->forwardingTermStructure(),
                    false)));
            usedStrike = temp->fairRate();
        }

        BusinessDayConvention bdc = swapIndex_->fixedLegConvention();
        underlyingSwap_ =
            MakeVanillaSwap(swapIndex_->tenor(),
                            swapIndex_->iborIndex(), usedStrike)
            .withEffectiveDate(swapIndex_->valueDate(fixingDate_))
            .withFixedLegCalendar(swapIndex_->fixingCalendar())
            .withFixedLegDayCount(swapIndex_->dayCounter())
            .withFixedLegTenor(swapIndex_->fixedLegTenor())
            .withFixedLegConvention(bdc)
            .withFixedLegTerminationDateConvention(bdc)
            .withType(underlyingType_)
            .withNominal(nominal_);

        ext::shared_ptr<Swaption> swaption(new
            Swaption(underlyingSwap_, exercise_, delivery_));
        swaption->setPricingEngine(engine_);
        return swaption;
    }
Exemplo n.º 6
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())) {}
Exemplo n.º 7
0
    MakeSwaption::operator boost::shared_ptr<Swaption>() const {

        const Date& evaluationDate = Settings::instance().evaluationDate();
        const Calendar& fixingCalendar = swapIndex_->fixingCalendar();
        fixingDate_ = fixingCalendar.advance(evaluationDate, optionTenor_,
                                             optionConvention_);
        if (exerciseDate_ == Null<Date>()) {
            exercise_ = boost::shared_ptr<Exercise>(new
                EuropeanExercise(fixingDate_));
        } else {
            QL_REQUIRE(exerciseDate_ <= fixingDate_,
                       "exercise date (" << exerciseDate_ << ") must be less "
                       "than or equal to fixing date (" << fixingDate_ << ")");
            exercise_ = boost::shared_ptr<Exercise>(new
                EuropeanExercise(exerciseDate_));
        }

        Rate usedStrike = strike_;
        if (strike_ == Null<Rate>()) {
            // ATM on the forecasting curve
            QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(),
                       "null term structure set to this instance of " <<
                       swapIndex_->name());
            boost::shared_ptr<VanillaSwap> temp =
                swapIndex_->underlyingSwap(fixingDate_);
            temp->setPricingEngine(boost::shared_ptr<PricingEngine>(
                new DiscountingSwapEngine(
                                        swapIndex_->forwardingTermStructure(),
                                        false)));
            usedStrike = temp->fairRate();
        }

        BusinessDayConvention bdc = swapIndex_->fixedLegConvention();
        underlyingSwap_ =
            MakeVanillaSwap(swapIndex_->tenor(),
                            swapIndex_->iborIndex(), usedStrike)
            .withEffectiveDate(swapIndex_->valueDate(fixingDate_))
            .withFixedLegCalendar(swapIndex_->fixingCalendar())
            .withFixedLegDayCount(swapIndex_->dayCounter())
            .withFixedLegConvention(bdc)
            .withFixedLegTerminationDateConvention(bdc);

        boost::shared_ptr<Swaption> swaption(new
            Swaption(underlyingSwap_, exercise_, delivery_));
        swaption->setPricingEngine(engine_);
        return swaption;
    }
Exemplo n.º 8
0
 VanillaSwap::VanillaSwap(
         const shared_ptr<ObjectHandler::ValueObject>& properties,
         const QuantLib::Period& swapTenor, 
         const shared_ptr<QuantLib::IborIndex>& index,
         QuantLib::Rate fixedRate,
         const QuantLib::Period& fwdStart,
         const QuantLib::DayCounter& fixDayCounter,
         QuantLib::Spread floatingLegSpread,
         bool permanent)
 : Swap(properties, permanent)
 {
     libraryObject_ = MakeVanillaSwap(swapTenor, index,
                                      fixedRate, fwdStart)
         .withFixedLegDayCount(fixDayCounter)
         .withFloatingLegSpread(floatingLegSpread)
         .operator shared_ptr<QuantLib::VanillaSwap>();
 }
    HullWhiteSmileSection::HullWhiteSmileSection(const Date& optionDate, const Period& swapLength, boost::shared_ptr<SwapIndex> swapIndex,
			const Handle<YieldTermStructure>& yts, const Real reversion, const Real sigma) : 
						SmileSection(optionDate,yts->dayCounter(),yts->referenceDate()), 
							optionDate_(optionDate), swapLength_(swapLength), swapIndex_(swapIndex), yts_(yts), reversion_(reversion), sigma_(sigma) {

        //std::cout << "model reversion = " << reversion << " sigma=" << sigma << std::endl;
		model_ = boost::shared_ptr<HullWhite>(new HullWhite(yts_,reversion,sigma));
		jamshidianEngine_ = boost::shared_ptr<JamshidianSwaptionEngine>(new JamshidianSwaptionEngine(model_));
		discountingEngine_ = boost::shared_ptr<DiscountingSwapEngine>(new DiscountingSwapEngine(yts_));
		boost::shared_ptr<VanillaSwap> underlying = MakeVanillaSwap(swapLength_,swapIndex_->iborIndex(),0.03) // dummy strike
																	.withEffectiveDate(swapIndex_->valueDate(optionDate_))  
																	.withFixedLegCalendar(swapIndex_->fixingCalendar())
													                .withFixedLegDayCount(swapIndex_->dayCounter())
													                .withFixedLegTenor(swapIndex_->fixedLegTenor())
													                .withFixedLegConvention(swapIndex_->fixedLegConvention())
													                .withFixedLegTerminationDateConvention(swapIndex_->fixedLegConvention());																
		underlying->setPricingEngine(discountingEngine_);
		atm_ = underlying->fairRate();
		//std::cout << "SECTION option date " << optionDate << " tenor " << swapLength << std::setprecision(8) << " atm " << atm_ << std::endl;

    }
Exemplo n.º 10
0
void CounterpartyAdjSwapEngine::calculate() const {
    /* both DTS, YTS ref dates and pricing date consistency
       checks? settlement... */
    QL_REQUIRE(!discountCurve_.empty(),
               "no discount term structure set");
    QL_REQUIRE(!defaultTS_.empty(),
               "no ctpty default term structure set");
    QL_REQUIRE(!swaptionletEngine_.empty(),
               "no swap option engine set");

    Date priceDate = defaultTS_->referenceDate();

    Real cumOptVal = 0.,
         cumPutVal = 0.;
    // Vanilla swap so 0 leg is floater

    std::vector<Date>::const_iterator nextFD =
        arguments_.fixedPayDates.begin();
    Date swapletStart = priceDate;
    while(*nextFD < priceDate) nextFD++;

    // Compute fair spread for strike value:
    // copy args into the non risky engine
    Swap::arguments * noCVAArgs = dynamic_cast<Swap::arguments*>(
                                      baseSwapEngine_->getArguments());
    QL_REQUIRE(noCVAArgs != 0, "wrong argument type");

    noCVAArgs->legs = this->arguments_.legs;
    noCVAArgs->payer = this->arguments_.payer;

    baseSwapEngine_->calculate();

    boost::shared_ptr<FixedRateCoupon> coupon = boost::dynamic_pointer_cast<FixedRateCoupon>(arguments_.legs[0][0]);
    QL_REQUIRE(coupon,"dynamic cast of fixed leg coupon failed.");
    Rate baseSwapRate = coupon->rate();

    const Swap::results * vSResults =
        dynamic_cast<const Swap::results *>(baseSwapEngine_->getResults());
    QL_REQUIRE(vSResults != 0, "wrong result type");

    Rate baseSwapFairRate = -baseSwapRate * vSResults->legNPV[1] /
                            vSResults->legNPV[0];
    Real baseSwapNPV = vSResults->value;

    VanillaSwap::Type reversedType = arguments_.type == VanillaSwap::Payer ?
                                     VanillaSwap::Receiver : VanillaSwap::Payer;

    // Swaplet options summatory:
    while(nextFD != arguments_.fixedPayDates.end()) {
        // iFD coupon not fixed, create swaptionlet:
        boost::shared_ptr<FloatingRateCoupon> floatCoupon = boost::dynamic_pointer_cast<FloatingRateCoupon>(arguments_.legs[1][0]);
        QL_REQUIRE(floatCoupon,"dynamic cast of floating leg coupon failed.");
        boost::shared_ptr<IborIndex> swapIndex = boost::dynamic_pointer_cast<IborIndex>(floatCoupon->index());
        QL_REQUIRE(swapIndex,"dynamic cast of floating leg index failed.");

        // Alternatively one could cap this period to, say, 1M
        // Period swapPeriod = boost::dynamic_pointer_cast<FloatingRateCoupon>(
        //   arguments_.legs[1][0])->index()->tenor();

        Period baseSwapsTenor(arguments_.fixedPayDates.back().serialNumber()
                              - swapletStart.serialNumber(), Days);
        boost::shared_ptr<VanillaSwap> swaplet = MakeVanillaSwap(
                    baseSwapsTenor,
                    swapIndex,
                    baseSwapFairRate // strike
                )
                .withType(arguments_.type)
                .withNominal(arguments_.nominal)
                ////////	    .withSettlementDays(2)
                .withEffectiveDate(swapletStart)
                .withTerminationDate(arguments_.fixedPayDates.back());
        boost::shared_ptr<VanillaSwap> revSwaplet = MakeVanillaSwap(
                    baseSwapsTenor,
                    swapIndex,
                    baseSwapFairRate // strike
                )
                .withType(reversedType)
                .withNominal(arguments_.nominal)
                /////////	    .withSettlementDays(2)
                .withEffectiveDate(swapletStart)
                .withTerminationDate(arguments_.fixedPayDates.back());

        Swaption swaptionlet(swaplet,
                             boost::make_shared<EuropeanExercise>(swapletStart));
        Swaption putSwaplet(revSwaplet,
                            boost::make_shared<EuropeanExercise>(swapletStart));
        swaptionlet.setPricingEngine(swaptionletEngine_.currentLink());
        putSwaplet.setPricingEngine(swaptionletEngine_.currentLink());

        // atm underlying swap means that the value of put = value
        // call so this double pricing is not needed
        cumOptVal += swaptionlet.NPV() * defaultTS_->defaultProbability(
                         swapletStart, *nextFD);
        cumPutVal += putSwaplet.NPV()  * invstDTS_->defaultProbability(
                         swapletStart, *nextFD);

        swapletStart = *nextFD;
        nextFD++;
    }

    results_.value = baseSwapNPV - (1.-ctptyRecoveryRate_) * cumOptVal
                     + (1.-invstRecoveryRate_) * cumPutVal;

    results_.fairRate =  -baseSwapRate * (vSResults->legNPV[1]
                                          - (1.-ctptyRecoveryRate_) * cumOptVal +
                                          (1.-invstRecoveryRate_) * cumPutVal )
                         / vSResults->legNPV[0];

}