using Qdp.Pricing.Base.Enums; using YLErp.Models; namespace YLErp.QdpModule { /// /// 雪球观察日列表帮助类 /// public static class QdpObservationHelperForSnowball { /// /// 生成观察日列表 /// public static IEnumerable GenerateObservationList(ObservationRequestForSnowball req) { if (req is null) { throw new ArgumentNullException(nameof(req)); } req.LockCount--; //前端锁3个月实际代表抹去2个月 if (req.LockCount < 0) { req.LockCount = 0; } var dates = GetDatesWithFixedTerm(req); if (dates.Length == 0 || dates[^1] != req.EndDate) { var arr = new DateTime[dates.Length + 1]; dates.CopyTo(arr, 0); dates = arr; dates[^1] = req.EndDate; } if (dates.Length <= req.LockCount) { req.LockCount = dates.Length - 1; } var kobarrier = req.KoBarrier; var touchLimit = Math.Abs(req.KoBarrierStep) < 1e-6; var list = new List(dates.Length); var noTouchLimit = req.KoBarrierStep > 0 ? req.KoBarrierLimit < req.KoBarrier : req.KoBarrierLimit > req.KoBarrier; for (var i = req.LockCount; i < dates.Length; i++) { var date = dates[i].ToString("yyyy-MM-dd"); var item = new ObservationItemForSnowball { KoDate = date, CouponDate = date, KoBarrier = kobarrier, KoCoupon = req.KoCoupon }; //票息支付日递延 if (req.CouponPaymentDateDeferred != 0) { item.CouponDate = QdpCalendarHelper.AddDate(dates[i], req.CouponPaymentDateDeferred).ToString("yyyy-MM-dd"); } if (i > req.LockCount) { if (noTouchLimit) { kobarrier += req.KoBarrierStep; item.KoBarrier = kobarrier; } else if (!touchLimit) { kobarrier += req.KoBarrierStep; touchLimit = req.KoBarrierStep > 0 ? kobarrier > req.KoBarrierLimit : kobarrier < req.KoBarrierLimit; if (touchLimit) { kobarrier = req.KoBarrierLimit; } item.KoBarrier = kobarrier; } } list.Add(item); } return list; } /// /// /// private static DateTime[] GetDatesWithFixedTerm(ObservationDatesRequest req) { //观察日间隔 if (string.IsNullOrEmpty(req.Interval)) { req.Interval = "1D"; } //节假日调整,可选值:None 不调整、Previous 向前调整、Following 向后调整,默认:向后调整 var bdc = BusinessDayConvention.Following; if (!string.IsNullOrWhiteSpace(req.HolidayAdjustment)) { bdc = req.HolidayAdjustment switch { "None" => BusinessDayConvention.None, "Previous" => BusinessDayConvention.Previous, "ModifiedPrevious" => BusinessDayConvention.ModifiedPrevious, "Following" => BusinessDayConvention.Following, "ModifiedFollowing" => BusinessDayConvention.ModifiedFollowing, _ => throw new ServiceException("请求参数'HolidayAdjustment'的值不符合要求"), }; } //对齐规则,可选值:EndDate 向到期日对齐、StartDate 向开始日对齐,默认:向到期日对齐 var alignEnd = true; if (!string.IsNullOrEmpty(req.Alignment)) { alignEnd = req.Alignment switch { "EndDate" or "向到期日对齐" => true, "StartDate" or "向开始日对齐" => false, _ => throw new ServiceException("请求参数'Alignment'的值不符合要求"), }; } if (!string.IsNullOrEmpty(req.CalcMode)) { switch (req.CalcMode) { case "00": case "01": case "10": case "11": break; default: throw new ServiceException("请求参数'CalcMode'的值不符合要求"); } } else { req.CalcMode = "01"; } return QdpObservationHelper.GetDatesWithFixedTerm(req.StartDate, req.EndDate, req.Interval, bdc, alignEnd, req.CalcMode); } } /// /// 雪球观察日列表数据项 /// public class ObservationItemForSnowball { /// /// 敲出观察日 /// public string KoDate { get; set; } /// /// 票息支付日 /// public string CouponDate { get; set; } /// /// 敲出障碍价格 /// public double KoBarrier { get; set; } /// /// 敲出票息 /// public string KoCoupon { get; set; } } }