using YLErp.Abstract.DataProviders; using YLErp.BLL; using YLErp.BLL.MarginCalculation; using YLErp.Helpers; namespace YLErp.Modules.EodModule.SettlementModule { /// /// 预付金计算 /// class EodWorstClientPayableCalc : EodSettleServiceBase { public EodWorstClientPayableCalc(EodSettlementContextBase context) : base(context) { } /// /// 预付金计算 /// public bool WorstClientPayableCalc(List tradeList, List ex_TradeSpans = null) { if (tradeList is null) { throw new ArgumentNullException(nameof(tradeList)); } var settleDate = _context.SettleDate; var req = new RunMarginCalculationReq(UserInfo) { tradeList = tradeList, settleDate = settleDate, CalcMarginType = Enums.CalcMarginTypeEnum.EodMargin, volType = PS.Config.IsTradeVol ? _context.Request.VolType : _context.SystemValue.EodSettleVolMode }; switch (PS.Config.Company) { case Configuration.CompanyEnum.国泰君安: case Configuration.CompanyEnum.瑞达: case Configuration.CompanyEnum.宏源: case Configuration.CompanyEnum.弘业: case Configuration.CompanyEnum.光大光子: case Configuration.CompanyEnum.海通: case Configuration.CompanyEnum.广期资本: case Configuration.CompanyEnum.渤海: case Configuration.CompanyEnum.中金: req.PriceProvider = _context.GetEodPriceProvider().GetPriceProvider(SettlementTypeEnum.ClosePrice); req.settlementType = SettlementTypeEnum.ClosePrice; break; default: req.PriceProvider = _context.GetEodPriceProvider().GetPriceProvider(SettlementTypeEnum.SettlePrice); req.settlementType = SettlementTypeEnum.SettlePrice; break; } List tradeSpans = new List(); //试算出交易买卖方向反向的tradeSpan List tradeSpansOtherSide = new List(); //是否单笔预付金与合计预付金计算方式不同 如果不同则调用合计预付金方法 forSingleTrade = false if (MarginDefault.IsMarginCalcNeedSpecial(req.settleDate)) { //远期不参与计算预付金逻辑 tradeSpans = MarginDefault.RunMarginCalculation(req.Clone(forOtherSide: false)); //试算出交易买卖方向反向的tradeSpan(目前只有国君有这个需求,做过处理) tradeSpansOtherSide = MarginDefault.RunMarginCalculation(req.Clone(forOtherSide: true)); } else { tradeSpans = MarginDefault.RunMarginCalculation(req.Clone()); } #region 额外追保 var clientAdditionalMarginDic = new Dictionary(); var tradeSpanDic = tradeSpans.ToDictionary(t => t.TradeId, t => t.WorstCastClientPayable); var todayNewPostionList = tradeList.Where(t => t.TradeDate == settleDate).ToList(); var clientGroups = todayNewPostionList.GroupBy(t => t.ClientId); foreach (var group in clientGroups) { var todayNewClientPostionList = group.ToList(); var todayNewTradePositionMargin = Math.Min(todayNewClientPostionList.Sum(t => tradeSpanDic.ContainsKey(t.id) ? ((tradeSpanDic[t.id] ?? 0) * -1) : 0), 0); //todo:收益互换没有OriginalNotional var todayNewTradeInitialMargin = Math.Min(todayNewClientPostionList.Sum(t => ((t.OriginalStockEqvNotional * t.Notional / t.OriginalNotional) ?? 0) * (t.BuySell == "买入" ? -1 : 1) * underlying_managerBLL.GetUpLimit(t.UnderlyingCode)), 0); var todayAdditionalMargin = -1 * Math.Max(Math.Abs(todayNewTradeInitialMargin) - Math.Abs(todayNewTradePositionMargin), 0); clientAdditionalMarginDic[group.Key] = todayAdditionalMargin; } #endregion var ids = tradeList.Select(l => l.id).Union(tradeSpans.Select(x => x.TradeId)).ToArray(); if (ex_TradeSpans != null) { ids = ids.Union(ex_TradeSpans.Select(x => x.TradeId)).ToArray(); } if (ids.Any()) { DbContext.BulkDelete($"{nameof(trade_span.ValueDate)}='{settleDate.ToSqlDate()}' and TradeId in ({string.Join(",", ids)})"); } if (ex_TradeSpans != null && ex_TradeSpans.Count() > 0) { tradeSpans.AddRange(ex_TradeSpans); } if (tradeSpans != null && tradeSpans.Count > 0) { DbContext.trade_span.AddRange(tradeSpans); } DbContext.SaveChanges(); //执行客户合计 var clientMarginReq = new CalcClientMarginReq(UserInfo) { settleDate = settleDate, tradeSpans = tradeSpans, tradeSpansOtherSide = tradeSpansOtherSide, SpanType = 0, clientAdditionalMarginDic = clientAdditionalMarginDic, ClientIds = _context.ClienIds }; MarginDefault.CalcClientMargin(clientMarginReq); return true; } } }