/// <summary>Initializes a new instance of the <see cref="SimpleThenPeriodicCompounding" /> class.
        /// </summary>
        /// <param name="frequency">The frequency of the compounding to apply after time-to-maturity of one year.</param>
        internal SimpleThenPeriodicCompounding(IDateScheduleFrequency frequency)
        {
            if (frequency == null)
            {
                throw new ArgumentNullException("frequency");
            }
            Frequency = frequency;

            var frequencyTenor = frequency.GetFrequencyTenor();

            if (TenorTimeSpan.IsNull(frequencyTenor) == true)
            {
                throw new ArgumentException("frequency");
            }

            if (frequencyTenor.Years != 0)
            {
                PaymentsPerYear = 1.0 / frequencyTenor.Years;
            }
            if (frequencyTenor.Months != 0)
            {
                PaymentsPerYear += 12.0 / frequencyTenor.Months;
            }
            if (frequencyTenor.Days != 0)
            {
                PaymentsPerYear += 365.0 / frequencyTenor.Days;
            }
            Name = new IdentifierString(String.Format("Simple;{0}", Frequency.Name.String));
        }
        /// <summary>Initializes a new instance of the <see cref="PeriodicInterestCompounding"/> class.
        /// </summary>
        /// <param name="frequency">The frequency of the compounding.</param>
        protected internal PeriodicInterestCompounding(IDateScheduleFrequency frequency)
        {
            if (frequency == null)
            {
                throw new ArgumentNullException("frequency");
            }
            Frequency = frequency;

            TenorTimeSpan frequencyTenor = frequency.GetFrequencyTenor();

            if (TenorTimeSpan.IsNull(frequencyTenor) == true)
            {
                throw new ArgumentException("frequency");
            }

            if (frequencyTenor.Years != 0)
            {
                PaymentsPerYear = 1.0 / frequencyTenor.Years;
            }
            if (frequencyTenor.Months != 0)
            {
                PaymentsPerYear += 12.0 / frequencyTenor.Months;
            }
            if (frequencyTenor.Days != 0)
            {
                PaymentsPerYear += 365.0 / frequencyTenor.Days;
            }
        }
예제 #3
0
        /// <summary>Creates a date schedule that contains the start and end dates of the interest periods of each caplets, i.e. T_0, T_1, T_2, ..., where [T_k; T_{k+1}] is the
        /// interest period of caplet k, k=0,...,n-1; The first caplet is already expired but it is part of the date schedule.
        /// </summary>
        /// <param name="referenceDate">The reference date, i.e. the trading date.</param>
        /// <param name="startDateAndEndDateDescription">A description of the start date of the first caplet as well as the end date of the last caplet, i.e. the start date and the maturity of the cap.</param>
        /// <param name="marketConventions">The market conventions.</param>
        /// <param name="holidayCalendar">The holiday calendar.</param>
        /// <param name="underlyingLiborTenor">A mapping of the null-based index of the start date of each caplet interest period to the tenor of the underlying Libor rate (output).</param>
        /// <param name="logger">An optional logger.</param>
        /// <returns>
        /// The date schedule of the interest periods, i.e. the start and end dates of each caplet; thus T_0, T_1, T_2, ..., where [T_k; T_{k+1}] is the
        /// interest period of caplet k, k=0,...,n-1; The first caplet is already expired but it is part of the date schedule.
        /// </returns>
        public ReadOnlyDateSchedule CreateInterestPeriodDateSchedule(DateTime referenceDate, ITimeframeDescription startDateAndEndDateDescription, ReadOnlyMoneyMarketConventions marketConventions, IHolidayCalendar holidayCalendar, out Func <int, TenorTimeSpan> underlyingLiborTenor, ILogger logger = null)
        {
            if (marketConventions == null)
            {
                throw new ArgumentNullException("marketConventions");
            }
            if (holidayCalendar == null)
            {
                throw new ArgumentNullException("holidayCalendar");
            }
            IBusinessDayConvention businessDayConvention = marketConventions.BusinessDayConvention;

            DateTime capStartDate, capEndDate;

            startDateAndEndDateDescription.GetStartAndEndDate(referenceDate, holidayCalendar, out capStartDate, out capEndDate);

            DateTime lastDate3M = businessDayConvention.GetAdjustedDate(capStartDate.AddTenorTimeSpan(sm_2YTenor), holidayCalendar); // it is the end date of the latest caplet with tenor 3M

            DateSchedule dateSchedule = new DateSchedule(holidayCalendar, logger: logger);

            if (capEndDate <= lastDate3M)
            {
                dateSchedule.Add(new ForwardDateScheduleRule(referenceDate, startDateAndEndDateDescription, sm_3MLiborRateTenor, businessDayConvention));
                underlyingLiborTenor = (i => sm_3MLiborRateTenor.GetFrequencyTenor());
            }
            else
            {
                ITimeframeDescription firstPeriod3M = TimeframeDescription.Create(lastDate3M);  // applied to reference date='capStartDate' shows [capStartDate; lastDate3M]
                dateSchedule.Add(new ForwardDateScheduleRule(capStartDate, firstPeriod3M, sm_3MLiborRateTenor, businessDayConvention));
                int indexOfLast3MPeriodEndDate = dateSchedule.Count - 1;

                ITimeframeDescription secondPeriod6M = TimeframeDescription.Create(capEndDate, endDateAdjustment: businessDayConvention); // applied to reference date ='lastDate3M' shows [lastDate3M; capEndDate]
                dateSchedule.Add(new ForwardDateScheduleRule(lastDate3M, secondPeriod6M, sm_6MLiborRateTenor, businessDayConvention));
                underlyingLiborTenor = (i => (i < indexOfLast3MPeriodEndDate) ? sm_3MLiborRateTenor.GetFrequencyTenor() : sm_3MLiborRateTenor.GetFrequencyTenor());
            }
            return(dateSchedule.AsReadOnly());
        }
 /// <summary>Gets the tenor of the underlying Libor rate if the tenor is equal for each caplet.
 /// </summary>
 /// <param name="liborTenor">The (unique) tenor of the underlying Libor rate.</param>
 /// <returns>
 /// A value indicating whether <paramref name="liborTenor"/> contains valid data
 /// and a unique tenor is available.
 /// </returns>
 /// <remarks>This method returns the same value as <see cref="IIRCapletTenorConvention.HasUniqueLiborTenor"/>.</remarks>
 public bool TryGetUniqueUnderlyingLiborTenor(out TenorTimeSpan liborTenor)
 {
     liborTenor = m_LiborRateTenor.GetFrequencyTenor();
     return(true);
 }
