using BaseOUDAL; using YieldChain.Security; using YLErp.BLL; using YLErp.DBModels.Enums; using YLErp.Model; namespace YLErp.Modules.ScenarioModule { /// /// 情景分析数据查询服务 /// public class TradeScenarioQueryService : YLBaseService { public TradeScenarioQueryService(OptUserInfo userInfo) : base(userInfo) { } //获取日终持仓 private SearchListResult GetEodPosition(TradeScenarioSearchModel searchModel) { var predicate = PredicateBuilder.Create( t => t.ValueDate == searchModel.PositionDate && !ScenarioHelper.ExcludeTradeTypes.Contains(t.TradeType) && t.UnderlyingCode != null); if (searchModel.UserAssets != null || searchModel.UserClients != null) { predicate = predicate.And(n => searchModel.UserAssets.Contains(n.BookId) || searchModel.UserClients.Contains(n.ClientId)); } if (searchModel.UnderlyingIds != null && searchModel.UnderlyingIds.Any(n => n > 0)) { predicate = predicate.And(x => searchModel.UnderlyingIds.Contains(x.UnderlyingId)); } if (searchModel.VarietyIds != null && searchModel.VarietyIds.Any(n => n > 0)) { predicate = predicate.And( x => DbContext.underlying_manager.Any(n => n.UnderlyingCode == x.UnderlyingCode && searchModel.VarietyIds.Contains(n.UnderlyingTypeId))); } if (searchModel.TradeTypes != null && searchModel.TradeTypes.Any(n => !string.IsNullOrEmpty(n))) { if (searchModel.TradeTypes.Contains("场外期权")) { predicate = predicate.And(x => x.TradeId > 0 || searchModel.TradeTypes.Contains(x.TradeType)); } else { predicate = predicate.And(x => searchModel.TradeTypes.Contains(x.TradeType)); } } if (searchModel.AssetIds != null && searchModel.AssetIds.Any()) { predicate = predicate.And(x => searchModel.AssetIds.Contains(x.BookId)); } if (searchModel.ClientIds != null && searchModel.ClientIds.Any()) { predicate = predicate.And(x => searchModel.ClientIds.Contains(x.ClientId)); } var tradePredicate = PredicateBuilder.Create(t => t.ValidState != ConsGlobal.InValid); var query = from et in DbContext.eod_trade_position.Where(predicate) join td in DbContext.trade.Where(tradePredicate) on et.TradeId equals td.id into temptd from td in temptd.DefaultIfEmpty() orderby td.TradeNumber descending, et.UnderlyingCode select new { et.id, et.TradeId, et.ClientId, et.BookId, et.TradeType, et.UnderlyingId, et.UnderlyingCode, BuySell = td != null ? td.BuySell : et.PositionType == "long" ? "买入" : "卖出", td.TradeNumber, td.ExerciseDate, td.OptionType, td.Strike, td.IsMoneynessOption, td.TradeDate, // Notional = td == null ? (et.PositionType == "long" ? et.Amount : - et.Amount) : et.Amount, Notional = et.Amount, ExchangeOptionCode = et.ExchangeOptionCode }; var searchResult = query.ToSearchList(searchModel); var list = new List(searchResult.rows.Count()); foreach (var td in searchResult.rows) { var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); if (underlying == null) { continue; } var tm = new TradePositionMerge { id = td.id + "_历史", //EncryptId = DataProtect.Encrypt(td.id) + "_历史", TradeEncryptId = td.TradeId > 0 ? DataProtect.Encrypt(td.TradeId) : string.Empty, TradeNumber = td.TradeNumber, BookId = td.BookId, ClientId = td.ClientId, ClientName = DataCacheProvider.GetClientDataSource().GetData(td.ClientId)?.Name, AssetBookName = DataCacheProvider.GetAssetUnitDataSource().GetData(td.BookId)?.Name, BuySell = td.BuySell, ExerciseDate = td.ExerciseDate, OptionType = td.OptionType, Strike = td.Strike, IsMoneynessOption = td.IsMoneynessOption, TradeDate = td.TradeDate, TradeType = td.TradeType, UnderlyingCode = td.UnderlyingCode, UnderlyingId = underlying.id, VarietyId = underlying.UnderlyingTypeId, UnderlyingAssetClass = underlying.UnderlyingType, TradeAmount = 0, }; tm.TradeAmount = td.Notional / underlying.CountRatio; if (td.TradeType == "场内期权") { var exchangeOption = DataCacheProvider.GetExchangeListOptionDataSource().GetData(td.ExchangeOptionCode); if (exchangeOption == null) { continue; } tm.ExerciseDate = exchangeOption.MaturityDate; tm.OptionType = exchangeOption.OptionType; tm.Strike = exchangeOption.Strike; } tm.CountRatio = underlying.CountRatio; list.Add(tm); } return new SearchListResult(searchResult, list); } //获取日间持仓 private SearchListResult GetIntradayPosition(TradeScenarioSearchModel searchModel) { var blQuery = true; #region----场外交易持仓过滤条件---- var tdPredicate = PredicateBuilder.Create( t => t.ExerciseDate >= valuedateBLL.ValueDate && ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus) && !ScenarioHelper.ExcludeTradeTypes.Contains(t.TradeType) && t.ClientId > 0 && t.ValidState != "InValid"); if (searchModel.UserAssets != null || searchModel.UserClients != null) { tdPredicate = tdPredicate.And(a => searchModel.UserAssets.Contains(a.AssetId) || searchModel.UserClients.Contains(a.ClientId)); } if (searchModel.TradeTypes != null && searchModel.TradeTypes.Any(n => !string.IsNullOrEmpty(n))) { if (!searchModel.TradeTypes.Contains("场外期权")) { blQuery = false; tdPredicate = PredicateBuilder.False(); } } if (blQuery) { if (searchModel.ClientIds != null && searchModel.ClientIds.Any(n => n > 0)) { tdPredicate = tdPredicate.And(x => searchModel.ClientIds.Contains(x.ClientId)); } if (searchModel.UnderlyingIds != null && searchModel.UnderlyingIds.Any(n => n > 0)) { tdPredicate = tdPredicate.And(x => searchModel.UnderlyingIds.Contains(x.UnderlyingId)); } if (searchModel.AssetIds != null&&searchModel.AssetIds.Any()) { tdPredicate = tdPredicate.And(x => searchModel.AssetIds.Contains(x.AssetId)); } if (searchModel.VarietyIds != null && searchModel.VarietyIds.Any(n => n > 0)) { tdPredicate = tdPredicate.And( x => DbContext.underlying_manager.Any(n => n.UnderlyingCode == x.UnderlyingCode && searchModel.VarietyIds.Contains(n.UnderlyingTypeId))); } } #endregion #region----场内交易持仓过滤条件---- blQuery = true; var exPredicate = PredicateBuilder.True(); if (searchModel.ClientIds != null && searchModel.ClientIds.Any(n => n > 0)) { blQuery = false; } if (blQuery && searchModel.TradeTypes != null && searchModel.TradeTypes.Any(n => !string.IsNullOrEmpty(n))) { var tradeTypes = searchModel.TradeTypes.Intersect(ConsTrade.TradeTypesForHedge).ToArray(); if (blQuery = tradeTypes.Any()) { exPredicate = exPredicate.And(x => tradeTypes.Contains(x.TradeType)); } } if (blQuery) { if (searchModel.UserAssets != null) { exPredicate = exPredicate.And(x => searchModel.UserAssets.Contains(x.BookId)); } if (searchModel.UnderlyingIds != null && searchModel.UnderlyingIds.Any(n => n > 0)) { exPredicate = exPredicate.And(x => searchModel.UnderlyingIds.Contains(x.UnderlyingId)); } if (searchModel.AssetIds != null && searchModel.AssetIds.Any()) { exPredicate = exPredicate.And(x => searchModel.AssetIds.Contains(x.BookId)); } if (searchModel.VarietyIds != null && searchModel.VarietyIds.Any(n => n > 0)) { exPredicate = exPredicate.And( x => DbContext.underlying_manager.Any(n => n.UnderlyingCode == x.UnderlyingCode && searchModel.VarietyIds.Contains(n.UnderlyingTypeId))); } } else { exPredicate = PredicateBuilder.False(); } #endregion #region----查询Linq---- var tdQuery = from td in DbContext.trade.Where(tdPredicate) select new { torder = 1, id = (long)td.id, td.ClientId, td.AssetId, td.TradeType, td.UnderlyingId, td.UnderlyingCode, BuySell = td.BuySell, td.TradeNumber, td.ExerciseDate, td.OptionType, td.Strike, td.IsMoneynessOption, td.TradeDate, Notional = td.Notional, ExchangeOptionCode = string.Empty }; var extdQuery = from td in DbContext.TradePosition.Where(exPredicate) select new { torder = 2, id = td.id, ClientId = 0, AssetId = td.BookId, td.TradeType, td.UnderlyingId, td.UnderlyingCode, BuySell = td.PositionType == PositionTypeFlag.Long ? "买入" : "卖出", TradeNumber = string.Empty, ExerciseDate = default(DateTime?), OptionType = string.Empty, Strike = default(double?), IsMoneynessOption = "否", TradeDate = default(DateTime?), Notional = td.Position, ExchangeOptionCode = td.InstrumentCode }; #endregion var searchResult = tdQuery.Concat(extdQuery).OrderBy(n => n.torder) .ThenByDescending(n => n.TradeNumber).ThenByDescending(n => n.UnderlyingCode).ToSearchList(searchModel); var list = new List(searchResult.rows.Count()); foreach (var td in searchResult.rows) { var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); if (underlying == null) { continue; } var isOtcTrade = td.torder == 1; var tm = new TradePositionMerge { id = td.id + (isOtcTrade ? "_场外" : "_场内"), TradeEncryptId = string.Empty, TradeNumber = td.TradeNumber, BookId = td.AssetId, ClientId = td.ClientId, ClientName = DataCacheProvider.GetClientDataSource().GetData(td.ClientId)?.Name, AssetBookName = DataCacheProvider.GetAssetUnitDataSource().GetData(td.AssetId)?.Name, BuySell = td.BuySell, ExerciseDate = td.ExerciseDate, OptionType = td.OptionType, Strike = td.Strike, IsMoneynessOption = td.IsMoneynessOption, TradeDate = td.TradeDate, TradeType = td.TradeType, UnderlyingCode = td.UnderlyingCode, UnderlyingId = underlying.id, VarietyId = underlying.UnderlyingTypeId, UnderlyingAssetClass = underlying.UnderlyingType, TradeAmount = 0, }; tm.TradeAmount = td.Notional / underlying.CountRatio; if (isOtcTrade) { tm.TradeEncryptId = DataProtect.Encrypt(td.id); } else if (td.TradeType == "场内期权") { var exchangeOption = DataCacheProvider.GetExchangeListOptionDataSource().GetData(td.ExchangeOptionCode); if (exchangeOption == null) { continue; } tm.ExerciseDate = exchangeOption.MaturityDate; tm.OptionType = exchangeOption.OptionType; tm.Strike = exchangeOption.Strike; } tm.CountRatio = underlying.CountRatio; list.Add(tm); } return new SearchListResult(searchResult, list); } public SearchListResult GetDatas(TradeScenarioSearchModel req, out bool isEodPosition) { if (req.PositionDate != null && req.PositionDate < valuedateBLL.ValueDate) { isEodPosition = true; return GetEodPosition(req); } else { isEodPosition = false; return GetIntradayPosition(req); } } } }