using Org.BouncyCastle.Ocsp; using Qdp.Foundation.Utilities; using YLErp.Commons; using YLErp.CustomizedBizLogic; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.DBModels.Helpers; using YLErp.Modules.ClientModule; using YLErp.Modules.TradeModule.DealModule; using static NPOI.HSSF.Util.HSSFColor; namespace YLErp.Modules.TradeModule.ExoticOptionModule { public class TradeCashServiceEx : TradeCashService { public TradeCashServiceEx(YLBaseService baseService) : base(baseService) { } public TradeCashServiceEx(OptUserInfo userInfo) : base(userInfo) { } public trade_cash SaveGroupUnwindCash(OtcTradeBase otcTrade, DateTime valueDate, double paymentAmount, double closePrice, out bool continueTradeCashHandle) { var childrenTrades = DbContext.trade.Where(x => x.ParentTradeId == otcTrade.ParentTradeId && x.ValidState != "InValid"); //子交易观察调用该方法处理主交易时,当前子交易会了结,但还没存数据库,所以只需要判断其他子交易是否已了结即可 var isAllCompleted = childrenTrades.Where(x => x.id != otcTrade.id).All(x => ConsTrade.TradeCompleteStatus.Contains(x.TradeStatus)); var parentTrade = DbContext.trade.Find(otcTrade.ParentTradeId); var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(parentTrade.UnderlyingCode); var tradeCashIds = DbContext.trade_cash.Where(x => x.TradeId == otcTrade.ParentTradeId && x.ValueDate == valueDate).Select(x => x.id); var tradeCashGroupAction = DbContext.trade_cash_group_action.FirstOrDefault(x => tradeCashIds.Contains(x.ParentTradeCashId) && x.IsEodSettle); var tradeCash = new trade_cash(); if (tradeCashGroupAction != null) { tradeCash = DbContext.trade_cash.Find(tradeCashGroupAction.ParentTradeCashId); var action = DbContext.trade_cash_group_action.FirstOrDefault(x => x.ParentTradeCashId == tradeCashGroupAction.ParentTradeCashId && x.TradeId == otcTrade.id); if (action != null) { if (!action.IsFinishedUnwindPercent) { tradeCash.Amount += paymentAmount; tradeCash.OptId = UserId; tradeCash.OptName = UserName; tradeCash.OptDate = DateTime.Now; if (isAllCompleted) { tradeCash.IsLastAction = true; } action.IsFinishedUnwindPercent = true; } else { continueTradeCashHandle = false; return tradeCash; } } else { tradeCash.Amount += paymentAmount; tradeCash.OptId = UserId; tradeCash.OptName = UserName; tradeCash.OptDate = DateTime.Now; if (isAllCompleted) { tradeCash.IsLastAction = true; tradeCash.UnwindNotional = tradeCash.Notional; tradeCash.UnwindTradeAmount = tradeCash.TradeAmount; tradeCash.UnwindPercentRate = 1; } tradeCashGroupAction = new trade_cash_group_action() { IsEodSettle = true, TradeId = otcTrade.id, ParentTradeId = otcTrade.ParentTradeId, ParentTradeCashId = tradeCash.id, Status = "已完成", OptId = UserId, OptName = UserName, OptDate = DateTime.Now, IsFinishedUnwindPercent = true }; DbContext.trade_cash_group_action.Add(tradeCashGroupAction); } } else { tradeCash = new trade_cash() { Action = ClientCashInCashOut.系统操作_票息, IsLastAction = false, TradeType = parentTrade.BuySell, Notional = parentTrade.Notional, TradeAmount = parentTrade.TradeAmount, TradeId = otcTrade.ParentTradeId, HappenedDate = valueDate, ValueDate = valueDate, FinalPrice = closePrice, Status = TradeCashStatusEnum.已执行, OptId = UserId, OptName = UserName, OptDate = DateTime.Now }; tradeCash.Amount += paymentAmount; if (isAllCompleted) { tradeCash.IsLastAction = true; tradeCash.UnwindNotional = tradeCash.Notional; tradeCash.UnwindTradeAmount = tradeCash.TradeAmount; tradeCash.UnwindPercentRate = 1; } DbContext.trade_cash.Add(tradeCash); DbContext.SaveChanges(); #region---存入ClientCashInCashOut--- var cl = ClientDataQueryService.GetClient(parentTrade.ClientId, true); var ee = new ClientCashInCashOut { Direction = "应收", Number = UniqueTimeId.GetStr(), ClientId = cl.id, ClientNumber = cl.Number, ClientName = cl.Name, HappenDate = tradeCash.ValueDate, State = ClientCashInCashOut.已确认, OptId = tradeCash.OptId, OptName = tradeCash.OptName, OptDate = tradeCash.OptDate, CreatorId = tradeCash.OptId, CreatorName = tradeCash.OptName, CreateDate = tradeCash.OptDate, TradeId = tradeCash.TradeId, TradeCashId = tradeCash.id, Action = tradeCash.Action, TradeNumber = tradeCash.TradeNumber, IsGroup = parentTrade.IsGroup }; DbContext.ClientCashInCashOut.Add(ee); #endregion tradeCashGroupAction = new trade_cash_group_action() { IsEodSettle = true, TradeId = otcTrade.id, ParentTradeId = otcTrade.ParentTradeId, ParentTradeCashId = tradeCash.id, Status = "已完成", OptId = UserId, OptName = UserName, OptDate = DateTime.Now, IsFinishedUnwindPercent = true }; DbContext.trade_cash_group_action.Add(tradeCashGroupAction); } if (isAllCompleted) { parentTrade.UnWindNotional = parentTrade.Notional; parentTrade.UnWindDate = tradeCash.ValueDate; parentTrade.FinalPrice = tradeCash.FinalPrice; } parentTrade.OptId = UserId; parentTrade.OptName = UserName; parentTrade.OptDate = DateTime.Now; DbContext.SaveChanges(); if (BLL.valuedateBLL.SystemDate.CloseReApprove != 1 || !HasTradeProcess()) { if (PS.Config.SalesCommissionCalculation == "公式1") { //销售提成 new SalesModule.SalesCommissionDetailDataService(UserInfo).CalcuSalesCommissionDetail(tradeCash); } if (PS.Config.Company == Configuration.CompanyEnum.招证) { new BizLogicZhaoZheng().GenerateZhaoZhengDealNumber(parentTrade, tradeCash); } if (PS.Config.Company == Configuration.CompanyEnum.物产中大) { new BizLogicWCZD().GenerateWCZDNumber(DbContext, parentTrade, tradeCash.ValueDate, tradeCash.id); } } if (tradeCash.IsLastAction) { var tradeIds = DbContext.trade_cash_group_action.Where(x => x.ParentTradeCashId == tradeCash.id).Select(x => x.TradeId).ToList(); var tradeStatusList = DbContext.trade.Where(x => tradeIds.Contains(x.id)).Select(x => x.TradeStatus).ToList(); if (tradeStatusList.Contains(ConsTrade.已执行)) { parentTrade.TradeStatus = ConsTrade.已执行; } else if (tradeStatusList.Contains(ConsTrade.已到期)) { parentTrade.TradeStatus = ConsTrade.已到期; } else { parentTrade.TradeStatus = ConsTrade.已平仓; } } DbContext.SaveChanges(); continueTradeCashHandle = true; return tradeCash; } public int SaveGroupCouponCash(OtcTradeBase trade, DateTime happenDate, double paymentAmount, double underlyingPrice) { var parentTradeCashId = 0; var childrenTrades = DbContext.trade.Where(x => x.ParentTradeId == trade.ParentTradeId && x.ValidState != "InValid"); var parentTrade = DbContext.trade.Find(trade.ParentTradeId); var tradeCashIds = DbContext.trade_cash.Where(x => x.TradeId == trade.ParentTradeId && x.ValueDate == happenDate).Select(x => x.id); var tradeCashGroupAction = DbContext.trade_cash_group_action.FirstOrDefault(x => tradeCashIds.Contains(x.ParentTradeCashId) && x.IsEodSettle); var tradeCash = new trade_cash(); if (tradeCashGroupAction != null) { parentTradeCashId = tradeCashGroupAction.ParentTradeCashId; if (DbContext.trade_cash_group_action.Any(x => x.ParentTradeCashId == tradeCashGroupAction.ParentTradeCashId && x.TradeId == trade.id)) { return parentTradeCashId; } else { tradeCash = DbContext.trade_cash.Find(tradeCashGroupAction.ParentTradeCashId); tradeCash.Amount += paymentAmount; tradeCash.OptId = UserId; tradeCash.OptName = UserName; tradeCash.OptDate = DateTime.Now; tradeCashGroupAction = new trade_cash_group_action() { IsEodSettle = true, TradeId = trade.id, ParentTradeId = trade.ParentTradeId, ParentTradeCashId = tradeCash.id, Status = "已完成", OptId = UserId, OptName = UserName, OptDate = DateTime.Now, IsFinishedUnwindPercent = false }; DbContext.trade_cash_group_action.Add(tradeCashGroupAction); } } else { tradeCash = new trade_cash() { Action = ClientCashInCashOut.系统操作_票息, IsLastAction = false, TradeType = parentTrade.BuySell, Notional = parentTrade.Notional, TradeAmount = parentTrade.TradeAmount, Amount = paymentAmount, TradeId = trade.ParentTradeId, HappenedDate = happenDate, ValueDate = happenDate, FinalPrice = underlyingPrice, Status = TradeCashStatusEnum.已执行, OptId = UserId, OptName = UserName, OptDate = DateTime.Now }; DbContext.trade_cash.Add(tradeCash); DbContext.SaveChanges(); parentTradeCashId = tradeCash.id; tradeCashGroupAction = new trade_cash_group_action() { IsEodSettle = true, TradeId = trade.id, ParentTradeId = trade.ParentTradeId, ParentTradeCashId = tradeCash.id, Status = "已完成", OptId = UserId, OptName = UserName, OptDate = DateTime.Now, IsFinishedUnwindPercent = false }; DbContext.trade_cash_group_action.Add(tradeCashGroupAction); DbContext.SaveChanges(); #region---存入ClientCashInCashOut--- var cl = ClientDataQueryService.GetClient(parentTrade.ClientId, true); var ee = new ClientCashInCashOut { Direction = "应收", Number = UniqueTimeId.GetStr(), ClientId = cl.id, ClientNumber = cl.Number, ClientName = cl.Name, HappenDate = tradeCash.ValueDate, State = ClientCashInCashOut.已确认, OptId = tradeCash.OptId, OptName = tradeCash.OptName, OptDate = tradeCash.OptDate, CreatorId = tradeCash.OptId, CreatorName = tradeCash.OptName, CreateDate = tradeCash.OptDate, TradeId = tradeCash.TradeId, TradeCashId = tradeCash.id, Action = tradeCash.Action, TradeNumber = tradeCash.TradeNumber, IsGroup = parentTrade.IsGroup }; DbContext.ClientCashInCashOut.Add(ee); #endregion } parentTrade.OptId = UserId; parentTrade.OptName = UserName; parentTrade.OptDate = DateTime.Now; DbContext.SaveChanges(); if (BLL.valuedateBLL.SystemDate.CloseReApprove != 1 || !HasTradeProcess()) { if (PS.Config.SalesCommissionCalculation == "公式1") { //销售提成 new SalesModule.SalesCommissionDetailDataService(UserInfo).CalcuSalesCommissionDetail(tradeCash); } if (PS.Config.Company == Configuration.CompanyEnum.招证) { new BizLogicZhaoZheng().GenerateZhaoZhengDealNumber(parentTrade, tradeCash); } if (PS.Config.Company == Configuration.CompanyEnum.物产中大) { new BizLogicWCZD().GenerateWCZDNumber(DbContext, parentTrade, tradeCash.ValueDate, tradeCash.id); } } return parentTradeCashId; } //如果两个票息的结算日设为同一天的情况下,用这个方法保存票息有问题 public trade_cash SaveCash(OtcTradeBase trade, string cashAction, string exerciseWay, double paymentAmount, DateTime valueDate, double underlyingPrice, DateTime happenDate, bool isKnockOut = false, bool isLastAction = false, int parentTradeId = 0, int parentTradeCashId = 0) { var notional = trade.Notional; var tradeAmount = trade.TradeAmount; // 保存trade_cash var tc = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == trade.id && t.Action == cashAction && !t.IsDeleted && t.HappenedDate == happenDate); var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode); //暂时只应用于累计期权的观察部分行权处理 trade_accumulator_option accumulator = new trade_accumulator_option(); if (trade.TradeType == "累计期权") { accumulator = DbContext.trade_accumulator_option.FirstOrDefault(x => x.TradeId == trade.id); tc = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == trade.id && t.Action == "系统操作-平仓费" && t.UnwindType == "部分行权" && !t.IsDeleted && t.HappenedDate == happenDate); if (tc == null) { trade.TradeAmount -= accumulator.AccumuTradeAmount; trade.Notional = trade.TradeAmount * underlying.CountRatio; trade.StockEqvNotional = TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor); } } if (tc == null) { tc = new trade_cash(); DbContext.trade_cash.Add(tc); tc.Notional = notional; tc.TradeAmount = tradeAmount; } else { if (paymentAmount == 0) { //如果是最后一笔资金记录但是查出来的tc没有设置最后一笔资金标识则重新设置 if (isLastAction && !tc.IsLastAction) { tc.IsLastAction = true; tc.UnwindNotional = trade.Notional; tc.UnwindTradeAmount = trade.TradeAmount; tc.UnwindPercentRate = trade.Notional / trade.OriginalNotional; DbContext.SaveChanges(); } return tc; } if (trade.TradeType != "累计期权") { tc.Notional = notional; tc.TradeAmount = tradeAmount; } } tc.ValidState = null; tc.OptId = UserId; tc.OptName = UserName; tc.OptDate = DateTime.Now; tc.ExceciseType = "现金"; tc.TradeType = trade.BuySell; tc.CallPut = trade.CallPut; tc.Amount = paymentAmount; tc.TradeId = trade.id; tc.ParentTradeId = parentTradeId; tc.ParentTradeCashId = parentTradeCashId; tc.HappenedDate = happenDate; if (trade.TradeType == "累计期权" && (cashAction == "部分行权" || cashAction == "到期行权")) { if (cashAction == "部分行权") { tc.Action = ClientCashInCashOut.系统操作_平仓费; tc.UnwindType = "部分行权"; tc.ExerciseWay = TradeCashExerciseWayEnum.提前终止行权; } else if (cashAction == "到期行权") { tc.Action = ClientCashInCashOut.系统操作_行权费; tc.UnwindType = "到期"; tc.ExerciseWay = TradeCashExerciseWayEnum.到期行权; } tc.UnwindTradeAmount = accumulator.AccumuTradeAmount; tc.UnwindNotional = accumulator.AccumuTradeAmount * underlying.CountRatio; tc.UnwindPrice = Math.Abs(accumulator.AccumuTradeAmount != 0 ? paymentAmount / accumulator.AccumuTradeAmount : 0); tc.UnwindPricePercentRate = Math.Abs(accumulator.AccumuTradeAmount != 0 && trade.SpotPrice != null && trade.SpotPrice != 0 ? paymentAmount / accumulator.AccumuTradeAmount / trade.SpotPrice.Value : 0); tc.UnwindPercentRate = accumulator.AccumuTradeAmount * underlying.CountRatio / trade.OriginalNotional; tc.NotionalPercentRate = tc.UnwindPercentRate; } else { tc.Action = cashAction; tc.ExerciseWay = exerciseWay; tc.UnwindPrice = Math.Abs(trade.Notional != 0 ? paymentAmount / trade.Notional : 0); tc.UnwindPricePercentRate = Math.Abs(trade.Notional != 0 && trade.SpotPrice != null && trade.SpotPrice != 0 ? paymentAmount / trade.Notional / trade.SpotPrice.Value : 0); tc.NotionalPercentRate = trade.Notional / trade.OriginalNotional; } tc.IsLastAction = isLastAction; if (exerciseWay == "到期行权") { tc.UnwindType = "到期"; if (cashAction == ClientCashInCashOut.系统操作_票息 && tc.Amount == 0) { tc.Action = ClientCashInCashOut.系统操作_行权费; } } tc.Status = TradeCashStatusEnum.已执行; tc.ValueDate = valueDate; tc.FinalPrice = underlyingPrice; if (isKnockOut) { tc.BarrierPrice = trade.IsMoneynessOptionData && trade.SpotPrice != 0 ? (underlyingPrice / trade.SpotPrice) : underlyingPrice; } if (isLastAction && !(cashAction == "部分行权" && trade.TradeType == "累计期权")) { tc.UnwindNotional = notional; tc.UnwindTradeAmount = tradeAmount; tc.UnwindPercentRate = notional / trade.OriginalNotional; } tc.NotionalPercentRate = trade.Notional / trade.OriginalNotional; DbContext.SaveChanges(); var tradeCashDetails = DbContext.trade_cash_detail.Where(x => x.TradeCashId == tc.id); DbContext.trade_cash_detail.RemoveRange(tradeCashDetails); SaveTradeCashDetail(tc); if ((BLL.valuedateBLL.SystemDate.CloseReApprove != 1 || !HasTradeProcess()) || isKnockOut || isLastAction) { if (PS.Config.SalesCommissionCalculation == "公式1") { //销售提成 new SalesModule.SalesCommissionDetailDataService(UserInfo).CalcuSalesCommissionDetail(tc); } if (PS.Config.Company == Configuration.CompanyEnum.招证) { new BizLogicZhaoZheng().GenerateZhaoZhengDealNumber(trade, tc); } if (PS.Config.Company == Configuration.CompanyEnum.物产中大 && cashAction!=ClientCashInCashOut.系统操作_期权费) { new BizLogicWCZD().GenerateWCZDNumber(DbContext, trade, tc.ValueDate, tc.id); } } // 保存ClientCashInCashOut var client = DbContextFactory.GetClientDbContext(UserInfo).client.Where(n => n.id == trade.ClientId) .Select(n => new { n.id, n.Number, n.Name }).FirstOrDefault(); if (client == null) { throw new Exception($"{trade.TradeType}'{trade.TradeNumber}'找不到客户信息,客户id:{trade.ClientId}"); } var cashInOutRecord = DbContext.ClientCashInCashOut.FirstOrDefault(c => c.TradeCashId == tc.id); if (cashInOutRecord == null) { cashInOutRecord = new ClientCashInCashOut(); cashInOutRecord.CreateDate = tc.OptDate; cashInOutRecord.CreatorId = tc.OptId; cashInOutRecord.CreatorName = tc.OptName; DbContext.ClientCashInCashOut.Add(cashInOutRecord); } cashInOutRecord.Direction = "应收"; cashInOutRecord.Number = UniqueTimeId.GetStr(); cashInOutRecord.ClientId = client.id; cashInOutRecord.ClientNumber = client.Number; cashInOutRecord.ClientName = client.Name; cashInOutRecord.Money = -tc.Amount; cashInOutRecord.HappenDate = valueDate; cashInOutRecord.State = ClientCashInCashOut.已确认; cashInOutRecord.OptDate = tc.OptDate; cashInOutRecord.OptId = tc.OptId; cashInOutRecord.OptName = tc.OptName; cashInOutRecord.TradeId = trade.id; cashInOutRecord.TradeCashId = tc.id; cashInOutRecord.Action = tc.Action; cashInOutRecord.TradeNumber = trade.TradeNumber; cashInOutRecord.IsGroup = trade.IsGroup; DbContext.SaveChanges(); return tc; } } }