Пример #1
0
        /// <summary>
        /// Returns spot date for a given val date
        /// e.g. for USD/ZAR, calendar would be for ZAR and otherCal would be for USD
        /// </summary>
        /// <param name="valDate"></param>
        /// <param name="spotLag"></param>
        /// <param name="calendar"></param>
        /// <param name="otherCal"></param>
        /// <returns></returns>
        public static DateTime SpotDate(this DateTime valDate, Frequency spotLag, Calendar calendar, Calendar otherCal)
        {
            var d = valDate.AddPeriod(RollType.F, calendar, spotLag);

            d = d.IfHolidayRollForward(otherCal);
            return(d);
        }
Пример #2
0
        /// <summary>
        /// Returns a date equal to the input date plus the specified period, adjusted for holidays
        /// </summary>
        /// <param name="date">Input date</param>
        /// <param name="rollType">RollType enum</param>
        /// <param name="calendar">Calendar</param>
        /// <param name="datePeriod">Period to add in the form of a Frequency object</param>
        /// <returns></returns>
        public static DateTime AddPeriod(this DateTime date, RollType rollType, Calendar calendar, Frequency datePeriod)
        {
            if (calendar == null && datePeriod.PeriodType == DatePeriodType.B)
            {
                return(date);
            }

            date = date.Date;
            if (datePeriod.PeriodCount == 0)
            {
                return(IfHolidayRoll(date, rollType, calendar));
            }

            if (datePeriod.PeriodType == DatePeriodType.B)
            {
                if (datePeriod.PeriodCount < 0) //actually a subtract
                {
                    return(date.SubtractPeriod(rollType, calendar, new Frequency(-datePeriod.PeriodCount, datePeriod.PeriodType)));
                }

                //Business day jumping so we need to do something different
                var d = date;
                for (var i = 0; i < datePeriod.PeriodCount; i++)
                {
                    d = d.AddDays(1);
                    d = IfHolidayRoll(d, rollType, calendar);
                }
                return(d);
            }

            DateTime dt;

            switch (datePeriod.PeriodType)
            {
            case DatePeriodType.D:
                dt = date.AddDays(datePeriod.PeriodCount);
                break;

            case DatePeriodType.M:
                dt = date.AddMonths(datePeriod.PeriodCount);
                break;

            case DatePeriodType.W:
                dt = date.AddDays(datePeriod.PeriodCount * 7);
                break;

            default:
                dt = date.AddYears(datePeriod.PeriodCount);
                break;
            }

            if ((rollType == RollType.MF_LIBOR) && (date == date.LastBusinessDayOfMonth(calendar)))
            {
                dt = date.LastBusinessDayOfMonth(calendar);
            }
            if (rollType == RollType.ShortFLongMF)
            {
                if (datePeriod.PeriodType == DatePeriodType.B || datePeriod.PeriodType == DatePeriodType.D || datePeriod.PeriodType == DatePeriodType.W)
                {
                    return(IfHolidayRoll(dt, RollType.F, calendar));
                }
                else
                {
                    return(IfHolidayRoll(dt, RollType.MF, calendar));
                }
            }
            return(IfHolidayRoll(dt, rollType, calendar));
        }
Пример #3
0
 public static DateTime[] AddPeriod(this DateTime[] dates, RollType rollType, Calendar calendar, Frequency datePeriod) => dates.Select(d => d.AddPeriod(rollType, calendar, datePeriod)).ToArray();
Пример #4
0
        /// <summary>
        /// Returns the input date, adjusted by rolling if the input date falls on a holiday according to the specified calendar.
        /// The type of roll is specfied in the input.
        /// </summary>
        /// <param name="date">Input date</param>
        /// <param name="rollType">RollType enum</param>
        /// <param name="calendar">Calendar</param>
        /// <returns></returns>
        public static DateTime IfHolidayRoll(this DateTime date, RollType rollType, Calendar calendar)
        {
            if (calendar == null)
            {
                return(date);
            }

            date = date.Date;
            DateTime d, d1, d2;
            double   distFwd, distBack;

            switch (rollType)
            {
            case RollType.F:
                return(date.IfHolidayRollForward(calendar));

            case RollType.MF:
            default:
                d = date.IfHolidayRollForward(calendar);
                if (d.Month == date.Month)
                {
                    return(d);
                }
                else
                {
                    return(date.IfHolidayRollBack(calendar));
                }

            case RollType.P:
                return(date.IfHolidayRollBack(calendar));

            case RollType.MP:
                d = date.IfHolidayRollBack(calendar);
                if (d.Month == date.Month)
                {
                    return(d);
                }
                else
                {
                    return(date.IfHolidayRollForward(calendar));
                }

            case RollType.NearestFollow:
                d1       = date.IfHolidayRollForward(calendar);
                d2       = date.IfHolidayRollBack(calendar);
                distFwd  = (d1 - date).TotalDays;
                distBack = (date - d2).TotalDays;
                if (distBack < distFwd)
                {
                    return(d2);
                }
                else
                {
                    return(d1);
                }

            case RollType.NearestPrev:
                d1       = date.IfHolidayRollForward(calendar);
                d2       = date.IfHolidayRollBack(calendar);
                distFwd  = (d1 - date).TotalDays;
                distBack = (date - d2).TotalDays;
                if (distFwd < distBack)
                {
                    return(d1);
                }
                else
                {
                    return(d2);
                }

            case RollType.LME:
                d1 = date.IfHolidayRollForward(calendar);
                if (d1.Month != date.Month)
                {
                    return(date.IfHolidayRollBack(calendar));
                }
                d2 = date.IfHolidayRollBack(calendar);
                if (d2.Month != date.Month)
                {
                    return(d1);
                }
                distFwd  = (d1 - date).TotalDays;
                distBack = (date - d2).TotalDays;
                if (distBack < distFwd)
                {
                    return(d2);
                }
                else
                {
                    return(d1);
                }

            case RollType.None:
                return(date);
            }
        }
