NoArbSabrSmileSection::NoArbSabrSmileSection( Time timeToExpiry, Rate forward, const std::vector<Real> &sabrParams, Real shift) : SmileSection(timeToExpiry, DayCounter()), forward_(forward), params_(sabrParams), shift_(shift) { init(); }
CappedFlooredCmsCoupon( const Date& paymentDate, Real nominal, const Date& startDate, const Date& endDate, Natural fixingDays, const boost::shared_ptr<SwapIndex>& index, Real gearing = 1.0, Spread spread= 0.0, const Rate cap = Null<Rate>(), const Rate floor = Null<Rate>(), const Date& refPeriodStart = Date(), const Date& refPeriodEnd = Date(), const DayCounter& dayCounter = DayCounter(), bool isInArrears = false) : CappedFlooredCoupon(boost::shared_ptr<FloatingRateCoupon>(new CmsCoupon(paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears)), cap, floor) {}
OvernightIndexedSwap::OvernightIndexedSwap( Type type, Real nominal, const Schedule& schedule, Rate fixedRate, const DayCounter& fixedDC, const boost::shared_ptr<OvernightIndex>& overnightIndex, Spread spread) : Swap(2), type_(type), nominal_(nominal), paymentFrequency_(schedule.tenor().frequency()), //schedule_(schedule), fixedRate_(fixedRate), fixedDC_(fixedDC), overnightIndex_(overnightIndex), spread_(spread) { if (fixedDC_==DayCounter()) fixedDC_ = overnightIndex_->dayCounter(); legs_[0] = FixedRateLeg(schedule) .withNotionals(nominal_) .withCouponRates(fixedRate_, fixedDC_); legs_[1] = OvernightLeg(schedule, overnightIndex_) .withNotionals(nominal_) .withSpreads(spread_); for (Size j=0; j<2; ++j) { for (Leg::iterator i = legs_[j].begin(); i!= legs_[j].end(); ++i) registerWith(*i); } switch (type_) { case Payer: payer_[0] = -1.0; payer_[1] = +1.0; break; case Receiver: payer_[0] = +1.0; payer_[1] = -1.0; break; default: QL_FAIL("Unknown overnight-swap type"); } }
boost::shared_ptr<QuantLib::Instrument> qlInstrumentFactory::noteInstrument(const boost::shared_ptr<FpmlSerialized::NoteInfo> xml_serial) { Date tradeDate = xml_serial->getTradeDate()->dateValue(); Date effectiveDate = xml_serial->getEffectiveDate()->dateValue(); Date maturityDate = xml_serial->getMaturityDate()->dateValue(); double notional = xml_serial->getNotional()->DValue(); DayCounter daycounter = DayCounter(); Calendar calendar = Calendar(); boost::shared_ptr<QuantLib::NoteInst> noteinst = boost::shared_ptr<QuantLib::NoteInst>( new NoteInst("test",notional, effectiveDate, maturityDate, daycounter, calendar)); return noteinst; }
Real GsrProcess::time(const Date &d) const { QL_REQUIRE( referenceDate_ != Null<Date>() && dc_ != DayCounter(), "time can not be computed without reference date and day counter"); return dc_.yearFraction(referenceDate_, d); }
AssetSwap::AssetSwap(bool parSwap, const boost::shared_ptr<Bond>& bond, Real bondCleanPrice, Real nonParRepayment, Real gearing, const boost::shared_ptr<IborIndex>& iborIndex, Spread spread, const DayCounter& floatingDayCounter, Date dealMaturity, bool payBondCoupon) : Swap(2), bond_(bond), bondCleanPrice_(bondCleanPrice), nonParRepayment_(nonParRepayment), spread_(spread), parSwap_(parSwap) { Schedule tempSch(bond_->settlementDate(), bond_->maturityDate(), iborIndex->tenor(), iborIndex->fixingCalendar(), iborIndex->businessDayConvention(), iborIndex->businessDayConvention(), DateGeneration::Backward, false); // endOfMonth if (dealMaturity==Date()) dealMaturity = bond_->maturityDate(); QL_REQUIRE(dealMaturity <= tempSch.dates().back(), "deal maturity " << dealMaturity << " cannot be later than (adjusted) bond maturity " << tempSch.dates().back()); // the following might become an input parameter BusinessDayConvention paymentAdjustment = Following; Date finalDate = tempSch.calendar().adjust( dealMaturity, paymentAdjustment); Schedule schedule = tempSch.until(finalDate); // bondCleanPrice must be the (forward) clean price // at the floating schedule start date upfrontDate_ = schedule.startDate(); Real dirtyPrice = bondCleanPrice_ + bond_->accruedAmount(upfrontDate_); Real notional = bond_->notional(upfrontDate_); /* In the market asset swap, the bond is purchased in return for payment of the full price. The notional of the floating leg is then scaled by the full price. */ if (!parSwap_) notional *= dirtyPrice/100.0; if (floatingDayCounter==DayCounter()) legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentAdjustment(paymentAdjustment) .withGearings(gearing) .withSpreads(spread); else legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentDayCounter(floatingDayCounter) .withPaymentAdjustment(paymentAdjustment) .withGearings(gearing) .withSpreads(spread); for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i) registerWith(*i); const Leg& bondLeg = bond_->cashflows(); Leg::const_iterator i = bondLeg.begin(); // skip bond redemption for (; i<bondLeg.end()-1 && (*i)->date()<=dealMaturity; ++i) { // whatever might be the choice for the discounting engine // bond flows on upfrontDate_ must be discarded bool upfrontDateBondFlows = false; if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows)) legs_[0].push_back(*i); } // if the first skipped cashflow is not the redemption // and it is a coupon then add the accrued coupon if (i<bondLeg.end()-1) { shared_ptr<Coupon> c = boost::dynamic_pointer_cast<Coupon>(*i); if (c) { shared_ptr<CashFlow> accruedCoupon(new SimpleCashFlow(c->accruedAmount(dealMaturity), finalDate)); legs_[0].push_back(accruedCoupon); } } // add the nonParRepayment_ shared_ptr<CashFlow> nonParRepaymentFlow(new SimpleCashFlow(nonParRepayment_, finalDate)); legs_[0].push_back(nonParRepaymentFlow); QL_REQUIRE(!legs_[0].empty(), "empty bond leg to start with"); // special flows if (parSwap_) { // upfront on the floating leg Real upfront = (dirtyPrice-100.0)/100.0*notional; shared_ptr<CashFlow> upfrontCashFlow(new SimpleCashFlow(upfront, upfrontDate_)); legs_[1].insert(legs_[1].begin(), upfrontCashFlow); // backpayment on the floating leg // (accounts for non-par redemption, if any) Real backPayment = notional; shared_ptr<CashFlow> backPaymentCashFlow(new SimpleCashFlow(backPayment, finalDate)); legs_[1].push_back(backPaymentCashFlow); } else { // final notional exchange shared_ptr<CashFlow> finalCashFlow (new SimpleCashFlow(notional, finalDate)); legs_[1].push_back(finalCashFlow); } QL_REQUIRE(!legs_[0].empty(), "empty bond leg"); for (Leg::const_iterator i=legs_[0].begin(); i<legs_[0].end(); ++i) registerWith(*i); if (payBondCoupon) { payer_[0]=-1.0; payer_[1]=+1.0; } else { payer_[0]=+1.0; payer_[1]=-1.0; } }
AssetSwap::AssetSwap(bool payBondCoupon, const shared_ptr<Bond>& bond, Real bondCleanPrice, const shared_ptr<IborIndex>& iborIndex, Spread spread, const Schedule& floatSchedule, const DayCounter& floatingDayCounter, bool parSwap) : Swap(2), bond_(bond), bondCleanPrice_(bondCleanPrice), nonParRepayment_(100), spread_(spread), parSwap_(parSwap) { Schedule schedule = floatSchedule; if (floatSchedule.empty()) schedule = Schedule(bond_->settlementDate(), bond_->maturityDate(), iborIndex->tenor(), iborIndex->fixingCalendar(), iborIndex->businessDayConvention(), iborIndex->businessDayConvention(), DateGeneration::Backward, false); // endOfMonth // the following might become an input parameter BusinessDayConvention paymentAdjustment = Following; Date finalDate = schedule.calendar().adjust( schedule.endDate(), paymentAdjustment); Date adjBondMaturityDate = schedule.calendar().adjust( bond_->maturityDate(), paymentAdjustment); QL_REQUIRE(finalDate==adjBondMaturityDate, "adjusted schedule end date (" << finalDate << ") must be equal to adjusted bond maturity date (" << adjBondMaturityDate << ")"); // bondCleanPrice must be the (forward) clean price // at the floating schedule start date upfrontDate_ = schedule.startDate(); Real dirtyPrice = bondCleanPrice_ + bond_->accruedAmount(upfrontDate_); Real notional = bond_->notional(upfrontDate_); /* In the market asset swap, the bond is purchased in return for payment of the full price. The notional of the floating leg is then scaled by the full price. */ if (!parSwap_) notional *= dirtyPrice/100.0; if (floatingDayCounter==DayCounter()) legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentAdjustment(paymentAdjustment) .withSpreads(spread); else legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentDayCounter(floatingDayCounter) .withPaymentAdjustment(paymentAdjustment) .withSpreads(spread); for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i) registerWith(*i); const Leg& bondLeg = bond_->cashflows(); for (Leg::const_iterator i=bondLeg.begin(); i<bondLeg.end(); ++i) { // whatever might be the choice for the discounting engine // bond flows on upfrontDate_ must be discarded bool upfrontDateBondFlows = false; if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows)) legs_[0].push_back(*i); } QL_REQUIRE(!legs_[0].empty(), "empty bond leg to start with"); // special flows if (parSwap_) { // upfront on the floating leg Real upfront = (dirtyPrice-100.0)/100.0*notional; shared_ptr<CashFlow> upfrontCashFlow(new SimpleCashFlow(upfront, upfrontDate_)); legs_[1].insert(legs_[1].begin(), upfrontCashFlow); // backpayment on the floating leg // (accounts for non-par redemption, if any) Real backPayment = notional; shared_ptr<CashFlow> backPaymentCashFlow(new SimpleCashFlow(backPayment, finalDate)); legs_[1].push_back(backPaymentCashFlow); } else { // final notional exchange shared_ptr<CashFlow> finalCashFlow(new SimpleCashFlow(notional, finalDate)); legs_[1].push_back(finalCashFlow); } QL_REQUIRE(!legs_[0].empty(), "empty bond leg"); for (Leg::const_iterator i=legs_[0].begin(); i<legs_[0].end(); ++i) registerWith(*i); if (payBondCoupon) { payer_[0]=-1.0; payer_[1]=+1.0; } else { payer_[0]=+1.0; payer_[1]=-1.0; } }
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; }