using BaseOUDAL; using System.Linq; using System.Linq.Expressions; using YLErp.BLL; using YLErp.BLL.MarginCalculation; using YLErp.DBModels.Consts; using YLErp.DBModels.Helpers; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Models; using YLErp.Modules.RiskModule; using YLErp.QdpModule; namespace YLErp.Modules.TradeModule { /// /// 交易查询服务 /// public class TradeQueryService : YLBaseService { public TradeQueryService(OptUserInfo userInfo) : base(userInfo) { } public TradeQueryService(YLBaseService baseService) : base(baseService) { } /// /// 查询trade /// public SearchListResult SearchList(TradeReq req, TradeQueryRequest req2 = null) { Dictionary settleTcDict = null; SubstandardTradeRule rule = null; if (req.SubstandardType.HasValue) { //获取不合规交易的ID req.TradeIds = GetSubstandardTradeIds(req.SubstandardType.Value, out settleTcDict, out rule); } var query = CreateTradeQuery(req, req2); var retListResult = query.ToSearchList(req); if (req2.GetSum) { var gsum = new tradeGridSum(); if (query.Any()) { gsum.TradePriceSum = query.Sum(q => q.TradePrice); } retListResult.Sum = gsum; } //获取销售提成信息 foreach (var item in retListResult.rows) { item.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(item.id); if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && item.SalesCommission?.Commission != null) { item.SalesCommission.Commission = item.SalesCommission.Commission * item.SalesCommission.SalesIds.Count(); } if (req.SubstandardType.HasValue) {//用于不合规交易页面,展示不合规项; item.MetaDic["IsStrikeOffset"] = (rule?.StrikeOffset == null || item.Strike == null ? false : item.IsMoneynessOptionData ? Math.Abs((item.Strike ?? 0) - 1) > rule.StrikeOffset : Math.Abs((item.Strike ?? 0) / (item.SpotPrice ?? 0) - 1) > rule.StrikeOffset).ToString(); item.MetaDic["IsMinTradingDay"] = (rule?.MinTradingDay == null ? false : (item.ExerciseDate - item.TradeDate).Value.Days < rule.MinTradingDay).ToString(); item.MetaDic["IsLockTradingDay"] = (settleTcDict != null && settleTcDict.ContainsKey(item.id)).ToString(); } } return retListResult; } /// /// 查询trade /// public SearchListResult SearchListWithGroup(TradeReq req, TradeQueryRequest req2 = null) { Dictionary settleTcDict = null; SubstandardTradeRule rule = null; if (req.SubstandardType.HasValue) { //获取不合规交易的ID req.TradeIds = GetSubstandardTradeIds(req.SubstandardType.Value, out settleTcDict, out rule); //这里让它能选择显示子交易 req添加某值设置 req2.withGroupChildren = true; } var query = CreateTradeQueryWithGroup(req, req2); if (req.sidx == "TradeOriginalAmount")//页面需要 有效成交数量 排序,TradeOriginalAmount排序报错,所以用OriginalNotional代替 { query = req.sord == "desc" ? query.OrderByDescending(a => a.OriginalNotional) : query.OrderBy(a => a.OriginalNotional); req.sidx = null; } var retListResult = query.ToSearchList(req); if (req2.GetSum) { var gsum = new tradeGridSum(); if (query.Any()) { gsum.TradePriceSum = query.Sum(q => q.TradePrice); } retListResult.Sum = gsum; } if (retListResult == null || retListResult.rows == null || !retListResult.rows.Any()) { return retListResult; } Dictionary dicSaleCommissionList; using (var commssionService = new SalesModule.SalesCommissionDataService(OptUser)) { dicSaleCommissionList = commssionService.GetTradeCommissionInfoByTradeIds(retListResult.rows.Select(p => p.id).ToList()); } if (dicSaleCommissionList == null) { dicSaleCommissionList = new Dictionary(); } List tradeBarrierOptionList = null; if (retListResult.rows.Any(p => "障碍期权".Equals(p.TradeType))) { var barrierTradeIds = retListResult.rows.Where(p => "障碍期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList(); if (barrierTradeIds != null && barrierTradeIds.Any()) { tradeBarrierOptionList = DbContext.trade_barrier_option.AsNoTracking().Where(p => barrierTradeIds.Contains(p.TradeId)).ToList(); } } if (tradeBarrierOptionList == null) { tradeBarrierOptionList = new List(); } List tradeDoublesharkfinOptionList = null; if (retListResult.rows.Any(p => "双鲨期权".Equals(p.TradeType))) { var doubleSharkfinTradeIds = retListResult.rows.Where(p => "双鲨期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList(); if (doubleSharkfinTradeIds != null && doubleSharkfinTradeIds.Any()) { tradeDoublesharkfinOptionList = DbContext.trade_double_sharkfin_option.AsNoTracking().Where(p => doubleSharkfinTradeIds.Contains(p.TradeId)).ToList(); } } if (tradeDoublesharkfinOptionList == null) { tradeDoublesharkfinOptionList = new List(); } List tradeAutocallList = null; if (retListResult.rows.Any(p => "凤凰期权".Equals(p.TradeType))) { var autocallTradeIds = retListResult.rows.Where(p => "凤凰期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList(); if (autocallTradeIds != null && autocallTradeIds.Any()) { tradeAutocallList = DbContext.trade_autocall.AsNoTracking().Where(p => autocallTradeIds.Contains(p.TradeId)).ToList(); } } if (tradeAutocallList == null) { tradeAutocallList = new List(); } List tradeSnowballList = null; if (retListResult.rows.Any(p => "雪球期权".Equals(p.TradeType))) { var snowballTradeIds = retListResult.rows.Where(p => "雪球期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList(); if (snowballTradeIds != null && snowballTradeIds.Any()) { tradeSnowballList = DbContext.trade_snowball.AsNoTracking().Where(p => snowballTradeIds.Contains(p.TradeId)).ToList(); } } if (tradeSnowballList == null) { tradeSnowballList = new List(); } List tradeAirbagList = null; if (retListResult.rows.Any(p => "气囊结构".Equals(p.TradeType) || "气囊结构".Equals(p.StructureType))) { var airbagTradeIds = retListResult.rows.Where(p => "气囊结构".Equals(p.TradeType) || "气囊结构".Equals(p.StructureType)).Select(p => p.id).Distinct().ToList(); if (airbagTradeIds != null && airbagTradeIds.Any()) { tradeAirbagList = DbContext.trade_airbag.AsNoTracking().Where(p => airbagTradeIds.Contains(p.TradeId)).ToList(); } } if (tradeAirbagList == null) { tradeAirbagList = new List(); } List tradeAccumulatorOptionList = null; if (retListResult.rows.Any(p => "累计期权".Equals(p.TradeType))) { var accumulatorOptionTradeIds = retListResult.rows.Where(p => "累计期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList(); if (accumulatorOptionTradeIds != null && accumulatorOptionTradeIds.Any()) { tradeAccumulatorOptionList = DbContext.trade_accumulator_option.AsNoTracking().Where(p => accumulatorOptionTradeIds.Contains(p.TradeId)).ToList(); } } if (tradeAccumulatorOptionList == null) { tradeAccumulatorOptionList = new List(); } //获取销售提成信息 foreach (var item in retListResult.rows) { if (item.TradeType == "障碍期权") { //var option = DbContext.trade_barrier_option.FirstOrDefault(x => x.TradeId == item.id); var option = tradeBarrierOptionList.FirstOrDefault(d => d.TradeId == item.id); item.KnockInOutStatusObservation = option?.KnockInOutStatusCn; } else if (item.TradeType == "双鲨期权") { //var option = DbContext.trade_double_sharkfin_option.FirstOrDefault(x => x.TradeId == item.id); var option = tradeDoublesharkfinOptionList.FirstOrDefault(d => d.TradeId == item.id); item.KnockInOutStatusObservation = option?.KnockInOutStatusCn; } else if (item.TradeType == "凤凰期权") { //var option = DbContext.trade_autocall.FirstOrDefault(x => x.TradeId == item.id); var option = tradeAutocallList.FirstOrDefault(d => d.TradeId == item.id); item.KnockInOutStatusObservation = option?.KnockInOutStatusCn; } else if (item.TradeType == "雪球期权") { //var option = DbContext.trade_snowball.FirstOrDefault(x => x.TradeId == item.id); var option = tradeSnowballList.FirstOrDefault(d => d.TradeId == item.id); item.KnockInOutStatusObservation = option?.KnockInOutStatusCn; } else if (item.TradeType == "气囊结构" || item.StructureType == "气囊结构") { //var option = DbContext.trade_airbag.FirstOrDefault(x => x.TradeId == item.id); var option = tradeAirbagList.FirstOrDefault(d => d.TradeId == item.id); item.KnockInOutStatusObservation = option?.KnockInOutStatusCn; } else if (item.TradeType == "累计期权") { //var option = DbContext.trade_accumulator_option.FirstOrDefault(x => x.TradeId == item.id); var option = tradeAccumulatorOptionList.FirstOrDefault(d => d.TradeId == item.id); item.KnockInOutStatusObservation = option?.KnockInOutStatusCn; } //item.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(item.id); if (dicSaleCommissionList.ContainsKey(item.id)) { item.SalesCommission = dicSaleCommissionList[item.id]; } else { item.SalesCommission = new TradeSalesCommissionInfo { SalesIds = new List() }; } if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && item.SalesCommission?.Commission != null) { item.SalesCommission.Commission = item.SalesCommission.Commission * item.SalesCommission.SalesIds.Count(); } if (req.SubstandardType.HasValue) {//用于不合规交易页面,展示不合规项; item.MetaDic["IsStrikeOffset"] = (rule?.StrikeOffset == null || item.Strike == null ? false : item.IsMoneynessOptionData ? Math.Abs((item.Strike ?? 0) - 1) > rule.StrikeOffset : Math.Abs((item.Strike ?? 0) / (item.SpotPrice ?? 0) - 1) > rule.StrikeOffset).ToString(); item.MetaDic["IsMinTradingDay"] = (rule?.MinTradingDay == null ? false : (item.ExerciseDate - item.TradeDate).Value.Days < rule.MinTradingDay).ToString(); item.MetaDic["IsLockTradingDay"] = (settleTcDict != null && settleTcDict.ContainsKey(item.id)).ToString(); } if (item.CountRatio == null) { item.CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.CountRatio ?? 1; } item.StockEqvNotionalMax = item.StockEqvNotionalMax.HasValue ? item.StockEqvNotionalMax : item.StockEqvNotional; } return retListResult; } public SearchListResult SearchGroupActionList(TradeReq req) { var predicate = CreateGroupActionPredicate(req); var query = from source in DbContext.trade.AsNoTracking().Where(predicate) join tc in DbContext.trade_cash.Where(x => x.ValidState != "InValid" && x.Status == null && x.Action != "系统操作-期权费") on source.id equals tc.TradeId select new GroupAction { id = source.id + "_" + tc.id, trade = source, trade_cash = tc }; if (string.IsNullOrEmpty(req.sidx)) { req.sidx = "trade.id"; req.sord = "desc"; } var retListResult = query.ToSearchList(req); return retListResult; } public List SearchGroupChildrenList(int id) { var trades = DbContext.trade.Where(x => x.ParentTradeId == id && x.ValidState != "InValid").ToList(); return trades; } public List SearchGroupActionChildrenList(SearchGroupActionChildrenListReq req) { var childTradeIds = DbContext.trade_cash_group_action.Where(x => x.ParentTradeCashId == req.TradeCashId).Select(x => x.TradeId).ToList(); var query = from source in DbContext.trade.AsNoTracking().Where(x => childTradeIds.Contains(x.id)) join gc in DbContext.trade_cash_group_action.AsNoTracking().Where(x => x.ParentTradeCashId == req.TradeCashId) on source.id equals gc.TradeId select new GroupAction { id = source.id + "_" + req.TradeCashId, trade = source, trade_cash_group_action = gc }; return query.ToList(); } public SearchListResult SearchTradeMarginTemplateList(TradeMarginTemplateReq req) { var predicate = CreateTradeMarginTmplateQueryWhere(req); var query = from trade in DbContext.trade.Where(predicate) join tmt in (from t in DbContext.trade_margin_template where t.IsLatest select t) on trade.id equals tmt.TradeId into tmts from tmt in tmts.DefaultIfEmpty() join mt in DbContext.margin_template_v2 on tmt.MarginTemplateId equals mt.id into mts from mt in mts.DefaultIfEmpty() select new TradeMarginTemplate() { TradeId = trade.id, ClientId = trade.ClientId, TradeNumber = trade.TradeNumber, ClientName = trade.ClientName, TradeType = trade.ParentTradeId > 0 ? trade.StructureType : trade.TradeType, TradeStatus = trade.TradeStatus, InitialMargin = trade.InitialMargin, MarginTemplateId = tmt == null ? -1 : tmt.MarginTemplateId, MarginRuleType = mt == null ? -1 : mt.RuleType, MarginTemplateName = mt == null ? "" : mt.Name, ValueDate = tmt == null ? DateTime.MinValue : tmt.ValueDate, TradeDate = trade.TradeDate, BuySell = trade.BuySell, UnWindDate = trade.UnWindDate, ExerciseDate = trade.ExerciseDate }; if (req.MarginTemplate != null && req.MarginTemplate.Any()) { query = query.Where(x => req.MarginTemplate.Contains((int)x.MarginTemplateId)); } if (req.MarginRuleType != null) { query = query.Where(x => x.MarginRuleType == req.MarginRuleType); } if (req.IsDefault != null) { if (req.IsDefault == 1) { query = query.Where(x => x.MarginTemplateId <= 0); } else { query = query.Where(x => x.MarginTemplateId > 0); } } if (string.IsNullOrEmpty(req.sidx)) { req.sidx = "TradeId"; req.sord = "desc"; } else { if ("MarginRuleTypeName".Equals(req.sidx)) { req.sidx = "MarginRuleType"; } } SearchListResult retListResult = query.ToSearchList(req); return retListResult; } private Expression> CreateTradeMarginTmplateQueryWhere(TradeMarginTemplateReq req) { var predicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && t.TradeType != "结构化交易"); if (req.UserAssets != null && req.UserClients != null) { predicate = predicate.And(t => req.UserAssets.Contains(t.AssetId) || req.UserClients.Contains(t.ClientId)); } if (req.ClientId != null) { predicate = predicate.And(x => x.ClientId == req.ClientId); } if (!string.IsNullOrEmpty(req.ClientName)) { predicate = predicate.And(x => x.ClientName.Contains(req.ClientName)); } if (!string.IsNullOrEmpty(req.TradeNumber)) { predicate = predicate.And(x => x.TradeNumber.Contains(req.TradeNumber)); } if (req.DateFromTradeDate != null) { predicate = predicate.And(x => x.TradeDate >= req.DateFromTradeDate); } if (req.DateToTradeDate != null) { req.DateToTradeDate = ((DateTime)req.DateToTradeDate).AddDays(1); predicate = predicate.And(x => x.TradeDate < req.DateToTradeDate); } if (req.DateFromExerciseDate != null) { predicate = predicate.And(x => x.ExerciseDate >= req.DateFromExerciseDate); } if (req.DateToExerciseDate != null) { req.DateToExerciseDate = ((DateTime)req.DateToExerciseDate).AddDays(1); predicate = predicate.And(x => x.ExerciseDate < req.DateToExerciseDate); } if (req.TradeTypes != null && req.TradeTypes.Any()) { predicate = predicate.And(x => req.TradeTypes.Contains(x.TradeType) || req.TradeTypes.Contains(x.StructureType)); } if (req.TradeStatus != null && req.TradeStatus.Any()) { predicate = predicate.And(x => req.TradeStatus.Contains(x.TradeStatus)); } if (req.DateFromUnwindDate != null) { predicate = predicate.And(x => x.UnWindDate != null && x.UnWindDate >= req.DateFromUnwindDate); } if (req.DateToUnwindDate != null) { req.DateToUnwindDate = ((DateTime)req.DateToUnwindDate).AddDays(1); predicate = predicate.And(x => x.UnWindDate != null && x.UnWindDate < req.DateToUnwindDate); } if (!string.IsNullOrEmpty(req.BuySell)) { predicate = predicate.And(x => x.BuySell.Equals(req.BuySell)); } if (req.InitialMargin > 0) { if (req.InitialMargin == 1) { predicate = predicate.And(x => x.InitialMargin == 0 || x.InitialMargin == null); } else { predicate = predicate.And(x => x.InitialMargin > 0 || x.InitialMargin < 0); } } return predicate; } /// /// 批量设置预付金 /// /// /// public bool BatchSetInitialMargin(TradeMarginTemplateReq req) { var predicate = CreateTradeMarginTmplateQueryWhere(req); predicate = predicate.And(x => x.InitialMargin == null && x.ClientId > 0 && x.IsGroup != 1); var query = from trade in DbContext.trade.Where(predicate) join tmt in (from t in DbContext.trade_margin_template where t.IsLatest select t) on trade.id equals tmt.TradeId into tmts from tmt in tmts.DefaultIfEmpty() join mt in DbContext.margin_template_v2 on tmt.MarginTemplateId equals mt.id into mts from mt in mts.DefaultIfEmpty() select new TradeMarginTemplate() { TradeId = trade.id, ClientId = trade.ClientId, TradeNumber = trade.TradeNumber, ClientName = trade.ClientName, TradeType = trade.TradeType, TradeStatus = trade.TradeStatus, InitialMargin = trade.InitialMargin, MarginTemplateId = tmt == null ? -1 : tmt.MarginTemplateId, MarginRuleType = mt == null ? -1 : mt.RuleType, MarginTemplateName = mt == null ? "" : mt.Name, ValueDate = tmt == null ? DateTime.MinValue : tmt.ValueDate, TradeDate = trade.TradeDate, BuySell = trade.BuySell, UnWindDate = trade.UnWindDate, ExerciseDate = trade.ExerciseDate }; if (req.MarginTemplate != null && req.MarginTemplate.Any()) { query = query.Where(x => req.MarginTemplate.Contains((int)x.MarginTemplateId)); } if (req.MarginRuleType != null) { query = query.Where(x => x.MarginRuleType == req.MarginRuleType); } if (req.IsDefault != null) { if (req.IsDefault == 1) { query = query.Where(x => x.MarginTemplateId <= 0); } else { query = query.Where(x => x.MarginTemplateId > 0); } } var list = query.ToList(); if (list == null || list.Count == 0) { return true; } var tradeIds = list.Select(p => p.TradeId).Distinct().ToList(); var tradesWithOutGroup = DbContext.trade.Where(p => tradeIds.Contains(p.id)).ToList(); tradesWithOutGroup.ForEach(x => { x.InitialMargin = MarginDefault.GetInitialMarginWithPreHandle(x); }); DbContext.SaveChanges(); //更新组合交易主预付金初始预付金 var parentTradeIds = tradesWithOutGroup.Where(p => p.ParentTradeId > 0).Select(p => p.ParentTradeId).Distinct().ToList(); if (parentTradeIds != null && parentTradeIds.Any()) { var tradesGroup = DbContext.trade.Where(x => x.ValidState != "InValid" && parentTradeIds.Contains(x.id)).ToList(); tradesGroup.ForEach(x => { x.InitialMargin = DbContext.trade.Where(y => y.ValidState != "InValid" && y.ParentTradeId == x.id).Sum(y => y.InitialMargin); }); DbContext.SaveChanges(); } return true; } public List SearchTradeMarginTemplateList(int tradeId) { var query = from tmt in DbContext.trade_margin_template join mt in DbContext.margin_template_v2 on tmt.MarginTemplateId equals mt.id select new TradeMarginTemplate() { TradeId = tmt.TradeId, MarginTemplateId = tmt.MarginTemplateId, MarginTemplateName = mt.Name, ValueDate = tmt.ValueDate, MarginRuleType = mt.RuleType, MarginType = mt.MarginType, Comments = mt.Comments, OptDate = tmt.OptDate }; query = query.Where(x => x.TradeId == tradeId); var retListResult = query.OrderBy(x => x.ValueDate).ToList(); return retListResult; } class SubstandardTradeDto { public int id; public DateTime? ExerciseDate; public DateTime? TradeDate; public double? Strike; public double SpotPrice; public string IsMoneynessOption; } private string GetSubstandardTradeIds(int substandardTradeType, out Dictionary closeTcDict, out SubstandardTradeRule rule) { var obj = new SubstandardTradeRuleService(OptUser).QueryCurrentRule(); rule = obj; closeTcDict = null; List codes = new List(); var query = from t in DbContext.trade where ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus) && t.ClientId > 0 && t.TradeType != "远期" && t.TradeType != "收益互换" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.ValidState != "InValid" select new SubstandardTradeDto() { id = t.id, ExerciseDate = t.ExerciseDate, TradeDate = t.TradeDate, Strike = t.Strike, SpotPrice = t.SpotPrice ?? 0, IsMoneynessOption = t.IsMoneynessOption }; if ((substandardTradeType == 0 || substandardTradeType == 1) && obj.StrikeOffset.HasValue) { codes.AddRange(query.Where(O => O.Strike != null && ((O.IsMoneynessOption == "是" && Math.Abs((O.Strike ?? 0) - 1) > obj.StrikeOffset) || (O.IsMoneynessOption != "是" && Math.Abs((O.Strike ?? 0) / O.SpotPrice - 1) > obj.StrikeOffset))) .Select(O => O.id).ToList()); } if ((substandardTradeType == 0 || substandardTradeType == 2) && obj.MinTradingDay.HasValue) { codes.AddRange(query.ToList().Where(O => (O.ExerciseDate - O.TradeDate) < new TimeSpan(obj.MinTradingDay.Value, 0, 0, 0)) .Select(O => O.id).ToList()); } if (obj.LockTradingDay.HasValue) { var queryTc = DbContext.trade_cash.Where(O => O.ValidState != ConsGlobal.InValid && !O.IsDeleted); queryTc = TradeHelper.GetSettleTradeCash(queryTc); var query1 = (from openTc in query join closeTc in queryTc on openTc.id equals closeTc.TradeId select new { openTc.id, openDt = openTc.TradeDate, closeDt = closeTc.HappenedDate ?? closeTc.ValueDate }) .ToList().Where(O => (O.closeDt - O.openDt.Value).Days < obj.LockTradingDay); closeTcDict = query1.AsEnumerable().GroupBy(O => O.id).ToDictionary(K => K.Key, V => V.First().closeDt); if ((substandardTradeType == 0 || substandardTradeType == 3) && obj.LockTradingDay.HasValue) { codes.AddRange(query1.Select(O => O.id)); } } if (codes.Count == 0) { codes.Add(0); } return string.Join(",", codes); } protected IQueryable CreateTradeQuery(TradeReq req, TradeQueryRequest req2) { var predicate = CreateTradePredicate(req, req2); var query = DbContext.trade.AsNoTracking().Where(predicate); if (!string.IsNullOrEmpty(req.ContractCode)) { query = from source in DbContext.trade join tcrConfirm in DbContext.trade_contract_r.Where(aa => aa.Type == ContractTypeEnum.Trade && aa.IsValid) on new { id = source.ParentTradeId > 0 ? source.ParentTradeId : source.id } equals new { id = tcrConfirm.TradeId } into tcrConfirms from tcrConfirm in tcrConfirms.DefaultIfEmpty() where tcrConfirm.ContractCode.Contains(req.ContractCode) select source; } if (req.UnWindTimes != null) { //根据了结日期,了结次数进行筛选 var tcGQuery = from tc in DbContext.trade_cash where tc.ValidState != "Invalid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费") group tc by tc.TradeId into tcg select new { tid = tcg.Key, UnWindTimes = tcg.Count() }; var tcpGQuery = from tc in DbContext.trade_cash where tc.ValidState != "Invalid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费") group tc by tc.ParentTradeId into tcpg select new { tid = tcpg.Key, UnWindTimes = tcpg.Count() }; if (req.UnWindTimes == 0) { var tdids = tcGQuery.Where(tg => tg.UnWindTimes >= 1).Select(n => n.tid); var tdPids = tcpGQuery.Where(tg => tg.UnWindTimes >= 1).Select(n => n.tid); query = query.Where(q => !tdids.Contains(q.id) && !tdPids.Contains(q.id)); } else { query = from q in query join tcg in tcGQuery on q.id equals tcg.tid into tcgs from tcg in tcgs.DefaultIfEmpty() join tcpg in tcpGQuery on q.id equals tcpg.tid into tcpgs from tcpg in tcpgs.DefaultIfEmpty() where tcg != null && tcg.UnWindTimes == req.UnWindTimes || tcpg != null && tcpg.UnWindTimes == req.UnWindTimes select q; } } if (string.IsNullOrEmpty(req.sidx)) { req.sidx = "id"; req.sord = "desc"; } query = query.OrderByDescending(s => s.OptDate); return query; } protected IQueryable CreateTradeQueryWithGroup(TradeReq req, TradeQueryRequest req2) { var predicate = CreateTradePredicate(req, req2, true, req2.withGroupChildren); //DbContext.SetDebugLog(); var query = DbContext.trade.AsNoTracking().Where(predicate); //if (!string.IsNullOrEmpty(req.ContractCode)) //{ // query = from source in DbContext.trade // join tcrConfirm in DbContext.trade_contract_r.Where(aa => aa.Type == ContractTypeEnum.Trade && aa.IsValid) on new { id = source.ParentTradeId > 0 ? source.ParentTradeId : source.id } equals new { id = tcrConfirm.TradeId } into tcrConfirms // from tcrConfirm in tcrConfirms.DefaultIfEmpty() // where tcrConfirm.ContractCode.Contains(req.ContractCode) // select source; //} if (req.UnWindTimes != null) { //根据了结日期,了结次数进行筛选 var tcGQuery = from tc in DbContext.trade_cash.AsNoTracking() where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费") group tc by tc.TradeId into tcg select new { tid = tcg.Key, UnWindTimes = tcg.Count() }; //var tcGQuery = from t in query // join tc in DbContext.trade_cash.AsNoTracking() // on t.id equals tc.TradeId // where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费") // select new // { // Trade = t, // TradeCash = tc // }; var tcpGQuery = from tc in DbContext.trade_cash.AsNoTracking() where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费") group tc by tc.ParentTradeId into tcpg select new { tid = tcpg.Key, UnWindTimes = tcpg.Count() }; //var tcpGQuery = from t in query // join tc in DbContext.trade_cash.AsNoTracking() // on t.id equals tc.ParentTradeId // where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费") // select t; if (req.UnWindTimes == 0) { var tdids = tcGQuery.Union(tcpGQuery).Select(n => n.tid); query = query.Where(q => !tdids.Contains(q.id)); } else { //var tdids = tcGQuery.Where(tg => tg.UnWindTimes == req.UnWindTimes).Select(n => n.tid).ToHashSet(); //var tdPids = tcpGQuery.Where(tg => tg.UnWindTimes == req.UnWindTimes).Select(n => n.tid).ToHashSet(); query = from t in query join tc in tcGQuery.Union(tcpGQuery) on t.id equals tc.tid where tc.UnWindTimes == req.UnWindTimes select t; //var ids = tdids.Union(tdPids).ToSearchList(req).rows.ToHashSet(); //query = query.Where(q => ids.Contains(q.id)); //query = query.Where(q => tdids.Contains(q.id) || tdPids.Contains(q.id)); } } if (req.TagIds != null && req.TagIds.Count > 0) { var tradeTagIdQuery = from tt in DbContext.trade_tag where req.TagIds.Contains(tt.TagId) select tt.TradeId; query = query.Where(p => tradeTagIdQuery.Contains(p.id)); } if (string.IsNullOrEmpty(req.sidx)) { req.sidx = "id"; req.sord = "desc"; } query = query.OrderByDescending(s => s.OptDate); return query; } protected Expression> CreateTradePredicate(TradeReq req, TradeQueryRequest req2, bool withGroup = false, bool withGroupChildren = false) { if (req2 == null) { req2 = new TradeQueryRequest { }; } var valueDate = valuedateBLL.ValueDate; var predicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && t.TradeType != "结构化交易"); if (withGroup) { if (withGroupChildren) { predicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1)); } else { predicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2); } } if (req.UserAssets != null && req.UserClients != null) { predicate = predicate.And(t => req.UserAssets.Contains(t.AssetId) || req.UserClients.Contains(t.ClientId)); } //----------------交易ID---------------- if (!string.IsNullOrEmpty(req.TradeIds)) { predicate = req2.StructureQueryFlag == StructureTradeQueryFlag.QueryMaster ? predicate.And(d => req.TradeIdList.Contains(d.id)) : predicate.And(d => req.TradeIdList.Contains(d.id) || req.TradeIdList.Contains(d.ParentTradeId)); if (req.onlyTradeIds) { return predicate; } } //if (req.ParentTradeId.HasValue) //{ // predicate = predicate.And(q => q.ParentTradeId == req.ParentTradeId.Value); //} //else //{ // predicate = req2.StructureQueryFlag == StructureTradeQueryFlag.QueryMaster // ? predicate.And(t => "结构化交易" != t.TradeType) // : predicate.And(t => t.ParentTradeId == null || t.ParentTradeId == 0); //} //----------------行权方式---------------- if (!string.IsNullOrEmpty(req.ExerciseMode)) { predicate = predicate.And(d => d.ExerciseMode.Contains(req.ExerciseMode)); } //----------------交易标的---------------- if (!string.IsNullOrEmpty(req.UnderlyingAssetClass)) { predicate = predicate.And(d => d.UnderlyingAssetClass.Contains(req.UnderlyingAssetClass)); } if (!string.IsNullOrEmpty(req.UnderlyingInstrumentTypes)) { predicate = predicate.And(d => req.UnderlyingInstrumentTypesList.Contains(d.UnderlyingInstrumentType)); } if (req.UnderlyingId != null) { predicate = predicate.And(d => d.UnderlyingId == req.UnderlyingId); } if (!string.IsNullOrEmpty(req.UnderlyingIds)) { predicate = predicate.And(d => req.UnderlyingIdsInt.Contains(d.UnderlyingId)); } if (!string.IsNullOrEmpty(req.UnderlyingCode)) { predicate = predicate.And(d => d.UnderlyingCode.Contains(req.UnderlyingCode)); } if (req.UnderlyingCodeList != null && req.UnderlyingCodeList.Any()) { predicate = predicate.And(d => req.UnderlyingCodeList.Contains(d.UnderlyingCode)); } //-------------------------------- if (!string.IsNullOrEmpty(req.TraderNames)) { predicate = predicate.And(d => req.TraderNamesList.Contains(d.TraderId)); } if (!string.IsNullOrEmpty(req.TradeNumber)) { var tradequery = DbContext.trade.Where(t => t.TradeNumber.Equals(req.TradeNumber)); predicate = predicate.And(d => d.TradeNumber.Contains(req.TradeNumber) || tradequery.Select(x => x.ParentTradeId).Contains(d.id) || tradequery.Select(x => x.ParentTradeId).Contains(d.ParentTradeId) && d.ParentTradeId > 0); } if (req.ClientId != null) { predicate = predicate.And(d => d.ClientId == req.ClientId); } if (!string.IsNullOrEmpty(req.ClientName)) { predicate = predicate.And(d => d.ClientName.Contains(req.ClientName)); } if (!string.IsNullOrEmpty(req.TradeType)) { predicate = predicate.And(d => d.TradeType.Equals(req.TradeType)); } if (!string.IsNullOrEmpty(req.StructureType)) { predicate = predicate.And(d => d.StructureType.Contains(req.StructureType)); } if (!string.IsNullOrEmpty(req.BuySell)) { predicate = predicate.And(d => d.BuySell.Contains(req.BuySell)); } if (!string.IsNullOrEmpty(req.OptionType)) { predicate = predicate.And(d => d.OptionType == req.OptionType); } if (req.StartDateStart != DateTime.MinValue) { predicate = predicate.And(d => d.StartDate >= req.StartDateStart); } if (req.StartDateEnd != DateTime.MinValue) { var StartDateTemp = req.StartDateEnd.AddDays(1); predicate = predicate.And(d => d.StartDate < StartDateTemp); } if (!string.IsNullOrEmpty(req.OptIds)) { predicate = predicate.And(d => req.OptIdsList.Contains(d.OptId + "")); } if (!string.IsNullOrEmpty(req.Comments)) { predicate = predicate.And(d => d.Comments.Contains(req.Comments)); } if (!string.IsNullOrEmpty(req.GroupNames)) { predicate = predicate.And(d => req.GroupNamesList.Contains(d.GroupName)); } //---------是否有配对交易--------- if (req.IsPairTrade == true) { predicate = predicate.And(q => !string.IsNullOrEmpty(q.PairTrade)); } else if (req.IsPairTrade == false) { predicate = predicate.And(q => string.IsNullOrEmpty(q.PairTrade)); } //---------了结日期--------- if (req.UnWindDateStart.HasValue) { predicate = predicate.And(t => t.UnWindDate >= req.UnWindDateStart); } if (req.UnWindDateEnd.HasValue) { predicate = predicate.And(t => t.UnWindDate <= req.UnWindDateEnd); } if (req.TagIds != null && req.TagIds.Count > 0) { var tradeTagIdQuery = from tt in DbContext.trade_tag where req.TagIds.Contains(tt.TagId) select tt.TradeId; predicate = predicate.And(p => tradeTagIdQuery.Contains(p.id)); } //----------------交易类型---------------- if (!string.IsNullOrEmpty(req.TradeTypes)) { var typeList = req.TradeTypesList; predicate = predicate.And(d => typeList.Contains(d.TradeType) || typeList.Contains(d.StructureType) || (typeList.Contains("黑箱结构") && d.IsGroup == 1)); } switch (req.TabIndex) { case (int)TradeTabIndexEnum.今日成交: predicate = predicate.And(d => d.ClientId > 0); break; case (int)TradeTabIndexEnum.场外成交记录: predicate = predicate.And(d => d.ClientId > 0 && d.TradeType != "远期" && d.TradeType != "收益互换"); break; case (int)TradeTabIndexEnum.场外衍生品交易: predicate = predicate.And(d => d.TradeType == "远期"); break; } //获取当日成交的数据 //当日成交包括操作日期和交易日为当前系统日期的数据 if (req.TabIndex == (int)TradeTabIndexEnum.今日成交) { var optDateStart = valueDate; var optDateEnd = valueDate.AddDays(1); var tradeDateStart = valueDate; var tradeDateEnd = valueDate.AddDays(1); predicate = predicate.And(d => (d.TradeDate >= tradeDateStart && d.TradeDate < tradeDateEnd) || (d.OptDate >= optDateStart && d.OptDate < tradeDateEnd)); } else { if (req.TradeDateStart > DateTime.MinValue) { predicate = predicate.And(d => d.TradeDate >= req.TradeDateStart); } if (req.TradeDateEnd > DateTime.MinValue) { var TradeDateTemp = req.TradeDateEnd.AddDays(1); predicate = predicate.And(d => d.TradeDate < TradeDateTemp); } if (req.OptDateStart > DateTime.MinValue) { predicate = predicate.And(d => d.OptDate >= req.OptDateStart); } if (req.OptDateEnd > DateTime.MinValue) { var OptDateTemp = req.OptDateEnd.AddDays(1); predicate = predicate.And(d => d.OptDate < OptDateTemp); } } //获取当日到期日数据 if (req.TabIndex == (int)TradeTabIndexEnum.今日到期) { predicate = predicate.And(d => d.ExerciseDate == valueDate); } //获取明日到期日数据 else if (req.TabIndex == (int)TradeTabIndexEnum.明日到期) { var tommorow = QdpCalendarHelper.GetNonHoliday(valueDate.AddDays(1)); predicate = predicate.And(d => d.ExerciseDate == tommorow); } else { if (req2.IsExerciseDateReport) { predicate = predicate.And(d => d.ExerciseDate != null); } if (req.ExerciseDateStart.HasValue) { predicate = predicate.And(d => d.ExerciseDate >= req.ExerciseDateStart); } if (req.ExerciseDateEnd.HasValue) { predicate = predicate.And(d => d.ExerciseDate <= req.ExerciseDateEnd); } } //过滤已平仓,已到期,已执行数据 if (req.TabIndex == (int)TradeTabIndexEnum.今日到期 || req.TabIndex == (int)TradeTabIndexEnum.明日到期) { predicate = predicate.And(d => d.TradeStatus != ConsTrade.已平仓 && d.TradeStatus != ConsTrade.已到期 && d.TradeStatus != ConsTrade.已执行); } else if (!string.IsNullOrEmpty(req.TradeStatus)) { var statuses = req.TradeStatus.Split(',').ToList(); predicate = predicate.And(d => statuses.Contains(d.TradeStatus)); } else if (req.TradeStatusList != null && req.TradeStatusList.Any(n => !string.IsNullOrEmpty(n))) { predicate = predicate.And(d => req.TradeStatusList.Contains(d.TradeStatus)); } if (!string.IsNullOrEmpty(req.OptName)) { predicate = predicate.And(d => d.OptName.Contains(req.OptName)); } //---------行权价--------- if (!string.IsNullOrEmpty(req.Strike)) { double.TryParse(req.Strike, out var strike); predicate = predicate.And(d => d.Strike == strike); } if (req.AssetIdList.Any()) { predicate = predicate.And(d => req.AssetIdList.Contains(d.AssetId)); } if (req.ClientIdsInt.Any()) { predicate = predicate.And(d => req.ClientIdsInt.Contains(d.ClientId)); } if (req.TradePrice != null) { predicate = predicate.And(d => req.TradePrice.Value == d.TradePrice); } return predicate; } protected Expression> CreateGroupActionPredicate(TradeReq req) { var predicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && t.IsGroup == 1 && t.TradeType != "收益互换"); if (req.UserAssets != null && req.UserClients != null) { predicate = predicate.And(d => req.UserAssets.Contains(d.AssetId) || req.UserClients.Contains(d.ClientId)); } if (!string.IsNullOrEmpty(req.TradeNumber)) { var childquery = DbContext.trade.Where(t => t.TradeNumber.Equals(req.TradeNumber) && t.ParentTradeId != 0); predicate = predicate.And(d => d.TradeNumber.Contains(req.TradeNumber) || childquery.Select(x => x.ParentTradeId).Contains(d.id)); } if (req.ClientIdsInt.Any()) { predicate = predicate.And(d => req.ClientIdsInt.Contains(d.ClientId)); } return predicate; } } public class TradeQueryRequest { /// /// 显示所有交易 /// public bool ShowAllTrades { get; set; } /// /// /// public List UserAssetUnits { get; set; } /// /// 结构化交易过滤选项 /// public StructureTradeQueryFlag StructureQueryFlag { get; set; } = StructureTradeQueryFlag.QueryMaster; /// /// /// public bool GetSum { get; set; } /// /// 是否来自行权报告 /// public bool IsExerciseDateReport { get; set; } public string VolType { get; set; } public bool withGroupChildren { get; set; } } /// /// 结构化交易过滤选项枚举 /// public enum StructureTradeQueryFlag { /// /// 只查询主交易 /// QueryMaster = 1, /// /// 只查询子交易 /// QuerySubs = 2 } }