예제 #1
0
        public void GetPaymentDetails(double[] tArray,
                                      double principal,
                                      double[] cpnArray,
                                      Frequency frequency,
                                      AmortizationType amortizationType,
                                      out double[] begPrincipal,
                                      out double[] interest,
                                      out double[] scheduledPrincipalPay,
                                      out double[] prepayment,
                                      out double[] defaultPrincipal,
                                      int numPastPayment)
        {
            var length = tArray.Length;

            begPrincipal          = new double[length];
            interest              = new double[length];
            scheduledPrincipalPay = new double[length];
            prepayment            = new double[length];
            defaultPrincipal      = new double[length];

            var uniqueCpns = cpnArray.Distinct();

            var remainingPrincipal = principal;

            var c       = amortizationType == AmortizationType.EqualPrincipal ? remainingPrincipal / (length) : GetLevelPayment(tArray.ToArray(), remainingPrincipal, cpnArray[0], frequency);
            var recalcC = PrepaymentModel.NeedRecalc() || DefaultModel.NeedRecalc() || uniqueCpns.Count() != 1;

            for (var i = 0; i < tArray.Length; ++i)
            {
                if (recalcC)
                {
                    c = amortizationType == AmortizationType.EqualPrincipal
                                                ? remainingPrincipal / (length - i)
                                                : GetLevelPayment(tArray.Skip(i).ToArray(), remainingPrincipal, cpnArray[i], frequency);
                }
                interest[i] = remainingPrincipal * GetPayRate(cpnArray[i], frequency, tArray[i]);
                scheduledPrincipalPay[i] = amortizationType == AmortizationType.EqualPrincipal ? c : (c - interest[i]);
                if (recalcC)
                {
                    prepayment[i] = (remainingPrincipal - scheduledPrincipalPay[i]) * PrepaymentModel.Smm(i + 1 + numPastPayment);

                    //remaining principal will default, and scheduled principal will also default and corresponding interest will lost
                    var defaultRate          = DefaultModel.Mdr(i + 1 + numPastPayment);
                    var paidPrincipalDefault = scheduledPrincipalPay[i] * defaultRate;
                    var paidInterestDefault  = interest[i] * defaultRate;
                    interest[i] -= paidInterestDefault;
                    scheduledPrincipalPay[i] -= paidPrincipalDefault;

                    defaultPrincipal[i] = (remainingPrincipal - scheduledPrincipalPay[i]) * defaultRate + paidPrincipalDefault;
                }
                else
                {
                    prepayment[i]       = 0.0;
                    defaultPrincipal[i] = 0.0;
                }

                remainingPrincipal -= (scheduledPrincipalPay[i] + prepayment[i] + defaultPrincipal[i]);
                begPrincipal[i]     = remainingPrincipal;
            }
        }
예제 #2
0
        public Amortization(Dictionary <Date, double> amortizationSchedule = null,
                            bool renormalizeFlag = false,
                            AmortizationType amortizationType = AmortizationType.None)
        {
            AmortizationSchedule         = amortizationSchedule;
            AmortizationType             = amortizationType;
            RenormalizeAfterAmoritzation = renormalizeFlag;

            if (amortizationSchedule != null && amortizationSchedule.Count > 0)
            {
                var sum = AmortizationSchedule.Sum(x => x.Value);
                if (!sum.AlmostEqual(1.0))
                {
                    throw new PricingLibraryException("Amortization must sum up to 1.0, but is not");
                }
            }
        }
예제 #3
0
 /// <summary>
 /// Creates an Amortization object depending on the passed parameter.
 /// </summary>
 /// <param name="amortizationType">Type of amortization to be created</param>
 /// <returns>Returns an Amortization object.</returns>
 public Amortization CreateAmortization(AmortizationType amortizationType,
     decimal amount,
     int numberOfPayments,
     AmortizationPaymentFrequencyType frequency,
     decimal anualInterest,
     int gracePeriod,
     DateTime startDate,
     decimal tax)
 {
     //Creates the necessary object depending on the parameter
     //Commented lines to be added in the future as soon as their
     //respective classes are created.
     switch (amortizationType)
     {
         case AmortizationType.CapitalConstante:
             return new ConstantPrincipalAmortization (amount,
                                                       numberOfPayments,
                                                       frequency,
                                                       anualInterest,
                                                       gracePeriod,
                                                       startDate,
                                                       tax);
         case AmortizationType.InteresFlat:
             return new FlatInterestAmortization (amount,
                                                  numberOfPayments,
                                                  frequency,
                                                  anualInterest,
                                                  gracePeriod,
                                                  startDate,
                                                  tax);
         case AmortizationType.Renta:
             return new RentAmortization (amount,
                                          numberOfPayments,
                                          frequency,
                                          anualInterest,
                                          gracePeriod,
                                          startDate,
                                          tax);
         default:
             return null;
     }
 }
