Ejemplo n.º 1
0
        public IAmortization Adjust(Schedule paymentSchedule,
                                    ICalendar calendar        = null,
                                    BusinessDayConvention bda = BusinessDayConvention.None,
                                    Frequency frequency       = Frequency.None)
        {
            Dictionary <Date, double> amortizationSchedule;

            if (AmortizationSchedule == null || !AmortizationSchedule.Any())
            {
                amortizationSchedule = new[] { Tuple.Create(paymentSchedule.Last(), 1.0) }.ToDictionary(x => x.Item1, x => x.Item2);
            }
            else
            {
                var principalPay =
                    AmortizationSchedule.Select(
                        x => Tuple.Create(
                            bda != BusinessDayConvention.None && calendar != null ? bda.Adjust(calendar, x.Key) : x.Key,
                            x.Value))
                    .OrderBy(x => x.Item1).ToList();
                if (paymentSchedule.Last() <= principalPay.First().Item1)
                {
                    return(new Amortization(new[] { Tuple.Create(paymentSchedule.Last(), 1.0) }.ToDictionary(x => x.Item1, x => x.Item2)));
                }

                var preMaturity      = principalPay.Where(x => x.Item1 <= paymentSchedule.Last()).OrderBy(x => x.Item1).ToList();
                var remaingPrincipal = principalPay.Where(x => x.Item1 > paymentSchedule.Last()).ToList().Sum(x => x.Item2);
                amortizationSchedule = preMaturity.Select(
                    (x, index) =>
                    Tuple.Create(x.Item1, index < preMaturity.Count - 1 ? x.Item2 : x.Item2 + remaingPrincipal))
                                       .ToDictionary(x => x.Item1, x => x.Item2);
            }

            return(new Amortization(amortizationSchedule, RenormalizeAfterAmoritzation, AmortizationType));
        }
Ejemplo n.º 2
0
        public static Date ApplyBusinessDayAdjustment([QuantSAExcelArgument(Description = "The date to be adjusted")]
                                                      Date date,
                                                      [QuantSAExcelArgument(Description = "The business day rule to apply to the date.")]
                                                      BusinessDayConvention convention,
                                                      [QuantSAExcelArgument(Description = "The calendar to use in the adjustment.")]
                                                      Calendar calendar)

        {
            return(convention.Adjust(date, calendar));
        }
Ejemplo n.º 3
0
        public Deposit(
            Date startDate,
            Date maturityDate,
            double depositRate,
            IDayCount dayCount,
            ICalendar calendar,
            BusinessDayConvention bda,
            CurrencyCode currency,
            double notional = 1.0,
            string tenor    = null
            )
        {
            StartDate = startDate;

            DepositRate            = depositRate;
            DayCount               = dayCount;
            Calendar               = calendar;
            Bda                    = bda;
            UnderlyingMaturityDate = Bda.Adjust(Calendar, maturityDate);
            Currency               = currency;
            Notional               = notional;

            Tenor = tenor ?? string.Format("{0},{1}", (int)(UnderlyingMaturityDate - StartDate), "D");
        }
