Files
zszq-trs/Framework/YLErp.Core/QdpModule/QdpCalendarHelper.cs
T
2024-05-09 14:06:26 +08:00

249 lines
9.5 KiB
C#

using Qdp.Foundation.Implementations;
using Qdp.Pricing.Base.Enums;
using Qdp.Pricing.Base.Implementations;
using Qdp.Pricing.Base.Utilities;
namespace YLErp.QdpModule
{
/// <summary>
/// QDP日历帮助类
/// </summary>
public static class QdpCalendarHelper
{
/// <summary>
/// 给定任一日期,按特定交易日历和偏移量,给出交易日。
/// 例如:
/// 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
/// </summary>
/// <param name="date">日期</param>
/// <param name="calendarName">交易日历名称</param>
/// <param name="offset">偏移天数</param>
/// <returns></returns>
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;
}
/// <summary>
/// 返回一个日期区间内的所有交易日
/// AllBizDays(2022-04-26,2022-04-26) null
/// AllBizDays(2022-04-26,2022-04-27) 2022-04-26
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <param name="calendarName"></param>
/// <returns></returns>
public static List<DateTime> 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();
}
/// <summary>
/// 从到期日天数转换成以年为单位的时间
/// </summary>
/// <param name="timeToMaturityDays">天数,可以是小数</param>
/// <param name="optionDayCount">DayCount规则名称</param>
/// <param name="referenceDate">参考日期,对于某些DayCount有效</param>
/// <returns></returns>
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));
}
/// <summary>
/// 获取date(包括)之前的第一个非假日
/// </summary>
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;
}
/// <summary>
/// 获取tuningdays后的工作日信息
/// </summary>
public static DateTime GetWorkingDay(DateTime fromdate, int tuningdays)
{
var calendar = CalendarImpl.Get("chn");
return calendar.AddBizDays(new Date(fromdate), tuningdays).DateTime;
}
/// <summary>
/// 获取工作日天数(不包括from,包括to)
/// </summary>
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<DateTime> 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);
}
/// <summary>
/// 获取fromDate到toDate天数
/// </summary>
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));
}
/// <summary>
/// 获取date(包括)之后的第一个非假日
/// </summary>
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));
}
/// <summary>
/// 获取不超过到期日的实行日
/// 1个月,2周,1周,到日期这样的规则向前计算
/// </summary>
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;
}
/// <summary>
/// 根据DayCount规则和调整天数来调整日期
/// </summary>
public static string ShiftDate(string date, string dayCount, int maturityShift)
{
return ShiftDate(DateTime.Parse(date), dayCount, maturityShift).ToString();
}
/// <summary>
/// 根据DayCount规则和调整天数来调整日期
/// </summary>
public static Date ShiftDate(DateTime date, string dayCount, int maturityShift)
{
return ShiftDate(new Date(date), dayCount, maturityShift);
}
/// <summary>
/// 根据DayCount规则和调整天数来调整日期
/// </summary>
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);
}
}
}
}