예제 #4
0
파일: Loan.cs 프로젝트: stepinto163/Qdp
        public Loan(Date startDate,
                    Date maturityDate,
                    Date firstPaymentDate,
                    double notional,
                    int numOfPayment,
                    IDayCount dayCount,
                    Frequency frequency,
                    double coupon,
                    Date resetDate,
                    bool isFloatingRate,
                    IndexType indexType,
                    double floatingRateMultiplier,
                    AmortizationType amortizationType,
                    CurrencyCode currency = CurrencyCode.CNY,
                    IMortgageCalculator mortgageCalculator = null,
                    double taxRate = 0.0
                    )
        {
            StartDate = startDate;
            UnderlyingMaturityDate = maturityDate;
            FirstPaymentDate       = firstPaymentDate;
            NumOfPayment           = numOfPayment;
            Notional               = notional;
            DayCount               = dayCount;
            Frequency              = frequency;
            Coupon                 = coupon;
            TaxRate                = taxRate;
            ResetDate              = resetDate;
            IsFloatingRate         = isFloatingRate;
            IndexType              = indexType;
            FloatingRateMultiplier = floatingRateMultiplier;
            Currency               = currency;
            _implicitAccStartDate  = Frequency.GetTerm().Prev(FirstPaymentDate);
            AmortizationType       = amortizationType;
            MortgageCalculator     = mortgageCalculator ?? new SimpleMortgageCalculator(new Psa(), new Sda());

            Accruals        = new Schedule(_implicitAccStartDate, UnderlyingMaturityDate, Frequency.GetTerm(), Stub.ShortEnd).ToArray();
            _numPastPayment = NumOfPayment - (Accruals.Length - 1);
        }
 private bool IsEqualPmtOrEqualPrin(AmortizationType amortizationType)
 {
     return(amortizationType == AmortizationType.EqualPmt ||
            amortizationType == AmortizationType.EqualPrin);
 }
