using Qdp.Foundation.Implementations; using Qdp.Pricing.Library.Options.Products.Autocall.Snowball; using YLErp.BLL; using YLErp.Commons; using YLErp.DBModels.Enums; using YLErp.Modules.CalculationModule; using YLErp.Modules.TradeModule; using YLErp.Modules.TradeModule.DealModule; namespace YLErp.Modules.EodModule.SettlementModule { /// /// 权利金应付日检查处理生成 /// class EodCheckPremiumPayDate : EodSettleServiceBase { public EodCheckPremiumPayDate(EodSettlementContextBase context) : base(context) { ResetDbContext(); } public void Execute() { var tradeStatus = new string[] { ConsTrade.已到期, ConsTrade.已执行 }; var clienIds = _context.Request.ClientIds; ////检查权利金应付日到期后支付 //var tradeCashList = DbContext.trade_cash.Where(t => t.Status == TradeCashStatusEnum.冻结 && t.Action == ClientCashInCashOut.系统操作_期权费).ToList(); //var frozenPremiumIds = tradeCashList.Select(t => t.TradeId).ToHashSet(); ////查询已存在有效期权费交易的期权 //var hasClientCashInOut = DbContext.ClientCashInCashOut // .Where(t => frozenPremiumIds.Contains(t.TradeId ?? 0) && t.ValidState != "InValid" && t.Action == ClientCashInCashOut.系统操作_期权费) // .Select(t => t.TradeId).ToHashSet(); ////系统中缺少期权费的交易id列表 //var lostPremiumIds = frozenPremiumIds.Where(t => !hasClientCashInOut.Contains(t)).ToHashSet(); //var tradeList = otcTradeList.Where(t => lostPremiumIds.Contains(t.id) && (t.PremiumPayDate <= _context.SettleDate || (t.UnWindDate <= _context.SettleDate && tradeStatus.Contains(t.TradeStatus)))); var query = from t in DbContext.trade join tc in DbContext.trade_cash on t.id equals tc.TradeId where t.TradeDate > _context.StartDate && ((t.PremiumPayDate != null && t.PremiumPayDate.Value <= _context.SettleDate) || (t.UnWindDate <= _context.SettleDate && ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus))) //既然是根据期权费发生日期插入资金记录,就不应该考虑是否冻结,已执行状态的期权费如果不存在于ClientCashInCashOut中也应该插入 --时嬴政; && tc.Status == TradeCashStatusEnum.冻结 && tc.Action == ClientCashInCashOut.系统操作_期权费 && !tc.IsDeleted && tc.ValidState != "InValid" && t.ValidState != "InValid" && !DbContext.ClientCashInCashOut.Any(cc => cc.ClientId == t.ClientId && cc.TradeId == t.id && cc.ValidState != "InValid" && cc.Action == ClientCashInCashOut.系统操作_期权费) select new { tc, td = new { t.ClientId, t.ClientName, t.TradeNumber, t.TradeStatus, t.UnWindDate, t.IsGroup } }; #region 新增客户筛选 tw if (clienIds != null) { query = query.Where(l => clienIds.Contains(l.td.ClientId)); } #endregion var items = query.ToArray(); foreach (var item in items) { var tc = item.tc; var td = item.td; //更改状态 tc.Status = TradeCashStatusEnum.已执行; tc.OptId = UserId; tc.OptDate = DateTime.Now; tc.OptName = UserName; tc.Comments = "PremiumPayDate自动处理,补充期权费"; new TradeCashService(this).SaveTradeCashDetail(tc); var client = DataCacheProvider.GetClientDataSource().GetData(td.ClientId); //添加出入金应收信息 var cic = new ClientCashInCashOut() { HappenDate = td.TradeStatus == ConsTrade.已平仓 ? td.UnWindDate : _context.SettleDate, Action = ClientCashInCashOut.系统操作_期权费, Direction = ClientCashInCashOut.应收, OptDate = DateTime.Now, OptId = UserId, OptName = UserName, CreatorId = UserId, CreatorName = UserName, CreateDate = DateTime.Now }; DbContext.ClientCashInCashOut.Add(cic); cic.ClientId = td.ClientId; cic.ClientName = td.ClientName; cic.ClientNumber = client.Number; cic.TradeId = tc.TradeId; cic.TradeCashId = tc.id; cic.TradeNumber = td.TradeNumber; //权利金默认为应收 已确认 cic.State = ClientCashInCashOut.已确认; cic.Number = UniqueTimeId.GetStr(); cic.OptDate = DateTime.Now; cic.Comments = "PremiumPayDate自动处理,补充期权费"; cic.Money = tc.Amount * -1; cic.IsGroup = td.IsGroup; } DbContext.SaveChanges(_context.CancellationToken); #region 当雪球期权即有年化期权费率,权利金应付日又晚于敲出日时,需要补充年化期权费 var tradeSnowballBll = new TradeSnowballBLL(OptUser); var trades = DbContext.trade.Where(x => x.ValidState != "InValid" && ConsTrade.TradeCompleteStatus.Contains(x.TradeStatus) && x.TradeDate != x.PremiumPayDate && x.UnWindDate == _context.SettleDate && x.TradeType == "雪球期权").ToList(); var tradeIds = trades.Select(x => x.id); var tradeSnowBalls = DbContext.trade_snowball.Where(x => tradeIds.Contains(x.TradeId)); var tradeCashes = DbContext.trade_cash.Where(x => tradeIds.Contains(x.TradeId) && x.Action == ClientCashInCashOut.系统操作_票息 && x.ValidState != "InValid" && !x.IsDeleted); var tradeOpenCashes = DbContext.ClientCashInCashOut.Where(x => tradeIds.Contains(x.TradeId ?? 0) && x.Action == ClientCashInCashOut.系统操作_期权费 && x.ValidState != "InValid"); trades.ForEach(x => { var tradeSnowball = tradeSnowBalls.First(y => y.TradeId == x.id); if (tradeSnowball.AnnualizedPremiumRate.HasValue && tradeSnowball.AnnualizedPremiumRate != 0) { var tradeCash = tradeCashes.Where(m => m.TradeId == x.id).OrderByDescending(x => x.ValueDate).FirstOrDefault(); if (tradeCash != null) { var request = new OptionTradeParamRequest(valuedateBLL.SysRiskFreeRate()); var optionTrade = QdpTradeBuilder.GetSnowballOptionTrade(x, tradeSnowball, request); var snowball = (SimpleSnowball)optionTrade.Instrument; if (!tradeOpenCashes.Any(y => y.TradeCashId == tradeCash.id)) { var tradePrice = x.OriginalStockEqvNotional * tradeCash.UnwindPercentRate * x.ParticipationRate * tradeSnowball.AnnualizedPremiumRate * snowball.CouponDayCount.CalcDayCountFraction(snowball.StartDate, new Date(x.UnWindDate)) ?? 0; if (tradePrice != 0) { tradeSnowballBll.SaveTradePrice(x, tradeCash, tradePrice, tradeCash.ValueDate); } } } } }); #endregion } } }