Пример #5
0
        /// <summary>
        /// Returns last business day, according to the specified calendar, of the month in which the input date falls
        /// </summary>
        /// <param name="input">Input date</param>
        /// <param name="calendar">Calendar</param>
        /// <returns></returns>
        public static DateTime LastBusinessDayOfMonth(this DateTime input, Calendar calendar)
        {
            var d = input.Date.AddMonths(1).FirstDayOfMonth();

            return(SubtractPeriod(d, RollType.P, calendar, 1.Bd()));
        }
Пример #6
0
        /// <summary>
        /// Calculates a year fraction from a day count method and two dates
        /// Start date is inclusive, end date exclusive
        /// </summary>
        /// <param name="startDate">Start Date (inclusive)</param>
        /// <param name="endDate">End Date (exclusive)</param>
        /// <param name="basis">DayCountBasis enum</param>
        /// <param name="ignoreTimeComponent">Ignore the time component of the DateTime inputs - defaults to true</param>
        /// <param name="calendar">Optional calendar object, required only for methods involving business days</param>
        /// <returns></returns>
        public static double CalculateYearFraction(this DateTime startDate, DateTime endDate, DayCountBasis basis, bool ignoreTimeComponent = true, Calendar calendar = null)
        {
            if (ignoreTimeComponent)
            {
                startDate = startDate.Date;
                endDate   = endDate.Date;
            }

            switch (basis)
            {
            case DayCountBasis.Act_360:
                return((endDate.Ticks - startDate.Ticks) * _ticksFraction360);

            case DayCountBasis.Act_365F:
                return((endDate.Ticks - startDate.Ticks) * _ticksFraction365);

            case DayCountBasis.Act_Act_ISDA:
            case DayCountBasis.Act_Act:
                if (endDate.Year == startDate.Year)
                {       //simple case
                    var eoY = new DateTime(endDate.Year, 12, 31);
                    return((endDate - startDate).TotalDays / eoY.DayOfYear);
                }
                else
                {
                    double nIntermediateYears = endDate.Year - startDate.Year - 1;

                    var eoYe = new DateTime(endDate.Year, 12, 31);
                    var e    = endDate.DayOfYear / (double)eoYe.DayOfYear;

                    var eoYs = new DateTime(startDate.Year, 12, 31);
                    var s    = (eoYs - startDate).TotalDays / eoYs.DayOfYear;

                    return(s + nIntermediateYears + e);
                }

            case DayCountBasis._30_360:
                double ydiff = endDate.Year - startDate.Year;
                double mdiff = endDate.Month - startDate.Month;
                double ddiff = endDate.Day - startDate.Day;
                return((ydiff * 360 + mdiff * 30 + ddiff) / 360);

            case DayCountBasis.ThirtyE360:
                double d1E    = Math.Min(startDate.Day, 30);
                double d2E    = Math.Min(endDate.Day, 30);
                double ydiffE = endDate.Year - startDate.Year;
                double mdiffE = endDate.Month - startDate.Month;
                var    ddiffE = d2E - d1E;
                return((ydiffE * 360 + mdiffE * 30 + ddiffE) / 360);

            case DayCountBasis.Bus252:
                return(startDate.BusinessDaysInPeriod(endDate.AddDays(-1), calendar).Count / 252.0);

            case DayCountBasis.Unity:
                return(1.0);
            }
            return(-1);
        }
Пример #7
0
        /// <summary>
        /// Returns a list of friday dates according to a specified calendar which are contained within two given dates.
        /// If a friday is a holiday, the preceeding good business day is returned
        /// Start and end dates are treated as inclusive
        /// </summary>
        /// <param name="startDateInc"></param>
        /// <param name="endDateInc"></param>
        /// <param name="calendars"></param>
        /// <returns></returns>
        public static List <DateTime> FridaysInPeriod(this DateTime startDateInc, DateTime endDateInc, Calendar calendars)
        {
            if (endDateInc < startDateInc)
            {
                throw new ArgumentException(nameof(endDateInc), "End date is before the start date");
            }
            var o    = new List <DateTime>((int)(endDateInc - startDateInc).TotalDays);
            var date = startDateInc;

            while (date <= endDateInc)
            {
                if (date.DayOfWeek == DayOfWeek.Friday)
                {
                    o.Add(date.IfHolidayRoll(RollType.P, calendars));
                }
                date = date.AddPeriod(RollType.None, null, 1.Day());
            }
            return(o);
        }
Пример #8
0
        /// <summary>
        /// Returns a list of business dates according to a specified calendar which are contained within two given dates.
        /// Start and end dates are treated as inclusive
        /// </summary>
        /// <param name="startDateInc"></param>
        /// <param name="endDateInc"></param>
        /// <param name="calendars"></param>
        /// <returns></returns>
        public static List <DateTime> BusinessDaysInPeriod(this DateTime startDateInc, DateTime endDateInc, Calendar calendars)
        {
            if (endDateInc < startDateInc)
            {
                throw new ArgumentException(nameof(endDateInc), "End date is before the start date");
            }
            var o    = new List <DateTime>((int)(endDateInc - startDateInc).TotalDays);
            var date = startDateInc.IfHolidayRollForward(calendars);

            while (date <= endDateInc)
            {
                o.Add(date);
                date = date.AddPeriod(RollType.F, calendars, 1.Bd());
            }
            return(o);
        }