예제 #6
0
파일: Bond.cs 프로젝트: stepinto163/Qdp
        public Bond(
            string id,
            Date startDate,
            Date maturityDate,
            double notional,
            CurrencyCode currency,
            ICoupon coupon,
            ICalendar calendar,
            Frequency paymentFreq,
            Stub stub,
            IDayCount accrualDayCount,
            IDayCount paymentDayCount,
            BusinessDayConvention accrualBizDayRule,
            BusinessDayConvention paymentBizDayRule,
            DayGap settlementGap,
            TradingMarket bondTradingMarket,
            bool stickToEom               = false,
            IRedemption redemption        = null,
            Date firstPaymentDate         = null,
            bool isZeroCouponBond         = false,
            double issuePrice             = double.NaN,
            double issueRate              = double.NaN,
            AmortizationType amortionType = AmortizationType.None,
            Dictionary <Date, double> amortizationInDates     = null,
            Dictionary <int, double> amortizationInIndex      = null,
            bool renormalizeAfterAmoritzation                 = false,
            Dictionary <int, double> stepWiseCompensationRate = null,
            Dictionary <string, double> optionToCall          = null,
            Dictionary <string, double> optionToPut           = null,
            Dictionary <string, double> optionToAssPut        = null,
            double settlementCoupon = double.NaN,
            bool roundCleanPrice    = false
            )
        {
            Id        = id;
            StartDate = startDate;
            UnderlyingMaturityDate = maturityDate;
            Notional                 = notional;
            Currency                 = currency;
            Coupon                   = coupon;
            Calendar                 = calendar;
            PaymentFreq              = paymentFreq;
            Stub                     = stub;
            AccrualDayCount          = accrualDayCount;
            PaymentDayCount          = paymentDayCount;
            AccrualBizDayRule        = accrualBizDayRule;
            PaymentBizDayRule        = paymentBizDayRule;
            SettlmentGap             = settlementGap;
            _settlementCoupon        = settlementCoupon;
            BondTradeingMarket       = bondTradingMarket;
            FirstPaymentDate         = firstPaymentDate;
            IsZeroCouponBond         = isZeroCouponBond;
            IssuePrice               = issuePrice;
            IssueRate                = issueRate;
            StickToEom               = stickToEom;
            StepWiseCompensationRate = stepWiseCompensationRate;
            RoundCleanPrice          = roundCleanPrice;

            OptionToCall   = optionToCall;
            OptionToPut    = optionToPut;
            OptionToAssPut = optionToAssPut;

            Tenor = string.Format("{0},{1}", (int)(UnderlyingMaturityDate - StartDate), "D");

            IrregularPayment = false;
            if (Coupon is CustomizedCoupon)
            {
            }
            else
            {
                List <Date> tmpDate;
                if (FirstPaymentDate == null)
                {
                    var schedule = new Schedule(StartDate, UnderlyingMaturityDate, PaymentFreq.GetTerm(), Stub, Calendar,
                                                AccrualBizDayRule);
                    tmpDate       = schedule.ToList();
                    _isRegualDate = schedule.IsRegular;
                }
                else
                {
                    var schedule    = new Schedule(FirstPaymentDate, UnderlyingMaturityDate, PaymentFreq.GetTerm(), Stub, Calendar, AccrualBizDayRule);
                    var regAccruals = schedule.ToList();
                    tmpDate = new List <Date> {
                        StartDate
                    };
                    tmpDate.AddRange(regAccruals);
                    IrregularPayment = false;
                    _isRegualDate    = new List <bool> {
                        IrregularPayment
                    };
                    _isRegualDate.AddRange(schedule.IsRegular);
                }

                if (tmpDate.Count > 2)
                {
                    if (PaymentBizDayRule.Adjust(calendar, tmpDate[tmpDate.Count - 2]).Equals(tmpDate.Last()))
                    {
                        tmpDate.RemoveAt(tmpDate.Count - 2);
                        _isRegualDate.RemoveAt(_isRegualDate.Count - 2);
                    }
                }

                Accruals = new Schedule(tmpDate);

                if (FirstPaymentDate == null)
                {
                    PaymentSchedule =
                        new Schedule(
                            new Schedule(StartDate, UnderlyingMaturityDate, PaymentFreq.GetTerm(), Stub, Calendar, PaymentBizDayRule).Skip(1));
                }
                else
                {
                    PaymentSchedule =
                        new Schedule(
                            new Schedule(FirstPaymentDate, UnderlyingMaturityDate, PaymentFreq.GetTerm(), Stub, Calendar, PaymentBizDayRule));
                }
            }

            if (Accruals.Count() != PaymentSchedule.Count() + 1)
            {
                throw new PricingLibraryException("Bond's number of accrual periods do not match number of payments");
            }

            AmortizationType             = amortionType;
            AmortizationInDates          = amortizationInDates;
            AmortizationInIndex          = amortizationInIndex;
            RenormalizeAfterAmoritzation = renormalizeAfterAmoritzation;
            IAmortization amortization;

            if (AmortizationInDates != null)
            {
                amortization = new Amortization(amortizationInDates, RenormalizeAfterAmoritzation);
            }
            else if (AmortizationInIndex != null)
            {
                amortization = new Amortization(ToAmortizationSchedule(PaymentSchedule.ToArray(), AmortizationInIndex), RenormalizeAfterAmoritzation);
            }
            else
            {
                //EqualPrincipal or EqualPrincipalAndInterest will be calculated later
                amortization = new Amortization();
            }
            Amoritzation        = amortization;
            _mortgageCalculator = new MortgageCalculator(new Psa(0.0), new Sda(0.0));

            Redemption = redemption ?? new Redemption(1.0, RedemptionType.None);
            //Redemption = redemption ?? new Redemption(1.0, PriceQuoteType.Clean);

            if (PaymentFreq == Frequency.None)
            {
                IrregularPayment = true;
            }
            else
            {
                for (var i = 0; i < Accruals.Count() - 1; ++i)
                {
                    if (PaymentFreq.GetTerm().Next(Accruals.ToArray()[i]) != Accruals.ToArray()[i + 1])
                    {
                        IrregularPayment = false;
                        break;
                    }
                }
            }

            _compensationRate = Accruals.Skip(1).Select(x => 0.0).ToArray();

            if (stepWiseCompensationRate != null)
            {
                var compensationCoupons = new List <double>();
                var arr = StepWiseCompensationRate.OrderBy(x => x.Key).Select(x => Tuple.Create(x.Key, x.Value)).ToArray();
                for (var i = 0; i < Accruals.Count() - 1; ++i)
                {
                    compensationCoupons.Add(i > 0 ? compensationCoupons[i - 1] : 0.0);
                    var updateCoupon       = arr.FirstOrDefault(x => x.Item1 == (i + 1));
                    var compensationCoupon = updateCoupon != null ? updateCoupon.Item2 : 0.0;
                    compensationCoupons[i] += compensationCoupon;
                }
                _compensationRate = compensationCoupons.ToArray();
            }
        }