예제 #5
0
        /// <summary>Adds some <see cref="System.DateTime"/> objects into a specific date schedule.
        /// </summary>
        /// <param name="dateSchedule">The date schedule.</param>
        /// <exception cref="NotOperableException">Thrown, if the current instance it not operable.</exception>
        public void AddDatesToDateSchedule(DateSchedule dateSchedule)
        {
            if (IsOperable == false)
            {
                throw new NotOperableException("BackwardDateScheduleRule");
            }
            DateTime firstDate, terminationDate;

            m_TimeSpanDescription.GetStartAndEndDate(m_ReferenceDate, dateSchedule.HolidayCalendar, out firstDate, out terminationDate, dateSchedule.Logging);

            if (terminationDate < firstDate)
            {
                throw new ArgumentException(String.Format(ExceptionMessages.ArgumentOutOfRangeGreaterEqual, "End date [" + terminationDate.ToShortDateString() + "]", "first date [" + firstDate.ToShortDateString() + "]"));
            }
            dateSchedule.Add(terminationDate);  // add the end date

            // gets the date which is used as 'base date' for the date generation loop:
            DateTime seed = terminationDate;

            if ((m_LastRegularDate != null) && (m_LastRegularDate.HasValue))  // 'last regular date' is given
            {
                seed = m_LastRegularDate.Value;
                if (seed > terminationDate)
                {
                    throw new ArgumentException(String.Format(ExceptionMessages.ArgumentOutOfRangeLessEqual, "Last regular date [" + seed.ToShortDateString() + "]", "end date [" + terminationDate.ToShortDateString() + "]"));
                }
            }
            if (m_SeedBusinessDayConvention != null)  // perhaps adjust the 'base date' which is used for the date generation loop
            {
                seed = m_SeedBusinessDayConvention.GetAdjustedDate(seed, dateSchedule.HolidayCalendar);
            }
            else
            {
                seed = m_BusinessDayConvention.GetAdjustedDate(seed, dateSchedule.HolidayCalendar);
            }
            dateSchedule.Add(seed);

            // gets the exit condition for the loop:
            DateTime exitDate = firstDate;  // perhaps not a business day

            if ((m_FirstRegularDate != null) && (m_FirstRegularDate.HasValue))
            {
                exitDate = m_FirstRegularDate.Value;
                if (exitDate > seed)
                {
                    throw new ArgumentException(String.Format(ExceptionMessages.ArgumentOutOfRangeLessEqual, "First regular date [" + exitDate.ToShortDateString() + "]", "last [regular] date [" + seed.ToShortDateString() + "]"));
                }
            }

            if (m_Frequency.IsOnceFrequency())  // end date and seed date are already added
            {
                if (exitDate != firstDate)      // perhaps add the first regular date
                {
                    dateSchedule.Add(exitDate); // one may apply the business day convention to the first regular date
                }
            }
            else  // do the loop with respect to the frequency
            {
                TenorTimeSpan frequencyTenor = m_Frequency.GetFrequencyTenor();
                DateTime      runningDate    = m_BusinessDayConvention.GetAdjustedDate(seed.AddTenorTimeSpan(frequencyTenor), dateSchedule.HolidayCalendar);
                int           periodIndex    = -1;

                while (runningDate >= exitDate)
                {
                    dateSchedule.Add(runningDate);
                    periodIndex--;

                    runningDate = seed.AddTenorTimeSpan(frequencyTenor, periodIndex);
                    runningDate = m_BusinessDayConvention.GetAdjustedDate(runningDate, dateSchedule.HolidayCalendar);
                }
            }
            dateSchedule.Add(firstDate);
        }
예제 #6
0
 /// <summary>Determines whether a specified date schedule frequency is the frequency 'once'.
 /// </summary>
 /// <param name="dateScheduleFrequency">The date schedule frequency.</param>
 /// <returns>
 ///     <c>true</c> if the specified date schedule frequency is the frequency 'once'; otherwise, <c>false</c>.
 /// </returns>
 public static bool IsOnceFrequency(this IDateScheduleFrequency dateScheduleFrequency)
 {
     return((dateScheduleFrequency != null) ? TenorTimeSpan.IsNull(dateScheduleFrequency.GetFrequencyTenor()) : false);
 }