using BaseOUDAL; using NPOI.POIFS.Properties; using NPOI.SS.Formula.Functions; using OfficeOpenXml.FormulaParsing.ExpressionGraph; using Org.BouncyCastle.Ocsp; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using YLErp.BLL; using YLErp.Commons; using YLErp.DBModels; using YLErp.DBModels.Helpers; using YLErp.Model; using YLErp.Modules.DataProviderModule; using YLErp.Modules.UnderlyingModule; using YLErp.Office.ExcelModule; namespace YLErp.Modules.RiskModule { public class RealtimePositionRisksQueryService : YLBaseService { public RealtimePositionRisksQueryService(OptUserInfo userInfo) : base(userInfo) { } public SearchListResult SearchList(RealTimePositionRisksReq req) { if (req?.IsParentTrade == true) { return SearchRealTimeOptionPostionRisksList(req); } else { return SearchRealTimePostionRisksList(req); } } /// /// 是否主交易 是 /// /// /// public SearchListResult SearchRealTimeOptionPostionRisksList(RealTimePositionRisksReq req) { var voltype = req?.VolType ?? string.Empty; var statusList = new List { ConsTrade.已到期, ConsTrade.已执行, ConsTrade.已平仓 }; var realtimePredicate = BuildPredicateOfRealTime(req); var tradePredicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2); if (req.UserAssets != null && req.UserClients != null) { tradePredicate = tradePredicate.And(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId)); } if (req.TraderIds != null && req.TraderIds.Any(x => x > 0)) { tradePredicate = tradePredicate.And(q => req.TraderIds.Contains(q.TraderId)); } if (req.TradeTypes != null && req.TradeTypes.Any(x => !string.IsNullOrWhiteSpace(x))) { tradePredicate = tradePredicate.And(d => req.TradeTypes.Contains(d.StructureType) || req.TradeTypes.Contains(d.TradeType) || (req.TradeTypes.Contains("黑箱结构") && d.IsGroup != 0)); } if (!string.IsNullOrWhiteSpace(req.TradeNumber)) { realtimePredicate = realtimePredicate.And(n => n.TradeId > 0); tradePredicate = tradePredicate.And(q => q.TradeNumber.Contains(req.TradeNumber)); } if (req.SettlementFlags != null && req.SettlementFlags.Any()) { tradePredicate = tradePredicate.And(d => req.SettlementFlags.Contains(d.SettlementFlag)); } if (!string.IsNullOrEmpty(req.GroupNames) && req.GroupNamesList != null && req.GroupNamesList.Count > 0) { var gname = req.GroupNamesList[0]; var groupNamePredicate = PredicateBuilder.Create(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname.ToString())); if (req.GroupNamesList.Count > 1) { for (int i = 1; i < req.GroupNamesList.Count; i++) { var gname1 = req.GroupNamesList[i]; groupNamePredicate = groupNamePredicate.Or(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname1.ToString())); } } tradePredicate = tradePredicate.And(groupNamePredicate); } 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; tradePredicate = tradePredicate.And(p => tradeTagIdQuery.Contains(p.id)); } var tradeList = new List { "收益互换", "远期", "掉期", "现金流交易" }; var query = from intradayTrade in DbContext.intraday_trade_position.Where(realtimePredicate) join trade in DbContext.trade.Where(tradePredicate) on intradayTrade.TradeId equals trade.id join tr in DbContext.trade_contract_r.Where(O => O.Type == "交易确认书" && O.IsValid) on trade.id equals tr.TradeId into trs from tr in trs.DefaultIfEmpty() join realtimeRisk in DbContext.realtime_trade_risk on intradayTrade.TradeId equals realtimeRisk.TradeId into realtimeRisk_t from realtimeRisk in realtimeRisk_t.DefaultIfEmpty() join assetUnit in DbContext.assetunit on trade.AssetId equals assetUnit.id into assetUnits from assetUnit in assetUnits.DefaultIfEmpty() join parentTrade in DbContext.trade.Where(tr => tr.ValidState != "InValid") on trade.ParentTradeId equals parentTrade.id into parentTrades from parentTrade in parentTrades.DefaultIfEmpty() join binary in DbContext.trade_binary_option on intradayTrade.TradeId equals binary.TradeId into binary_t from binary in binary_t.DefaultIfEmpty() join asian in DbContext.trade_asian_option on intradayTrade.TradeId equals asian.TradeId into asian_t from asian in asian_t.DefaultIfEmpty() join barrier in DbContext.trade_barrier_option on intradayTrade.TradeId equals barrier.TradeId into barrier_t from barrier in barrier_t.DefaultIfEmpty() join um in DbContext.underlying_manager on intradayTrade.UnderlyingCode equals um.UnderlyingCode into um_t from um in um_t.DefaultIfEmpty() where !statusList.Contains(intradayTrade.TradeStatus) && (!req.VarietyIds.Any() || um != null && req.VarietyIds.Contains(um.UnderlyingTypeId)) && (!req.UnderlyingIds.Any() || um != null && req.UnderlyingIds.Contains(um.id)) && !tradeList.Contains(intradayTrade.TradeType) && realtimeRisk.VolType == voltype select new RealTimePositionRisksDTO { GroupName = trade.GroupName, id = trade.id, OptionType = trade.OptionType, ClientName = trade.ClientName, TraderName = trade.TraderName, AssetBookName = assetUnit != null ? assetUnit.Name : null, CurrentVolatility = realtimeRisk.Vol, PositionPnl = intradayTrade != null ? intradayTrade.PositionPnL : 0,//浮动盈亏 RoundedPositionPnl = intradayTrade != null ? intradayTrade.RoundedPositionPnl : 0, PV = intradayTrade != null ? (double)intradayTrade.Pv : 0, RoundedPV = intradayTrade != null ? (double)intradayTrade.RoundedPv : 0, Vega = realtimeRisk.Vega, //实现盈亏 Theta = realtimeRisk.Theta, Rho = realtimeRisk.Rho, Delta = realtimeRisk.Delta, Gamma = realtimeRisk.Gamma, DeltaCash = realtimeRisk.DeltaCash, GammaCash = realtimeRisk.GammaCash, VegaCash = realtimeRisk.VegaCash, ExerciseDate = trade.ExerciseDate, ExerciseMode = trade.ExerciseMode, Notional = intradayTrade != null ? intradayTrade.Amount : 0, StockEqvNotionalMax = trade.StockEqvNotionalMax, OriginalStockEqvNotional = trade.OriginalStockEqvNotional, Strike = trade.Strike, IsMoneynessOption = trade.IsMoneynessOption, ExchangeOptionCode = intradayTrade != null ? intradayTrade.ExchangeOptionCode : "", IsUsePremiumRate = trade.IsUsePremiumRate, PremiumRate = trade.PremiumRate, TradeDate = trade.TradeDate, ParentTradeNumber = parentTrade != null ? parentTrade.TradeNumber : trade.TradeNumber, ContractCode = tr.ContractCode, TradeNumber = trade.TradeNumber, ParentTradeId = trade.ParentTradeId, TradePrice = trade.TradePrice, BuySell = trade.BuySell, TradeSinglePrice = trade.TradeSinglePrice, TradeType = trade.TradeType, StructureType = trade.StructureType != "结构化交易" ? trade.StructureType : null, UnderlyingCode = intradayTrade.UnderlyingCode, IsGroup = trade.IsGroup, Margin = intradayTrade != null ? intradayTrade.Margin : 0, Exposure = realtimeRisk.CreditExposure, RealizedPnl = realtimeRisk != null ? realtimeRisk.RealizedPnl.Value : 0, HedgeUniqueCode = intradayTrade != null ? intradayTrade.HedgeUniqueCode : "", OriginalPrincipalSum = trade.OriginalPrincipalSum, SurvivingNominalPrincipal = trade.SpotPrice * intradayTrade.Amount, UnderlyingPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0, CalSpotPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0, trade = trade, OptDate = realtimeRisk.OptDate }; query = query.OrderByDescending(O => O.id).ThenBy(O => O.ParentTradeNumber).ThenBy(O => O.TradeNumber); //所有子交易 var childTradeList = query.Where(n => n.ParentTradeId > 0).ToList(); //过滤掉所有子交易 //query = query.Where(n => n.ParentTradeId == 0); var searchResult = query.ToSearchList(req); var tcActions = new[] { ClientCashInCashOut.系统操作_平仓费, ClientCashInCashOut.系统操作_行权费,ClientCashInCashOut.系统操作_票息,ClientCashInCashOut.系统操作_互换,ClientCashInCashOut.人工操作_其他}; BLL.tradeBLL.SetFieldsByTradeType(searchResult.rows.Select(o => o.trade)); foreach (var r in searchResult.rows) { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode); if (um == null) { um = new underlying_manager(); } else { r.UnderlyingPrice = um.Price ?? 0; r.UnderlyingId = um.id; r.VarietyId = um.UnderlyingTypeId; r.UnderlyingAssetName = um.UnderlyingName; r.CountRatio = um.CountRatio; if (PS.Config.IsGuoJun) { r.UnderlyingVariety = UnderlyingHelper.GetUnderlyingVarietyCode(r.UnderlyingCode); } } if (r.IsGroup == 1 || r.TradeType == "结构化交易") { var cTrades = childTradeList.Where(n => n.ParentTradeId == r.id).ToList(); if (cTrades.Count() == 0) { var childTradeIds = DbContext.trade.Where(n => n.ParentTradeId == r.id).Select(n => n.id).ToList(); cTrades = (from childRealTimeRisk in DbContext.realtime_trade_risk join childIntradayTrade in DbContext.intraday_trade_position on childRealTimeRisk.TradeId equals childIntradayTrade.TradeId where childTradeIds.Contains(childRealTimeRisk.TradeId.Value) select new RealTimePositionRisksDTO { PV = childRealTimeRisk.Pv, RoundedPV = childRealTimeRisk.RoundedPv, PositionPnl = childRealTimeRisk.PositionPnl, RoundedPositionPnl = childRealTimeRisk.RoundedPositionPnl, RealizedPnl = childRealTimeRisk.RealizedPnl ?? 0, Margin = childIntradayTrade.Margin, Delta = childRealTimeRisk.Delta, Gamma = childRealTimeRisk.Gamma, Vega = childRealTimeRisk.Vega, Theta = childRealTimeRisk.Theta, Rho = childRealTimeRisk.Rho, }).ToList(); } r.PV = cTrades.Sum(y => y.PV); r.RoundedPV = cTrades.Sum(y => y.RoundedPV); r.PositionPnl = cTrades.Sum(y => y.PositionPnl); r.RoundedPositionPnl = cTrades.Sum(y => y.RoundedPositionPnl); r.RealizedPnl = cTrades.Sum(n => n.RealizedPnl); r.Margin = cTrades.Sum(y => y.Margin); r.Delta = cTrades.Sum(y => y.Delta); r.Gamma = cTrades.Sum(y => y.Gamma); r.Vega = cTrades.Sum(y => y.Vega); r.Theta = cTrades.Sum(y => y.Theta); r.Rho = cTrades.Sum(y => y.Rho); r.RiskFreeRate = r.trade?.NoRiskRate ?? valuedateBLL.RiskFreeRate / 100; r.DividendRate = r.trade?.DividendRate ?? r.RiskFreeRate; r.OriginalNotional = r.trade?.OriginalNotional; r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio; r.TradeStatus = r.trade?.TradeStatus; r.StockEqvNotional = r.trade?.StockEqvNotional; r.InitialSpotPrice = r.trade?.SpotPrice; r.etcTradePrice = r.TradePrice * (r.trade == null ? r.Notional / r.OriginalNotional : r.trade?.StockEqvNotional / r.trade?.OriginalStockEqvNotional); r.SinglePV = TradeHelper.GetTradeSinglePriceByTradePrice(PS.Config.IsPVRounded ? r.RoundedPV : r.PV, r.Notional , PS.Config.ErpElement.IsPVIncludePrincipal ? r.trade.PrincipalSum() : 0, r.trade.BuySell, r.trade.TradeType, false); if (um != null) { r.GammaLots = (r.Gamma ?? 0) / um.ContractSize; r.DeltaLots = (r.Delta ?? 0) / um.ContractSize; } } else { r.RiskFreeRate = r.trade?.NoRiskRate ?? valuedateBLL.RiskFreeRate / 100; r.DividendRate = r.trade?.DividendRate ?? r.RiskFreeRate; r.OriginalNotional = r.trade?.OriginalNotional; r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio; r.TradeStatus = r.trade?.TradeStatus; r.StockEqvNotional = r.trade?.StockEqvNotional; r.InitialSpotPrice = r.trade?.SpotPrice; r.etcTradePrice = r.TradePrice * (r.trade == null ? r.Notional / r.OriginalNotional : r.trade?.StockEqvNotional / r.trade?.OriginalStockEqvNotional); r.SinglePV = TradeHelper.GetTradeSinglePriceByTradePrice(PS.Config.IsPVRounded ? r.RoundedPV : r.PV, r.Notional , PS.Config.ErpElement.IsPVIncludePrincipal ? r.trade.PrincipalSum() : 0, r.trade.BuySell, r.trade.TradeType, false); if (um != null) { r.GammaLots = (r.Gamma ?? 0) / um.ContractSize; r.DeltaLots = (r.Delta ?? 0) / um.ContractSize; } } if (r.ParentTradeId > 0) { var childTrades = DbContext.trade.Where(x => x.ParentTradeId == r.ParentTradeId).OrderBy(x => x.TradeNumber).Select(x => x.id).ToList(); r.ChildLeg = (childTrades.IndexOf(r.id) + 1).ToString(); } r.ClientNumber = DataCacheProvider.GetClientDataSource().GetData(r.trade.ClientId)?.Number; switch (r.TradeType) { case "雪球期权": r.KnockInOutStatus = r.trade?.trade_snowball.KnockInOutStatusCn; break; case "凤凰期权": r.KnockInOutStatus = r.trade?.trade_autocall.KnockInOutStatusCn; break; case "双鲨期权": r.KnockInOutStatus = r.trade?.trade_double_sharkfin_option.KnockInOutStatusCn; break; case "障碍期权": r.KnockInOutStatus = r.trade?.trade_barrier_option.KnockInOutStatusCn; break; case "气囊结构": r.KnockInOutStatus = r.trade?.trade_airbag.KnockInOutStatusCn; break; case "累计期权": r.Strike = r.trade?.Strike; var settleMode = DbContext.autocall_observation.Where(n => n.TradeId == r.id && n.EndDate <= req.ValueDate) .OrderByDescending(n => n.EndDate).Select(n => n.SettlementMode).FirstOrDefault(); r.KnockInOutStatus = settleMode == "敲出" ? "敲出" : "观察中"; break; } r.Rho *= 100; } if (searchResult.rows.Count() > 0) { searchResult.Msg = searchResult.rows.FirstOrDefault().OptDate?.ToString("yyyy-MM-dd HH:mm:ss"); } return searchResult; } /// /// 是否主交易 否 /// /// /// public SearchListResult SearchRealTimePostionRisksList(RealTimePositionRisksReq req) { var voltype = req?.VolType ?? string.Empty; var statusList = new List { ConsTrade.已到期, ConsTrade.已执行, ConsTrade.已平仓 }; var realtimePredicate = BuildPredicateOfRealTime(req); var tradePredicate = PredicateBuilder.Create(t => t.ValidState != "InValid" && t.TradeType != "结构化交易" && t.IsGroup != 1); if (req.UserAssets != null && req.UserClients != null) { tradePredicate = tradePredicate.And(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId)); } if (req.TraderIds != null && req.TraderIds.Any(x => x > 0)) { tradePredicate = tradePredicate.And(q => req.TraderIds.Contains(q.TraderId)); } if (req.TradeTypes != null && req.TradeTypes.Any(x => !string.IsNullOrWhiteSpace(x))) { tradePredicate = tradePredicate.And(d => req.TradeTypes.Contains(d.StructureType) || req.TradeTypes.Contains(d.TradeType) || (req.TradeTypes.Contains("黑箱结构") && d.IsGroup != 0)); } if (!string.IsNullOrWhiteSpace(req.TradeNumber)) { realtimePredicate = realtimePredicate.And(n => n.TradeId > 0); tradePredicate = tradePredicate.And(q => q.TradeNumber.Contains(req.TradeNumber)); } if (req.SettlementFlags != null && req.SettlementFlags.Any()) { tradePredicate = tradePredicate.And(d => req.SettlementFlags.Contains(d.SettlementFlag)); } if (!string.IsNullOrEmpty(req.GroupNames) && req.GroupNamesList != null && req.GroupNamesList.Count > 0) { var gname = req.GroupNamesList[0]; var groupNamePredicate = PredicateBuilder.Create(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname.ToString())); if (req.GroupNamesList.Count > 1) { for (int i = 1; i < req.GroupNamesList.Count; i++) { var gname1 = req.GroupNamesList[i]; groupNamePredicate = groupNamePredicate.Or(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname1.ToString())); } } tradePredicate = tradePredicate.And(groupNamePredicate); } 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; tradePredicate = tradePredicate.And(p => tradeTagIdQuery.Contains(p.id)); } var tradeList = new List { "收益互换", "远期", "掉期", "现金流交易" }; var query = from intradayTrade in DbContext.intraday_trade_position.Where(realtimePredicate) join trade in DbContext.trade.Where(tradePredicate) on intradayTrade.TradeId equals trade.id join tr in DbContext.trade_contract_r.Where(O => O.Type == "交易确认书" && O.IsValid) on trade.id equals tr.TradeId into trs from tr in trs.DefaultIfEmpty() join realtimeRisk in DbContext.realtime_trade_risk on intradayTrade.TradeId equals realtimeRisk.TradeId into realtimeRisk_t from realtimeRisk in realtimeRisk_t.DefaultIfEmpty() join assetUnit in DbContext.assetunit on trade.AssetId equals assetUnit.id into assetUnits from assetUnit in assetUnits.DefaultIfEmpty() join parentTrade in DbContext.trade.Where(tr => tr.ValidState != "InValid") on trade.ParentTradeId equals parentTrade.id into parentTrades from parentTrade in parentTrades.DefaultIfEmpty() join binary in DbContext.trade_binary_option on intradayTrade.TradeId equals binary.TradeId into binary_t from binary in binary_t.DefaultIfEmpty() join asian in DbContext.trade_asian_option on intradayTrade.TradeId equals asian.TradeId into asian_t from asian in asian_t.DefaultIfEmpty() join barrier in DbContext.trade_barrier_option on intradayTrade.TradeId equals barrier.TradeId into barrier_t from barrier in barrier_t.DefaultIfEmpty() join um in DbContext.underlying_manager on intradayTrade.UnderlyingCode equals um.UnderlyingCode into um_t from um in um_t.DefaultIfEmpty() where !statusList.Contains(intradayTrade.TradeStatus) && (!req.VarietyIds.Any() || um != null && req.VarietyIds.Contains(um.UnderlyingTypeId)) && (!req.UnderlyingIds.Any() || um != null && req.UnderlyingIds.Contains(um.id)) && !tradeList.Contains(intradayTrade.TradeType) && realtimeRisk.VolType == voltype select new RealTimePositionRisksDTO { GroupName = trade.GroupName, id = trade.id, OptionType = trade.OptionType, ClientName = trade.ClientName, TraderName = trade.TraderName, AssetBookName = assetUnit != null ? assetUnit.Name : null, CurrentVolatility = realtimeRisk.Vol, PositionPnl = intradayTrade != null ? intradayTrade.PositionPnL : 0,//浮动盈亏 RoundedPositionPnl = intradayTrade != null ? intradayTrade.RoundedPositionPnl : 0, PV = intradayTrade != null ? (double)intradayTrade.Pv : 0, RoundedPV = intradayTrade != null ? (double)intradayTrade.RoundedPv : 0, Vega = realtimeRisk.Vega, //实现盈亏 Theta = realtimeRisk.Theta, Rho = realtimeRisk.Rho, Delta = realtimeRisk.Delta, Gamma = realtimeRisk.Gamma, DeltaCash = realtimeRisk.DeltaCash, GammaCash = realtimeRisk.GammaCash, VegaCash = realtimeRisk.VegaCash, ExerciseDate = trade.ExerciseDate, ExerciseMode = trade.ExerciseMode, Notional = intradayTrade != null ? intradayTrade.Amount : 0, StockEqvNotionalMax = trade.StockEqvNotionalMax, OriginalStockEqvNotional = trade.OriginalStockEqvNotional, Strike = trade.Strike, IsMoneynessOption = trade.IsMoneynessOption, ExchangeOptionCode = intradayTrade != null ? intradayTrade.ExchangeOptionCode : "", IsUsePremiumRate = trade.IsUsePremiumRate, PremiumRate = trade.PremiumRate, TradeDate = trade.TradeDate, ParentTradeNumber = parentTrade != null ? parentTrade.TradeNumber : trade.TradeNumber, ContractCode = tr.ContractCode, TradeNumber = trade.TradeNumber, ParentTradeId = trade.ParentTradeId, TradePrice = trade.TradePrice, BuySell = trade.BuySell, TradeSinglePrice = trade.TradeSinglePrice, TradeType = trade.TradeType, StructureType = trade.TradeType == "自定义交易" ? trade.StructureType : trade.TradeType, UnderlyingCode = intradayTrade.UnderlyingCode, IsGroup = trade.IsGroup, Margin = intradayTrade != null ? intradayTrade.Margin : 0, Exposure = realtimeRisk.CreditExposure, RealizedPnl = realtimeRisk != null ? realtimeRisk.RealizedPnl.Value : 0, HedgeUniqueCode = intradayTrade != null ? intradayTrade.HedgeUniqueCode : "", OriginalPrincipalSum = trade.OriginalPrincipalSum, SurvivingNominalPrincipal = trade.SpotPrice * intradayTrade.Amount, UnderlyingPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0, CalSpotPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0, trade = trade, OptDate = realtimeRisk.OptDate }; query = query.OrderByDescending(O => O.id).ThenBy(O => O.ParentTradeNumber).ThenBy(O => O.TradeNumber); var searchResult = query.ToSearchList(req); var tcActions = new[] { ClientCashInCashOut.系统操作_平仓费, ClientCashInCashOut.系统操作_行权费,ClientCashInCashOut.系统操作_票息,ClientCashInCashOut.系统操作_互换,ClientCashInCashOut.人工操作_其他}; BLL.tradeBLL.SetFieldsByTradeType(searchResult.rows.Select(o => o.trade)); foreach (var r in searchResult.rows) { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode); if (um == null) { um = new underlying_manager(); } else { r.UnderlyingPrice = um.Price ?? 0; r.UnderlyingId = um.id; r.VarietyId = um.UnderlyingTypeId; r.UnderlyingAssetName = um.UnderlyingName; r.CountRatio = um.CountRatio; if (PS.Config.IsGuoJun) { r.UnderlyingVariety = UnderlyingHelper.GetUnderlyingVarietyCode(r.UnderlyingCode); } } r.RiskFreeRate = r.trade?.NoRiskRate ?? valuedateBLL.RiskFreeRate / 100; r.DividendRate = r.trade?.DividendRate ?? r.RiskFreeRate; r.OriginalNotional = r.trade?.OriginalNotional; r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio; r.TradeStatus = r.trade?.TradeStatus; r.StockEqvNotional = r.trade?.StockEqvNotional; r.InitialSpotPrice = r.trade?.SpotPrice; switch (r.TradeType) { case "雪球期权": r.KnockInOutStatus = r.trade?.trade_snowball.KnockInOutStatusCn; break; case "凤凰期权": r.KnockInOutStatus = r.trade?.trade_autocall.KnockInOutStatusCn; break; case "双鲨期权": r.KnockInOutStatus = r.trade?.trade_double_sharkfin_option.KnockInOutStatusCn; break; case "障碍期权": r.KnockInOutStatus = r.trade?.trade_barrier_option.KnockInOutStatusCn; break; case "气囊结构": r.KnockInOutStatus = r.trade?.trade_airbag.KnockInOutStatusCn; break; case "累计期权": r.Strike = r.trade?.Strike; var settleMode = DbContext.autocall_observation.Where(n => n.TradeId == r.id && n.EndDate <= req.ValueDate) .OrderByDescending(n => n.EndDate).Select(n => n.SettlementMode).FirstOrDefault(); r.KnockInOutStatus = settleMode == "敲出" ? "敲出" : "观察中"; break; } r.etcTradePrice = r.TradePrice * (r.trade == null ? r.Notional / r.OriginalNotional : r.trade?.StockEqvNotional / r.trade?.OriginalStockEqvNotional); if (r.trade != null) { r.SinglePV = TradeHelper.GetTradeSinglePriceByTradePrice(PS.Config.IsPVRounded ? r.RoundedPV : r.PV, r.Notional , PS.Config.ErpElement.IsPVIncludePrincipal ? r.trade.PrincipalSum() : 0, r.trade.BuySell, r.trade.TradeType, false); } if (r.trade != null) { r.ClientNumber = DataCacheProvider.GetClientDataSource().GetData(r.trade.ClientId)?.Number; } if (r.trade != null && r.trade.IsGroup == 1) { var eodtrade = DbContext.eod_trade.Where(x => x.ValueDate == req.ValueDate && x.ParentTradeId == r.id && ConsTrade.LiveTradeStatusList.Contains(x.TradeStatus)).ToList(); r.etcTradePrice = eodtrade.Select(x => (x.trade.BuySell == "买入" ? -1 : 1) * x.trade.TradePrice * x.trade.StockEqvNotional / x.trade.OriginalStockEqvNotional).Sum(); } if (r.ParentTradeId > 0) { var childTrades = DbContext.trade.Where(x => x.ParentTradeId == r.ParentTradeId).OrderBy(x => x.TradeNumber).Select(x => x.id).ToList(); r.ChildLeg = (childTrades.IndexOf(r.id) + 1).ToString(); } if (um != null) { r.GammaLots = (r.Gamma ?? 0) / um.ContractSize; r.DeltaLots = (r.Delta ?? 0) / um.ContractSize; } r.Rho *= 100; } if (searchResult.rows.Count() > 0) { searchResult.Msg = searchResult.rows.FirstOrDefault().OptDate?.ToString("yyyy-MM-dd HH:mm:ss"); } return searchResult; } public Expression> BuildPredicateOfRealTime(RealTimePositionRisksReq reqModel) { var predicate = PredicateBuilder.Create(t => t.ValueDate == valuedateBLL.ValueDate); if (reqModel.UserAssets != null || reqModel.UserClients != null) { predicate = predicate.And(t => reqModel.UserAssets.Contains(t.BookId) || reqModel.UserClients.Contains(t.ClientId)); } if (reqModel.ClientIds != null && reqModel.ClientIds.Any(x => x > 0)) { predicate = predicate.And(q => reqModel.ClientIds.Contains(q.ClientId)); } if (reqModel.BookIds != null && reqModel.BookIds.Any(x => x > 0)) { predicate = predicate.And(q => reqModel.BookIds.Contains(q.BookId)); } if (reqModel.TradeIds != null && reqModel.TradeIds.Any(x => x != 0)) { predicate = predicate.And(q => reqModel.TradeIds.Contains(q.TradeId)); } reqModel.VarietyIds = reqModel.VarietyIds == null ? Enumerable.Empty() : reqModel.VarietyIds.Where(n => n > 0).ToArray(); reqModel.UnderlyingIds = reqModel.UnderlyingIds == null ? Enumerable.Empty() : reqModel.UnderlyingIds.Where(n => n > 0).ToArray(); reqModel.SettlementFlags = reqModel.SettlementFlags == null ? Enumerable.Empty() : reqModel.SettlementFlags.ToArray(); return predicate; } public byte[] ExportRealtimePositionRisksToExcel(RealTimePositionRisksReq req) { var results = GettRealtimePositionRisksDataHandle(req); var list2 = results.Select(n => new ExpandoDictionary(n)).ToArray(); var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/实时持仓风险.xlsx"); return ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = list2 }).GenerateBytes(); } public List> GettRealtimePositionRisksDataHandle(RealTimePositionRisksReq req) { if (req.TradeIds == null || !req.TradeIds.Any()) { req.page = 0; req.rows = 10000; } req.IsOnlyExport = true; IEnumerable sList = null; sList = SearchList(req).rows; if (sList == null || sList.Count() == 0) { throw new ServiceException("没有可导出的数据"); } var isPvRounded = PS.Config.IsPVRounded; var results = new List>(sList.Count()); foreach (var item in sList) { var dic = new Dictionary(); if (string.IsNullOrWhiteSpace(item.UnderlyingCode)) { item.DeltaLots = 0; item.GammaLots = 0; } dic.Add("交易编号", item.TradeNumber); dic.Add("分组名", item.GroupName); dic.Add("确认书编号", item.ContractCode); dic.Add("期权代码", item.ExchangeOptionCode); dic.Add("多腿编号", item.ChildLeg); dic.Add("浮动盈亏", (isPvRounded ? item.RoundedPositionPnl : item.PositionPnl).OtcFormatMoney()); dic.Add("实现盈亏", item.RealizedPnl.OtcFormatMoney()); dic.Add("TraderName", item.TraderName); dic.Add("当前波动率", item.CurrentVolatility.OtcFormatFlex(2, 2, percent: true)); dic.Add("Delta", OtcFormatExtensions.OtcFormat(item.Delta, OtcFormatFlag.greek)); dic.Add("Delta手数", OtcFormatExtensions.OtcFormat(item.DeltaLots, OtcFormatFlag.notional)); dic.Add("Gamma", OtcFormatExtensions.OtcFormat(item.Gamma, OtcFormatFlag.greek)); dic.Add("Gamma手数", OtcFormatExtensions.OtcFormat(item.GammaLots, OtcFormatFlag.notional)); dic.Add("Theta", OtcFormatExtensions.OtcFormat(item.Theta, OtcFormatFlag.greek)); dic.Add("Rho", OtcFormatExtensions.OtcFormat(item.Rho, OtcFormatFlag.greek)); dic.Add("Vega", OtcFormatExtensions.OtcFormat(item.Vega, OtcFormatFlag.greek)); dic.Add("到期日期", item.ExerciseDate.OtcFormatDate()); dic.Add("行权方式", TradeHelper.GetExerciseModeCn(item.ExerciseMode)); dic.Add("结构类型", item.StructureType); dic.Add("观察状态", item.KnockInOutStatus); dic.Add("交易对手方", item.ClientName); dic.Add("交易对手编号", item.ClientNumber); dic.Add("簿记账户", item.AssetBookName); dic.Add("成交日期", item.TradeDate.OtcFormatDate()); dic.Add("看涨看跌", item.OptionType); dic.Add("买卖方向", item.BuySell); dic.Add("标的代码", item.UnderlyingCode); dic.Add("标的品种", item.UnderlyingVariety); dic.Add("标的名称", item.UnderlyingAssetName); dic.Add("期初标的价格", item.InitialSpotPrice.OtcFormatUmPrice()); dic.Add("保底收益总额", item.OriginalPrincipalSum.OtcFormatUmPrice()); if (item.TradeType == "自定义交易") { dic.Add("执行价格", string.Empty); } else { dic.Add("执行价格", item.Strike.OtcFormatUmPrice(item.IsMoneynessOption == "是")); } if (item.IsUsePremiumRate == true) { dic.Add("权利金成交", item.PremiumRate.OtcFormat(OtcFormatFlag.premiumRateP)); } else { dic.Add("权利金成交", (item.TradeSinglePrice ?? 0).OtcFormat(OtcFormatFlag.tradeSinglePrice)); } var tradeOriginalAmount = PS.Config.IsUseDisplayNotional ? Math.Abs((item.TradeOriginalAmount ?? 0) * (item.CountRatio ?? 1)) : Math.Abs(item.TradeOriginalAmount ?? 0); var strTradeOriginalAmount = tradeOriginalAmount.OtcFormatNotional(); dic.Add("有效成交数量", strTradeOriginalAmount); if (item.trade != null) { strTradeOriginalAmount = Math.Abs(CalculationModule.TradeCalcHelper.GetTradeAmountV(item.trade, tradeOriginalAmount, 1)).OtcFormatNotional(); } dic.Add("成交数量", strTradeOriginalAmount); var tradeDirection = item.BuySell == "买入" || item.BuySell == "多头开仓" || item.BuySell == "空头开仓" ? -1 : 1; dic.Add("成交金额", (item.TradePrice * tradeDirection).OtcFormatMoney()); dic.Add("存续成本", (item.IsGroup == 1 ? item.etcTradePrice : item.etcTradePrice * tradeDirection).OtcFormatMoney()); dic.Add("名义本金", item.StockEqvNotionalToShow.OtcFormat(OtcFormatFlag.StockEqvNotional)); dic.Add("存续名义本金", item.SurvivingNominalPrincipal.OtcFormat(OtcFormatFlag.StockEqvNotional)); dic.Add("最新标的价格", item.UnderlyingPrice.OtcFormatUmPrice()); dic.Add("无风险利率", item.RiskFreeRate.OtcFormatFlex(2, 2, percent: true)); dic.Add("分红率", item.DividendRate.OtcFormatFlex(2, 2, percent: true)); if (item.IsUsePremiumRate == true) { var dd = TradeHelper.GetPremiumRateByTradeSinglePrice(item.SinglePV, item.InitialSpotPrice); dic.Add("权利金存续", dd.OtcFormat(OtcFormatFlag.premiumRateP)); } else { dic.Add("权利金存续", item.SinglePV.HasValue ? Convert.ToDouble(item.SinglePV.Value).OtcFormat(OtcFormatFlag.tradePrice) : ""); } var tradeAmount = PS.Config.IsUseDisplayNotional ? Math.Abs((item.TradeAmount * (item.CountRatio ?? 1)) ?? 0) : Math.Abs(item.TradeAmount ?? 0); var strTradeAmount = tradeAmount.OtcFormatNotional(); dic.Add("有效存续数量", strTradeAmount); if (item.trade != null) { strTradeAmount = Math.Abs(CalculationModule.TradeCalcHelper.GetTradeAmountV(item.trade, tradeAmount, 1)).OtcFormatNotional(); } dic.Add("存续数量", strTradeAmount); var pv = Convert.ToDouble((isPvRounded ? item.RoundedPV : item.PV) ?? 0); dic.Add("存续市值", pv.OtcFormatMoney()); dic.Add("计算标的价格", item.CalSpotPrice.OtcFormatMoney()); dic.Add("维持预付金", item.Margin.OtcFormatMoney()); results.Add(dic); } return results; } } }