using Qdp.Foundation.Implementations; using Qdp.Pricing.Base.Enums; using Qdp.Pricing.Base.Implementations; using Qdp.Pricing.Base.Utilities; namespace YLErp.QdpModule { /// /// QDP日历帮助类 /// public static class QdpCalendarHelper { /// /// 给定任一日期,按特定交易日历和偏移量,给出交易日。 /// 例如: /// 2018-06-16,2018-06-17,2018-06-18三天是chn假期 /// /// BizDayShift("2018-06-15", "chn", 0); //2018-06-15 /// BizDayShift("2018-06-15", "chn", 1); //2018-06-19 /// BizDayShift("2018-06-16", "chn", 0); //2018-06-19 /// BizDayShift("2018-06-17", "chn", 0); //2018-06-19 /// BizDayShift("2018-06-18", "chn", 0); //2018-06-19 /// BizDayShift("2018-06-19", "chn", 0); //2018-06-19 /// BizDayShift("2018-06-16", "chn", 1); //2018-06-20 /// BizDayShift("2018-06-17", "chn", 1); //2018-06-20 /// BizDayShift("2018-06-18", "chn", 1); //2018-06-20 /// BizDayShift("2018-06-19", "chn", 1); //2018-06-20 /// BizDayShift("2018-06-16", "chn", -1); //2018-06-15 /// BizDayShift("2018-06-17", "chn", -1); //2018-06-15 /// BizDayShift("2018-06-18", "chn", -1); //2018-06-15 /// BizDayShift("2018-06-19", "chn", -1); //2018-06-15 /// /// 日期 /// 交易日历名称 /// 偏移天数 /// public static DateTime BizDayShift(DateTime date, int offset = 0, string calendarName = "chn") { return BizDayShift2(date, offset, calendarName).DateTime; } public static Date BizDayShift2(DateTime date, int offset = 0, string calendarName = "chn") { if (string.IsNullOrEmpty(calendarName)) { calendarName = "chn"; } var calendar = CalendarImpl.Get(calendarName); if (calendar == null) { return new Date(date); } var qdpDate = new Date(date); var bizDay = calendar.IsBizDay(qdpDate) ? qdpDate : calendar.NextBizDay(qdpDate); return calendar.AddBizDays(bizDay, offset); } public static DateTime PrevBizDayShift(DateTime date, int offset = 0, string calendarName = "chn") { if (string.IsNullOrEmpty(calendarName)) { calendarName = "chn"; } var calendar = CalendarImpl.Get(calendarName); if (calendar == null) { return date; } var qdpDate = new Date(date); var bizDay = calendar.IsBizDay(qdpDate) ? qdpDate : calendar.PrevBizDay(qdpDate); return calendar.AddBizDays(bizDay, offset).DateTime; } /// /// 返回一个日期区间内的所有交易日 /// AllBizDays(2022-04-26,2022-04-26) null /// AllBizDays(2022-04-26,2022-04-27) 2022-04-26 /// /// /// /// /// public static List AllBizDays(DateTime startDate, DateTime endDate, string calendarName = "chn") { if (string.IsNullOrEmpty(calendarName)) { calendarName = "chn"; } var calendar = CalendarImpl.Get(calendarName); if (calendar == null) { return null; } var qdpStartDate = new Date(startDate); var qdpEndDate = new Date(endDate); var holidays = calendar.BizDaysBetweenDates(qdpStartDate, qdpEndDate); return holidays.Select(x => x.DateTime).ToList(); } /// /// 从到期日天数转换成以年为单位的时间 /// /// 天数,可以是小数 /// DayCount规则名称 /// 参考日期,对于某些DayCount有效 /// public static double CalculateTFromDays(double timeToMaturityDays, string optionDayCount, DateTime referenceDate) { if (double.IsNaN(timeToMaturityDays)) { return double.NaN; } var dayCount = optionDayCount.ToDayCountImpl(); return timeToMaturityDays / dayCount.DaysInYear(new Date(referenceDate)); } /// /// 获取date(包括)之前的第一个非假日 /// public static DateTime GetNonHolidayDefore(DateTime date, string country = "chn") { var calendar = CalendarImpl.Get(country); var qdpDate = new Date(date); return calendar.IsBizDay(qdpDate) ? date : calendar.PrevBizDay(qdpDate).DateTime; } /// /// 获取tuningdays后的工作日信息 /// public static DateTime GetWorkingDay(DateTime fromdate, int tuningdays) { var calendar = CalendarImpl.Get("chn"); return calendar.AddBizDays(new Date(fromdate), tuningdays).DateTime; } /// /// 获取工作日天数(不包括from,包括to) /// public static int GetWorkDayCount(DateTime from, DateTime to) { var calendar = CalendarImpl.Get("chn"); return (int)Math.Round(calendar.NumberBizDaysBetweenDate(new Date(from), new Date(to), excludeEndDate: true)); } public static List GetWorkingDatesBeforeDate(DateTime toDate, int days) { var calendar = CalendarImpl.Get("chn"); var toQdpDate = new Date(toDate); var fromQdpDate = calendar.AddBizDays(toQdpDate, -days + 1); return calendar.BizDaysBetweenDatesInclEndDay(fromQdpDate, toQdpDate).Select(x => x.DateTime).Reverse().ToList(); } public static DateTime AddDate(DateTime fromDate,int days) { var calendar = CalendarImpl.Get("chn"); var toQdpDate = new Date(fromDate); return calendar.AddBizDays(toQdpDate,days); } /// /// 获取fromDate到toDate天数 /// public static int GetNonHolidayDaysBetween(DateTime fromDate, DateTime toDate, string country = "chn") { var calendar = CalendarImpl.Get(country); return (int)Math.Round(calendar.NumberBizDaysBetweenDate(new Date(fromDate), new Date(toDate), excludeEndDate: true)); } /// /// 获取date(包括)之后的第一个非假日 /// public static DateTime GetNonHoliday(DateTime date, string country = "chn") { var calendar = CalendarImpl.Get(country); var qdpDate = new Date(date); return calendar.IsBizDay(qdpDate) ? date : calendar.NextBizDay(qdpDate).DateTime; } public static bool IsHoliday(DateTime date, string country = "chn") { var calendar = CalendarImpl.Get(country); return calendar.IsHoliday(new Date(date)); } /// /// 获取不超过到期日的实行日 /// 1个月,2周,1周,到日期这样的规则向前计算 /// public static DateTime GetUnderlyingExerciseDate(DateTime underlyingMaturityDate, DateTime SystemDate) { //OTC - 6717 组合报价-默认的到期日为交易日后一个月,且算头不算尾 DateTime exerciseDate = GetNonHoliday(SystemDate.AddMonths(1).AddDays(-1)); if (underlyingMaturityDate < exerciseDate) { exerciseDate = GetNonHoliday(SystemDate.AddDays(14)); if (underlyingMaturityDate < exerciseDate) { exerciseDate = GetNonHoliday(SystemDate.AddDays(7)); if (underlyingMaturityDate < exerciseDate) { exerciseDate = GetNonHolidayDefore(underlyingMaturityDate); } } } return exerciseDate; } /// /// 根据DayCount规则和调整天数来调整日期 /// public static string ShiftDate(string date, string dayCount, int maturityShift) { return ShiftDate(DateTime.Parse(date), dayCount, maturityShift).ToString(); } /// /// 根据DayCount规则和调整天数来调整日期 /// public static Date ShiftDate(DateTime date, string dayCount, int maturityShift) { return ShiftDate(new Date(date), dayCount, maturityShift); } /// /// 根据DayCount规则和调整天数来调整日期 /// public static Date ShiftDate(Date qdpDate, string dayCount, int maturityShift) { if (dayCount == "Act365") { return CalendarImpl.Get("chn").AddDays(qdpDate, maturityShift); } else { return CalendarImpl.Get("chn").AddBizDays(qdpDate, maturityShift, BusinessDayConvention.Following); } } } }