using BaseOUDAL; using NPOI.SS.Formula.Functions; using System.Data; using YLErp.BLL.Eod; using YLErp.BLL.EodSettlement; using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.Model; using YLErp.Modules.DataProviderModule; using YLErp.Modules.SwapModule; using YLErp.Modules.TradeModule; using YLErp.QdpModule; namespace YLErp.Modules.ClientModule { /// /// 客户持仓查询服务 /// public class ClientPositionQueryService : YLBaseService { public ClientPositionQueryService(YLBaseService baseService) : base(baseService) { } public ClientPositionQueryService(OptUserInfo userInfo) : base(userInfo) { } /// /// 是否需要确认书合约号,默认true /// public bool NeedTradeContractCode { get; set; } = true; /// /// API:获取客户持仓 /// public SearchListResult GetClientPositionAPI(DateTime valueDate, int clientId, int page, int pageRowCount) { var list = SearchPositionList(new TradeSpanReq { ValueDate = valueDate, ClientId = clientId, page = page, rows = pageRowCount }, null); foreach (var item in list.rows) { item.Variety = new Variety2 { TradeUnitValue = UnderlyingDataProvider.GetUnderlying(item.UnderlyingCode)?.ContractSize ?? 1 }; } return list; } /// /// 查询所有客户持仓数据 /// public List SearchPositionListAll(TradeSpanReq req, IEnumerable userAssetUnits) { if (!req.ValueDate.HasValue) { throw new ServiceException("缺少参数:请求日期"); } IQueryable query = null; var ireq = CreateReq(req, userAssetUnits); var isTodayQuery = ireq.isTodayQuery; if (isTodayQuery) { query = CreateTodayQuery(ireq); } else { query = CreateEodQuery(ireq); } //国投要求默认按成交日正序 if (string.IsNullOrEmpty(req.sidx) && PS.Config.Is国投) { query = query.OrderBy(n => n.TradeDate).ThenByDescending(n => n.TradeNumber); } //国君要求先查期货后查权益类 else if (string.IsNullOrEmpty(req.sidx)) { query = query.OrderBy(n => n.InstrumentType).ThenByDescending(n => n.TradeNumber); } else { req.sidx = req.sidx.Split(' ')[0]; if (string.IsNullOrEmpty(req.sord)) { req.sord = "desc"; } query.SortBy($"{nameof(eod_position.InstrumentType)},{req.sidx} {req.sord}"); } var queryList = query.ToList(); SwapEodPositionService swapEodPositionService = new SwapEodPositionService(this); queryList.AddRange(swapEodPositionService.GetSwapPositions(req.ClientId??0,req.ValueDate.Value)); var underlyingDataSource = DataCacheProvider.GetUnderlyingDataSource(); new TradeExtendService(this).SetTradeExtendWithCnKey(queryList.Select(x => x.trade).ToArray(), true, req.ValueDate); var eodPriceProvider = new Lazy(() => new EodPriceProvider(req.ValueDate.Value).Initialize()); var xmxyUseSettlePrice = PS.Config.Is厦门象屿 && req.ValueDate.Value > new DateTime(2021, 12, 30); Dictionary contractCodeDic = null; if (NeedTradeContractCode) { var tids = queryList.Select(n => n.TradeId).ToArray(); var q2 = from aa in DbContext.trade_contract_r where tids.Contains(aa.TradeId) && aa.Type == ContractTypeEnum.Trade && aa.IsValid orderby aa.id descending select new { aa.TradeId, aa.ContractCode }; contractCodeDic = CollectionHelper.ToDictionary2(q2.ToArray(), n => n.TradeId, n => n.ContractCode); } foreach (var x in queryList) { var um = underlyingDataSource.GetData(x.UnderlyingCode); if (um != null) { x.CountRatio = um.CountRatio; x.ContractSize = um.ContractSize; x.QuoteUnitSingle = um.QuoteUnitString; x.MarketCode = um.MarketCode; x.BBGTicker = um.BBGTicker; //if (isTodayQuery) //{ // x.UnderlyingPrice = um.Price; //} if (um.IsSynthetic()) { var sy = underlyingDataSource.GetSyntheticUnderlying(x.UnderlyingCode); if (sy != null) { x.SyntheticUnderlyingTipsInfo = sy.UnderlyingTipsInfo; } } else if (isTodayQuery && um.IsBasket()) { underlyingDataSource.TryGetPrice(x.UnderlyingCode, out var price); x.UnderlyingPrice = price; } } else { x.CountRatio = 1; x.ContractSize = 1; x.QuoteUnitSingle = ""; } if (isTodayQuery) { if (x.IsGroup == 1) { var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList(); var childRisks = DbContext.realtime_trade_risk.Where(tr => tr.ValueDate == ireq.valueDate && tr.VolType == "持仓" && childTradeIds.Contains(tr.TradeId ?? 0)).ToList(); var childPositions = DbContext.intraday_trade_position.Where(tr => tr.ValueDate == ireq.valueDate && childTradeIds.Contains(tr.TradeId)).ToList(); x.PvDouble = childRisks.Sum(y => -y.Pv); x.RoundedPvDouble = childRisks.Sum(y => -y.RoundedPv); x.PnlDouble = childRisks.Sum(y => -y.PositionPnl); x.RoundedPnlDouble = childRisks.Sum(y => -y.RoundedPositionPnl); x.Margin = childPositions.Sum(y => y.Margin); x.Delta = childRisks.Sum(y => y.Delta); x.Gamma = childRisks.Sum(y => y.Gamma); x.Vega = childRisks.Sum(y => y.Vega); x.Theta = childRisks.Sum(y => y.Theta); x.Rho = childRisks.Sum(y => y.Rho); x.GammaCash = childRisks.Sum(y => y.GammaCash); } x.Pv = x.PvDouble; x.RoundedPv = x.RoundedPvDouble; x.Pnl = x.PnlDouble; x.RoundedPnl = x.RoundedPnlDouble; } else { if (x.IsGroup == 1) { var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList(); if (PS.Config.Is格林大华 || PS.Config.Is伴兴) { var childEodPositions = DbContext.eod_trade_position_extend.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList(); var eodTradeRisks = DbContext.eod_trade_risk_extend.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList(); x.Pv = childEodPositions.Sum(y => -y.Pv); x.RoundedPv = childEodPositions.Sum(y => -y.RoundedPv); x.Pnl = childEodPositions.Sum(y => -y.PositionPnL); x.RoundedPnl = childEodPositions.Sum(y => -y.RoundedPositionPnL); x.Margin = childEodPositions.Sum(y => y.Margin); x.Delta = eodTradeRisks.Sum(y => y.Delta); x.Gamma = eodTradeRisks.Sum(y => y.Gamma); x.Vega = eodTradeRisks.Sum(y => y.Vega); x.Theta = eodTradeRisks.Sum(y => y.Theta); x.Rho = eodTradeRisks.Sum(y => y.Rho); x.GammaCash = eodTradeRisks.Sum(y => y.GammaCash); } else if (PS.Config.Is广发商贸) { var childEodPositions = DbContext.eod_trade_position_hedgevol.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList(); var eodTradeRisks = DbContext.eod_trade_risk_hedgevol.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList(); x.Pv = childEodPositions.Sum(y => -y.Pv); x.RoundedPv = childEodPositions.Sum(y => -y.RoundedPv); x.Pnl = childEodPositions.Sum(y => -y.PositionPnL); x.RoundedPnl = childEodPositions.Sum(y => -y.RoundedPositionPnL); x.Margin = childEodPositions.Sum(y => y.Margin); x.Delta = eodTradeRisks.Sum(y => y.Delta); x.Gamma = eodTradeRisks.Sum(y => y.Gamma); x.Vega = eodTradeRisks.Sum(y => y.Vega); x.Theta = eodTradeRisks.Sum(y => y.Theta); x.Rho = eodTradeRisks.Sum(y => y.Rho); x.GammaCash = eodTradeRisks.Sum(y => y.GammaCash); } else { var childEodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList(); var eodTradeRisks = DbContext.eod_trade_risk.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList(); x.Pv = childEodPositions.Sum(y => -y.Pv); x.RoundedPv = childEodPositions.Sum(y => -y.RoundedPv); x.Pnl = childEodPositions.Sum(y => -y.PositionPnL); x.RoundedPnl = childEodPositions.Sum(y => -y.RoundedPositionPnL); x.Margin = childEodPositions.Sum(y => y.Margin); x.Delta = eodTradeRisks.Sum(y => y.Delta); x.Gamma = eodTradeRisks.Sum(y => y.Gamma); x.Vega = eodTradeRisks.Sum(y => y.Vega); x.Theta = eodTradeRisks.Sum(y => y.Theta); x.Rho = eodTradeRisks.Sum(y => y.Rho); x.GammaCash = eodTradeRisks.Sum(y => y.GammaCash); } x.PvDouble = x.Pv; x.RoundedPvDouble = x.RoundedPv; x.PnlDouble = x.Pnl; x.RoundedPnlDouble = x.RoundedPnl; } } if (PS.Config.IsGuoJun) { var dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate, -1); if (isTodayQuery) { dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate); } if (x.IsGroup == 1) { var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList(); var childEodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == dt && childTradeIds.Contains(tr.TradeId)).ToList(); x.ChangeMargin = x.Margin - childEodPositions.Sum(y => y.Margin); } else { var EodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == dt && tr.TradeId == x.TradeId).ToList(); x.ChangeMargin = x.Margin - EodPositions.Sum(y => y.Margin); } } if (PS.Config.Is厦门象屿) { if (x.IsGroup == 1) { var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList(); var tradespan = DbContext.trade_span.Where(o => o.ValueDate == ireq.valueDate && childTradeIds.Contains(o.TradeId)).ToList(); x.MaxlossMargin = tradespan.Sum(y => y.MaxlossMargin); } else { var tradespan = DbContext.trade_span.Where(o => o.TradeId == x.TradeId && o.ValueDate == ireq.valueDate)?.FirstOrDefault(); x.MaxlossMargin = tradespan?.MaxlossMargin; } if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode , xmxyUseSettlePrice ? SettlementTypeEnum.SettlePrice : x.SettlementType, out var price)) { x.UnderlyingPrice = price; } } else if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode, x.SettlementType, out var price)) { x.UnderlyingPrice = price; } if (x.IsGroup == 1) { var parentTradeCashIds = DbContext.trade_cash.Where(t => (t.Action == "系统操作-票息" || t.Action == "系统操作-互换") && t.ValidState != "InValid" && t.ValueDate <= req.ValueDate && t.TradeId == x.TradeId && !t.IsLastAction).Select(y => y.id).ToArray(); var childTradeCashs = DbContext.trade_cash.Where(t => parentTradeCashIds.Contains(t.ParentTradeCashId)).ToList(); var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList(); var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList(); var tcTradePrice = 0.0; childTradeCashs.ForEach(y => { var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId); tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0; }); x.PositionRelizedAmount = -((childTradeCashs.Sum(y => (double?)y.Amount) ?? 0) + tcTradePrice); } var client = DataCacheProvider.GetClientDataSource().GetData(x.ClientId ?? 0); if (client != null) { x.ClientName = client.Name; x.MarginOptionType = client.MarginOptionType; } x.dic = x.trade.MetaDic; if (x.TradeMultipleType == "现金流交易") { x.trade.OriginalNotional = null; } x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate; if (contractCodeDic != null && contractCodeDic.TryGetValue(x.TradeId, out var contractCode)) { x.TradeContractCode = contractCode; } if (PS.Config.Is广发商贸) { var eps = DbContext.eod_trade_position.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate); x.Margin = eps == null ? 0 : eps.Margin; var erisk = DbContext.eod_trade_risk.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate); x.Vol = erisk == null ? 0 : erisk.Vol; } } return queryList; } /// /// 查询所有客户持仓数据 /// public List SearchPositionChildrenListAll(TradeSpanReq req, IEnumerable userAssetUnits) { if (!req.ValueDate.HasValue) { throw new ServiceException("缺少参数:请求日期"); } IQueryable query = null; var ireq = CreateReq(req, userAssetUnits); var isTodayQuery = ireq.isTodayQuery; if (isTodayQuery) { query = CreateTodayChildrenQuery(ireq); } else { query = CreateEodChildrenQuery(ireq); } //国投要求默认按成交日正序 if (string.IsNullOrEmpty(req.sidx) && PS.Config.Is国投) { query = query.OrderBy(n => n.TradeDate).ThenByDescending(n => n.TradeNumber); } //国君要求先查期货后查权益类 else if (string.IsNullOrEmpty(req.sidx)) { query = query.OrderBy(n => n.InstrumentType).ThenByDescending(n => n.TradeNumber); } else { req.sidx = req.sidx.Split(' ')[0]; if (string.IsNullOrEmpty(req.sord)) { req.sord = "desc"; } query.SortBy($"{nameof(eod_position.InstrumentType)},{req.sidx} {req.sord}"); } var queryList = query.ToList(); var underlyingDataSource = DataCacheProvider.GetUnderlyingDataSource(); new TradeExtendService(this).SetTradeExtendWithCnKey(queryList.Select(x => x.trade).ToArray(), true, req.ValueDate); var eodPriceProvider = new Lazy(() => new EodPriceProvider(req.ValueDate.Value).Initialize()); var xmxyUseSettlePrice = PS.Config.Is厦门象屿 && req.ValueDate.Value > new DateTime(2021, 12, 30); Dictionary contractCodeDic = null; if (NeedTradeContractCode) { var tids = queryList.Select(n => n.TradeId).ToArray(); var q2 = from aa in DbContext.trade_contract_r where tids.Contains(aa.TradeId) && aa.Type == ContractTypeEnum.Trade && aa.IsValid orderby aa.id descending select new { aa.TradeId, aa.ContractCode }; contractCodeDic = CollectionHelper.ToDictionary2(q2.ToArray(), n => n.TradeId, n => n.ContractCode); } foreach (var x in queryList) { var um = underlyingDataSource.GetData(x.UnderlyingCode); if (um != null) { x.CountRatio = um.CountRatio; x.ContractSize = um.ContractSize; x.QuoteUnitSingle = um.QuoteUnitString; x.MarketCode = um.MarketCode; x.BBGTicker = um.BBGTicker; if (um.IsSynthetic()) { var sy = underlyingDataSource.GetSyntheticUnderlying(x.UnderlyingCode); if (sy != null) { x.SyntheticUnderlyingTipsInfo = sy.UnderlyingTipsInfo; } } else if (isTodayQuery && um.IsBasket()) { underlyingDataSource.TryGetPrice(x.UnderlyingCode, out var price); x.UnderlyingPrice = price; } } else { x.CountRatio = 1; x.ContractSize = 1; x.QuoteUnitSingle = ""; } if (isTodayQuery) { x.Pv = x.PvDouble; x.RoundedPv = x.RoundedPvDouble; x.Pnl = x.PnlDouble; x.RoundedPnl = x.RoundedPnlDouble; } if (PS.Config.IsGuoJun) { var dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate, -1); if (isTodayQuery) { dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate); } var EodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == dt && tr.TradeId == x.TradeId).ToList(); x.ChangeMargin = x.Margin - EodPositions.Sum(y => y.Margin); } if (PS.Config.Is厦门象屿) { var tradespan = DbContext.trade_span.Where(o => o.TradeId == x.TradeId && o.ValueDate == ireq.valueDate)?.FirstOrDefault(); x.MaxlossMargin = tradespan?.MaxlossMargin; if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode , xmxyUseSettlePrice ? SettlementTypeEnum.SettlePrice : x.SettlementType, out var price)) { x.UnderlyingPrice = price; } } else if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode, x.SettlementType, out var price)) { x.UnderlyingPrice = price; } var client = DataCacheProvider.GetClientDataSource().GetData(x.ClientId ?? 0); if (client != null) { x.ClientName = client.Name; x.MarginOptionType = client.MarginOptionType; } x.dic = x.trade.MetaDic; if (x.TradeMultipleType == "现金流交易") { x.trade.OriginalNotional = null; } x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate; if (contractCodeDic != null && contractCodeDic.TryGetValue(x.TradeId, out var contractCode)) { x.TradeContractCode = contractCode; } if (PS.Config.Is广发商贸) { var eps = DbContext.eod_trade_position.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate); x.Margin = eps == null ? 0 : eps.Margin; var erisk = DbContext.eod_trade_risk.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate); x.Vol = erisk == null ? 0 : erisk.Vol; } } return queryList; } /// /// 根据ValueDate获取客户持仓 /// public SearchListResult SearchPositionList(TradeSpanReq req, IEnumerable userAssetUnits) { var queryList = SearchPositionListAll(req, userAssetUnits); var gsum = new EodPnlGridSum(); if (queryList.Any()) { gsum.PvSum = queryList.Sum(q => q.Pv); gsum.RoundedPvSum = queryList.Sum(q => q.RoundedPv); gsum.DailyPnLSum = queryList.Sum(q => q.Pnl); gsum.RoundedDailyPnLSum = queryList.Sum(q => q.RoundedPnl); gsum.OriginalStockEqvNotionalSum = queryList.Sum(q => q.OriginalStockEqvNotional); gsum.StockEqvNotionalSum = queryList.Sum(q => q.StockEqvNotional); gsum.TradePriceSum = queryList.Sum(q => OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0)); gsum.MarginSum = queryList.Sum(q => q.Margin); } var searchList = queryList.AsQueryable().ToSearchList(req); var tradeIds = searchList.rows.Select(x => x.TradeId).ToList(); foreach (var item in searchList.rows) { item.trade.TradeSinglePrice = item.trade.TradeSinglePrice.IsNormalize() ? Math.Abs(item.trade.TradeSinglePrice.Value) : item.trade.TradeSinglePrice; //处理累计换月交易数据 new OptionTradeActionRestoreService(UserInfo).RestoreTradeDataToSpecialDay(item.trade, Convert.ToDateTime(req.ValueDate)); item.CountRatio = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.CountRatio ?? 1; } searchList.Sum = gsum; return searchList; } /// /// 根据ValueDate获取客户持仓 /// public SearchListResult SearchPositionChildrenList(TradeSpanReq req, IEnumerable userAssetUnits) { var queryList = SearchPositionChildrenListAll(req, userAssetUnits); var gsum = new EodPnlGridSum(); if (queryList.Any()) { gsum.PvSum = queryList.Sum(q => q.Pv); gsum.RoundedPvSum = queryList.Sum(q => q.RoundedPv); gsum.DailyPnLSum = queryList.Sum(q => q.Pnl); gsum.RoundedDailyPnLSum = queryList.Sum(q => q.RoundedPnl); gsum.OriginalStockEqvNotionalSum = queryList.Sum(q => q.OriginalStockEqvNotional); gsum.StockEqvNotionalSum = queryList.Sum(q => q.StockEqvNotional); gsum.TradePriceSum = queryList.Sum(q => OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0)); gsum.MarginSum = queryList.Sum(q => q.Margin); } var searchList = queryList.AsQueryable().ToSearchList(req); var tradeIds = searchList.rows.Select(x => x.TradeId).ToList(); var tradeSwaps = DbContext.trade_swap.Where(x => tradeIds.Contains(x.TradeId)).ToList(); foreach (var item in searchList.rows) { item.trade.trade_swap = tradeSwaps.FirstOrDefault(x => x.TradeId == item.TradeId); if (item.trade.TradeType == "收益互换") { if (item.trade.trade_swap.IsGetFloatingProfit) { var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(item.trade.trade_swap.GetUnderlyingId ?? 0); if (underlying != null && underlying.ContractSize > 0) { item.trade.trade_swap.GetContractSize = underlying.ContractSize; item.trade.trade_swap.GetCountRatio = underlying.CountRatio; } } else if (item.trade.trade_swap.IsPayFloatingProfit) { var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(item.trade.trade_swap.PayUnderlyingId ?? 0); if (underlying != null && underlying.ContractSize > 0) { item.trade.trade_swap.PayContractSize = underlying.ContractSize; item.trade.trade_swap.PayCountRatio = underlying.CountRatio; } } } item.trade.TradeSinglePrice = item.trade.TradeSinglePrice.IsNormalize() ? Math.Abs(item.trade.TradeSinglePrice.Value) : item.trade.TradeSinglePrice; //处理累计换月交易数据 new OptionTradeActionRestoreService(UserInfo).RestoreTradeDataToSpecialDay(item.trade, Convert.ToDateTime(req.ValueDate)); item.CountRatio = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.CountRatio ?? 1; } searchList.Sum = gsum; return searchList; } #region---内部处理---- private InnerRequest CreateReq(TradeSpanReq req, IEnumerable userAssetUnits) { var isBaseClient = false; var clientId = req.ClientId ?? 0; //if (clientId > 0) //{ // isBaseClient = ClientDataProvider.IsBaseClient(clientId); // if (isBaseClient) // { // clientId = 0; // } //} if (userAssetUnits != null && !userAssetUnits.Any()) { userAssetUnits = null; } var valueDate = req.ValueDate ?? DateTime.MinValue; var lastValueDate = EodOperationBase.GetLastSettlementDate(valueDate); return new InnerRequest { clientId = clientId, tradeNumber = req.TradeNumber, userAssetUnits = userAssetUnits, bookIds = req.BookIds, tradeTypes = req.TradeTypes, notInTradeTypes = req.NotInTradeTypes, underlyingIds = req.UnderlyingIds, tradeDateStart = req.TradeDateStart, tradeDateEnd = req.TradeDateEnd, exerciseDateStart = req.ExerciseDateStart, exerciseDateEnd = req.ExerciseDateEnd, valueDate = valueDate, lastValueDate = lastValueDate, isBaseClient = isBaseClient, ParentFlag = req.ParentFlag }; } private IQueryable CreateTodayQuery(InnerRequest req) { var suspensionUnderlyingIdList = DataCacheProvider.GetUnderlyingDataSource().AsQueryable() .Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList(); var predicate = PredicateBuilder.Create(t => t.ClientId > 0 && ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus) && (t.ValidState != "InValid" || t.ValidState == null) && (t.TradeType != "结构化交易" && t.IsGroup != 1 || t.IsGroup == 1 && t.TradeType == "结构化交易") && (t.IsGroup != 2 || t.TradeType != "收益互换") && (t.ExerciseDate >= req.valueDate || suspensionUnderlyingIdList.Contains(t.UnderlyingId))); if (req.clientId > 0 && req.ParentFlag) { var lists = ClientBalanceUtility.GetSubclientId(req.clientId); predicate = predicate.And(t => lists.Contains(t.ClientId)); } else if (req.clientId > 0 && !req.ParentFlag) { predicate = predicate.And(t => t.ClientId == req.clientId); } if(!string.IsNullOrEmpty(req.tradeNumber)) { predicate = predicate.And(t => t.TradeNumber.Contains(req.tradeNumber)); } if (req.userAssetUnits != null) { predicate = predicate.And(t => req.userAssetUnits.Contains(t.AssetId)); } if (req.bookIds != null && req.bookIds.Any()) { predicate = predicate.And(t => req.bookIds.Contains(t.AssetId)); } if (req.tradeTypes != null && req.tradeTypes.Any()) { predicate = predicate.And(t => req.tradeTypes.Contains(t.TradeType)); } if (req.notInTradeTypes != null && req.notInTradeTypes.Any()) { predicate = predicate.And(t => !req.notInTradeTypes.Contains(t.TradeType)); } if (req.underlyingIds != null && req.underlyingIds.Any()) { predicate = predicate.And(t => req.underlyingIds.Contains(t.UnderlyingId)); } if (req.tradeDateStart != null || req.tradeDateEnd != null) { if (req.tradeDateEnd == null) { req.tradeDateEnd = DateTime.MaxValue; } if (req.tradeDateStart == null) { req.tradeDateStart = DateTime.MinValue; } predicate = predicate.And(d => d.TradeDate >= req.tradeDateStart && d.TradeDate <= req.tradeDateEnd); } if (req.exerciseDateStart != null || req.exerciseDateEnd != null) { if (req.exerciseDateEnd == null) { req.exerciseDateEnd = DateTime.MaxValue; } if (req.exerciseDateStart == null) { req.exerciseDateStart = DateTime.MinValue; } predicate = predicate.And(d => d.ExerciseDate >= req.exerciseDateStart && d.ExerciseDate <= req.exerciseDateEnd); } var volType = PS.Config.Is国投 ? "开仓" : "持仓"; var query = from t in DbContext.trade.Where(predicate) join parentTrade in DbContext.trade.Where(x => x.IsGroup == 1 && x.TradeType == "收益互换") on t.ParentTradeId equals parentTrade.id into parentTrades from parentTrade in parentTrades.DefaultIfEmpty() join risk in DbContext.realtime_trade_risk.Where(tr => tr.ValueDate == req.valueDate && tr.VolType == volType) on t.id equals risk.TradeId into risks from risk in risks.DefaultIfEmpty() join position in DbContext.intraday_trade_position.Where(tp => tp.ValueDate == req.valueDate) on t.id equals position.TradeId into positions from position in positions.DefaultIfEmpty() join asset in DbContext.assetunit on t.AssetId equals asset.id into assets from asset in assets.DefaultIfEmpty() select new eod_position { TradeId = t.id, TradeType = t.IsGroup == 1 ? t.StructureType : t.TradeType, ClientId = t.ClientId, TradeNumber = parentTrade == null ? t.TradeNumber : parentTrade.TradeNumber, TradeDate = t.TradeDate, ExerciseDate = t.ExerciseDate, UnderlyingCode = t.UnderlyingCode, tradeOrigin = t, BasisUnderlyingCode = t.BasisUnderlyingCode, BasisGap = t.BasisGap ?? 0, Lots = t.Lots ?? 0, ValueDate = req.valueDate, TradeJson = "", Pv = 0, AnnualizeFactor = t.AnnualizeFactor ?? 0, PrincipalRate = t.PrincipalRate ?? 0, NoRiskRate = t.NoRiskRate ?? 0, ParticipationRate = t.ParticipationRate ?? 0, RoundedPv = 0, Pnl = 0, RoundedPnl = 0, UnderlyingPrice = risk.UnderlyingPrice, PvDouble = risk.Pv * -1, RoundedPvDouble = risk.RoundedPv * -1, PnlDouble = risk.PositionPnl * -1, RoundedPnlDouble = risk.RoundedPositionPnl * -1, Vol = risk == null ? 0 : risk.Vol, Delta = risk == null ? 0 : risk.Delta, Gamma = risk == null ? 0 : risk.Gamma, Theta = risk == null ? 0 : risk.Theta, Vega = risk == null ? 0 : risk.Vega, Rho = risk == null ? 0 : risk.Rho, GammaCash = risk == null ? 0 : risk.GammaCash, Margin = position == null ? 0 : position.Margin, PositionRelizedAmount = position == null ? 0 : position.PositionRelizedAmount * -1, InstrumentType = t.UnderlyingInstrumentType, IsGroup = t.IsGroup, SettlementFlag = t.SettlementFlag, UserGroup = asset.UserGroup }; return query; } private IQueryable CreateTodayChildrenQuery(InnerRequest req) { var suspensionUnderlyingIdList = DataCacheProvider.GetUnderlyingDataSource().AsQueryable() .Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList(); var predicate = PredicateBuilder.Create(t => t.ClientId > 0 && ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus) && (t.ValidState != "InValid" || t.ValidState == null) && (t.TradeType != "结构化交易" && t.IsGroup != 1 || t.IsGroup == 2) && (t.ExerciseDate >= req.valueDate || suspensionUnderlyingIdList.Contains(t.UnderlyingId))); if (req.clientId > 0 && req.ParentFlag) { var lists = ClientBalanceUtility.GetSubclientId(req.clientId); predicate = predicate.And(t => lists.Contains(t.ClientId)); } else if (req.clientId > 0 && !req.ParentFlag) { predicate = predicate.And(t => t.ClientId == req.clientId); } if (!string.IsNullOrEmpty(req.tradeNumber)) { predicate = predicate.And(t => t.TradeNumber.Contains(req.tradeNumber)); } if (req.userAssetUnits != null) { predicate = predicate.And(t => req.userAssetUnits.Contains(t.AssetId)); } if (req.bookIds != null && req.bookIds.Any()) { predicate = predicate.And(t => req.bookIds.Contains(t.AssetId)); } if (req.tradeTypes != null && req.tradeTypes.Any()) { predicate = predicate.And(t => req.tradeTypes.Contains(t.StructureType) || req.tradeTypes.Contains(t.TradeType)); } if (req.notInTradeTypes != null && req.notInTradeTypes.Any()) { predicate = predicate.And(t => !req.notInTradeTypes.Contains(t.TradeType)); } if (req.underlyingIds != null && req.underlyingIds.Any()) { predicate = predicate.And(t => req.underlyingIds.Contains(t.UnderlyingId)); } if (req.tradeDateStart != null || req.tradeDateEnd != null) { if (req.tradeDateEnd == null) { req.tradeDateEnd = DateTime.MaxValue; } if (req.tradeDateStart == null) { req.tradeDateStart = DateTime.MinValue; } predicate = predicate.And(d => d.TradeDate >= req.tradeDateStart && d.TradeDate <= req.tradeDateEnd); } if (req.exerciseDateStart != null || req.exerciseDateEnd != null) { if (req.exerciseDateEnd == null) { req.exerciseDateEnd = DateTime.MaxValue; } if (req.exerciseDateStart == null) { req.exerciseDateStart = DateTime.MinValue; } predicate = predicate.And(d => d.ExerciseDate >= req.exerciseDateStart && d.ExerciseDate <= req.exerciseDateEnd); } var volType = PS.Config.Is国投 ? "开仓" : "持仓"; var query = from t in DbContext.trade.Where(predicate) join parentTrade in DbContext.trade.Where(x => x.IsGroup == 1 && x.TradeType == "收益互换") on t.ParentTradeId equals parentTrade.id into parentTrades from parentTrade in parentTrades.DefaultIfEmpty() join risk in DbContext.realtime_trade_risk.Where(tr => tr.ValueDate == req.valueDate && tr.VolType == volType) on t.id equals risk.TradeId into risks from risk in risks.DefaultIfEmpty() join position in DbContext.intraday_trade_position.Where(tp => tp.ValueDate == req.valueDate) on t.id equals position.TradeId into positions from position in positions.DefaultIfEmpty() select new eod_position { TradeId = t.id, TradeType = t.TradeType, ClientId = t.ClientId, TradeNumber = parentTrade == null ? t.TradeNumber : parentTrade.TradeNumber, TradeDate = t.TradeDate, ExerciseDate = t.ExerciseDate, UnderlyingCode = t.UnderlyingCode, tradeOrigin = t, BasisUnderlyingCode = t.BasisUnderlyingCode, BasisGap = t.BasisGap ?? 0, Lots = t.Lots ?? 0, ValueDate = req.valueDate, TradeJson = "", Pv = 0, AnnualizeFactor = t.AnnualizeFactor ?? 0, PrincipalRate = t.PrincipalRate ?? 0, NoRiskRate = t.NoRiskRate ?? 0, ParticipationRate = t.ParticipationRate ?? 0, RoundedPv = 0, Pnl = 0, RoundedPnl = 0, UnderlyingPrice = risk.UnderlyingPrice, PvDouble = risk.Pv * -1, RoundedPvDouble = risk.RoundedPv * -1, PnlDouble = risk.PositionPnl * -1, RoundedPnlDouble = risk.RoundedPositionPnl * -1, Vol = risk == null ? 0 : risk.Vol, Delta = risk == null ? 0 : risk.Delta, Gamma = risk == null ? 0 : risk.Gamma, Theta = risk == null ? 0 : risk.Theta, Vega = risk == null ? 0 : risk.Vega, Rho = risk == null ? 0 : risk.Rho, GammaCash = risk == null ? 0 : risk.GammaCash, Margin = position == null ? 0 : position.Margin, PositionRelizedAmount = position == null ? 0 : position.PositionRelizedAmount * -1, InstrumentType = t.UnderlyingInstrumentType, IsGroup = t.IsGroup, SettlementFlag = t.SettlementFlag, }; return query; } private IQueryable CreateEodQuery(InnerRequest req) { var eodTradeQuery = DbContext.eod_trade.Where(et => ConsTrade.NeedMarginTradeStatusList.Contains(et.TradeStatus) && et.ValueDate == req.lastValueDate&&et.TradeType!="收益互换"); if (req.clientId > 0 && req.ParentFlag) { var lists = ClientBalanceUtility.GetSubclientId(req.clientId); eodTradeQuery = eodTradeQuery.Where(t => lists.Contains(t.ClientId)); } else if (req.clientId > 0 && !req.ParentFlag) { eodTradeQuery = eodTradeQuery.Where(n => n.ClientId == req.clientId); } if(!string.IsNullOrEmpty(req.tradeNumber)) { eodTradeQuery = eodTradeQuery.Where(n => n.TradeNumber.Contains(req.tradeNumber)); } if (req.userAssetUnits != null) { eodTradeQuery = eodTradeQuery.Where(t => req.userAssetUnits.Contains(t.AssetId)); } if (req.bookIds != null && req.bookIds.Any()) { eodTradeQuery = eodTradeQuery.Where(t => req.bookIds.Contains(t.AssetId)); } if (req.tradeTypes != null && req.tradeTypes.Any()) { eodTradeQuery = eodTradeQuery.Where(t => req.tradeTypes.Contains(t.TradeType)); } if (req.notInTradeTypes != null && req.notInTradeTypes.Any()) { eodTradeQuery = eodTradeQuery.Where(t => !req.notInTradeTypes.Contains(t.TradeType)); } if (req.underlyingIds != null && req.underlyingIds.Any()) { eodTradeQuery = eodTradeQuery.Where(t => req.underlyingIds.Contains(t.UnderlyingId)); } if (req.tradeDateStart != null || req.tradeDateEnd != null) { if (req.tradeDateEnd == null) { req.tradeDateEnd = DateTime.MaxValue; } if (req.tradeDateStart == null) { req.tradeDateStart = DateTime.MinValue; } var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.TradeDate >= req.tradeDateStart && d.trade.TradeDate <= req.tradeDateEnd).Select(x => x.TradeId).ToArray(); eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId)); } if (req.exerciseDateStart != null || req.exerciseDateEnd != null) { if (req.exerciseDateEnd == null) { req.exerciseDateEnd = DateTime.MaxValue; } if (req.exerciseDateStart == null) { req.exerciseDateStart = DateTime.MinValue; } var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.ExerciseDate >= req.exerciseDateStart && d.trade.ExerciseDate <= req.exerciseDateEnd).Select(x => x.TradeId).ToArray(); eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId)); } IQueryable GetQuery() where TPosition : EodTradePosition where TRisk : EodTradeRisk { var posQuery = DbContext.Set().Where(t => t.ValueDate == req.lastValueDate && t.TradeId > 0); var tradeOriginQuery = from x in DbContext.trade where (x.TradeType != "结构化交易" && x.IsGroup != 1 || x.IsGroup == 1 && x.TradeType == "结构化交易") && (x.IsGroup != 2) && x.ValidState != ConsGlobal.InValid select x; return from trade in eodTradeQuery join tradeOrigin in tradeOriginQuery on trade.TradeId equals tradeOrigin.id join parentTrade in DbContext.trade.Where(x => x.IsGroup == 1 && x.TradeType == "收益互换") on trade.ParentTradeId equals parentTrade.id into parentTrades from parentTrade in parentTrades.DefaultIfEmpty() join epos in posQuery on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = epos.ValueDate, id = epos.TradeId } into positions from epos in positions.DefaultIfEmpty() join erisk in DbContext.Set() on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = erisk.ValueDate, id = erisk.TradeId } into t_erisk from erisk in t_erisk.DefaultIfEmpty() join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets from asset in assets.DefaultIfEmpty() select new eod_position { TradeId = tradeOrigin.id, TradeType = tradeOrigin.IsGroup == 1 ? tradeOrigin.StructureType : tradeOrigin.TradeType, ClientId = tradeOrigin.ClientId, TradeNumber = parentTrade == null ? tradeOrigin.TradeNumber : parentTrade.TradeNumber, TradeDate = tradeOrigin.TradeDate, ExerciseDate = tradeOrigin.ExerciseDate, PrincipalRate = tradeOrigin.PrincipalRate ?? 0, BasisUnderlyingCode = tradeOrigin.BasisUnderlyingCode, BasisGap = tradeOrigin.BasisGap ?? 0, Lots = tradeOrigin.Lots ?? 0, ParticipationRate = tradeOrigin.ParticipationRate ?? 0, NoRiskRate = tradeOrigin.NoRiskRate ?? 0, UnderlyingCode = trade.UnderlyingCode, UnderlyingPrice = null, Pv = epos == null ? 0 : epos.Pv * -1, RoundedPv = epos == null ? 0 : epos.RoundedPv * -1, Pnl = epos == null ? 0 : epos.PositionPnL * -1, RoundedPnl = epos == null ? 0 : epos.RoundedPositionPnL * -1, ValueDate = req.lastValueDate, TradeJson = trade.TradeJson, PvDouble = 0, PnlDouble = 0, Vol = erisk == null ? 0 : erisk.Vol, Delta = erisk == null ? 0 : (double)erisk.Delta, Gamma = erisk == null ? 0 : (double)erisk.Gamma, Theta = erisk == null ? 0 : (double)erisk.Theta, Vega = erisk == null ? 0 : (double)erisk.Vega, Rho = erisk == null ? 0 : (double)erisk.Rho, GammaCash = erisk == null ? 0 : (double)erisk.GammaCash, Margin = epos == null ? 0 : epos.Margin, PositionRelizedAmount = epos == null ? 0 : epos.PositionRelizedAmount * -1, InstrumentType = tradeOrigin.UnderlyingInstrumentType, IsGroup = tradeOrigin.IsGroup, SettlementType = tradeOrigin.SettlementType, SettlementFlag = tradeOrigin.SettlementFlag, UserGroup = asset.UserGroup }; } if (PS.Config.Is伴兴) { return GetQuery(); } else if (PS.Config.Is国投) { return GetQuery(); } else if (PS.Config.Is广发商贸) { return GetQuery(); } return GetQuery(); } private IQueryable CreateEodChildrenQuery(InnerRequest req) { var eodTradeQuery = DbContext.eod_trade.Where(et => ConsTrade.NeedMarginTradeStatusList.Contains(et.TradeStatus) && et.ValueDate == req.lastValueDate); if (req.clientId > 0 && req.ParentFlag) { var lists = ClientBalanceUtility.GetSubclientId(req.clientId); eodTradeQuery = eodTradeQuery.Where(t => lists.Contains(t.ClientId)); } else if (req.clientId > 0 && !req.ParentFlag) { eodTradeQuery = eodTradeQuery.Where(n => n.ClientId == req.clientId); } if (!string.IsNullOrEmpty(req.tradeNumber)) { eodTradeQuery = eodTradeQuery.Where(n => n.TradeNumber.Contains(req.tradeNumber)); } if (req.userAssetUnits != null) { eodTradeQuery = eodTradeQuery.Where(t => req.userAssetUnits.Contains(t.AssetId)); } if (req.bookIds != null && req.bookIds.Any()) { eodTradeQuery = eodTradeQuery.Where(t => req.bookIds.Contains(t.AssetId)); } if (req.tradeTypes != null && req.tradeTypes.Any()) { var tradeIds = eodTradeQuery.ToList().Where(t => req.tradeTypes.Contains(t.trade.StructureType) || req.tradeTypes.Contains(t.TradeType)).Select(x => x.TradeId).ToArray(); eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId)); } if (req.notInTradeTypes != null && req.notInTradeTypes.Any()) { eodTradeQuery = eodTradeQuery.Where(t => !req.notInTradeTypes.Contains(t.TradeType)); } if (req.underlyingIds != null && req.underlyingIds.Any()) { eodTradeQuery = eodTradeQuery.Where(t => req.underlyingIds.Contains(t.UnderlyingId)); } if (req.tradeDateStart != null || req.tradeDateEnd != null) { if (req.tradeDateEnd == null) { req.tradeDateEnd = DateTime.MaxValue; } if (req.tradeDateStart == null) { req.tradeDateStart = DateTime.MinValue; } var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.TradeDate >= req.tradeDateStart && d.trade.TradeDate <= req.tradeDateEnd).Select(x => x.TradeId).ToArray(); eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId)); } if (req.exerciseDateStart != null || req.exerciseDateEnd != null) { if (req.exerciseDateEnd == null) { req.exerciseDateEnd = DateTime.MaxValue; } if (req.exerciseDateStart == null) { req.exerciseDateStart = DateTime.MinValue; } var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.ExerciseDate >= req.exerciseDateStart && d.trade.ExerciseDate <= req.exerciseDateEnd).Select(x => x.TradeId).ToArray(); eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId)); } IQueryable GetQuery() where TPosition : EodTradePosition where TRisk : EodTradeRisk { var posQuery = DbContext.Set().Where(t => t.ValueDate == req.lastValueDate && t.TradeId > 0); var tradeOriginQuery = from x in DbContext.trade where (x.TradeType != "结构化交易" && x.IsGroup != 1 || x.IsGroup == 2) && x.ValidState != ConsGlobal.InValid select x; return from trade in eodTradeQuery join tradeOrigin in tradeOriginQuery on trade.TradeId equals tradeOrigin.id join epos in posQuery on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = epos.ValueDate, id = epos.TradeId } into positions from epos in positions.DefaultIfEmpty() join erisk in DbContext.Set() on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = erisk.ValueDate, id = erisk.TradeId } into t_erisk from erisk in t_erisk.DefaultIfEmpty() select new eod_position { TradeId = tradeOrigin.id, TradeType = tradeOrigin.TradeType, ClientId = tradeOrigin.ClientId, TradeNumber = tradeOrigin.TradeNumber, TradeDate = tradeOrigin.TradeDate, ExerciseDate = tradeOrigin.ExerciseDate, PrincipalRate = tradeOrigin.PrincipalRate ?? 0, BasisUnderlyingCode = tradeOrigin.BasisUnderlyingCode, BasisGap = tradeOrigin.BasisGap ?? 0, Lots = tradeOrigin.Lots ?? 0, ParticipationRate = tradeOrigin.ParticipationRate ?? 0, NoRiskRate = tradeOrigin.NoRiskRate ?? 0, UnderlyingCode = trade.UnderlyingCode, UnderlyingPrice = null, Pv = epos == null ? 0 : epos.Pv * -1, RoundedPv = epos == null ? 0 : epos.RoundedPv * -1, Pnl = epos == null ? 0 : epos.PositionPnL * -1, RoundedPnl = epos == null ? 0 : epos.RoundedPositionPnL * -1, ValueDate = req.lastValueDate, TradeJson = trade.TradeJson, PvDouble = 0, PnlDouble = 0, Vol = erisk == null ? 0 : erisk.Vol, Delta = erisk == null ? 0 : (double)erisk.Delta, Gamma = erisk == null ? 0 : (double)erisk.Gamma, Theta = erisk == null ? 0 : (double)erisk.Theta, Vega = erisk == null ? 0 : (double)erisk.Vega, Rho = erisk == null ? 0 : (double)erisk.Rho, GammaCash = erisk == null ? 0 : (double)erisk.GammaCash, Margin = epos == null ? 0 : epos.Margin, PositionRelizedAmount = epos == null ? 0 : epos.PositionRelizedAmount * -1, InstrumentType = tradeOrigin.UnderlyingInstrumentType, IsGroup = tradeOrigin.IsGroup, SettlementType = tradeOrigin.SettlementType, SettlementFlag = tradeOrigin.SettlementFlag }; } if (PS.Config.Is伴兴) { return GetQuery(); } else if (PS.Config.Is国投) { return GetQuery(); } else if (PS.Config.Is广发商贸) { return GetQuery(); } return GetQuery(); } class InnerRequest { public int clientId { get; set; } public string tradeNumber { get; set; } public IEnumerable tradeTypes { get; set; } public IEnumerable notInTradeTypes { get; set; } public IEnumerable userAssetUnits { get; set; } public IEnumerable bookIds { get; set; } public IEnumerable underlyingIds { get; set; } public DateTime? tradeDateStart { get; set; } public DateTime? tradeDateEnd { get; set; } public DateTime? exerciseDateStart { get; set; } public DateTime? exerciseDateEnd { get; set; } public DateTime valueDate { get; set; } public DateTime lastValueDate { get; set; } public bool isBaseClient { get; set; } public bool isTodayQuery => valueDate > lastValueDate; public bool ParentFlag { get; set; } } #endregion } }