using BaseOUDAL; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.Helpers; using YLErp.Model; using YLErp.Modules.CalculationModule; using YLErp.Modules.SuperviseReportModule.CFMMC2022.Model; using static iTextSharp.text.pdf.AcroFields; namespace YLErp.Modules.SuperviseReportModule.CFMMC2022.Service { /// /// 日监管报告服务 /// public class SuperviseReportTodayService : SuperviseReportBaseService { public SuperviseReportTodayService(SuperviseReportReq req, OptUserInfo userInfo) : base(req, userInfo) { } #region 新成交报送报表 private SearchListResult NewReportQuery(SuperviseReportReq req) { var commodityList = new List { ConsGlobal.InstrumentType.CommodityFutures, ConsGlobal.InstrumentType.CommoditySpot }; var umQuery = DbContext.underlying_manager.AsQueryable(); if (!string.IsNullOrWhiteSpace(req.sidx)) { req.sidx = req.sidx.Replace("StartDateString", "StartDate"); } else { req.sidx = "StartDate"; req.sord = "desc"; } req.sidx += ",OptDate"; 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" && (ConsTrade.TradeTypesForOtcOptions.Contains(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 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 NewSuperviseReportTodayModel { GroupPercentTradeId = trade.IsGroup == 1 ? trade.id : 0, ParentTradeId = trade.ParentTradeId, TradeJson = eodTrade.TradeJson, OriginalTradeNumber = eodTrade == null ? trade.TradeNumber : eodTrade.TradeNumber, TradeCashId = tradeCash.id, ClientId = trade.ClientId, TradeDate = tradeCash.ValueDate, TradeType = (tradeCash.Action == "系统操作-行权费" || (trade.TradeType == "American" && tradeCash.IsLastAction)) ? "ED" : (tradeCash.Action == "系统操作-期权费" ? "NT" : (tradeCash.UnwindType != null && tradeCash.UnwindType.StartsWith("部分") && !tradeCash.IsLastAction ? "PU" : "FU")), TradeStatus = eodTrade.TradeStatus, ForeignCurrencyRate = null, SettlementMethod = "C", UnWindDate = tradeCash.ExerciseWay != "到期行权" && tradeCash.Action != "系统操作-期权费" ? (DateTime?)tradeCash.ValueDate : null, LastUnWindDate = tradeCash.Action == "系统操作-期权费" ? null : trade.UnWindDate, TradeId = trade.id, ContractCode = tempParentTrade != null ? tempParentTrade.TradeNumber : trade.TradeNumber, TradeNumber = tempParentTrade != null ? tempParentTrade.TradeNumber : trade.TradeNumber, PositionCode = tempParentTrade != null ? tempParentTrade.TradeNumber : trade.TradeNumber, OptionType = trade.OptionType, _delta = er != null ? er.Delta : 0, ProductType = tempParentTrade == null ? trade.TradeType : tempParentTrade.TradeType, StructureType = tempParentTrade == null ? trade.StructureType : tempParentTrade.StructureType, ClosedUnderlyingPrice = tradeCash.FinalPrice == null ? null : tradeCash.FinalPrice.Value.ToString(),//平仓或终止时的标的价格 OptionProductStructure = eodTrade.TradeType, RoyaltyIncomeExpenditure = tradeCash.Amount, FinalPrice = tradeCash.FinalPrice, ExtendInfo = trade.ExtendInfo, UnwindPercentRate = tradeCash.UnwindPercentRate, TradeCashAmount = tradeCash.Amount, ValueDate = req.ValueDate, StartDate = trade.TradeDate, OptDate = tradeCash.OptDate, _price = cPrice != null ? cPrice.ClosePrice : sPrice.ClosePrice }; query = query.OrderByDescending(O => O.TradeStatus).ThenBy(n => n.ContractCode).ThenBy(n => n.OriginalTradeNumber); var retListResult = query.ToSearchList(_req, true); var groupTradeList = retListResult.rows.Where(O => O.GroupPercentTradeId > 0); var tradeIds = groupTradeList.Select(O => O.GroupPercentTradeId).Distinct(); 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" && (ConsTrade.TradeTypesForOtcOptions.Contains(t.TradeType) || t.TradeType == "远期" || t.TradeType == "收益互换") && t.TradeType != "场内期权" && t.TradeType != "现金流交易" && ((tc.HappenedDate != null && tc.HappenedDate == req.ValueDate) || (tc.HappenedDate == null && tc.ValueDate == req.ValueDate)) && (tc.Action == "系统操作-期权费") && tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted select new { t.ParentTradeId, er.Delta }).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._delta = info.Sum(O => O.Delta); } } return retListResult; } public SearchListResult NewSearchReportList() { var retListResult = NewReportQuery(_req); using (var basedb = new ErpBaseContext()) { var tcIdArr = retListResult.rows.Select(O => O.TradeCashId); var clientIdArr = retListResult.rows.Select(O => O.ClientId).ToHashSet(); 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 varietySuffixList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "标的资产后缀" select i).ToList(); 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 clientReportInfo = clientMetaQuery.Where(O => O.MetaKey == "ReportName").ToDictionary(K => K.ClientId, V => V.MetaValue); var tIdArr = retListResult.rows.Select(O => O.TradeId); var tpIdArr = retListResult.rows.Select(O => O.ParentTradeId); var tradeContractRInfo = DbContext.trade_contract_r.Where(O => (tIdArr.Contains(O.TradeId) || tpIdArr.Contains(O.TradeId)) && O.IsValid).ToList(); var tcRinfos = tradeContractRInfo.Where(O => O.Type == ContractTypeEnum.Trade).Select(O => new { TradeId = O.TradeId, O.ContractCode }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().ContractCode); var tradeNumberInfo = tradeContractRInfo.Select(O => new { TradeCashId = (O.TradeCashId ?? 0), O.ContractCode }).GroupBy(O => O.TradeCashId).ToDictionary(K => K.Key, V => V.First().ContractCode); var tradeMetaList = DbContext.TradeMeta.Where(O => tIdArr.Contains(O.TradeId)).ToList(); var iccInfo = tradeMetaList.Where(O => O.MetaKey == "中央对手方清算").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); var ccpInfo = tradeMetaList.Where(O => O.MetaKey == "中央清算平台").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); var tpInfo = tradeMetaList.Where(O => O.MetaKey == "交易平台").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); //敲入观察频率 var kiObservatonRate = tradeMetaList.Where(O => O.MetaKey == "敲入观察周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); //敲出观察频率 var koObservationRate = tradeMetaList.Where(O => O.MetaKey == "敲出观察周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); //远期 周期 var getObservatonRate = tradeMetaList.Where(O => O.MetaKey == "收取周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); var payObservatonRate = tradeMetaList.Where(O => O.MetaKey == "支付周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); //外币汇率 var exChangeRate = tradeMetaList.Where(O => O.MetaKey == "ExchangeRate").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue); var ptIdArr = retListResult.rows.Where(O => O.ParentTradeId != null).Select(O => O.ParentTradeId).ToHashSet(); var ptInfos = DbContext.trade.Where(O => ptIdArr.Contains(O.id)).Select(O => new { O.id, O.TradeType, O.StructureType, O.TradeNumber }).ToDictionary(K => K.id, V => V); var tcRInfos = new Dictionary(); var tmInfos = new Dictionary(); var dealNoInfos = new Dictionary(); var tCashInfosList = new List(); switch (PS.Config.Company) { case Configuration.CompanyEnum.长江: tcRInfos = DbContext.trade_contract_r.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.Type == ContractTypeEnum.Trade && O.IsValid).Select(O => new { O.TradeId, O.ContractCode }).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.FirstOrDefault().ContractCode); 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; case Configuration.CompanyEnum.浙期: 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; case Configuration.CompanyEnum.中粮: tCashInfosList = DbContext.trade_cash.Where(O => tIdArr.Contains(O.TradeId) && (O.Action == "系统操作-平仓费" || O.Action == "系统操作-行权费" || O.Action == "系统操作-票息") && O.ValidState != ConsGlobal.InValid && !O.IsDeleted).ToList(); break; case Configuration.CompanyEnum.招证: dealNoInfos = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.MetaKey.StartsWith("期货报送成交编号")).ToDictionary(K => K.TradeId + K.MetaKey, V => V.MetaValue); break; case Configuration.CompanyEnum.物产中大: tmInfos = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.MetaKey == ConsTradeMetaKey.ContractCode).ToDictionary(K => K.TradeId, V => V.MetaValue); dealNoInfos = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.MetaKey.StartsWith("期货报送成交编号")).ToDictionary(K => K.TradeId + K.MetaKey, V => V.MetaValue); break; } try { BLL.tradeBLL.SetFieldsByTradeType(retListResult.rows.Select(o => o.trade)); foreach (var item in retListResult.rows) { //累计期权并且 SettlementMode 是实物交割时赋值P if (item.TradeType == "累计期权" && item.trade.trade_accumulator_option.SettlementMode == "实物交割") { if (PS.Config.Company != Configuration.CompanyEnum.浙期) item.SettlementMethod = "P"; } //交易确认书 tcRinfos.TryGetValue(item.ParentTradeId > 0 ? item.ParentTradeId.Value : item.TradeId, out var tcValue); if (string.IsNullOrEmpty(tcValue)) { tcRinfos.TryGetValue(item.TradeId, out var tcValue2); tcValue = tcValue2; } //成交编号 tradeNumberInfo.TryGetValue(item.TradeCashId, out var tnValue); item.ContractCode = tnValue ?? tcValue ?? null; ptInfos.TryGetValue(item.ParentTradeId ?? 0, out var parentTrade); switch (PS.Config.Company) { case Configuration.CompanyEnum.长江: tcRInfos.TryGetValue(item.ParentTradeId ?? 0, out var pTcR); tcRInfos.TryGetValue(item.TradeId, out var tcR); tmInfos.TryGetValue(item.TradeId, out var tmValue); tmInfos.TryGetValue(item.ParentTradeId ?? 0, out var ptmValue); item.PositionCode = pTcR ?? tcR ?? ptmValue ?? tmValue ?? ""; break; case Configuration.CompanyEnum.浙期: tmInfos.TryGetValue(item.TradeId, out tmValue); tmInfos.TryGetValue(item.ParentTradeId ?? 0, out ptmValue); item.PositionCode = ptmValue ?? tmValue ?? parentTrade?.TradeNumber ?? item.OriginalTradeNumber; item.OriginalTradeNumber = tmValue ?? item.OriginalTradeNumber; break; case Configuration.CompanyEnum.东吴: if (item.TradeType == "NT") { item.TradeNumber = item.PositionCode + "-O"; } else { item.TradeNumber = item.PositionCode + "-C-"+item.ValueDate.ToString("yyyMMdd"); } break; case Configuration.CompanyEnum.招证: if (item.TradeType == "NT") { item.TradeNumber = item.PositionCode; } else { var metaKeySuffix = "期货报送成交编号" + item.TradeCashId; dealNoInfos.TryGetValue(item.TradeId + metaKeySuffix, out tmValue); dealNoInfos.TryGetValue((item.ParentTradeId ?? 0) + metaKeySuffix, out ptmValue); item.TradeNumber = ptmValue ?? tmValue; } break; case Configuration.CompanyEnum.上期资本: trade_contract_r tCR = null; trade_contract_r tCR2 = null; //交易确认书编号 tCR = tradeContractRInfo.FirstOrDefault(n => n.TradeId == item.TradeId && n.Type == "交易确认书"); if (item.TradeType != "NT") { //结算确认书编号 tCR2 = tradeContractRInfo.FirstOrDefault(n => n.TradeCashId == item.TradeCashId && (n.Type == "结算确认书" || n.Type == "提前终止确认书")); } if (tCR != null) { item.ContractCode = tCR.ContractCode; item.TradeNumber = tCR.ContractCode; item.PositionCode = tCR.ContractCode; if (tCR2 != null) { item.ContractCode = tCR2.ContractCode; item.TradeNumber = tCR2.ContractCode; } } else { item.ContractCode = null; item.TradeNumber = null; item.PositionCode = null; } break; case Configuration.CompanyEnum.中粮: //开仓交易的成交编号=持仓编号 if (item.TradeType == "NT") { item.TradeNumber = item.PositionCode; } //了结交易的成交编号=持仓编号+了结状态 else { var tcList = tCashInfosList.Where(n => n.TradeId == item.TradeId).OrderBy(n => n.id).ToList(); var curTC = tCashInfosList.FirstOrDefault(n => n.id == item.TradeCashId); if (curTC != null) { if (curTC.Action.Contains("票息") && curTC.IsLastAction) { item.TradeNumber = item.PositionCode + "-E"; } else if (curTC.Notional == curTC.UnwindNotional) { if (curTC.ExerciseWay == TradeCashExerciseWayEnum.到期行权) { item.TradeNumber = item.PositionCode + "-E"; } else { item.TradeNumber = item.PositionCode + "-C"; } } else { int tcIndex = 1; foreach (var tc in tcList) { if (tc.id == curTC.id) { break; } tcIndex++; } item.TradeNumber = item.PositionCode + "-P" + tcIndex; } } } break; case Configuration.CompanyEnum.兴证: item.PositionCode = item.trade.TradeNumber; break; case Configuration.CompanyEnum.物产中大: tmInfos.TryGetValue(item.TradeId, out tmValue); tmInfos.TryGetValue(item.ParentTradeId ?? 0, out ptmValue); item.PositionCode = ptmValue ?? tmValue; if (item.TradeType == "NT") { var metaKeySuffix = "期货报送成交编号"; dealNoInfos.TryGetValue(item.TradeId + metaKeySuffix, out tmValue); dealNoInfos.TryGetValue((item.ParentTradeId ?? 0) + metaKeySuffix, out ptmValue); item.TradeNumber = ptmValue ?? tmValue; } else { var metaKeySu = "期货报送成交编号" + item.TradeCashId; dealNoInfos.TryGetValue(item.TradeId + metaKeySu, out tmValue); dealNoInfos.TryGetValue((item.ParentTradeId ?? 0) + metaKeySu, out ptmValue); item.TradeNumber = ptmValue ?? tmValue; } var trade_Contract_R_Number =DbContext.trade_contract_r_number.Where(l => l.TradeId == item.TradeId && l.TradeConfirmNumberType == "C").FirstOrDefault(); item.ContractCode = (trade_Contract_R_Number?.TradeConfirmNumber??""); break; case Configuration.CompanyEnum.弘业: trade_contract_r tC = null; if (item.TradeType != "NT") { //结算确认书编号 tC = tradeContractRInfo.FirstOrDefault(n => n.TradeCashId == item.TradeCashId && (n.Type == "结算确认书" || n.Type == "提前终止确认书")); if (tC!=null) { item.ContractCode = tC.ContractCode; item.TradeNumber = tC.ContractCode; } else { item.ContractCode = null; } } else { if (!string.IsNullOrEmpty(tcValue)) { item.ContractCode = tcValue; item.TradeNumber = tcValue; } else { item.ContractCode = null; } } break; default: var defautPositionCode = parentTrade?.TradeNumber ?? item.OriginalTradeNumber; if (defautPositionCode != null) { item.PositionCode = defautPositionCode; } break; } var um1 = UnderlyingDataProvider.GetUnderlying(item.trade.UnderlyingCode); var variety = DataCacheProvider.GetVarietyDataSource().GetData(um1.UnderlyingTypeId); exChangeRate.TryGetValue(item.TradeId, out var ecRate); if (!string.IsNullOrEmpty(variety.QuoteCurrency) && variety.QuoteCurrency != "CNY") { if (!string.IsNullOrEmpty(ecRate)) item.ForeignCurrencyRate = double.Parse(ecRate); item.QuoteCurrency = variety.QuoteCurrency; if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)")) { if (item.ForeignCurrencyRate != null) item.ForeignCurrencyRate = item.ForeignCurrencyRate; } } else { item.QuoteCurrency = "CNY"; } FormatModel(item, assetTypeList, varietySuffixList, varietyCodeList, out var syntheticPrice); if (item.TradeType != "NT") { //item.GuaranteedIncome = (item.trade.OriginalPrincipalSum ?? 0) * item.UnwindPercentRate; item.DeltaCash = ""; } var protocalTyp = "协议签署版本"; 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 client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); if (client != null) { while (client.IsDocShowParentName == 1 && client.ParentId > 0) { client = DataCacheProvider.GetClientDataSource().GetData(client.ParentId) ?? throw new ServiceException($"{client.Name} 的所属机构不存在,请维护后生成!"); } item.ClientName = clientReportInfo.TryGetValue(client.id, out var reportName) && !string.IsNullOrWhiteSpace(reportName) ? reportName : client.Name; item.ClientLicenseCode = client.LicenseCode; item.ProtocalType = (!string.IsNullOrWhiteSpace(client.ProtocolSignVersion) && protocalTypeList.TryGetValue(client.ProtocolSignVersion, out var value) ? value : "9"); item.ProtocolSignDate = item.VarietyType == "EQ" ? client.RightProtocolSignDate : client.ProtocolSignDate; //获取交易对手方LEI item.ClientLEI = client.LEICode; } //中央对手方清算 iccInfo.TryGetValue(item.TradeId, out var icc); item.IsCentralClearingPlatform = icc ?? "N"; //是否中央对方清算“字段不是”Y“时,中央清算平台才赋值 if (item.IsCentralClearingPlatform == "Y") { ccpInfo.TryGetValue(item.TradeId, out var ccp); item.CentralClearingPlatform = ccp ?? null; } if (item.TradeType == "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.EndDate = newActualExerciseDate; } } else if (item.trade.TradeType == "累计期权") { item.LastUnWindDate = item.TradeDate; } //交易平台 tpInfo.TryGetValue(item.TradeId, out var tp); item.TradePlatform = tp ?? null; if (item.ToolType == "FW" || item.ToolType == "SW") { item.OptionProductStructure = null; } var IsUSC = false; //非黑箱交易时处理 if (string.IsNullOrEmpty(item.trade.ExtendInfo) || item.trade.TradeType == "自定义交易") { if (item.trade.TradeType != "远期" && item.trade.TradeType != "掉期") { //雪球、凤凰 if (item.OptionProductStructure == "SA" || item.OptionProductStructure == "GSA" || item.OptionProductStructure == "PA") { if (item.ObserveType == "DISCRETE") { //雪球、凤凰 观察频率 koObservationRate.TryGetValue(item.TradeId, out var observationRate); formatObservationRate(item, observationRate); } #region 雪球凤凰 敲入观察判断是否到期观察 var isTerminal = false; var observeStartDates = ""; if (item.OptionProductStructure == "PA") { observeStartDates = item.trade.trade_autocall?.ObservationDates; } else { observeStartDates = item.trade.trade_snowball?.ObservationDates; } if (!string.IsNullOrEmpty(observeStartDates)) { var odArrs = observeStartDates.Split(';'); if (odArrs.Length > 0) { DateTime.TryParse(odArrs[0], out DateTime koOD); if (koOD == item.EndDate.Value) { isTerminal = true; } } } #endregion if (!isTerminal) { //雪球、凤凰敲入观察频率 kiObservatonRate.TryGetValue(item.TradeId, out var kiOR); formatKiObservationRate(item, kiOR); } } //累计期权 else if (item.OptionProductStructure == "AC") { if (item.ObserveType == "DISCRETE") { koObservationRate.TryGetValue(item.TradeId, out var observationRate); formatObservationRate(item, observationRate); } } else { //其他产品观察频率观察频率 if (item.ObserveType == "DISCRETE") { kiObservatonRate.TryGetValue(item.TradeId, out var observationRate); formatObservationRate(item, observationRate); } } } //互换产品、掉期产品 if (item.ToolType == "SW") { getObservatonRate.TryGetValue(item.TradeId, out var getOR); payObservatonRate.TryGetValue(item.TradeId, out var payOR); formatSWObservationRate(item, getOR, payOR); item.OptionProductStructure = null; //当是互换、掉期时,计价单位是外币时,期初货币单位、执行价格货币单位需显示外币 if (item.QuoteCurrency != "CNY") { if (item.UnderlyingInitialPriceSymbol == "3") { if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)")) { IsUSC = true; } } if (item.UnderlyingInitialPriceSymbol == "1") { if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)")) { IsUSC = true; item.QuoteCurrency = "USD"; } item.UnderlyingInitialPriceCurrency = item.UnderlyingInitialPriceCurrency.Replace("CNY", item.QuoteCurrency); } } // 如遇货币单位为美分,如USD(cent)或USc,且价格符号为1或3时,以下涉及报送的字段需除以100 if (IsUSC) { item.UnderlyingInitialPrice = (Convert.ToDecimal(item.UnderlyingInitialPrice) / 100).ToString(); item.ClosedUnderlyingPrice = string.IsNullOrWhiteSpace(item.ClosedUnderlyingPrice) ? item.ClosedUnderlyingPrice : (Convert.ToDecimal(item.ClosedUnderlyingPrice) / 100).ToString(); } item.StrikeSymbol = null; item.StrikeCurrency = null; item.Strike = null; item.GuaranteedIncome = null; item.GuaranteedIncomeCurrency = null; item.GuaranteedIncomeSymbol = null; } else if (item.QuoteCurrency != "CNY") { if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)")) { IsUSC = true; item.QuoteCurrency = "USD"; } item.UnderlyingInitialPriceCurrency = string.IsNullOrEmpty(item.UnderlyingInitialPriceCurrency) ? null : item.UnderlyingInitialPriceCurrency.Replace("CNY", item.QuoteCurrency); item.StrikeCurrency = string.IsNullOrEmpty(item.StrikeCurrency) ? null : item.StrikeCurrency.Replace("CNY", item.QuoteCurrency); item.GuaranteedIncomeCurrency = string.IsNullOrEmpty(item.GuaranteedIncomeCurrency) ? null : item.GuaranteedIncomeCurrency.Replace("CNY", item.QuoteCurrency); item.ExerciseBenefitsCurrency = string.IsNullOrEmpty(item.ExerciseBenefitsCurrency) ? null : item.ExerciseBenefitsCurrency.Replace("CNY", item.QuoteCurrency); item.CompensationIncomeCurrency = string.IsNullOrEmpty(item.CompensationIncomeCurrency) ? null : item.CompensationIncomeCurrency.Replace("CNY", item.QuoteCurrency); item.ForwardPriceCurrency = string.IsNullOrEmpty(item.ForwardPriceCurrency) ? null : item.ForwardPriceCurrency.Replace("CNY", item.QuoteCurrency); } if (item.TradeType == "ED") { item.UnWindDate = null; } if (item.UnderlyingInitialPriceSymbol == "3") { item.UnderlyingInitialPriceCurrency = null; if (item.StrikeSymbol == "1") { item.StrikeSymbol = "3"; item.StrikeCurrency = null; } if (item.ForwardPriceSymbol == "1") { item.ForwardPriceSymbol = "3"; item.ForwardPriceCurrency = null; } } // 如遇货币单位为美分,如USD(cent)或USc,且价格符号为1或3时,以下涉及报送的字段需除以100 标的期初价格、平仓或终止时的标的价格、执行价格1、执行价格2、执行价格3、障碍价1、障碍价2、远期价格 if (IsUSC && (item.UnderlyingInitialPriceSymbol == "1" || item.UnderlyingInitialPriceSymbol == "3")) { item.UnderlyingInitialPrice = (Convert.ToDecimal(item.UnderlyingInitialPrice) / 100).ToString(); item.ClosedUnderlyingPrice = string.IsNullOrWhiteSpace(item.ClosedUnderlyingPrice) ? item.ClosedUnderlyingPrice : (Convert.ToDecimal(item.ClosedUnderlyingPrice) / 100).ToString(); } if (IsUSC && (item.StrikeSymbol == "1" || item.StrikeSymbol == "3")) { item.Strike /= 100; item.Strike2 /= 100; item.Strike3 /= 100; item.BarriersPrice /= 100; item.BarriersPrice2 /= 100; } if (IsUSC && (item.ForwardPriceSymbol == "1" || item.ForwardPriceSymbol == "3")) { item.ForwardPrice /= 100; } //雪球初始敲入时,”敲入障碍价“、”敲入观察期“字段为空 if (item.OptionProductStructure == "SA" || item.OptionProductStructure == "GSA") { if (item.trade.trade_snowball != null && item.trade.trade_snowball.IsInitialKnockedIn) { item.KnockInBarrierPrice = null; item.KnockInObservationPeriod = null; } } } else { //当是黑箱时,计价单位是外币时,期初货币单位、执行价格货币单位需显示外币 if (item.QuoteCurrency != "CNY") { if (item.UnderlyingInitialPriceSymbol == "3") { if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)")) { IsUSC = true; } } if (item.UnderlyingInitialPriceSymbol == "1") { if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)")) { IsUSC = true; item.QuoteCurrency = "USD"; } item.UnderlyingInitialPriceCurrency = item.UnderlyingInitialPriceCurrency.Replace("CNY", item.QuoteCurrency); } } // 如遇货币单位为美分,如USD(cent)或USc,且价格符号为1或3时,以下涉及报送的字段需除以100 标的期初价格、平仓或终止时的标的价格、执行价格1、执行价格2、执行价格3、障碍价1、障碍价2、远期价格 if (IsUSC) { item.UnderlyingInitialPrice = (Convert.ToDecimal(item.UnderlyingInitialPrice) / 100).ToString(); item.ClosedUnderlyingPrice = string.IsNullOrWhiteSpace(item.ClosedUnderlyingPrice) ? item.ClosedUnderlyingPrice : (Convert.ToDecimal(item.ClosedUnderlyingPrice) / 100).ToString(); } } //成交数量 var tradeNum = item.trade.OriginalNotional; if (item.GuaranteedIncomeSymbol == "1") { if (item.GuaranteedIncome != null) { item.GuaranteedIncome /= tradeNum; } } //行权收益 if (item.ExerciseBenefitsSymbol == "1") { if (item.ExerciseBenefits != null) { item.ExerciseBenefits /= tradeNum; } if (item.ExerciseBenefits2 != null) { item.ExerciseBenefits2 /= tradeNum; } if (item.ExerciseBenefits3 != null) { item.ExerciseBenefits3 /= tradeNum; } } //补偿收益 if (item.CompensationIncomeSymbol == "1") { if (item.CompensationIncome != null) { item.CompensationIncome /= tradeNum; } if (item.CompensationIncome2 != null) { item.CompensationIncome2 /= tradeNum; } } //固定收益 if (item.FixedIncomeSymbol == "1") { if (item.FixedIncome != null) { item.FixedIncome /= tradeNum; } } if (PS.Config.Is招证) { if (item.GuaranteedIncome == 0) { item.GuaranteedIncome = null; item.GuaranteedIncomeCurrency = null; item.GuaranteedIncomeSymbol = null; } } } } catch (ServiceException ex) { LogFactory.GetLogger("NewSuperviseReportTodayService").Error(ex, "已知错误"); throw; } catch (Exception ex) { LogFactory.GetLogger("NewSuperviseReportTodayService").Error(ex, "未知错误"); throw; } } return retListResult; } #endregion /// /// 凤凰雪球 敲入 /// /// /// private void formatKiObservationRate(NewSuperviseReportTodayModel item, string kiOR = "") { string[] kiORArray; string unitStr; string unit; string num; //敲入观察频率 if (!string.IsNullOrEmpty(kiOR)) { kiORArray = kiOR.Split('|'); if (kiORArray.Length == 2) { num = kiORArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", ""); unitStr = kiORArray[1].Replace(num, ""); item.KnockInObservationPeriod = unitStr; } else { num = kiOR.Substring(0, kiOR.Length - 1); unit = kiOR.Substring(kiOR.Length - 1); unitStr = getUnitStr(unit); item.KnockInObservationPeriod = unitStr; } } else { num = "1"; unit = "D"; unitStr = getUnitStr(unit); if (item.OptionProductStructure == "GSA") { unitStr = ""; } item.KnockInObservationPeriod = unitStr; } } /// /// 观察频率 /// /// /// private void formatObservationRate(NewSuperviseReportTodayModel item, string observationRate = "") { string[] orArray; string unitStr; string unit; string num; if (!string.IsNullOrEmpty(observationRate)) { orArray = observationRate.Split('|'); if (orArray.Length == 2) { if (orArray[1] == "OTHER") { item.ObservationPeriod = orArray[1]; } else { num = orArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", ""); unitStr = orArray[1].Replace(num, ""); item.ObservationPeriod = unitStr; item.ObservePeriodMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN; } } else { num = observationRate.Substring(0, observationRate.Length - 1); unit = observationRate.Substring(observationRate.Length - 1); unitStr = getUnitStr(unit); item.ObservationPeriod = unitStr; item.ObservePeriodMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN; } } else { if ((item.OptionProductStructure != "SA" && item.OptionProductStructure != "GSA" && item.OptionProductStructure != "PA")) { if (item.ObserveType == "DISCRETE") { num = "1"; unit = "D"; unitStr = getUnitStr(unit); item.ObservationPeriod = unitStr; item.ObservePeriodMultiplier = double.Parse(num); } else if (item.trade.TradeType == "自定义交易") { item.ObservationPeriod = "OTHER"; } } else if (item.OptionProductStructure == "SA" || item.OptionProductStructure == "GSA" || item.OptionProductStructure == "PA") { num = "1"; unit = "M"; unitStr = getUnitStr(unit); item.ObservationPeriod = unitStr; item.ObservePeriodMultiplier = double.Parse(num); } } } /// /// 互换产品收取观察频率 /// /// /// /// private void formatSWObservationRate(NewSuperviseReportTodayModel item, string getOR = "", string payOR = "") { string num = "", unit = "", unitStr = ""; string[] getORArray; string[] payORArray; if (!string.IsNullOrEmpty(getOR) && getOR != "TERM") { getORArray = getOR.Split('|'); if (getORArray.Length == 2) { if (getORArray[1] == "OTHER" || getORArray[1] == "TERM") { unitStr = getORArray[1]; } else { num = getORArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", ""); unitStr = getORArray[1].Replace(num, ""); } } else { num = getOR.Substring(0, getOR.Length - 1); unit = getOR.Substring(getOR.Length - 1); unitStr = getUnitStr(unit); } item.PaymentCycle = unitStr; item.PaymentCycleMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN; } else if (!string.IsNullOrEmpty(payOR) && payOR != "TERM") { payORArray = payOR.Split('|'); if (payORArray.Length == 2) { if (payORArray[1] == "OTHER" || payORArray[1] == "TERM") { unitStr = payORArray[1]; } else { num = payORArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", ""); unitStr = payORArray[1].Replace(num, ""); } } else { num = payOR.Substring(0, payOR.Length - 1); unit = payOR.Substring(payOR.Length - 1); unitStr = getUnitStr(unit); } item.PaymentCycle = unitStr; item.PaymentCycleMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN; } else { //互换产品未选支付周期,默认TERM item.PaymentCycle = "TERM"; } } private string getUnitStr(string inputVal) { switch (inputVal) { case "D": return "DAIL"; case "W": return "WEEK"; case "M": return "MNTH"; case "Y": return "YEAR"; default: return "Other"; } } /// /// /// /// /// 资产类型 /// 标的资产品种后缀和标的资产对应合约后缀 /// 组合标的价格 /// EodTrade不存在时抛出 protected override void FormatModel(SuperviseReportBaseModel model, List assetTypes, List varietySuffixs, List varietyCodeList, out SyntheticPriceModel syntheticPrice) { NewSuperviseReportTodayModel obj = (NewSuperviseReportTodayModel)model; obj.StartDate = obj.trade.TradeDate; obj.EndDate = obj.trade.ExerciseDate; obj.ExerciseDate = obj.trade.ExerciseDate; base.FormatModel(obj, assetTypes, varietySuffixs, varietyCodeList, out syntheticPrice); double eqv = 0, endEqv = 0; var annualizeFactor = obj.trade.IsAnnualized ? obj.trade.AnnualizeFactor : 1; //组合标的 if (syntheticPrice != null && syntheticPrice.SuList.Count() > 0) { var underlyingPrices = syntheticPrice.SuList.ToArray(); var arrSEN = new string[underlyingPrices.Length]; var arrAmount = new string[underlyingPrices.Length]; var arrEndAmount = new string[underlyingPrices.Length]; var arrEndSEN = new string[underlyingPrices.Length]; var arrUnderlyingInitialPrice = new string[underlyingPrices.Length]; var arrUnderlyingInitialPriceCurrency = new string[underlyingPrices.Length]; //组合标的 平仓或终止时的标的价格 var arrClosedUnderlyingPrice = new string[underlyingPrices.Length]; double sumArrClosedUnderlyingPrice = 0; var notional = obj.trade.OriginalNotional; if (PS.Config.Is广期资本 && "自定义交易".Equals(obj.trade.TradeType) && obj.trade.Propertys != null && obj.trade.Propertys.Any(d => "总数量".Equals(d.name))) { double totalCount = 0; if (double.TryParse(obj.trade.Propertys.First(d => "总数量".Equals(d.name)).value, out totalCount)) { notional = totalCount * obj.trade.CountRatio ?? 1; } } for (var i = 0; i < underlyingPrices.Length; i++) { var originalStockEqvNotional = (underlyingPrices[i].Price * notional / annualizeFactor / obj.trade.ParticipationRate * underlyingPrices[i].Coefficient) ?? 0; eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1); endEqv = formatEndStockEqvNotionalReal(eqv, ((obj.TradeType == "NT" || obj.TradeType == "MD") ? 1 : (obj.UnwindPercentRate ?? 0))); arrSEN[i] = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate : eqv).ToString(); arrEndSEN[i] = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate : endEqv).ToString(); var um1 = UnderlyingDataProvider.GetUnderlying(underlyingPrices[i].UnderlyingCode); var variety = DataCacheProvider.GetVarietyDataSource().GetData(um1.UnderlyingTypeId); if (variety.QuoteCurrency != null && (variety.QuoteCurrency.ToLower() == "usc" || variety.QuoteCurrency.ToLower() == "usd(cent)")) { arrSEN[i] = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate / 100 : eqv).ToString(); arrEndSEN[i] = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate / 100 : endEqv).ToString(); } arrAmount[i] = formatTradeAmount(eqv / underlyingPrices[i].Price); arrEndAmount[i] = formatTradeAmount(endEqv / underlyingPrices[i].Price); arrUnderlyingInitialPrice[i] = underlyingPrices[i].Price.ToString(); arrUnderlyingInitialPriceCurrency[i] = string.IsNullOrEmpty(variety.QuoteCurrency) ? "CNY" : variety.QuoteCurrency; //多标的,平仓或终止时的标的价格需和标的物数量一致 if (obj.TradeType == "PU" || obj.TradeType == "FU" || obj.TradeType == "ED") { if (i + 1 == underlyingPrices.Length) { //最后一个标的物需减去前n个的价格后除以当前标的物的系数 arrClosedUnderlyingPrice[i] = (((obj.FinalPrice ?? 0) - sumArrClosedUnderlyingPrice) / underlyingPrices[i].Coefficient).ToString(); } else { //前n-1个标的物取当日收盘价 sumArrClosedUnderlyingPrice += _priceProvider.GetPrice(underlyingPrices[i].UnderlyingCode) * underlyingPrices[i].Coefficient; arrClosedUnderlyingPrice[i] = _priceProvider.GetPrice(underlyingPrices[i].UnderlyingCode).ToString(); } } } //初始名义金额 obj.InitialNominalAmount = string.Join(base._separator, arrSEN); //初始名义数量 obj.InitialNominalNumber = string.Join(base._separator, arrAmount); //交易名义金额 obj.NominalTransactionAmount = string.Join(base._separator, arrEndSEN); //交易名义数量 obj.NominalTransactionNumber = string.Join(base._separator, arrEndAmount); //组合标的价格 obj.UnderlyingInitialPrice = string.Join(base._separator, arrUnderlyingInitialPrice); obj.UnderlyingInitialPriceCurrency = string.Join(base._separator, arrUnderlyingInitialPriceCurrency); //平仓或终止时的标的价格 if (obj.TradeType == "PU" || obj.TradeType == "FU" || obj.TradeType == "ED") { obj.ClosedUnderlyingPrice = string.Join(base._separator, arrClosedUnderlyingPrice); } else { obj.ClosedUnderlyingPrice = null; } } else { var notional = obj.trade.OriginalNotional; if (PS.Config.Is广期资本 && "自定义交易".Equals(obj.trade.TradeType) && obj.trade.Propertys != null && obj.trade.Propertys.Any(d => "总数量".Equals(d.name))) { double totalCount = 0; if (double.TryParse(obj.trade.Propertys.First(d => "总数量".Equals(d.name)).value, out totalCount)) { notional = totalCount * obj.trade.CountRatio ?? 1; obj.trade.OriginalStockEqvNotional = (obj.trade.SpotPrice * notional / annualizeFactor / obj.trade.ParticipationRate); } } var originalStockEqvNotional = (obj.trade.OriginalStockEqvNotional == 0 ? (obj.trade.SpotPrice * notional / annualizeFactor / obj.trade.ParticipationRate) : obj.trade.OriginalStockEqvNotional) ?? 0; eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1); endEqv = formatEndStockEqvNotionalReal(eqv, ((obj.TradeType == "NT" || obj.TradeType == "MD") ? 1 : (obj.UnwindPercentRate ?? 0))); //初始名义金额 obj.InitialNominalAmount = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate : eqv).ToString(); //交易名义金额 obj.NominalTransactionAmount = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate : endEqv).ToString(); if (obj.QuoteCurrency != null && (obj.QuoteCurrency.ToLower() == "usc" || obj.QuoteCurrency.ToLower() == "usd(cent)")) { obj.InitialNominalAmount = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate / 100 : eqv).ToString(); obj.NominalTransactionAmount = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate / 100 : endEqv).ToString(); } //初始名义数量 obj.InitialNominalNumber = formatTradeAmount(eqv / obj.trade.SpotPrice).ToString(); //交易名义数量 obj.NominalTransactionNumber = formatTradeAmount(endEqv / obj.trade.SpotPrice).ToString(); //平仓或终止时的标的价格 if (obj.TradeType == "NT") { obj.ClosedUnderlyingPrice = null; } } if (obj.OptionProductStructure == "DI" || obj.OptionProductStructure == "RA") { if (obj.TradeType != "NT") { if (string.IsNullOrEmpty(obj.trade.ExtendInfo)) { obj.ExerciseBenefits = obj.TradeCashAmount; obj.ExerciseBenefitsSymbol = "1"; obj.ExerciseBenefitsCurrency = "CNY"; if (obj.Strike2 > 0) { obj.ExerciseBenefits2 = obj.TradeCashAmount; } } } } } } }