public GFunctionExactYield(CmsCoupon coupon) { SwapIndex swapIndex = coupon.swapIndex(); VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); Schedule schedule = swap.fixedSchedule(); Handle <YieldTermStructure> rateCurve = swapIndex.forwardingTermStructure(); DayCounter dc = swapIndex.dayCounter(); double swapStartTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); double swapFirstPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.date(1)); double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); delta_ = (paymentTime - swapStartTime) / (swapFirstPaymentTime - swapStartTime); List <CashFlow> fixedLeg = new List <CashFlow>(swap.fixedLeg()); int n = fixedLeg.Count; accruals_ = new List <double>(); for (int i = 0; i < n; ++i) { Coupon coupon1 = fixedLeg[i] as Coupon; accruals_.Add(coupon1.accrualPeriod()); } }
public void visit(CmsCoupon c) { CmsCouponPricer cmsCouponPricer = pricer_ as CmsCouponPricer; Utils.QL_REQUIRE(cmsCouponPricer != null, () => "pricer not compatible with CMS coupon"); c.setPricer(cmsCouponPricer); }
public DigitalCmsCoupon(CmsCoupon underlying, double?callStrike = null, Position.Type callPosition = Position.Type.Long, bool isCallATMIncluded = false, double?callDigitalPayoff = null, double?putStrike = null, Position.Type putPosition = Position.Type.Long, bool isPutATMIncluded = false, double?putDigitalPayoff = null, DigitalReplication replication = null) : base(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication) { }
//===========================================================================// // GFunctionWithShifts // //===========================================================================// public GFunctionWithShifts(CmsCoupon coupon, Handle <Quote> meanReversion) { meanReversion_ = meanReversion; calibratedShift_ = 0.03; tmpRs_ = 10000000.0; accuracy_ = 1.0e-14; SwapIndex swapIndex = coupon.swapIndex(); VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); swapRateValue_ = swap.fairRate(); objectiveFunction_ = new ObjectiveFunction(this, swapRateValue_); Schedule schedule = swap.fixedSchedule(); Handle <YieldTermStructure> rateCurve = swapIndex.forwardingTermStructure(); DayCounter dc = swapIndex.dayCounter(); swapStartTime_ = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); discountAtStart_ = rateCurve.link.discount(schedule.startDate()); double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); shapedPaymentTime_ = shapeOfShift(paymentTime); List <CashFlow> fixedLeg = new List <CashFlow>(swap.fixedLeg()); int n = fixedLeg.Count; shapedSwapPaymentTimes_ = new List <double>(); swapPaymentDiscounts_ = new List <double>(); accruals_ = new List <double>(); for (int i = 0; i < n; ++i) { Coupon coupon1 = fixedLeg[i] as Coupon; accruals_.Add(coupon1.accrualPeriod()); Date paymentDate = new Date(coupon1.date().serialNumber()); double swapPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), paymentDate); shapedSwapPaymentTimes_.Add(shapeOfShift(swapPaymentTime)); swapPaymentDiscounts_.Add(rateCurve.link.discount(paymentDate)); } discountRatio_ = swapPaymentDiscounts_.Last() / discountAtStart_; }
// Factory - for Leg generators public virtual CashFlow factory(CmsCoupon underlying, double?callStrike, Position.Type callPosition, bool isCallATMIncluded, double?callDigitalPayoff, double?putStrike, Position.Type putPosition, bool isPutATMIncluded, double?putDigitalPayoff, DigitalReplication replication) { return(new DigitalCmsCoupon(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication)); }
public static GFunction newGFunctionWithShifts(CmsCoupon coupon, Handle <Quote> meanReversion) { return(new GFunctionWithShifts(coupon, meanReversion) as GFunction); }
public static GFunction newGFunctionExactYield(CmsCoupon coupon) { return(new GFunctionExactYield(coupon) as GFunction); }
public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as CmsSpreadCoupon; Utils.QL_REQUIRE(coupon_ != null, () => "CMS spread coupon needed"); index_ = coupon_.swapSpreadIndex(); gearing_ = coupon_.gearing(); spread_ = coupon_.spread(); fixingDate_ = coupon_.fixingDate(); paymentDate_ = coupon_.date(); // if no coupon discount curve is given just use the discounting curve // from the _first_ swap index. // for double calculation this curve cancels out in the computation, so // e.g. the discounting // swap engine will produce correct results, even if the // couponDiscountCurve is not set here. // only the price member function in this class will be dependent on the // coupon discount curve. today_ = Settings.Instance.evaluationDate(); if (couponDiscountCurve_.empty()) { couponDiscountCurve_ = index_.swapIndex1().exogenousDiscount() ? index_.swapIndex1().discountingTermStructure() : index_.swapIndex1().forwardingTermStructure(); } discount_ = paymentDate_ > couponDiscountCurve_.currentLink().referenceDate() ? couponDiscountCurve_.currentLink().discount(paymentDate_) : 1.0; spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_; gearing1_ = index_.gearing1(); gearing2_ = index_.gearing2(); Utils.QL_REQUIRE(gearing1_ > 0.0 && gearing2_ < 0.0, () => "gearing1 (" + gearing1_ + ") should be positive while gearing2 (" + gearing2_ + ") should be negative"); c1_ = new CmsCoupon( coupon_.nominal(), coupon_.date(), coupon_.accrualStartDate(), coupon_.accrualEndDate(), coupon_.fixingDays, index_.swapIndex1(), 1.0, 0.0, coupon_.referencePeriodStart, coupon_.referencePeriodEnd, coupon_.dayCounter(), coupon_.isInArrears()); c2_ = new CmsCoupon( coupon_.nominal(), coupon_.date(), coupon_.accrualStartDate(), coupon_.accrualEndDate(), coupon_.fixingDays, index_.swapIndex2(), 1.0, 0.0, coupon_.referencePeriodStart, coupon_.referencePeriodEnd, coupon_.dayCounter(), coupon_.isInArrears()); c1_.setPricer(cmsPricer1_); c2_.setPricer(cmsPricer2_); if (fixingDate_ > today_) { fixingTime_ = cmsPricer1_.swaptionVolatility().currentLink().timeFromReference( fixingDate_); swapRate1_ = c1_.indexFixing(); swapRate2_ = c2_.indexFixing(); adjustedFixing1_ = c1_.adjustedFixing; adjustedFixing2_ = c2_.adjustedFixing; SwaptionVolatilityStructure swvol = cmsPricer1_.swaptionVolatility(); SwaptionVolatilityCube swcub = swvol as SwaptionVolatilityCube; if (inheritedVolatilityType_ && volType_ == VolatilityType.ShiftedLognormal) { shift1_ = swvol.shift(fixingDate_, index_.swapIndex1().tenor()); shift2_ = swvol.shift(fixingDate_, index_.swapIndex2().tenor()); } if (swcub == null) { // not a cube, just an atm surface given, so we can // not easily convert volatilities and just forbid it Utils.QL_REQUIRE(inheritedVolatilityType_, () => "if only an atm surface is given, the volatility type must be inherited"); vol1_ = swvol.volatility( fixingDate_, index_.swapIndex1().tenor(), swapRate1_); vol2_ = swvol.volatility( fixingDate_, index_.swapIndex2().tenor(), swapRate2_); } else { vol1_ = swcub.smileSection(fixingDate_, index_.swapIndex1().tenor()) .volatility(swapRate1_, volType_, shift1_); vol2_ = swcub.smileSection(fixingDate_, index_.swapIndex2().tenor()) .volatility(swapRate2_, volType_, shift2_); } if (volType_ == VolatilityType.ShiftedLognormal) { mu1_ = 1.0 / fixingTime_ * Math.Log((adjustedFixing1_ + shift1_) / (swapRate1_ + shift1_)); mu2_ = 1.0 / fixingTime_ * Math.Log((adjustedFixing2_ + shift2_) / (swapRate2_ + shift2_)); } // for the normal volatility case we do not need the drifts // but rather use adjusted doubles directly in the integrand rho_ = Math.Max(Math.Min(correlation().currentLink().value(), 0.9999), -0.9999); // avoid division by zero in integrand } else { // fixing is in the past or today adjustedFixing1_ = c1_.indexFixing(); adjustedFixing2_ = c2_.indexFixing(); } }