コード例 #1
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        public static double accruedAmount(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null)
        {
            if (settlementDate == null)
            {
                settlementDate = Settings.Instance.evaluationDate();
            }

            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);
        }
コード例 #2
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        //! NPV and BPS of the cash flows.
        // The NPV and BPS of the cash flows calculated together for performance reason
        public static void npvbps(Leg leg, YieldTermStructure discountCurve, bool includeSettlementDateFlows,
                                  Date settlementDate, Date npvDate, out double npv, out double bps)
        {
            npv = bps = 0.0;
            if (leg.empty())
            {
                bps = 0.0;
                return;
            }

            for (int i = 0; i < leg.Count; ++i)
            {
                CashFlow cf = leg[i];
                if (!cf.hasOccurred(settlementDate, includeSettlementDateFlows) &&
                    !cf.tradingExCoupon(settlementDate))
                {
                    Coupon cp = leg[i] as Coupon;
                    double df = discountCurve.discount(cf.date());
                    npv += cf.amount() * df;
                    if (cp != null)
                    {
                        bps += cp.nominal() * cp.accrualPeriod() * df;
                    }
                }
            }
            double d = discountCurve.discount(npvDate);

            npv /= d;
            bps  = Const.BASIS_POINT * bps / d;
        }
コード例 #3
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        //! NPV of a single cash flows
        public static double npv(CashFlow cashflow, YieldTermStructure discountCurve,
                                 Date settlementDate = null, Date npvDate = null, int exDividendDays = 0)
        {
            double NPV = 0.0;

            if (cashflow == null)
            {
                return(0.0);
            }

            if (settlementDate == null)
            {
                settlementDate = Settings.Instance.evaluationDate();
            }

            if (npvDate == null)
            {
                npvDate = settlementDate;
            }

            if (!cashflow.hasOccurred(settlementDate + exDividendDays))
            {
                NPV = cashflow.amount() * discountCurve.discount(cashflow.date());
            }


            return(NPV / discountCurve.discount(npvDate));
        }
コード例 #4
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        public static Date nextCashFlowDate(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null)
        {
            CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate);

            if (cf == null)
            {
                return(null);
            }
            return(cf.date());
        }
コード例 #5
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        public static double?nextCashFlowAmount(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null)
        {
            CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate);

            if (cf == null)
            {
                return(null);
            }

            Date   paymentDate = cf.date();
            double result      = 0.0;

            result = leg.Where(cf1 => cf1.date() == paymentDate).Sum(cf1 => cf1.amount());
            return(result);
        }
コード例 #6
0
        protected void setSingleRedemption(double notional, CashFlow redemption)
        {
            notionals_.Clear();
            notionalSchedule_.Clear();
            redemptions_.Clear();

            notionalSchedule_.Add(new Date());
            notionals_.Add(notional);

            notionalSchedule_.Add(redemption.date());
            notionals_.Add(0.0);

            cashflows_.Add(redemption);
            redemptions_.Add(redemption);
        }
コード例 #7
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        // At-the-money rate of the cash flows.
        // The result is the fixed rate for which a fixed rate cash flow  vector, equivalent to the input vector, has the required NPV according to the given term structure. If the required NPV is
        //  not given, the input cash flow vector's NPV is used instead.
        public static double atmRate(Leg leg, YieldTermStructure discountCurve, bool includeSettlementDateFlows,
                                     Date settlementDate = null, Date npvDate = null, double?targetNpv = null)
        {
            if (settlementDate == null)
            {
                settlementDate = Settings.Instance.evaluationDate();
            }

            if (npvDate == null)
            {
                npvDate = settlementDate;
            }

            double        npv  = 0.0;
            BPSCalculator calc = new BPSCalculator(discountCurve);

            for (int i = 0; i < leg.Count; ++i)
            {
                CashFlow cf = leg[i];
                if (!cf.hasOccurred(settlementDate, includeSettlementDateFlows) &&
                    !cf.tradingExCoupon(settlementDate))
                {
                    npv += cf.amount() * discountCurve.discount(cf.date());
                    cf.accept(calc);
                }
            }

            if (targetNpv == null)
            {
                targetNpv = npv - calc.nonSensNPV();
            }
            else
            {
                targetNpv *= discountCurve.discount(npvDate);
                targetNpv -= calc.nonSensNPV();
            }

            if (targetNpv.IsEqual(0.0))
            {
                return(0.0);
            }

            double bps = calc.bps();

            Utils.QL_REQUIRE(bps.IsNotEqual(0.0), () => "null bps: impossible atm rate");

            return(targetNpv.Value / bps);
        }
コード例 #8
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        public static int accrualDays(Leg leg, bool includeSettlementDateFlows, Date settlementDate = null)
        {
            CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate);

            if (cf == null)
            {
                return(0);
            }
            Date paymentDate = cf.date();

            foreach (CashFlow x in leg.Where(x => x.date() == paymentDate))
            {
                Coupon cp = x as Coupon;
                if (cp != null)
                {
                    return(cp.accrualDays());
                }
            }
            return(0);
        }
コード例 #9
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        public static Date referencePeriodEnd(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.referencePeriodEnd);
                }
            }
            return(null);
        }
コード例 #10
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        private static double aggregateRate(Leg leg, CashFlow cf)
        {
            if (cf == null)
            {
                return(0.0);
            }

            Date       paymentDate      = cf.date();
            bool       firstCouponFound = false;
            double     nominal          = 0.0;
            double     accrualPeriod    = 0.0;
            DayCounter dc     = null;
            double     result = 0.0;

            foreach (CashFlow x in leg.Where(x => x.date() == paymentDate))
            {
                Coupon cp = x as Coupon;
                if (cp != null)
                {
                    if (firstCouponFound)
                    {
                        Utils.QL_REQUIRE(nominal.IsEqual(cp.nominal()) &&
                                         accrualPeriod.IsEqual(cp.accrualPeriod()) &&
                                         dc == cp.dayCounter(), () =>
                                         "cannot aggregate two different coupons on "
                                         + paymentDate);
                    }
                    else
                    {
                        firstCouponFound = true;
                        nominal          = cp.nominal();
                        accrualPeriod    = cp.accrualPeriod();
                        dc = cp.dayCounter();
                    }
                    result += cp.rate();
                }
            }

            Utils.QL_REQUIRE(firstCouponFound, () => "no coupon paid at cashflow date " + paymentDate);
            return(result);
        }
コード例 #11
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
        // 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));
            }
        }
コード例 #12
0
ファイル: CashFlows.cs プロジェクト: OpenDerivatives/QLCore
 public void visit(CashFlow cf)
 {
     nonSensNPV_ += cf.amount() * discountCurve_.discount(cf.date());
 }
コード例 #13
0
 protected double cashFlowRiskyValue(CashFlow cf, NotionalPath notionalPath)
 {
     return(cf.amount() * notionalPath.notionalRate(cf.date())); //TODO: fix for more complicated cashflows
 }
コード例 #14
0
        // 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();
                }
            }
        }