using System.Text; using YLErp.BLL; using YLErp.Models; namespace YLErp.Modules.UnderlyingModule { public class UnderlyingHisDataService : YLBaseService { public UnderlyingHisDataService(OptUserInfo userInfo) : base(userInfo) { } public UnderlyingHisDataService(YLBaseService baseService) : base(baseService) { } /// /// 更新标的历史数据 /// public int AddOrUpdateHisData(UnderlyingHisDataAddOrUpdateRequest req, bool saveChanges = true) { if (req is null) { throw new ArgumentNullException(nameof(req)); } if (string.IsNullOrWhiteSpace(req.UnderlyingCode)) { throw new ServiceException("标的代码 必须有值"); } if (saveChanges && !DbContext.underlying_manager.Any(n => n.UnderlyingCode == req.UnderlyingCode)) { throw new ServiceException("标的数据 不存在"); } switch (req.ValueType) { case nameof(MarginParamModel.MarginRate): case nameof(MarginParamModel.UpDownLimit): case nameof(MarginParamModel.VolatilityRate): break; default: throw new ServiceException("ValueType 不支持:" + req.ValueType); } if (string.IsNullOrWhiteSpace(req.ValueFlag)) { req.ValueFlag = "F"; } else if (req.ValueFlag != "F" && req.ValueFlag != "%") { throw new ServiceException("ValueFlag 不支持"); } var hisdata = DbContext.UnderlyingHisData.OrderByDescending(n => n.ValueDate).FirstOrDefault( n => n.UnderlyingCode == req.UnderlyingCode && n.ValueDate <= req.ValueDate && n.ValueType == req.ValueType); if (hisdata != null) { //如果新值和旧值一致则不需要处理 var newValue = req.Value; if (newValue.HasValue && Math.Abs(newValue.Value - hisdata.Value) < 1e-6) { return 0; } //新值为null并且为第一条时清掉 if (!newValue.HasValue && hisdata.ValueDate == req.ValueDate && !DbContext.UnderlyingHisData.Any(n => n.UnderlyingCode == req.UnderlyingCode && n.ValueDate < req.ValueDate && n.ValueType == req.ValueType)) { DbContext.UnderlyingHisData.Remove(hisdata); return saveChanges ? DbContext.SaveChanges() : 0; } } else if (!req.Value.HasValue) { return 0; //如果没有历史数据并且新值为null } if (hisdata == null || hisdata.ValueDate < req.ValueDate) { hisdata = new UnderlyingHisData { UnderlyingCode = req.UnderlyingCode, ValueDate = req.ValueDate, ValueType = req.ValueType }; DbContext.UnderlyingHisData.Add(hisdata); } SetDBModelOpt(hisdata); hisdata.Value = req.Value ?? 0; hisdata.ValueFlag = req.Value.HasValue ? req.ValueFlag : "N"; return saveChanges ? DbContext.SaveChanges() : 0; } /// /// 删除标的历史数据 /// public int RemoveHisData(string underlyingCode, DateTime valueDate, string valueType) { if (string.IsNullOrWhiteSpace(underlyingCode) || string.IsNullOrWhiteSpace(valueType)) { return 0; } valueDate = valueDate.Date; var data = DbContext.UnderlyingHisData.FirstOrDefault( n => n.UnderlyingCode == underlyingCode && n.ValueDate == valueDate && n.ValueType == valueType); if (data != null) { DbContext.UnderlyingHisData.Remove(data); return DbContext.SaveChanges(); } return 0; } /// /// 回写历史数据到主表 /// public int BackHisDataToMainTable() { var db = DbContextFactory.GetYLDbContext(); var valueDate = valuedateBLL.ValueDate; var startDate = valuedateBLL.ValueDate.AddDays(-3); var uhgQuery = from a in db.UnderlyingHisData where a.ValueDate >= startDate && a.ValueDate <= valueDate group a by new { a.UnderlyingCode, a.ValueType } into aa select new { aa.Key.UnderlyingCode, aa.Key.ValueType, ValueDate = aa.Max(n => n.ValueDate) }; var uhQuery = from a in uhgQuery join b in db.UnderlyingHisData on new { a.UnderlyingCode, a.ValueType, a.ValueDate } equals new { b.UnderlyingCode, b.ValueType, b.ValueDate } select new { b.UnderlyingCode, b.Value, b.ValueType, b.ValueFlag }; var hisdatas = uhQuery.ToArray(); if (!hisdatas.Any()) { return 0; } var sb = new StringBuilder(1000); const string sqlfmtMarginRate = "update underlying_manager set MarginRate='{0}' WHERE UnderlyingCode='{1}';"; const string sqlfmtUpDownLimit = "update underlying_manager set UpDownLimit='{0}' WHERE UnderlyingCode='{1}';"; const string sqlfmtVolatilityRate = "update underlying_manager set VolatilityRate='{0}' WHERE UnderlyingCode='{1}';"; //new underlying_manager().MarginRate; foreach (var item in hisdatas) { switch (item.ValueType) { case nameof(MarginParamModel.MarginRate): if (item.ValueFlag == "N") { sb.AppendFormat("update underlying_manager set MarginRate=null WHERE UnderlyingCode='{0}';", item.UnderlyingCode).AppendLine(); } else { sb.AppendFormat(sqlfmtMarginRate, item.Value.ToString("0.0#####"), item.UnderlyingCode).AppendLine(); } break; case nameof(MarginParamModel.UpDownLimit): var fmt = item.ValueFlag == "%" ? "0.0###%" : "0.0#####"; sb.AppendFormat(sqlfmtUpDownLimit, item.ValueFlag == "N" ? "" : item.Value.ToString(fmt), item.UnderlyingCode).AppendLine(); break; case nameof(MarginParamModel.VolatilityRate): sb.AppendFormat(sqlfmtVolatilityRate, item.ValueFlag == "N" ? "" : item.Value.ToString("0.0###%"), item.UnderlyingCode).AppendLine(); break; } } var sql = sb.ToString(); LogFactory.GetLogger("回写标的历史数据到主表").Info(sql); return DbContext.Database.ExecuteSqlRaw(sql); } } /// /// /// public class UnderlyingHisDataAddOrUpdateRequest { public string UnderlyingCode { get; set; } /// /// 使用MarginParamModel的属性字段 /// public string ValueType { get; set; } public string ValueFlag { get; set; } public DateTime ValueDate { get; set; } public double? Value { get; set; } } }