コード例 #1
0
      private static double couponRate(List<CashFlow> leg, CashFlow cf) 
      {
         if (cf == null) return 0.0;

         Date paymentDate = cf.date();
         bool firstCouponFound = false;
         double nominal = 0;
         double accrualPeriod = 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) {
                     if (!(nominal == cp.nominal() && accrualPeriod == cp.accrualPeriod() && dc == cp.dayCounter()))
                         throw new ApplicationException("cannot aggregate two different coupons on " + paymentDate);
                 } else {
                     firstCouponFound = true;
                     nominal = cp.nominal();
                     accrualPeriod = cp.accrualPeriod();
                     dc = cp.dayCounter();
                 }
                 result += cp.rate();
             }
         }

         if (!firstCouponFound) throw new ApplicationException("next cashflow (" + paymentDate + ") is not a coupon");
         return result;
      }
コード例 #2
0
ファイル: CashFlows.cs プロジェクト: akasolace/qlnet
      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 == cp.nominal() &&
                                   accrualPeriod == 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;
        }
コード例 #3
0
ファイル: CashFlows.cs プロジェクト: akasolace/qlnet
      //! 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.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 プロジェクト: akasolace/qlnet
 public void visit(CashFlow cf) 
 {
    nonSensNPV_ += cf.amount() * discountCurve_.discount(cf.date());
 }
