using BaseOUDAL; using System.Data; using YLErp.BLL.EodSettlement; using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Modules.ClientModule; namespace YLErp.Modules.TradeModule.QueryModule { /// /// 历史交易查询服务(迁移自TradeBLL) /// public class TradeHistoryQueryService : YLBaseService { public TradeHistoryQueryService(YLBaseService baseService) : base(baseService) { } public TradeHistoryQueryService(OptUserInfo userInfo) : base(userInfo) { } /// /// 盯市报告历史交易总数 /// public int SearchHistoryCount(TradeReq req) { return CreateTradeHistoryQuery(req).Count(); } public List SearchHistoryListOnly(TradeReq req, bool isFromTradeMarketReport = false) { var query = CreateTradeHistoryQuery(req, isFromTradeMarketReport); List retListResult = query.ToList(); retListResult.ForEach(x => { var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.CountRatio ?? 1; x.CountRatio = CountRatio; if (x.trade_cash.IsLastAction) { if (x.trade.TradeType == "凤凰期权" || x.trade.IsGroup == 1) { var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-票息" && y.id != x.trade_cash.id); if (tradeCashs.Any()) { x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount); } } else if (x.trade.TradeType == "收益互换") { var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-互换" && y.id != x.trade_cash.id); if (tradeCashs.Any()) { x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount); } } } if (x.trade.IsGroup == 1) { //如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理 var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == x.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && x.trade_cash.IsLastAction).Select(y => y.id).ToArray(); var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == x.trade_cash.id || tradeCashCouponIds.Contains(y.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; var tcTradeNotional = 0.0; childTradeCashs.ForEach(y => { var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId); tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0; tcTradeNotional += y.UnwindNotional??0.0; }); x.WinLoss = -(x.trade_cash.Amount + tcTradePrice); x.trade_cash.UnwindNotional = tcTradeNotional; } if (x.TradeMultipleType == "现金流交易") { x.trade.OriginalNotional = null; x.trade.TradeOriginalAmount = null; x.trade_cash.TradeAmount = null; x.trade_cash.UnwindTradeAmount = null; } }); return retListResult; } /// /// 查询历史交易 /// public SearchListResult SearchHistoryList(TradeReq req, out trade_contract_groupGridSum gsum) { var query = CreateTradeHistoryQuery(req); var retListResult = query.ToSearchList(req, true); var parentTradeIds = retListResult.rows.Select(x => x.trade.ParentTradeId).ToArray(); var parentTrades = DbContext.trade.Where(x => parentTradeIds.Contains(x.id)).ToArray(); foreach (var x in retListResult.rows) { //处理累计换月交易数据 new Modules.TradeModule.OptionTradeActionRestoreService(this.UserInfo).RestoreTradeDataToSpecialDay(x.trade, Convert.ToDateTime(req.ValueDateEnd)); var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.CountRatio ?? 1; x.CountRatio = CountRatio; if (!ConsTrade.TradeTypesForHedge.Contains(x.trade.TradeType)) { x.trade.TradeOriginalAmount = x.trade.OriginalNotional / CountRatio; } //针对最后一次了结的记录,需要把存续的票息和互换金额算进最后一次的了结金额里 if (x.trade_cash.IsLastAction) { if (x.trade.TradeType == "凤凰期权" || x.trade.IsGroup == 1) { var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-票息" && y.id != x.trade_cash.id); if (tradeCashs.Any()) { x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount); } } else if (x.trade.TradeType == "收益互换") { var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-互换" && y.id != x.trade_cash.id); if (tradeCashs.Any()) { x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount); } } } if (x.trade.IsGroup == 1) { //如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理 var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == x.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && x.trade_cash.IsLastAction).Select(y => y.id).ToArray(); var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == x.trade_cash.id || tradeCashCouponIds.Contains(y.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.WinLoss = -(x.trade_cash.Amount + tcTradePrice); } if (x.TradeMultipleType == "现金流交易") { x.trade.OriginalNotional = null; x.trade.TradeOriginalAmount = null; x.trade_cash.TradeAmount = null; x.trade_cash.UnwindTradeAmount = null; } if (x.trade.IsGroup == 2 && x.trade.TradeType == "收益互换") { var parentTrade = parentTrades.FirstOrDefault(y => y.id == x.trade.ParentTradeId); if (parentTrade != null) { x.trade.TradeNumber = parentTrade.TradeNumber; } } if (PS.Config.ErpElement.IsSettlementReportAccOptionContainMultiplier && x.TradeType == "累计期权" && x.trade.trade_accumulator_option != null) { x.trade.trade_accumulator_option = DbContext.trade_accumulator_option.Where(l => l.TradeId == x.trade.id).FirstOrDefault(); // 累计了结时相应的乘数(标准累计:看涨乘数,看跌乘数;三段式:乘数1,乘数2,乘数3) 当乘数为0不处理 x.ACCMultiplier = ClientAssetDataService.GetTradeAccumulatorOptionMultiplier(x.trade, x.trade_cash.FinalPrice.Value, x.trade_cash.ValueDate); } x.trade.UnderlyingAssetName = x.trade.UnderlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.UnderlyingName; x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate; } gsum = new trade_contract_groupGridSum(); if (query.Any()) { var queryList = query.ToList(); foreach (var item in queryList) { if (item.trade.IsGroup == 1) { //如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理 var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == item.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && item.trade_cash.IsLastAction).Select(y => y.id).ToArray(); var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == item.trade_cash.id || tradeCashCouponIds.Contains(y.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; }); item.WinLoss = -(item.trade_cash.Amount + tcTradePrice); } } gsum.TradePriceSum = queryList.Select(x => new { x.trade.id, x.trade.TradePrice, x.trade.BuySell, x.trade.OptionType, x.trade.TradeType }) .Distinct().Sum(q => OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0) * ("卖出".Equals(q.BuySell) || q.TradeType == "远期" ? -1 : 1)); gsum.MinusAmountSum = queryList.Sum(q => -q.trade_cash.Amount).FormatValue(2); gsum.StockEqvNotionalSum = queryList.Select(x => new { x.trade.id, x.trade.OriginalStockEqvNotional }).Distinct().Sum(q => Math.Round((q.OriginalStockEqvNotional ?? 0) * 100) / 100); gsum.WinLossSum = queryList.Sum(n => n.WinLoss).FormatValue(2); } retListResult.Sum = gsum; return retListResult; } private IQueryable CreateTradeHistoryQuery(TradeReq req, bool isFromTradeMarketReport = false) { var actionList = new[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费 }; var actionAllList = new[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费, ClientCashInCashOut.系统操作_期权费 }; IQueryable query; if (isFromTradeMarketReport && PS.Config.Is申万) { query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" && tradeObj.IsGroup != 1 || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 && tradeObj.TradeType == "收益互换") select tradeObj join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionAllList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id where trade.ValidState != ConsGlobal.InValid && tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted select new trade_contract_group_simple { id = tradeCash.id, trade = trade, ClientName = trade.ClientName, trade_cash = tradeCash, underlying_manager = underlyingInfo, UnwindVol = tradeCash.Action == ClientCashInCashOut.系统操作_平仓费 ? tradeCash.UnwindVol : null }; } else if (!req.IsHistoryWithUnconfirmed) { query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" && tradeObj.IsGroup != 1 || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 && tradeObj.TradeType == "收益互换") select tradeObj join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id into underlyings from underlyingInfo in underlyings.DefaultIfEmpty() join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets from asset in assets.DefaultIfEmpty() where trade.ValidState != ConsGlobal.InValid && tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted select new trade_contract_group_simple { id = tradeCash.id, trade = trade, ClientName = trade.ClientName, trade_cash = tradeCash, underlying_manager = underlyingInfo, UnwindVol = tradeCash.Action == ClientCashInCashOut.系统操作_平仓费 ? tradeCash.UnwindVol : null, UserGroup = asset.UserGroup }; DbContext.SetDebugLog(); } else { query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 ) select tradeObj join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id into underlyings from underlyingInfo in underlyings.DefaultIfEmpty() join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets from asset in assets.DefaultIfEmpty() where trade.ValidState != "InValid" && (tradeCash.ValidState != "InValid" || (trade.TradeStatus == "平仓待复核" && tradeCash.Action == ClientCashInCashOut.系统操作_平仓费) || (trade.TradeStatus == "行权待复核" && tradeCash.Action == ClientCashInCashOut.系统操作_行权费)) && !tradeCash.IsDeleted select new trade_contract_group_simple { id = tradeCash.id, trade = trade, ClientName = trade.ClientName, trade_cash = tradeCash, underlying_manager = underlyingInfo, UnwindVol = tradeCash.Action == ClientCashInCashOut.系统操作_平仓费 ? tradeCash.UnwindVol : null, UserGroup = asset.UserGroup }; } //if (req.ClientId != null && !EodPnlBLL.IsBaseClient(req.ClientId.Value)) //{ //query = query.Where(d => d.trade.ClientId == req.ClientId); //} if (req.ClientId != null && req.ParentFlag) { var lists = ClientBalanceUtility.GetSubclientId(req.ClientId.Value); query = query.Where(d => lists.Contains(d.trade.ClientId)); } else if (req.ClientId != null && !req.ParentFlag) { query = query.Where(d => d.trade.ClientId == req.ClientId); } if (req.ValueDateStart.Year > 2000) { query = query.Where(d => d.trade_cash.ValueDate >= req.ValueDateStart && d.trade_cash.HappenedDate == null || d.trade_cash.HappenedDate >= req.ValueDateStart); } if (req.ValueDateEnd.Year > 2000) { DateTime ValueDateTemp = req.ValueDateEnd.AddDays(1); query = query.Where(d => d.trade_cash.ValueDate < ValueDateTemp && d.trade_cash.HappenedDate == null || d.trade_cash.HappenedDate < ValueDateTemp); } if (!string.IsNullOrEmpty(req.ClientIds)) { query = query.Where(d => req.ClientIdsInt.Contains(d.trade.ClientId)); } if (!string.IsNullOrEmpty(req.TradeTypes)) { query = query.Where(d => req.TradeTypesList.Contains(d.trade.TradeType) || req.TradeTypesList.Contains(d.trade.StructureType)); } if (req.NotInTradeTypes != null && req.NotInTradeTypes.Any()) { query = query.Where(d => !req.NotInTradeTypes.Contains(d.trade.TradeType)); } if (!string.IsNullOrEmpty(req.UnderlyingIds)) { query = query.Where(d => req.UnderlyingIdsInt.Contains(d.trade.UnderlyingId)); } if (!string.IsNullOrEmpty(req.BuySell)) { query = query.Where(d => d.trade.BuySell.Contains(req.BuySell)); } if (!string.IsNullOrEmpty(req.OptionType)) { query = query.Where(d => d.trade.OptionType == req.OptionType); } if (!string.IsNullOrEmpty(req.ExerciseMode)) { query = query.Where(d => d.trade.ExerciseMode == req.ExerciseMode); } if (req.TradeDateStart.Year > 2000) { query = query.Where(d => d.trade.TradeDate >= req.TradeDateStart); } if (req.TradeDateEnd.Year > 2000) { DateTime TradeDateTemp = req.TradeDateEnd.AddDays(1); query = query.Where(d => d.trade.TradeDate < TradeDateTemp); } if (req.TabIndex == (int)TradeTabIndexEnum.今日终止) { //已平仓,部分平仓,美式期权提前行权 if (req.IsHistoryWithUnconfirmed) { query = query.Where(d => d.trade_cash.Action == ClientCashInCashOut.系统操作_平仓费 || ((d.trade.TradeStatus == ConsTrade.已执行 || d.trade.TradeStatus == ConsTrade.行权待复核) && d.trade.ExerciseMode == "American" && d.trade_cash.ExerciseWay != "到期行权")); } else { query = query.Where(d => d.trade_cash.Action == ClientCashInCashOut.系统操作_平仓费 || (d.trade.TradeStatus == ConsTrade.已执行 && d.trade.ExerciseMode == "American" && d.trade_cash.ExerciseWay != "到期行权")); } } if (req.ExerciseDateStart != null || req.ExerciseDateEnd != null) { if (req.ExerciseDateEnd == null) { req.ExerciseDateEnd = DateTime.MaxValue; } if (req.ExerciseDateStart == null) { req.ExerciseDateStart = DateTime.MinValue; } //股票的到期日为null query = query.Where(d => string.IsNullOrEmpty(d.trade.ExerciseMode) || d.trade.ExerciseDate == null || ((d.trade.ExerciseMode == "European" && d.trade.ExerciseDate >= req.ExerciseDateStart && d.trade.ExerciseDate <= req.ExerciseDateEnd) || (d.trade.ExerciseMode == "American" && ((d.trade.ExerciseDate >= req.ExerciseDateStart && d.trade.ExerciseDate <= req.ExerciseDateEnd) || (d.trade.StartDate >= req.ExerciseDateStart && d.trade.StartDate <= req.ExerciseDateEnd) || (d.trade.StartDate <= req.ExerciseDateStart && d.trade.ExerciseDate >= req.ExerciseDateEnd) )) )); } if (!string.IsNullOrEmpty(req.TradeStatus)) { List statuses = req.TradeStatus.Split(',').ToList(); query = query.Where(d => statuses.Contains(d.trade.TradeStatus)); } if (req.TradeStatusList != null) { query = query.Where(d => req.TradeStatusList.Contains(d.trade.TradeStatus)); } if (!string.IsNullOrEmpty(req.TraderNames)) { query = query.Where(d => req.TraderNamesList.Contains(d.trade.TraderId)); } if (req.AssetIdList.Any()) { query = query.Where(d => req.AssetIdList.Contains(d.trade.AssetId)); } if (string.IsNullOrEmpty(req.sidx)) { query = query.OrderBy(n => n.trade.UnderlyingInstrumentType).ThenByDescending(s => s.trade_cash.id); } else if (req.sidx == "trade_cash.ValueDateString") { req.sidx = "trade_cash.ValueDate"; } else { query = query.OrderBy(n => n.trade.UnderlyingInstrumentType); } return query; } } }