public static Date accrualEndDate(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); if (cf == null) { return(null); } Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) { Coupon cp = x as Coupon; if (cp != null) { return(cp.accrualEndDate()); } } return(null); }
public static double accruedAmount(List <CashFlow> leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); if (cf == null) { return(0); } Date paymentDate = cf.Date; double result = 0.0; foreach (CashFlow x in leg.Where(x => x.Date == paymentDate)) { Coupon cp = x as Coupon; if (cp != null) { result += cp.accruedAmount(settlementDate); } } return(result); }
// helper function used to calculate Time-To-Discount for each stage when calculating discount factor stepwisely public static double getStepwiseDiscountTime(CashFlow cashFlow, DayCounter dc, Date npvDate, Date lastDate) { Date cashFlowDate = cashFlow.date(); Date refStartDate, refEndDate; Coupon coupon = cashFlow as Coupon; if (coupon != null) { refStartDate = coupon.referencePeriodStart; refEndDate = coupon.referencePeriodEnd; } else { if (lastDate == npvDate) { // we don't have a previous coupon date, // so we fake it refStartDate = cashFlowDate - new Period(1, TimeUnit.Years); } else { refStartDate = lastDate; } refEndDate = cashFlowDate; } if (coupon != null && lastDate != coupon.accrualStartDate()) { double couponPeriod = dc.yearFraction(coupon.accrualStartDate(), cashFlowDate, refStartDate, refEndDate); double accruedPeriod = dc.yearFraction(coupon.accrualStartDate(), lastDate, refStartDate, refEndDate); return(couponPeriod - accruedPeriod); } else { return(dc.yearFraction(lastDate, cashFlowDate, refStartDate, refEndDate)); } }
public static double nextCouponRate(List <CashFlow> leg, bool includeSettlementDateFlows, Date refDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, refDate); return(couponRate(leg, cf)); }
public static double previousCouponRate(List <CashFlow> leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = previousCashFlow(leg, includeSettlementDateFlows, settlementDate); return(aggregateRate(leg, cf)); }
public void visit(CashFlow cf) { nonSensNPV_ += cf.amount() * discountCurve_.discount(cf.date()); }
public void visit(CashFlow c) { // nothing to do }
// other public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); Arguments arguments = args as Arguments; Utils.QL_REQUIRE(arguments != null, () => "argument type does not match"); arguments.type = type_; arguments.nominal1 = nominal1_; arguments.nominal2 = nominal2_; arguments.index1 = index1_; arguments.index2 = index2_; List <CashFlow> leg1Coupons = leg1(); List <CashFlow> leg2Coupons = leg2(); arguments.leg1ResetDates = arguments.leg1PayDates = arguments.leg1FixingDates = new InitializedList <Date>(leg1Coupons.Count); arguments.leg2ResetDates = arguments.leg2PayDates = arguments.leg2FixingDates = new InitializedList <Date>(leg2Coupons.Count); arguments.leg1Spreads = arguments.leg1AccrualTimes = arguments.leg1Gearings = new InitializedList <double>(leg1Coupons.Count); arguments.leg2Spreads = arguments.leg2AccrualTimes = arguments.leg2Gearings = new InitializedList <double>(leg2Coupons.Count); arguments.leg1Coupons = new InitializedList <double?>(leg1Coupons.Count, null); arguments.leg2Coupons = new InitializedList <double?>(leg2Coupons.Count, null); arguments.leg1IsRedemptionFlow = new InitializedList <bool>(leg1Coupons.Count, false); arguments.leg2IsRedemptionFlow = new InitializedList <bool>(leg2Coupons.Count, false); arguments.leg1CappedRates = arguments.leg1FlooredRates = new InitializedList <double?>(leg1Coupons.Count, null); arguments.leg2CappedRates = arguments.leg2FlooredRates = new InitializedList <double?>(leg2Coupons.Count, null); for (int i = 0; i < leg1Coupons.Count; ++i) { FloatingRateCoupon coupon = leg1Coupons[i] as FloatingRateCoupon; if (coupon != null) { arguments.leg1AccrualTimes[i] = coupon.accrualPeriod(); arguments.leg1PayDates[i] = coupon.date(); arguments.leg1ResetDates[i] = coupon.accrualStartDate(); arguments.leg1FixingDates[i] = coupon.fixingDate(); arguments.leg1Spreads[i] = coupon.spread(); arguments.leg1Gearings[i] = coupon.gearing(); try { arguments.leg1Coupons[i] = coupon.amount(); } catch (Exception) { arguments.leg1Coupons[i] = null; } CappedFlooredCoupon cfcoupon = leg1Coupons[i] as CappedFlooredCoupon; if (cfcoupon != null) { arguments.leg1CappedRates[i] = cfcoupon.cap(); arguments.leg1FlooredRates[i] = cfcoupon.floor(); } } else { CashFlow cashflow = leg1Coupons[i] as CashFlow; int j = arguments.leg1PayDates.FindIndex(x => x == cashflow.date()); Utils.QL_REQUIRE(j != -1, () => "nominal redemption on " + cashflow.date() + "has no corresponding coupon"); int jIdx = j; // Size jIdx = j - arguments->leg1PayDates.begin(); arguments.leg1IsRedemptionFlow[i] = true; arguments.leg1Coupons[i] = cashflow.amount(); arguments.leg1ResetDates[i] = arguments.leg1ResetDates[jIdx]; arguments.leg1FixingDates[i] = arguments.leg1FixingDates[jIdx]; arguments.leg1AccrualTimes[i] = 0.0; arguments.leg1Spreads[i] = 0.0; arguments.leg1Gearings[i] = 1.0; arguments.leg1PayDates[i] = cashflow.date(); } } for (int i = 0; i < leg2Coupons.Count; ++i) { FloatingRateCoupon coupon = leg2Coupons[i] as FloatingRateCoupon; if (coupon != null) { arguments.leg2AccrualTimes[i] = coupon.accrualPeriod(); arguments.leg2PayDates[i] = coupon.date(); arguments.leg2ResetDates[i] = coupon.accrualStartDate(); arguments.leg2FixingDates[i] = coupon.fixingDate(); arguments.leg2Spreads[i] = coupon.spread(); arguments.leg2Gearings[i] = coupon.gearing(); try { arguments.leg2Coupons[i] = coupon.amount(); } catch (Exception) { arguments.leg2Coupons[i] = null; } CappedFlooredCoupon cfcoupon = leg2Coupons[i] as CappedFlooredCoupon; if (cfcoupon != null) { arguments.leg2CappedRates[i] = cfcoupon.cap(); arguments.leg2FlooredRates[i] = cfcoupon.floor(); } } else { CashFlow cashflow = leg2Coupons[i] as CashFlow; int j = arguments.leg2PayDates.FindIndex(x => x == cashflow.date()); Utils.QL_REQUIRE(j != -1, () => "nominal redemption on " + cashflow.date() + "has no corresponding coupon"); int jIdx = j; // j - arguments->leg2PayDates.begin(); arguments.leg2IsRedemptionFlow[i] = true; arguments.leg2Coupons[i] = cashflow.amount(); arguments.leg2ResetDates[i] = arguments.leg2ResetDates[jIdx]; arguments.leg2FixingDates[i] = arguments.leg2FixingDates[jIdx]; arguments.leg2AccrualTimes[i] = 0.0; arguments.leg2Spreads[i] = 0.0; arguments.leg2Gearings[i] = 1.0; arguments.leg2PayDates[i] = cashflow.date(); } } }
public static double dirtyPriceFromYield(double faceAmount, List <CashFlow> cashflows, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, Date settlement) { if (frequency == Frequency.NoFrequency || frequency == Frequency.Once) { frequency = Frequency.Annual; } InterestRate y = new InterestRate(yield, dayCounter, compounding, frequency); double price = 0.0; double discount = 1.0; Date lastDate = null; for (int i = 0; i < cashflows.Count - 1; ++i) { if (cashflows[i].hasOccurred(settlement)) { continue; } Date couponDate = cashflows[i].Date; double amount = cashflows[i].amount(); if (lastDate == null) { // first not-expired coupon if (i > 0) { lastDate = cashflows[i - 1].Date; } else { if (cashflows[i].GetType().IsSubclassOf(typeof(Coupon))) { lastDate = ((Coupon)cashflows[i]).accrualStartDate(); } else { lastDate = couponDate - new Period(1, TimeUnit.Years); } } discount *= y.discountFactor(settlement, couponDate, lastDate, couponDate); } else { discount *= y.discountFactor(lastDate, couponDate); } lastDate = couponDate; price += amount * discount; } CashFlow redemption = cashflows.Last(); if (!redemption.hasOccurred(settlement)) { Date redemptionDate = redemption.Date; double amount = redemption.amount(); if (lastDate == null) { // no coupons lastDate = redemptionDate - new Period(1, TimeUnit.Years); discount *= y.discountFactor(settlement, redemptionDate, lastDate, redemptionDate); } else { discount *= y.discountFactor(lastDate, redemptionDate); } price += amount * discount; } return(price / faceAmount * 100.0); }
protected double cashFlowRiskyValue(CashFlow cf, NotionalPath notionalPath) { return(cf.amount() * notionalPath.notionalRate(cf.date())); //TODO: fix for more complicated cashflows }