public DiscretizedCallableFixedRateBond(CallableBond.Arguments args, Date referenceDate, DayCounter dayCounter) { arguments_ = args; redemptionTime_ = dayCounter.yearFraction(referenceDate, args.redemptionDate); for (int i = 0; i < args.couponDates.Count; ++i) { couponTimes_.Add(dayCounter.yearFraction(referenceDate, args.couponDates[i])); } for (int i = 0; i < args.callabilityDates.Count; ++i) { callabilityTimes_.Add(dayCounter.yearFraction(referenceDate, args.callabilityDates[i])); } // similar to the tree swaption engine, we collapse similar coupon // and exercise dates to avoid mispricing. Delete if unnecessary. for (int i = 0; i < callabilityTimes_.Count; i++) { double exerciseTime = callabilityTimes_[i]; for (int j = 0; j < couponTimes_.Count; j++) { if (withinNextWeek(exerciseTime, couponTimes_[j])) { couponTimes_[j] = exerciseTime; } } } }
public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); CallableBond.Arguments arguments = args as CallableBond.Arguments; Utils.QL_REQUIRE(arguments != null, () => "no arguments given"); Date settlement = arguments.settlementDate; arguments.redemption = redemption().amount(); arguments.redemptionDate = redemption().date(); List <CashFlow> cfs = cashflows(); arguments.couponDates = new List <Date>(cfs.Count - 1); arguments.couponAmounts = new List <double>(cfs.Count - 1); for (int i = 0; i < cfs.Count; i++) { if (!cfs[i].hasOccurred(settlement, false)) { if (cfs[i] is QLCore.FixedRateCoupon) { arguments.couponDates.Add(cfs[i].date()); arguments.couponAmounts.Add(cfs[i].amount()); } } } arguments.callabilityPrices = new List <double>(putCallSchedule_.Count); arguments.callabilityDates = new List <Date>(putCallSchedule_.Count); arguments.paymentDayCounter = paymentDayCounter_; arguments.frequency = frequency_; arguments.putCallSchedule = putCallSchedule_; for (int i = 0; i < putCallSchedule_.Count; i++) { if (!putCallSchedule_[i].hasOccurred(settlement, false)) { arguments.callabilityDates.Add(putCallSchedule_[i].date()); arguments.callabilityPrices.Add(putCallSchedule_[i].price().amount()); if (putCallSchedule_[i].price().type() == Callability.Price.Type.Clean) { /* calling accrued() forces accrued interest to be zero * if future option date is also coupon date, so that dirty * price = clean price. Use here because callability is * always applied before coupon in the tree engine. */ arguments.callabilityPrices[arguments.callabilityPrices.Count - 1] += this.accrued(putCallSchedule_[i].date()); } } } }
public double value(double x) { CallableBond.Arguments args = bond_.engine_.getArguments() as CallableBond.Arguments; // Pops the original value when function finishes double originalSpread = args.spread; args.spread = x; bond_.engine_.calculate(); args.spread = originalSpread; return(results_.value.Value); }