using System.ComponentModel.DataAnnotations.Schema; using YLErp.Modules.DataProviderModule; namespace YLErp.Modules.EodModule.SettlementModule { /// /// 合成组合标的价格服务 /// class EodSyntheticPriceSaveService : EodSettleServiceBase { public const string Step = "合成组合标的价格"; public EodSyntheticPriceSaveService(EodSettlementContextBase context) : base(context) { } //todo:还没有经过单元测试 /// /// 保存组合标的日终结算价格 /// public void Execute() { _context?.LogInfo("开始执行,获取组合标的数据"); //------------------------------- //组合标的获取 //------------------------------- var query = from a in DbContext.synthetic_underlying join b in DbContext.underlying_manager on a.Name equals b.UnderlyingCode join c in DbContext.eod_commodity_future_price.Where(n => n.ValueDate == SettleDate) on b.UnderlyingCode equals c.UnderlyingCode into c_t from c in c_t.DefaultIfEmpty() join d in DbContext.eod_stock_price.Where(n => n.ValueDate == SettleDate) on b.UnderlyingCode equals d.UnderlyingCode into d_t from d in d_t.DefaultIfEmpty() where b.CommodityCode == "组合标的" && b.MaturityDate >= SettleDate select new synthetic_underlyingDto { id = a.id, Name = a.Name, Constant = a.Constant, Coefficient1 = a.Coefficient1, Coefficient3 = a.Coefficient3, Coefficient2 = a.Coefficient2, Coefficient4 = a.Coefficient4, UnderlyingCode1 = a.UnderlyingCode1, UnderlyingCode2 = a.UnderlyingCode2, UnderlyingCode3 = a.UnderlyingCode3, UnderlyingCode4 = a.UnderlyingCode4, RelUnderlyingId = b.id, RelUnderlyingInstrumentType = b.UnderlyingInstrumentType, CommodityPrice = c, StockPrice = d, }; var synArr = query.ToArray(); var synLen = synArr.Length; if (synLen < 1) { _context?.LogInfo("未获取到组合标的数据"); return; } _context?.LogInfo("获取到的组合标的数量:" + synLen); //------------------------------- //更新组合标的价格 //------------------------------- var eodPriceProvider = _context.GetEodPriceProvider(); foreach (var item in synArr) { GetCombinClosePrice(item, eodPriceProvider); } var changes = DbContext.SaveChanges(); _context?.LogInfo($"组合标的合成价格后保存到数据库,组合标的数量:{synLen},更新数量:{changes}"); } /// /// 获取组合标的收盘价 /// private void GetCombinClosePrice(synthetic_underlyingDto dto, EodPriceProvider eodPriceProvider) { double closePrice = 0; double settlePrice = 0; var arr = new (string, double)[] { (dto.UnderlyingCode1,dto.Coefficient1??0), (dto.UnderlyingCode2,dto.Coefficient2??0), (dto.UnderlyingCode3,dto.Coefficient3??0), (dto.UnderlyingCode4,dto.Coefficient4??0) }; _context?.LogInfo($"[组合标的:{dto.Name}]开始合成收盘价"); if (ConsGlobal.InstrumentType.CalcTypeIsFutures(dto.RelUnderlyingInstrumentType)) { foreach ((var underlyingcode, var coefficient) in arr) { if (string.IsNullOrWhiteSpace(underlyingcode)) { continue; } if (eodPriceProvider.TryGetEodPrice(underlyingcode, out var price)) { closePrice += price.ClosePrice * coefficient; settlePrice += price.SettlePrice * coefficient; } else { _context?.LogError($"[组合标的:{dto.Name}]未取到标的收盘价,标的代码:{underlyingcode}"); return; } } closePrice += dto.Constant ?? 0; settlePrice += dto.Constant ?? 0; _context?.LogInfo($"[组合标的:{dto.Name}]收盘价:{closePrice}"); if (dto.CommodityPrice != null) { DbContext.Entry(dto.CommodityPrice).State = EntityState.Unchanged; if (Math.Abs(dto.CommodityPrice.ClosePrice - closePrice) > 0.0001 || Math.Abs(dto.CommodityPrice.SettlePrice - settlePrice) > 0.0001) { dto.CommodityPrice.OptDate = DateTime.Now; dto.CommodityPrice.ClosePrice = closePrice; dto.CommodityPrice.SettlePrice = settlePrice; dto.CommodityPrice.DataSource = "系统"; } } else { dto.CommodityPrice = new eod_commodity_future_price { UnderlyingCode = dto.Name, ValueDate = SettleDate, OptDate = DateTime.Now, UnderlyingId = dto.RelUnderlyingId, ClosePrice = closePrice, SettlePrice = settlePrice, DataSource = "系统" }; DbContext.eod_commodity_future_price.Add(dto.CommodityPrice); } SetDBModelOpt(dto.CommodityPrice); } else if ("Stock".Equals(dto.RelUnderlyingInstrumentType, StringComparison.OrdinalIgnoreCase)) { foreach ((var underlyingcode, var coefficient) in arr) { if (string.IsNullOrWhiteSpace(underlyingcode)) { continue; } if (eodPriceProvider.TryGetEodPrice(underlyingcode, out var price)) { closePrice += price.ClosePrice * coefficient; } else { _context?.LogError($"[组合标的:{dto.Name}]未取到标的收盘价,标的代码:{underlyingcode}"); return; } } closePrice += dto.Constant ?? 0; _context?.LogInfo($"[组合标的:{dto.Name}]收盘价:{closePrice}"); if (dto.StockPrice != null) { DbContext.Entry(dto.StockPrice).State = EntityState.Unchanged; if (Math.Abs(dto.StockPrice.ClosePrice - closePrice) > 0.0001) { dto.StockPrice.OptDate = DateTime.Now; dto.StockPrice.ClosePrice = closePrice; } } else { dto.StockPrice = new eod_stock_price { UnderlyingCode = dto.Name, ValueDate = DateTime.Today, OptDate = DateTime.Now, ClosePrice = closePrice, SettlePrice = closePrice, DataSource = "系统", }; DbContext.eod_stock_price.Add(dto.StockPrice); } SetDBModelOpt(dto.StockPrice); } else { _context?.LogInfo($"[组合标的:{dto.Name},未处理]标的类型不支持:" + dto.RelUnderlyingInstrumentType); } } /// /// DTO /// [NotMapped] private class synthetic_underlyingDto : SyntheticUnderlying { public int RelUnderlyingId { get; set; } public string RelUnderlyingInstrumentType { get; set; } public eod_stock_price StockPrice { get; set; } public eod_commodity_future_price CommodityPrice { get; set; } } } }