コード例 #5
0
ファイル: Program.cs プロジェクト: vina0007/qlnetApps
        static void Main(string[] args)
        {
            /*
             * TODO:
             *  FIXES
             *      1. WAC vs Net Coupon (meanings are reversed, names are bad)
             *      2. CashFlows needs to be replaced with Expected CashFlows to get the correct price
             *  NEW IMPLEMENTATION
             *      1. Add delay
             *      2. Add SecType enum PT, PO, IO
             */

            Date referenceDate = new Date(16, 11, 2015);

            Settings.setEvaluationDate(referenceDate);
            int                   settlementDays    = 0;
            Calendar              calendar          = new TARGET();
            int                   origTerm          = 360;
            Frequency             sinkingFrequency  = Frequency.Monthly;
            DayCounter            accrualDayCounter = new Thirty360();
            BusinessDayConvention paymentConvention = BusinessDayConvention.Unadjusted;


            double wac          = 0.03875;
            int    wam          = 357;
            int    wala         = origTerm - wam;
            Date   factorDate   = new Date(1, 12, 2015);
            Date   issueDate    = calendar.advance(factorDate, -wala, TimeUnit.Months, BusinessDayConvention.Unadjusted);
            double factor       = 1.0;
            double currentFace  = 1000000;
            double originalFace = currentFace / factor;
            int    statedDelay  = 30; //54;
            double netCoupon    = 0.030;
            string secType      = "PT";
            Date   settleDate   = referenceDate;

            double yield_be = 0.0270;
            //double price;


            double speed = 0.08;

            IPrepayModel prepaymodel = new ConstantCPR(speed);
            //IPrepayModel prepaymodel = new PSACurve(factorDate, speed);

            MBSFixedRateBond mbs = new MBSFixedRateBond(
                settlementDays,
                calendar,
                currentFace,
                factorDate,
                new Period(wam, TimeUnit.Months),
                new Period(origTerm, TimeUnit.Months),
                sinkingFrequency,
                wac,
                netCoupon,
                accrualDayCounter,
                prepaymodel,
                paymentConvention,
                issueDate);

            YieldTermStructure discountCurve = new FlatForward(referenceDate, yield_be, new Thirty360(), Compounding.Compounded, Frequency.Semiannual);

            DiscountingBondEngine discountingBondEngine = new DiscountingBondEngine(new Handle <YieldTermStructure>(discountCurve));

            mbs.setPricingEngine(discountingBondEngine);

            // display results
            Console.WriteLine("WAC         : {0:F5}", wac);
            Console.WriteLine("WALA        : {0}", wala);
            Console.WriteLine("WAM         : {0}", wam);
            Console.WriteLine("Factor Date : {0}", factorDate.ToShortDateString());
            Console.WriteLine("Factor      : {0:F10}", factor);
            Console.WriteLine("Orig Face   : {0:N}", originalFace);
            Console.WriteLine("Curr Face   : {0:N}", currentFace);
            Console.WriteLine("Stated Delay: {0}", statedDelay);
            Console.WriteLine("Net Coupon  : {0:F3}", netCoupon);
            Console.WriteLine("Sec Type    : {0}", secType);
            Console.WriteLine("Settle Date : {0}", settleDate.ToShortDateString());
            Console.WriteLine("Model Type  : {0}", prepaymodel.GetType().ToString());
            Console.WriteLine("Model Speed : {0:F3}", speed);
            Console.WriteLine("Yield       : {0:F5}", yield_be);

            Console.WriteLine("Clean Price : {0:F6}", mbs.cleanPrice());
            Console.WriteLine("Dirty Price : {0:F6}", mbs.dirtyPrice());
            Console.WriteLine("Accrued     : {0:F6}", mbs.accruedAmount());

            // month, factor, pay date, ending prin, interest, reg principal, prepaid principal, total principal, net flow, cpr, smm, wala, wam, p&i payment, i payment, beg balance, days, discount, pv
            double ebal = currentFace;

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("output.csv"))
            {
                DayCounter dc      = discountCurve.dayCounter();
                Date       refdate = discountCurve.referenceDate();



                sw.WriteLine("month,factor date,factor,pay date,ending principal,interest,regular principal,prepaid principal,total principal,net flow,cpr,smm,wala,wam,p&i payment,interest payment,beginning balance,days,discount,pv");
                for (int i = 0; i < wam; i++)
                {
                    double upmt = 0;
                    double ppmt = 0;
                    double ipmt = 0;
                    double bbal = ebal;

                    Date paydate = null;

                    for (int j = 0; j <= 2; j++)
                    {
                        int      k  = i * 3 + j;
                        CashFlow cf = mbs.expectedCashflows()[k];
                        if (cf.GetType() == typeof(VoluntaryPrepay))
                        {
                            upmt    = cf.amount();
                            paydate = cf.date();
                        }
                        if (cf.GetType() == typeof(AmortizingPayment))
                        {
                            ppmt = cf.amount();
                        }
                        if (cf.GetType() == typeof(FixedRateCoupon))
                        {
                            ipmt = cf.amount();
                        }
                    }
                    int    days = dc.dayCount(refdate, paydate);
                    double df   = discountCurve.discount(paydate);
                    ebal = bbal - upmt - ppmt;
                    double smm = upmt / (bbal - ppmt);

                    sw.Write("{0},", i + 1);                                                                              //month
                    sw.Write("{0},", calendar.advance(factorDate, i, TimeUnit.Months, BusinessDayConvention.Unadjusted)); //factor date
                    sw.Write("{0:F10},", factor * bbal / currentFace);                                                    //factor
                    sw.Write("{0},", paydate.ToShortDateString());                                                        //pay date
                    sw.Write("{0:F2},", ebal);                                                                            //ending principal
                    sw.Write("{0:F2},", ipmt);                                                                            //interest
                    sw.Write("{0:F2},", ppmt);                                                                            //regular principal
                    sw.Write("{0:F2},", upmt);                                                                            //prepaid principal
                    sw.Write("{0:F2},", ppmt + upmt);                                                                     //total principal
                    sw.Write("{0:F2},", ipmt + ppmt + upmt);                                                              //net flow
                    sw.Write("{0:F4},", 1 - Math.Pow(1 - smm, 12));                                                       //cpr
                    sw.Write("{0:F6},", smm);                                                                             //smm
                    sw.Write("{0},", wala + i);                                                                           //wala
                    sw.Write("{0},", wam - i);                                                                            //wam
                    sw.Write("{0},", i);                                                                                  //p&i payment
                    sw.Write("{0},", i);                                                                                  //interest payment
                    sw.Write("{0:F2},", bbal);                                                                            //beginning balance
                    sw.Write("{0},", days);                                                                               //days
                    sw.Write("{0:F8},", df);                                                                              //discount
                    sw.WriteLine("{0}", df * (ipmt + ppmt + upmt));                                                       //pv
                }
            }
        }