Ejemplo n.º 4
0
        public Schedule(Date startDate, Date endDate, ITerm stepTerm, Stub stub, ICalendar calendar = null, BusinessDayConvention bda = BusinessDayConvention.None, bool stickEom = false)
        {
            var unadjustedDates = new List <Date>();

            IsRegular = new List <bool>();

            if (Convert.ToInt32(stepTerm.Length) == Convert.ToInt32(Term.Infinity.Length))
            {
                if (startDate != endDate)
                {
                    unadjustedDates.Add(startDate);
                    IsRegular.Add(true);
                }
                unadjustedDates.Add(endDate);
                IsRegular.Add(true);
            }
            else
            {
                switch (stub)
                {
                case Stub.LongEnd:
                case Stub.ShortEnd:
                {
                    var  numPeriods = 1;
                    Date date;
                    for (date = startDate; date < endDate; date = stepTerm.Next(startDate, numPeriods++, stickEom))
                    {
                        unadjustedDates.Add(date);
                        IsRegular.Add(true);
                    }
                    if (date != endDate && stub == Stub.LongEnd)
                    {
                        if (unadjustedDates.Count == 1)
                        {
                            unadjustedDates.Add(endDate);
                            IsRegular.Add(date == startDate);
                        }
                        else
                        {
                            unadjustedDates[unadjustedDates.Count - 1] = endDate;
                            IsRegular[IsRegular.Count - 1]             = date == startDate;
                        }
                    }
                    else
                    {
                        unadjustedDates.Add(endDate);
                        IsRegular.Add(date == startDate);
                    }
                    break;
                }

                case Stub.LongStart:
                case Stub.ShortStart:
                {
                    var  numPeriods = 1;
                    Date date;
                    for (date = endDate; date > startDate; date = stepTerm.Prev(endDate, numPeriods++, stickEom))
                    {
                        unadjustedDates.Add(date);
                        IsRegular.Add(true);
                    }
                    if (date != startDate && stub == Stub.LongStart)
                    {
                        if (unadjustedDates.Count == 1)
                        {
                            unadjustedDates.Add(startDate);
                            IsRegular.Add(date == startDate);
                        }
                        else
                        {
                            unadjustedDates[unadjustedDates.Count - 1] = startDate;
                            IsRegular[IsRegular.Count - 1]             = date == startDate;
                        }
                    }
                    else
                    {
                        unadjustedDates.Add(startDate);
                        IsRegular.Add(date == startDate);
                    }
                    unadjustedDates.Reverse();
                    IsRegular.Reverse();
                    break;
                }
                }
            }

            if (bda != BusinessDayConvention.None && calendar != null)
            {
                _dates = new List <Date>();
                foreach (var date in unadjustedDates)
                {
                    var adjustedDate = bda.Adjust(calendar, date);
                    var finalDate    = _dates.LastOrDefault();
                    if (finalDate == null || finalDate != adjustedDate)
                    {
                        _dates.Add(adjustedDate);
                    }
                }
            }
            else
            {
                _dates = unadjustedDates;
            }
        }
Ejemplo n.º 5
0
        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();
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// 将日期调整到交易日
 /// </summary>
 /// <param name="date">基准日期</param>
 /// <param name="bda">交易日规则</param>
 /// <returns>调整后的日期</returns>
 public Date Adjust(Date date, BusinessDayConvention bda = BusinessDayConvention.None)
 {
     return(bda.Adjust(this, date));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// 根据日历在某日期上按指定日期间隔调整得到的日期
        /// </summary>
        /// <param name="date">基准日期</param>
        /// <param name="term">日期间隔</param>
        /// <param name="bda">交易日规则</param>
        /// <returns>调整后的日期</returns>
        public Date AddBizDays(Date date, ITerm term, BusinessDayConvention bda = BusinessDayConvention.None)
        {
            var nextDate = term.Next(date);

            return(bda.Adjust(this, nextDate));
        }
Ejemplo n.º 8
0
 /// <summary>
 /// 根据日历在某日期上增加交易日天数得到的日期
 /// </summary>
 /// <param name="date">基准日期</param>
 /// <param name="offset">调整天数,可以为负数</param>
 /// <param name="bda">交易日规则</param>
 /// <returns>调整后的日期</returns>
 public Date AddBizDays(Date date, int offset, BusinessDayConvention bda = BusinessDayConvention.None)
 {
     return(AddBizDayFast(bda.Adjust(this, date), offset));
 }
Ejemplo n.º 9
0
 /// <summary>
 /// 根据日历在某日期上增加自然日天数得到的日期
 /// </summary>
 /// <param name="date">基准日期</param>
 /// <param name="offset">调整天数,可以为负数</param>
 /// <param name="bda">交易日规则</param>
 /// <returns>调整后的日期</returns>
 public Date AddDays(Date date, int offset, BusinessDayConvention bda = BusinessDayConvention.None)
 {
     return(bda.Adjust(this, date.AddDays(offset)));
 }