using BaseOUDAL; using Org.BouncyCastle.Ocsp; using YLErp.Commons; using YLErp.Configuration; using YLErp.DBModels.Consts; using YLErp.Helpers; using YLErp.Model; using YLErp.Modules.SuperviseReportModule.CFMMC.Model; using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData; namespace YLErp.Modules.SuperviseReportModule.CFMMC.Service { /// /// 日监管报告服务 /// public class SuperviseReportTodayService : SuperviseReportBaseService { public SuperviseReportTodayService(SuperviseReportReq req, OptUserInfo userInfo) : base(req, userInfo) { } private SearchListResult ReportQuery(SuperviseReportReq req) { var config = DbContext.valuedate.FirstOrDefault(x => x.State == valuedate.当前使用); var commodityList = new List { ConsGlobal.InstrumentType.CommodityFutures, ConsGlobal.InstrumentType.CommoditySpot }; var umQuery = DbContext.underlying_manager.AsQueryable(); switch (req.DataSource) { case "权益": umQuery = umQuery.Where(O => !commodityList.Contains(O.UnderlyingInstrumentType)); break; case "商品": umQuery = umQuery.Where(O => commodityList.Contains(O.UnderlyingInstrumentType)); break; case "全量": default: break; } var action = new List() { "系统操作-期权费", "系统操作-平仓费", "系统操作-行权费", }; var insidedClientIds = DataCacheProvider.GetClientDataSource().AsQueryable().Where(O => O.IsInsided == 1).Select(O => O.id).ToList(); var query = from tradeCash in (from tCash in DbContext.trade_cash where ((tCash.HappenedDate != null && tCash.HappenedDate == req.ValueDate) || (tCash.HappenedDate == null && tCash.ValueDate == req.ValueDate)) && (action.Contains(tCash.Action) || tCash.IsLastAction) && tCash.ValidState != ConsGlobal.InValid && !tCash.IsDeleted select tCash) join eodTrade in (from et in DbContext.eod_trade where et.ValueDate == req.ValueDate select et) on tradeCash.TradeId equals eodTrade.TradeId join trade in (from t in DbContext.trade where t.ValidState != "InValid" && (t.TradeType.Contains("期权") || t.TradeType == "远期" || t.TradeType == "收益互换" || t.TradeType == "自定义交易" || t.TradeType == "气囊结构" || t.IsGroup == 1) && t.IsGroup != 2 && t.TradeType != "场内期权" && t.TradeType != "现金流交易" select t) on tradeCash.TradeId equals trade.id join um in umQuery on trade.UnderlyingCode equals um.UnderlyingCode join er in (from tempEr in DbContext.eod_trade_risk where tempEr.ValueDate == req.ValueDate select tempEr) on tradeCash.TradeId equals er.TradeId into tempEr from er in tempEr.DefaultIfEmpty() join parentTrade in (from tr in DbContext.trade where tr.ValidState != "InValid" && tr.TradeType == "结构化交易" select tr) on trade.ParentTradeId equals parentTrade.id into parentTrades from tempParentTrade in parentTrades.DefaultIfEmpty() join eodPnl in (from ep in DbContext.eod_trade_position where ep.ValueDate == req.ValueDate select ep) on trade.id equals eodPnl.TradeId into eodP from tempEodPnl in eodP.DefaultIfEmpty() join tradeSpan in (from ts in DbContext.trade_span where ts.ValueDate == req.ValueDate select ts) on trade.id equals tradeSpan.TradeId into tradeS from tempTradeSpan in tradeS.DefaultIfEmpty() join credit in (from c in DbContext.credit where c.ProcessStatus == "已审批" && (!c.CreditDeadLine.HasValue || c.CreditDeadLine >= req.ValueDate) && (!c.CreditStartDate.HasValue || c.CreditStartDate <= req.ValueDate) select c) on trade.ClientId equals credit.ClientId into credits from tempCredit in credits.DefaultIfEmpty() join binaryOpt in DbContext.trade_binary_option on eodTrade.TradeId equals binaryOpt.TradeId into bo from binaryOpt in bo.DefaultIfEmpty() join cPrice in DbContext.eod_commodity_future_price.Where(O => O.ValueDate == req.ValueDate) on trade.UnderlyingCode equals cPrice.UnderlyingCode into tempCPrice from cPrice in tempCPrice.DefaultIfEmpty() join sPrice in DbContext.eod_stock_price.Where(O => O.ValueDate == req.ValueDate) on trade.UnderlyingCode equals sPrice.UnderlyingCode into tempSPrice from sPrice in tempSPrice.DefaultIfEmpty() where !insidedClientIds.Contains(trade.ClientId) select new SuperviseReportTodayModel { GroupPercentTradeId = trade.IsGroup == 1 ? trade.id : 0, TradeJson = eodTrade.TradeJson, originalTrade = null, ClosePrice = cPrice != null ? cPrice.ClosePrice : (sPrice != null ? sPrice.ClosePrice : 0), TradeSpan_WorstCastClientPayable = tempTradeSpan == null ? null : (tempTradeSpan.WorstCastClientPayable == null ? 0 : tempTradeSpan.WorstCastClientPayable), //OriginalVarietyCode = variety.VarietyCode, UnwindPercentRate = tradeCash.UnwindPercentRate, OriginalTradeNumber = eodTrade == null ? trade.TradeNumber : eodTrade.TradeNumber, TradeCashId = tradeCash.id, MainName = config.SuperviseMainName, MainCode = config.SuperviseMainCode, ClientId = trade.ClientId, //ClientName = client.Name, //ClientLicenseCode = client.LicenseCode, //ProtocalType = client.ProtocolSignVersion, //ProtocolSignDate = client.ProtocolSignDate, TradeDate = tradeCash.ValueDate, IsCredit = tempCredit != null ? "Y" : "N", Credit = tempCredit != null ? (tempCredit.Credit ?? 0) : 0, OperationType = tradeCash.Action == "系统操作-行权费" ? "ED" : (tradeCash.Action == "系统操作-期权费" ? "NT" : (tradeCash.UnwindType != null && tradeCash.UnwindType.StartsWith("部分") && !tradeCash.IsLastAction ? "PU" : "FU")), RealExerciseDate = tradeCash.ExerciseWay == "到期行权" ? (DateTime?)tradeCash.ValueDate : null, UnWindDate = tradeCash.ExerciseWay != "到期行权" && tradeCash.Action != "系统操作-期权费" ? (DateTime?)tradeCash.ValueDate : null, TradeType = tempParentTrade == null ? trade.TradeType : tempParentTrade.TradeType, TradePrice = tradeCash.Amount, StructureType = tempParentTrade == null ? trade.StructureType : tempParentTrade.StructureType, PayoffType = binaryOpt != null ? binaryOpt.PayoffType : "", TradeStatus = eodTrade.TradeStatus, PriceSymbol = 1, QuoteCurrency = "CNY", ForeignCurrencyRate = null, Pv = tradeCash.Action != "系统操作-期权费" ? (double)(tempEodPnl == null ? 0 : tempEodPnl.Pv) : (tradeCash != null ? tradeCash.Amount : 0), ParticipateRate = 1, ValuationMethod = "O", SettlementMethod = tradeCash.Action == "系统操作-期权费" ? "" : "C", LastUnWindDate = tradeCash.Action == "系统操作-期权费" ? null : trade.UnWindDate, SettlementPriceType = tradeCash.Action == "系统操作-期权费" ? null : (int?)9, FixedPrice = null, ReferencePrice = tradeCash.Action != "系统操作-期权费" ? tradeCash.FinalPrice ?? 0 : (Nullable)null, TradeId = trade.id, ContractCode = tempParentTrade != null ? tempParentTrade.TradeNumber : trade.TradeNumber, IsAnnualTrade = "N", _deltaCash = er != null ? (er.Delta * trade.SpotPrice) : 0, //UnRealizedPnL = tempEodPnl.UnRealizedPnL }; query = query.OrderByDescending(O => O.TradeStatus).ThenBy(n => n.ContractCode).ThenBy(n => n.OriginalTradeNumber); var retListResult = query.ToSearchList(_req, false); var groupTradeList = retListResult.rows.Where(O => O.GroupPercentTradeId > 0); var tradeIds = groupTradeList.Select(O => O.GroupPercentTradeId); var exInfoDict = (from t in DbContext.trade join tc in DbContext.trade_cash on t.id equals tc.TradeId join ts in DbContext.trade_span on new { TradeId = t.id, req.ValueDate } equals new { ts.TradeId, ts.ValueDate } into tempTs from ts in tempTs.DefaultIfEmpty() join ep in DbContext.eod_trade_position on new { TradeId = t.id, req.ValueDate } equals new { ep.TradeId, ep.ValueDate } into tempEp from ep in tempEp.DefaultIfEmpty() join er in DbContext.eod_trade_risk on new { TradeId = t.id, req.ValueDate } equals new { er.TradeId, er.ValueDate } into tempEr from er in tempEr.DefaultIfEmpty() join binaryOption in DbContext.trade_binary_option on t.id equals binaryOption.TradeId into tempBo from binaryOption in tempBo.DefaultIfEmpty() where tradeIds.Contains(t.ParentTradeId) && t.ValidState != "InValid" && (t.TradeType.Contains("期权") || t.TradeType == "远期" || t.TradeType == "气囊结构" || t.TradeType == "收益互换" || t.TradeType == "自定义交易") && t.TradeType != "场内期权" && t.TradeType != "现金流交易" && ((tc.HappenedDate != null && tc.HappenedDate == req.ValueDate) || (tc.HappenedDate == null && tc.ValueDate == req.ValueDate)) && (action.Contains(tc.Action) || tc.IsLastAction) && tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted select new { t.ParentTradeId, WorstCastClientPayable = ts == null ? null : (ts.WorstCastClientPayable == null ? 0 : ts.WorstCastClientPayable), PayoffType = binaryOption != null ? binaryOption.PayoffType : "", Pv = tc.Action != "系统操作-期权费" ? (double)(ep == null ? 0 : ep.Pv) : (tc != null ? tc.Amount : 0), DeltaCash = er.Delta * t.SpotPrice }).AsEnumerable() .GroupBy(O => O.ParentTradeId).ToDictionary(K => K.Key, V => V.ToList()); foreach (var item in retListResult.rows) { if (exInfoDict.TryGetValue(item.GroupPercentTradeId, out var info)) { item.TradeSpan_WorstCastClientPayable = info.Sum(O => O.WorstCastClientPayable); item.PayoffType = info.FirstOrDefault()?.PayoffType; item.Pv = info.Sum(O => O.Pv); item._deltaCash = info.Sum(O => O.DeltaCash); } item.DeltaCash = item._deltaCash.OtcFormat(OtcFormatFlag.greek); } return retListResult; } public SearchListResult SearchReportList() { var retListResult = ReportQuery(_req); using (var basedb = new ErpBaseContext()) { var marketCode = _isEquity ? "权益监管市场代码" : "监管市场代码"; var protocalTyp = _isEquity ? "权益类签署版本" : "协议签署版本"; var tcIdArr = retListResult.rows.Select(O => O.TradeCashId); var clientIdArr = retListResult.rows.Select(O => O.ClientId).ToHashSet(); var varietyTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "品种类型" select i).ToList(); var assetTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "资产类型" select i).ToList(); var marketNoList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == marketCode select i).ToList(); var varietySuffixList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "标的资产后缀" select i).ToList(); var protocalTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == protocalTyp select i).ToDictionary(K => K.Name, V => V.ShortName); var varietyCodeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "标的对应资产品种" select i).ToList(); var clientMetaQuery = DbContextFactory.GetClientDbContext(UserInfo).ClientMeta.Where(O => clientIdArr.Contains(O.ClientId)); var clientEquityInfo = clientMetaQuery.Where(O => O.MetaKey == "RightProtocolSignVersion").ToDictionary(K => K.ClientId, V => V.MetaValue); var clientReportInfo = clientMetaQuery.Where(O => O.MetaKey == "ReportName").ToDictionary(K => K.ClientId, V => V.MetaValue); Dictionary tcRinfos = new Dictionary(); var tmInfos = new Dictionary(); switch (PS.Config.Company) { case Configuration.CompanyEnum.上期资本: case Configuration.CompanyEnum.长江: tcRinfos = DbContext.trade_contract_r.Where(O => tcIdArr.Contains(O.TradeCashId ?? 0) && O.IsValid).Select(O => new { TradeCashId = (O.TradeCashId ?? 0), O.ContractCode }).AsEnumerable().GroupBy(O => O.TradeCashId).ToDictionary(K => K.Key, V => V.First().ContractCode); break; case Configuration.CompanyEnum.浙期: var tIdArr = retListResult.rows.Select(O => O.TradeId); var ptIdArr = retListResult.rows.Where(O => O.trade.ParentTradeId > 0).Select(O => O.trade.ParentTradeId).ToHashSet(); tmInfos = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.MetaKey == ConsTradeMetaKey.ContractCode).ToDictionary(K => K.TradeId, V => V.MetaValue); break; default: break; } try { foreach (var item in retListResult.rows) { var um1 = UnderlyingDataProvider.GetUnderlying(item.trade.UnderlyingCode); var variety = DataCacheProvider.GetVarietyDataSource().GetData(um1.UnderlyingTypeId); var dbTradeMeta = DbContext.TradeMeta.Where(O => O.TradeId == item.TradeId && O.MetaKey == "ExchangeRate").OrderByDescending(m => m.CreateTime).FirstOrDefault(); if (!string.IsNullOrEmpty(variety.QuoteCurrency) && variety.QuoteCurrency != "CNY") { item.QuoteCurrency = variety.QuoteCurrency; item.ForeignCurrencyRate = double.TryParse(dbTradeMeta?.MetaValue, out var meta) ? meta : item.ForeignCurrencyRate;// double.TryParse(dbTradeMeta?.MetaValue, out double meta) ? meta : 1; } FormatModel(item, varietyTypeList, assetTypeList, varietySuffixList, varietyCodeList, out var syntheticPrice); if (item.trade.TradeType == "远期" && item.OperationType == "FU" && item.TradeDate.GetValueOrDefault().Date == item.trade.ExerciseDate.GetValueOrDefault().Date && item.EndStockEqvNotional == item.StockEqvNotional) { item.RealExerciseDate = item.UnWindDate; item.UnWindDate = null; item.OperationType = "ED"; } List SpecialCompanys = new List { CompanyEnum.润和, CompanyEnum.宏源, CompanyEnum.弘业, CompanyEnum.国投, CompanyEnum.华安, CompanyEnum.国信金阳, CompanyEnum.光大光子, CompanyEnum.伴兴, CompanyEnum.兴证, CompanyEnum.中粮 }; if (SpecialCompanys.Contains(PS.Config.Company) && item.TradeType == "收益互换") { item.Strike2 = new List(); var spotprice = item.SpotPrice.Split(',').ToList(); foreach (var x in spotprice) { item.Strike2.Add(Convert.ToDouble(x)); } } switch (PS.Config.Company) { case Configuration.CompanyEnum.上期资本: case Configuration.CompanyEnum.长江: tcRinfos.TryGetValue(item.TradeCashId, out var tcValue); item.ContractCode = tcValue ?? ""; break; case Configuration.CompanyEnum.浙期: tmInfos.TryGetValue(item.TradeId, out var tmValue); tmInfos.TryGetValue(item.trade.ParentTradeId, out var ptmValue); var ContractCode = item.ContractCode; item.ContractCode = ptmValue ?? tmValue ?? ContractCode; if (string.IsNullOrWhiteSpace(item.SettlementMethod)) { item.SettlementMethod = "C"; } if (item.OperationType == "NT") { item.LastUnWindDate = item.trade.SettlementDate ?? item.trade.ExerciseDate; var actualExerciseDate = DbContext.TradeMeta.Where(a => a.TradeId == item.TradeId && a.MetaKey == "ActualExerciseDate").FirstOrDefault()?.MetaValue; if (!string.IsNullOrEmpty(actualExerciseDate) && DateTime.TryParse(actualExerciseDate, out DateTime newActualExerciseDate)) { item.ExerciseDate = newActualExerciseDate; } } else if (item.trade.TradeType == "累计期权") { item.LastUnWindDate = item.TradeDate; } if (item.SettlementPriceType == null) { if (item.trade.TradeType == "亚式期权" || (item.trade.TradeType == "远期" && item.trade.StructureType == "掉期" && ConsGlobal.InstrumentType.GetSpotTypes().Contains(um1.UnderlyingInstrumentType))) { item.SettlementPriceType = 3; } else { item.SettlementPriceType = 9; } } if (item.ReferencePrice == null) { item.ReferencePrice = item.ClosePrice; if (!string.IsNullOrWhiteSpace(item.trade.BasisUnderlyingCode)) { item.ReferencePrice -= _priceProvider.GetPrice(item.trade.BasisUnderlyingCode); } } break; default: break; } item.OriginalVarietyCode = um1.CommodityCode; if (um1.IsSynthetic()) { var underlyingPrices = syntheticPrice.SuList.ToArray(); var arrMarket = new string[underlyingPrices.Length]; var arrMarketEn = new string[underlyingPrices.Length]; for (var i = 0; i < underlyingPrices.Length; i++) { var um = UnderlyingDataProvider.GetUnderlying(underlyingPrices[i].UnderlyingCode); arrMarket[i] = string.IsNullOrWhiteSpace(um?.MarketName) ? "O" : um?.MarketName; arrMarketEn[i] = formatDictItem(marketNoList, um?.MarketCode, um?.MarketCode); } item.TradingMarket = JoinArr(arrMarket); item.TradingMarketEn = JoinArr(arrMarketEn); } else { item.TradingMarket = string.IsNullOrWhiteSpace(um1?.MarketName) ? "O" : um1?.MarketName; item.TradingMarketEn = formatDictItem(marketNoList, um1?.MarketCode, um1?.MarketCode); } var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); if (client != null) { item.ClientName = clientReportInfo.TryGetValue(client.id, out var reportName) && !string.IsNullOrWhiteSpace(reportName) ? reportName : client.Name; item.ClientLicenseCode = client.LicenseCode; item.ProtocalType = _isEquity ? (clientEquityInfo.TryGetValue(client.id, out var value) ? value : "") : client.ProtocolSignVersion; item.ProtocolSignDate = _isEquity ? client.RightProtocolSignDate : client.ProtocolSignDate; } item.ProtocalType = !string.IsNullOrWhiteSpace(item.ProtocalType) && protocalTypeList.TryGetValue(item.ProtocalType, out var protocalType) ? protocalType : "9"; } } catch (ServiceException ex) { LogFactory.GetLogger("SuperviseReportTodayService").Error(ex, "已知错误"); throw ex; } catch (Exception ex) { LogFactory.GetLogger("SuperviseReportTodayService").Error(ex, "未知错误"); throw; } } return retListResult; } /// /// /// /// /// 标的资产类型 /// 资产类型 /// 标的资产品种后缀和标的资产对应合约后缀 /// 组合标的价格 /// EodTrade不存在时抛出 protected override void FormatModel(SuperviseReportBaseModel model, List varietyTypes, List assetTypes, List varietySuffixs, List varietyCodeList, out SyntheticPriceModel syntheticPrice) { SuperviseReportTodayModel obj = (SuperviseReportTodayModel)model; base.FormatModel(obj, varietyTypes, assetTypes, varietySuffixs, varietyCodeList, out syntheticPrice); double eqv = 0, endEqv = 0; obj.StartDate = obj.trade.TradeDate; obj.ExerciseDate = obj.trade.ExerciseDate; //obj.TradePrice = formatTradePrice(obj); obj.InitCastClientPayable = formatInitCastClientPayable(obj.trade); obj.WorstCastClientPayable = formatWorstCastClientPayable(obj.trade, obj.TradeSpan_WorstCastClientPayable); var annualizeFactor = obj.trade.IsAnnualized ? obj.trade.AnnualizeFactor : 1; if (syntheticPrice != null && syntheticPrice.SuList.Count() > 0) { var underlyingPrices = syntheticPrice.SuList.ToArray(); var arrAmount = new string[underlyingPrices.Length]; var arrEndAmount = new string[underlyingPrices.Length]; var arrSEN = new string[underlyingPrices.Length]; var arrEndSEN = new string[underlyingPrices.Length]; var arrSpotPrice = new string[underlyingPrices.Length]; for (var i = 0; i < underlyingPrices.Length; i++) { var originalStockEqvNotional = (underlyingPrices[i].Price * obj.trade.OriginalNotional / annualizeFactor / obj.trade.ParticipationRate * underlyingPrices[i].Coefficient) ?? 0; eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1); endEqv = formatEndStockEqvNotionalReal(eqv, (obj.OperationType == "NT" ? 1 : (obj.UnwindPercentRate ?? 0))); if (obj.ForeignCurrencyRate != null) { arrSEN[i] = (eqv * obj.ForeignCurrencyRate).ToString(); arrEndSEN[i] = (endEqv * obj.ForeignCurrencyRate).ToString(); } else { arrSEN[i] = eqv.ToString(); arrEndSEN[i] = endEqv.ToString(); } arrAmount[i] = formatTradeAmount(eqv / underlyingPrices[i].Price, (underlyingPrices[i].Coefficient > 0 ? 1 : -1)); arrEndAmount[i] = formatTradeAmount(endEqv / underlyingPrices[i].Price, (underlyingPrices[i].Coefficient > 0 ? 1 : -1)); arrSpotPrice[i] = underlyingPrices[i].Price.ToString(); } obj.StockEqvNotional = string.Join(base._separator, arrSEN); obj.EndStockEqvNotional = string.Join(base._separator, arrEndSEN); obj.TradeAmount = string.Join(base._separator, arrAmount); obj.EndTradeAmount = string.Join(base._separator, arrEndAmount); obj.SpotPrice = string.Join(base._separator, arrSpotPrice); } else { var originalStockEqvNotional = (obj.trade.OriginalStockEqvNotional == 0 ? (obj.trade.SpotPrice * obj.trade.OriginalNotional / annualizeFactor / obj.trade.ParticipationRate) : obj.trade.OriginalStockEqvNotional) ?? 0; eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1); endEqv = formatEndStockEqvNotionalReal(eqv, (obj.OperationType == "NT" ? 1 : (obj.UnwindPercentRate ?? 0))); if (obj.ForeignCurrencyRate != null) { obj.StockEqvNotional = (eqv * obj.ForeignCurrencyRate).ToString(); obj.EndStockEqvNotional = (endEqv * obj.ForeignCurrencyRate).ToString(); } else { obj.StockEqvNotional = eqv.ToString(); obj.EndStockEqvNotional = endEqv.ToString(); } obj.TradeAmount = formatTradeAmount(eqv / obj.trade.SpotPrice); obj.EndTradeAmount = formatTradeAmount(endEqv / obj.trade.SpotPrice); obj.SpotPrice = OtcFormatHelper.FormatValue(obj.trade.SpotPrice ?? 0, 6).ToString(); } if (PS.Config.Company == Configuration.CompanyEnum.国投) { obj.SpotPrice = OtcFormatHelper.FormatValue(obj.trade.SpotPrice ?? 0, 2).ToString(); } } private double formatWorstCastClientPayable(trade t, double? TradeSpan_WorstCastClientPayable) { double result = 0; if (t != null && TradeSpan_WorstCastClientPayable != null) { result = TradeSpan_WorstCastClientPayable.Value; } return Math.Max(0, result); } } }