using BaseOUDAL; using YLErp.BLL; using YLErp.Commons; using YLErp.Configuration; using YLErp.DBModels.Consts; using YLErp.Helpers; using YLErp.Model; using YLErp.Modules.ClientModule; using YLErp.Modules.SuperviseReportModule.CFMMC.Model; using YLErp.Modules.TradeModule; using YLErp.QdpModule; using static YLErp.ConsGlobal; namespace YLErp.Modules.SuperviseReportModule.CFMMC.Service { public class SuperviseReportPositionService : SuperviseReportBaseService { private string _volType { get; set; } public SuperviseReportPositionService(SuperviseReportReq req, OptUserInfo userInfo) : base(req, userInfo) { var arr = req.DataSource?.Split(',') ?? new string[2]; _volType = arr[0]; req.DataSource = arr[1]; } private SearchListResult ReportQuery(SuperviseReportReq req) { var commodityList = new List { InstrumentType.CommodityFutures, 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 insidedClientIds = DataCacheProvider.GetClientDataSource().AsQueryable().Where(O => O.IsInsided == 1).Select(O => O.id).ToList(); var tId = DbContext.eod_trade_position.Where(O => !insidedClientIds.Contains(O.ClientId) && O.ValueDate == req.ValueDate && (O.TradeType.EndsWith("期权") || O.TradeType == "远期" || O.TradeType == "收益互换" || O.TradeType == "自定义交易" || O.TradeType == "气囊结构") && O.TradeType != "场内期权" && O.TradeId != 0).Select(O => O.TradeId); var query = from eodTrade in DbContext.eod_trade join trade in DbContext.trade on eodTrade.TradeId equals trade.id join um in umQuery on trade.UnderlyingCode equals um.UnderlyingCode where eodTrade.ValueDate == req.ValueDate && (tId.Contains(eodTrade.TradeId) || trade.IsGroup == 1) && trade.IsGroup != 2 && trade.TradeType != "现金流交易" && eodTrade.ClientId != 0 && ConsTrade.LiveTradeStatusList.Contains(eodTrade.TradeStatus) select new SuperviseReportPositionModel { PositionDate = eodTrade.ValueDate, TradeId = eodTrade.TradeId, ClientId = eodTrade.ClientId, UnderlyingCode = eodTrade.UnderlyingCode, ParentTradeId = eodTrade.ParentTradeId, TradeStatus = eodTrade.TradeStatus, OriginalTradeNumber = eodTrade.TradeNumber, TradeJson = eodTrade.TradeJson, ValuationMethod = "O", UnwindPercentRate = 0, QuoteCurrency = "CNY", ForeignCurrencyRate = null, IsAnnualTrade = "N", PriceSymbol = 1, ParticipateRate = 1, IsGroup = trade.IsGroup }; var clientcontext = new ClientDBContext(); var clientids = query.Select(x => x.ClientId).Distinct().ToArray(); var clients = clientcontext.client.Where(x => clientids.Contains(x.id) && x.IsInsided != 1).Select(x => x.id).ToArray(); query = query.Where(x => clients.Contains(x.ClientId)).OrderBy(O => O.OriginalTradeNumber); var retListResult = query.ToSearchList(req, false); return retListResult; } public SearchListResult SearchReportList() { SearchListResult retListResult = null; using (var basedb = new ErpBaseContext()) { IQueryable etr = null; IQueryable etp = null; switch (_volType) { case "开仓": etr = DbContext.eod_trade_risk_openvol.Where(O => O.ValueDate == _req.ValueDate); etp = DbContext.eod_trade_position_openvol.Where(O => O.ValueDate == _req.ValueDate); break; case "持仓": default: etr = DbContext.eod_trade_risk.Where(O => O.ValueDate == _req.ValueDate); etp = DbContext.eod_trade_position.Where(O => O.ValueDate == _req.ValueDate); break; } if (!etp.Any()) { throw new ServiceException("数据不存在"); } retListResult = ReportQuery(_req); var ignoreTradeTypes = new List() { "远期", "收益互换", "掉期", }; 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 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(); try { var config = DbContext.valuedate.FirstOrDefault(x => x.State == valuedate.当前使用); var tIdArr = retListResult.rows.Select(O => O.TradeId); Dictionary ePnlInfos = null; Dictionary eRiskInfos = null; var func = new Func(O => new EodTradeRisk { TradeId = O.TradeId, Delta = O.Delta, DeltaCash = O.DeltaCash, GammaCash = O.GammaCash, Theta = O.Theta, Gamma = O.Gamma, Rho = O.Rho, Vega = O.Vega, Vol = O.Vol, OtherRisks = O.OtherRisks }); ePnlInfos = etp.Where(O => tIdArr.Contains(O.TradeId)).Select(O => new EodTradePosition { TradeId = O.TradeId, Pv = O.Pv, Margin = O.Margin }).ToDictionary(K => K.TradeId, V => V); eRiskInfos = etr.Where(O => tIdArr.Contains(O.TradeId)).Select(func).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First()); var clientIdArr = retListResult.rows.Select(O => O.ClientId); //var clientInfos = DbContext.client.Where(O => clientIdArr.Contains(O.id)).Select(O => new { O.id, O.Name, O.LicenseCode }).ToDictionary(K => K.id, V => V); 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(); 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; } var dbTradeMeta = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId))).ToList(); var obsvitionInfos = dbTradeMeta.Where(O => (O.MetaKey == ConsTradeMetaKey.ObservationRemark1 || O.MetaKey == ConsTradeMetaKey.ObservationRemark2)).ToList(); var tbInfos = DbContext.trade_binary_option.Where(O => tIdArr.Contains(O.TradeId)).Select(O => new { O.TradeId, O.PayoffType }).ToDictionary(K => K.TradeId, V => V.PayoffType); 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); foreach (var item in retListResult.rows) { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode); var variety = DataCacheProvider.GetVarietyDataSource().GetData(um.UnderlyingTypeId); //clientInfos.TryGetValue(item.ClientId, out var client); var client = ClientDataQueryService.GetClient(item.ClientId); ptInfos.TryGetValue(item.ParentTradeId ?? 0, out var parentTrade); tbInfos.TryGetValue(item.TradeId, out var payoffType); ePnlInfos.TryGetValue(item.TradeId, out var positionInfo); _priceProvider.TryGetPrice(item.UnderlyingCode, out var price); eRiskInfos.TryGetValue(item.TradeId, out var eRisk); var metaModel = dbTradeMeta.Where(m => m.TradeId == item.TradeId && m.MetaKey == "ExchangeRate").OrderByDescending(m => m.CreateTime).FirstOrDefault(); if (!string.IsNullOrEmpty(variety.QuoteCurrency) && variety.QuoteCurrency != "CNY") { item.QuoteCurrency = variety.QuoteCurrency; item.ForeignCurrencyRate = double.TryParse(metaModel?.MetaValue, out double meta) ? meta : item.ForeignCurrencyRate; } item.OriginalVarietyCode = variety.VarietyCode; item.MainName = config.SuperviseMainName; item.MainCode = config.SuperviseMainCode; item.ClientName = clientReportInfo.TryGetValue(client.id, out var reportName) && !string.IsNullOrWhiteSpace(reportName) ? reportName : client.Name; item.ClientLicenseCode = client?.LicenseCode; item.PositionDate = _req.ValueDate; item.TradeType = parentTrade?.TradeType ?? item.trade.TradeType; item.StructureType = parentTrade?.StructureType ?? item.trade.StructureType; item.PayoffType = payoffType ?? ""; if (item.TradeType == "远期" || item.TradeType == "收益互换") { item.ValuationMethod = "M"; } 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.ContractCode = pTcR ?? tcR ?? ptmValue ?? tmValue ?? ""; break; case Configuration.CompanyEnum.浙期: tmInfos.TryGetValue(item.TradeId, out tmValue); tmInfos.TryGetValue(item.ParentTradeId ?? 0, out ptmValue); item.ContractCode = ptmValue ?? tmValue ?? parentTrade?.TradeNumber ?? item.OriginalTradeNumber; item.OriginalTradeNumber = tmValue ?? item.OriginalTradeNumber; 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; } break; default: item.ContractCode = parentTrade?.TradeNumber ?? item.OriginalTradeNumber; break; } item.InitialSpotPrice = price.ToString(); item.Pv = (double)(positionInfo?.Pv ?? 0); item.Vol = eRisk?.Vol ?? 0; if (item.TradeType == "凤凰期权") { var autocall = item.trade.trade_autocall; if (autocall.ObservationDates != null) { var ko = TradeObservationHelper.GetAutocallKOObservationAndCoupon(autocall.KOObservationDates, autocall.CouponBarrier); var koarr = ko.Item2.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); item.KOObservationDates = koarr[0]; item.KOBarrier = koarr[1]; } } if (item.TradeType == "雪球期权") { item.SpotPrice = item.trade.SpotPrice ?? 0; var snowball = item.trade.trade_snowball; var koObservationList = QdpHelper.ParseAutocallCustomizedInfo(snowball.KOObservationDates); var index = koObservationList.Item1?.Where(O => O.DateTime <= _req.ValueDate).Count() ?? 0; if (koObservationList.Item1 != null) { index = koObservationList.Item1 == null || index < koObservationList.Item1.Length ? index : koObservationList.Item1.Length - 1; } double[] koBarrier; //国投 敲入观察价格,执行价格,敲出价格 处理两位小数 if (!item.trade.IsMoneynessOptionData && (PS.Config.Company == Configuration.CompanyEnum.国投 || PS.Config.Company == Configuration.CompanyEnum.浙期)) { koBarrier = koObservationList.Item2?.Select(O => OtcFormatHelper.FormatValue(O, 2)).ToArray() ?? new double[0]; } else { koBarrier = koObservationList.Item2?.Select(O => OtcFormatHelper.FormatValue(O, 6)).ToArray() ?? new double[0]; } var kiBarrier = snowball.KIBarrier; if (item.trade.IsMoneynessOptionData) { if (PS.Config.Company == Configuration.CompanyEnum.国投 || PS.Config.Company == Configuration.CompanyEnum.浙期) { koBarrier = koBarrier.Select(O => OtcFormatHelper.FormatValue(O * (item.trade.SpotPrice ?? 0), 2)).ToArray(); } else { koBarrier = koBarrier.Select(O => OtcFormatHelper.FormatValue(O * (item.trade.SpotPrice ?? 0), 6)).ToArray(); } kiBarrier *= item.trade.SpotPrice ?? 0; } item.SnowStatus = formatSnowStatus(snowball.KnockInOutStatus, koBarrier.Length > 0 ? koBarrier[index] : double.NaN, price); item.SnowStructureInfo = formatSnowStructureType(item.SnowType, snowball.KIPayoffType, koObservationList.Item2 ?? new double[0]); item.ClientType = formatClientType(client.id); if (koObservationList.Item1?.Length > 0) { var remark = obsvitionInfos.Where(O => O.TradeId == item.trade.id && O.MetaKey == ConsTradeMetaKey.ObservationRemark2).FirstOrDefault(); if (remark == null || remark.MetaValue.IsNullOrWhiteSpace()) { item.KOObservationDates = string.Join(";", koObservationList.Item1.Select(O => O.DateTime.ToString("yyyy-MM-dd"))); } else { item.KOObservationDates = remark.MetaValue; } } else { item.KOObservationDates = "逐日"; } item.KOBarrier = string.Join(";", koBarrier); if (PS.Config.Company == CompanyEnum.国投) { item.KOBarrier = string.Join(";", koBarrier.Select(l => l.ToString("#.00")).ToArray()); } if (snowball.KIPayoffType != KIPayoffTypeEnum.None && !snowball.IsInitialKnockedIn) { if (snowball.ObservationDates.IsNullOrWhiteSpace()) { item.KIObservationDates = "逐日"; } else { var remark = obsvitionInfos.Where(O => O.TradeId == item.trade.id && O.MetaKey == ConsTradeMetaKey.ObservationRemark1).FirstOrDefault(); if (remark == null || remark.MetaValue.IsNullOrWhiteSpace()) { item.KIObservationDates = snowball.ObservationDates.Replace(",", ";"); } else { item.KIObservationDates = remark.MetaValue; } } if (PS.Config.Company == Configuration.CompanyEnum.浙期) { item.KIBarrier = OtcFormatHelper.FormatValue(kiBarrier, 2); } else { item.KIBarrier = kiBarrier; } } item.PremiumRate = snowball.AnnualizedPremiumRate.HasValue ? snowball.AnnualizedPremiumRate?.ToString("0.######%") : item.trade.PremiumRate.HasValue ? item.trade.PremiumRate?.ToString("0.######%") : (item.trade.TradePrice / item.trade.OriginalStockEqvNotional)?.ToString("0.######%"); item.SnowType = formatSnowType2(item.trade, koObservationList.Item2); if (snowball.KIPayoffType == KIPayoffTypeEnum.ToCallSpreadOption || snowball.KIPayoffType == KIPayoffTypeEnum.ToPutSpreadOption) { var strikeLow = Math.Abs((snowball.SpreadStrikeAtMaturity1 ?? 0) - (snowball.SpreadStrikeAtMaturity ?? 0)); if (PS.Config.Is浙期) { strikeLow = snowball.SpreadStrikeAtMaturity ?? 0; item.PrincipalRate = ((item.trade.IsMoneynessOptionData ? strikeLow : strikeLow / item.trade.SpotPrice) ?? 0).ToString("0.######%"); } else { item.PrincipalRate = ((1 - (item.trade.IsMoneynessOptionData ? strikeLow : strikeLow / item.trade.SpotPrice)) ?? 0).ToString("0.######%"); } } if (item.PrincipalRate == "0%") { item.PrincipalRate = null; } item.InitialMargin = formatInitCastClientPayable(item.trade); item.PositionMargin = positionInfo?.Margin ?? 0; item.RiskYield = (item.trade.NoRiskRate - item.trade.DividendRate).ToString(); item.Coupon = item.trade.trade_snowball.Coupon; item.KOCoupon = item.trade.trade_snowball.KORebate; item.KIPayoffType = formatKIPayoffType(item.trade.trade_snowball.KIPayoffType); } if (item.IsGroup == 1) { var childIds = DbContext.trade.Where(x => x.ParentTradeId == item.TradeId).Select(x => x.id); var riskChilds = DbContext.eod_trade_risk.Where(x => childIds.Contains(x.TradeId) && x.ValueDate == _req.ValueDate).ToList(); item.Pv = riskChilds.Sum(x => x.Pv); if (_req.DataSource == "权益") { item.Delta = riskChilds.Sum(x => x.Delta / um.ContractSize).OtcFormat(OtcFormatFlag.greek); } else { item.Delta = riskChilds.Sum(x => x.Delta).OtcFormat(OtcFormatFlag.greek); } item.Vega = riskChilds.Sum(x => x.Vega); item.Theta = riskChilds.Sum(x => x.Theta); item.Rho = riskChilds.Sum(x => x.Rho) * 100; item.DeltaCash = riskChilds.Sum(x => x.DeltaCash).OtcFormat(OtcFormatFlag.greek); item.GammaCash = riskChilds.Sum(x => x.GammaCash); if (_req.DataSource == "权益") { item.InnerGamma = riskChilds.Sum(x => x.Gamma / um.ContractSize); } else { item.InnerGamma = riskChilds.Sum(x => x.Gamma); } } else if (!ignoreTradeTypes.Contains(item.TradeType)) { if (_req.DataSource == "权益") { item.Delta = ((double)(eRisk?.Delta ?? 0) / um.ContractSize).OtcFormat(OtcFormatFlag.greek); } else { item.Delta = ((double)(eRisk?.Delta ?? 0)).OtcFormat(OtcFormatFlag.greek); } item.Vega = eRisk?.Vega ?? 0; item.Theta = eRisk?.Theta ?? 0; item.Rho = (eRisk?.Rho ?? 0) * 100; item.DeltaCash = (eRisk?.DeltaCash ?? 0).OtcFormat(OtcFormatFlag.greek); item.GammaCash = eRisk?.GammaCash ?? 0; var otherRisks = JsonHelper.Parse(eRisk?.OtherRisks); if (otherRisks == null || string.IsNullOrWhiteSpace(otherRisks.CrossGamma)) { if (_req.DataSource == "权益") { item.InnerGamma = (double)(eRisk?.Gamma / um.ContractSize ?? 0); ; } else { item.InnerGamma = (double)(eRisk?.Gamma ?? 0); } } else { if (_req.DataSource == "权益") { item.CrossGamma = double.TryParse(otherRisks.CrossGamma, out var temp) ? (temp / um.ContractSize).OtcFormat(OtcFormatFlag.greek) : ""; } else { item.CrossGamma = otherRisks.CrossGamma; } } if (PS.Config.Company == Configuration.CompanyEnum.浙期 && item.SnowType != "2") { item.PrincipalRate = null; } } else { if (_req.DataSource == "权益") { item.Delta = ((double)(eRisk?.Delta ?? 0) / um.ContractSize).OtcFormat(OtcFormatFlag.greek); } else { item.Delta = ((double)(eRisk?.Delta ?? 0)).OtcFormat(OtcFormatFlag.greek); } item.DeltaCash = (eRisk?.DeltaCash ?? 0).OtcFormat(OtcFormatFlag.greek); item.GammaCash = eRisk?.GammaCash ?? 0; if (PS.Config.Company == Configuration.CompanyEnum.浙期 && !string.IsNullOrWhiteSpace(item.trade.BasisUnderlyingCode)) { if (item.SnowType != "2") { item.PrincipalRate = ""; } item.Delta += "," + item.Delta; item.DeltaCash += "," + item.DeltaCash; item.GammaCash = 0; } if (_req.DataSource == "权益") { item.InnerGamma = (double)(eRisk?.Gamma / um.ContractSize ?? 0); ; } else { item.InnerGamma = (double)(eRisk?.Gamma ?? 0); } } if (PS.Config.Is国投) { item.SpotPrice = item.trade.SpotPrice ?? 0; } FormatModel(item, varietyTypeList, assetTypeList, varietySuffixList, varietyCodeList, out _); } } catch (ServiceException ex) { LogFactory.GetLogger("SuperviseReportPositionService").Error(ex, "已知错误"); throw ex; } catch (Exception ex) { LogFactory.GetLogger("SuperviseReportPositionService").Error(ex, "未知错误"); throw; } } return retListResult; } /// /// /// /// /// 标的资产类型 /// 资产类型 /// 标的资产品种后缀和标的资产对应合约后缀 /// 组合标的价格 /// EodTrade不存在时抛出 protected override void FormatModel(SuperviseReportBaseModel model, List varietyTypes, List assetTypes, List varietySuffixs, List varietyCodeList, out SyntheticPriceModel syntheticPrice) { var obj = (SuperviseReportPositionModel)model; base.FormatModel(obj, varietyTypes, assetTypes, varietySuffixs, varietyCodeList, out syntheticPrice); obj.TradeDate = obj.trade.TradeDate; obj.ExerciseDate = obj.ExerciseDate == null ? obj.trade.ExerciseDate : obj.ExerciseDate; //var annualizeFactor = obj.trade.IsAnnualized ? obj.trade.AnnualizeFactor : 1; double endEqv, eqv; if (syntheticPrice != null && syntheticPrice.SuList.Count() > 0) { var underlyingPrices = syntheticPrice.SuList.ToArray(); var arrSEN = new string[underlyingPrices.Length]; var arrEndSEN = new string[underlyingPrices.Length]; var arrAmount = new string[underlyingPrices.Length]; var arrEndAmount = 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 / obj.trade.AnnualizeFactor / obj.trade.ParticipationRate * underlyingPrices[i].Coefficient) ?? 0; ////var stockEqvNotional = underlyingPrices[i].Price * obj.trade.Notional * underlyingPrices[i].Coefficient; //if (obj.trade.TradeType == "凤凰期权" && (obj.trade.trade_autocall?.IsAnnualized2).GetValueOrDefault()) //{ // originalStockEqvNotional = originalStockEqvNotional * (obj.trade.trade_autocall.AnnualizeFactor2 ?? 1); // //stockEqvNotional = stockEqvNotional * (obj.trade.trade_autocall.AnnualizeFactor2 ?? 1); //} //else if (obj.trade.TradeType == "雪球期权" && (obj.trade.trade_snowball?.IsAnnualized2).GetValueOrDefault()) //{ // originalStockEqvNotional = originalStockEqvNotional * (obj.trade.trade_snowball.AnnualizeFactor2 ?? 1); // //stockEqvNotional = stockEqvNotional * (obj.trade.trade_snowball.AnnualizeFactor2 ?? 1); //} eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1); endEqv = formatEndStockEqvNotionalReal(eqv, (1 - (obj.trade.Notional / obj.trade.OriginalNotional ?? 1))); 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] = _priceProvider.GetPrice(underlyingPrices[i].UnderlyingCode).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.InitialSpotPrice = string.Join(base._separator, arrSpotPrice);//只有多标的时才采用期初价格,单标的时会采用最新价格; } else { var originalStockEqvNotional = (obj.trade.OriginalStockEqvNotional == 0 ? (obj.trade.SpotPrice * obj.trade.OriginalNotional / obj.trade.AnnualizeFactor / obj.trade.ParticipationRate) : obj.trade.OriginalStockEqvNotional) ?? 0; //if (obj.trade.TradeType == "凤凰期权" && (obj.trade.trade_autocall?.IsAnnualized2).GetValueOrDefault()) //{ // originalStockEqvNotional = originalStockEqvNotional * (obj.trade.trade_autocall.AnnualizeFactor2 ?? 1); //} //else if (obj.trade.TradeType == "雪球期权" && (obj.trade.trade_snowball?.IsAnnualized2).GetValueOrDefault()) //{ // originalStockEqvNotional = originalStockEqvNotional * (obj.trade.trade_snowball.AnnualizeFactor2 ?? 1); //} eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1); endEqv = formatEndStockEqvNotionalReal(eqv, (1 - (obj.trade.Notional / (obj.trade.OriginalNotional ?? 1)))); 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(); } obj.NoRiskRate = obj.trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate * 0.01); obj.DiscountRate = obj.trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate * 0.01); //obj.Delta /= um.ContractSize; //obj.InnerGamma /= um.ContractSize; } /// /// 格式化敲入期权类型 /// /// 敲入期权类型 /// private string formatKIPayoffType(KIPayoffTypeEnum kiPayoffType) { var result = ""; switch (kiPayoffType) { case KIPayoffTypeEnum.ToPutOption: result = "1"; break; case KIPayoffTypeEnum.ToPutSpreadOption: result = "3"; break; case KIPayoffTypeEnum.ToCallOption: result = "2"; break; case KIPayoffTypeEnum.ToCallSpreadOption: result = "4"; break; case KIPayoffTypeEnum.None: default: result = "9"; break; } return result; } /// /// 格式化雪球期权状态 /// /// 期权观察状态 /// 敲出障碍价格 /// 现价 /// private string formatSnowStatus(string knockInOutStatus, double koBarrier, double price) { if (knockInOutStatus == "KnockedIn") { return koBarrier > price ? "3" : "2";//2:敲入过且现价大于等于敲出价;3:敲入过且现价小于敲出价; } else if (knockInOutStatus != "KnockedOut") { return "1";// "未敲入过"; } else { return ""; } } /// /// 格式化客户类型 /// /// 客户Id /// private string formatClientType(int clientId) { var result = ""; var clientInfo = DataCacheProvider.GetClientDataSource().GetData(clientId); if (clientInfo.ClientType == "产品") { result = "1";//产品 } else { if (clientInfo.BusinessType == null) { result = "9";//其他 } else if (clientInfo.BusinessType.Contains("券商")) { result = "2";//券商 } else if (clientInfo.BusinessType.Contains("银行")) { result = "3";//银行 } else if (clientInfo.BusinessType.Contains("期货")) { result = "4";//期货公司风险管理子公司 } else { result = "9";//其他 } } return result; } private string formatSnowType2(trade t, double[] koObservationPrice) { var result = "9";//其他 var snowball = t.trade_snowball; if (snowball.KORebate != 0) { if ((snowball.KIPayoffType == KIPayoffTypeEnum.ToPutOption || snowball.KIPayoffType == KIPayoffTypeEnum.ToCallOption) && koObservationPrice != null && koObservationPrice.ToHashSet().Count() > 1) { if (t.PrincipalRate.GetValueOrDefault() == 0) { result = "3";//阶梯价雪球 } else { result = "9";//其他 } } else if (snowball.KIPayoffType == KIPayoffTypeEnum.ToPutSpreadOption || snowball.KIPayoffType == KIPayoffTypeEnum.ToCallSpreadOption) { result = "2";//保底雪球 } else if (snowball.KIPayoffType == KIPayoffTypeEnum.ToPutOption || snowball.KIPayoffType == KIPayoffTypeEnum.ToCallOption) { result = "1";//传统雪球和带敲出观察空窗的传统雪球 } else if (snowball.KIPayoffType == KIPayoffTypeEnum.None) { result = "4";//小雪球 } } return result; } /// /// 格式化雪球结构要素 /// /// 雪球类型 /// 敲入支付方式 /// 敲出价格列表 /// private string formatSnowStructureType(string snowType, KIPayoffTypeEnum kiPayoffType, double[] koObservationPrice) { var result = new List(); if (kiPayoffType == KIPayoffTypeEnum.ToPutOption) { result.Add("1");//普通 } if (koObservationPrice.ToHashSet().Count() > 1) { //由于现阶段敲入观察价格不支持多个,所以只要是阶梯价雪球,一定是敲出要素变化 result.Add("3");//敲出要素变化 } if (kiPayoffType == KIPayoffTypeEnum.ToCallSpreadOption) { result.Add("4");//敲入转牛市价差 } if (kiPayoffType == KIPayoffTypeEnum.ToPutSpreadOption) { result.Add("5");//敲入转熊市价差 } if (snowType == "4" || result.Count == 0) { result.Add("9");//其他 } return string.Join(";", result); } } }