using BaseOUDAL; using CsvHelper; using CsvHelper.Configuration; using ICSharpCode.SharpZipLib.Zip; using System.Data; using YLErp.Commons; using YLErp.DBModels.Helpers; using YLErp.Modules.ClientModule; using YLErp.Modules.TradeModule; using YLErp.Office.ExcelModule; using YLErp.QdpModule; namespace YLErp.Modules.EodModule.QueryModule { /// /// 日终持仓导出服务 /// 暂时用于兴证数据接口导出 /// public class EodTradePositionExportService : YLBaseService { public EodTradePositionExportService(OptUserInfo optUser) : base(optUser) { } /// /// 查询场外期权持仓列表 /// public void SearchOptionTradeListForExport(DateTime valueDate , out List listOption , out List listSwap) { listSwap = null; listOption = null; var IsPVRounded = PS.Config.IsPVRounded; valueDate = valueDate.Date; var query = from et in DbContext.eod_trade join etp in DbContext.eod_trade_position on et.TradeId equals etp.TradeId join etr in DbContext.eod_trade_risk on et.TradeId equals etr.TradeId where et.ValueDate == valueDate && etp.ValueDate == valueDate && etr.ValueDate == valueDate && et.TradeId > 0 && etp.TradeId > 0 && etr.TradeId > 0 && et.TradeType != "结构化交易" && et.ClientId > 0 select new { et.TradeId, et.TradeJson, etp.Amount, etp.Pv, PositionPv = IsPVRounded ? etp.RoundedPv : etp.Pv, PositionPnl = IsPVRounded ? etp.RoundedPositionPnL : etp.PositionPnL, etr.Vol }; //因为query还在读取中,所以不要用同一个dbcontext var extendService = new TradeExtendService(OptUser); foreach (var item in query) { var td = TradeHelper2.Deserialize(item.TradeJson); if (td == null) { td = DbContext.trade.Find(item.TradeId); } if (td == null) { continue; } extendService.SetTradeExtend(new[] { td }, true); if (td.TradeType == "收益互换") { var f = GetEodPayOffSwapPostionFields(td, item.Amount, item.PositionPnl, item.PositionPv); if (listSwap == null) { listSwap = new List(); } listSwap.Add(f); } else if (td.TradeType == "远期") { } else { var f = GetEodOptionPostionFields(td, item.Amount, item.PositionPnl, item.PositionPv, item.Vol); if (listOption == null) { listOption = new List(); } listOption.Add(f); } } } //场外期权 private EodOptionPositionExportFields GetEodOptionPostionFields(trade td, double PositionTradeAmount, double PositionPnl, double PositionPv, double PositionVol) { var isMoneyness = td.IsMoneynessOption == "是"; var isPremiumRate = td.IsUsePremiumRate == true; var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); var volFormat = PS.Config.ErpElement.VolMoreAccurate ? "P2" : "P4"; var f = new EodOptionPositionExportFields { TradeNumber = td.TradeNumber, AssetBookName = td.AssetBookName, TraderName = td.TraderName, ClientName = td.ClientName, StructureType = td.TradeType, ExerciseMode = td.ExerciseModeCn, CallPut = td.CallPut, TradeDate = td.TradeDate.OtcFormatDate(), ExerciseDate = td.ExerciseDate.OtcFormatDate(), SettlementDate = td.SettlementDate.OtcFormatDate(), TradeSide = td.BuySell, UnderlyingCode = td.UnderlyingCode, UnderlyingName = underlying?.UnderlyingName, InitSpotPrice = td.SpotPrice.OtcFormatUmPrice(), Strike = td.Strike.OtcFormatUmPrice(isMoneyness), IsMoneynessOption = isMoneyness ? "是" : "否", Premium = isPremiumRate ? td.PremiumRate.OtcFormat(OtcFormatFlag.premiumRateP) : td.TradeSinglePrice.OtcFormat(OtcFormatFlag.tradeSinglePrice), IsUsePremiumRate = isPremiumRate ? "是" : "否", InitialMargin = td.InitialMargin.OtcFormatMoney(), TradeAmount = td.OriginalNotional.OtcFormatNotional(), TradePrice = td.TradePrice.OtcFormatMoney(), StockEqvNotional = td.OriginalStockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional), StockEqvNotionalReal = td.StockEqvNotionalReal.OtcFormat(OtcFormatFlag.StockEqvNotional), IsAnnualized = td.IsAnnualized ? "是" : "否", AnnualizeFactor = td.AnnualizeFactor?.ToString("F8"), PrincipalRate = td.PrincipalRate.OtcFormatPercent(), ParticipationRate = td.ParticipationRate.OtcFormatPercent(), NoRiskRate = td.NoRiskRate.OtcFormatPercent(), DividendRate = td.DividendRate.OtcFormatPercent(), TradeOpenVolatility = td.TradeOpenVolatility?.ToString(volFormat), TradeCloseVolatility = td.TradeCloseVolatility?.ToString(volFormat), NumOfSmoothingDays = td.NumOfSmoothingDays?.ToString(), Comments = td.Comments, PositionPnl = Convert.ToDouble(PositionPnl).OtcFormatMoney(), PositionPv = Convert.ToDouble(PositionPv).OtcFormatMoney(), PositionTradeAmount = PositionTradeAmount.OtcFormatNotional(), PositionVol = PositionVol.ToString(volFormat) }; f.ClientNumber = ClientDataQueryService.GetClient(td.ClientId)?.Number; switch (f.StructureType) { case "亚式期权": if (td.trade_asian_option != null) { var ext = td.trade_asian_option; f.AsianAveragingPeriodStartDate = ext.AveragingPeriodStartDate.OtcFormatDate(); f.AsianPayoffType = ext.PayoffTypeCn; f.AsianStrikeType = ext.StrikeTypeCn; f.AsianStrikeGearingFactor = ext.StrikeGearingFactor.OtcFormatPercent(); } break; case "障碍期权": if (td.trade_barrier_option != null) { var ext = td.trade_barrier_option; f.BarrierType = ext.BarrierType; f.BarrierPrice = ext.BarrierPrice.OtcFormatUmPrice(isMoneyness); f.BarrierPriceHigh = ext.UpperBarrierPrice.OtcFormatUmPrice(isMoneyness); f.BarrierShift = ext.BarrierShift.OtcFormatUmPrice(); f.BarrierRebate = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.RebateRate, ext.Rebate); f.BarrierRebateType = ext.RebateTypeCn; f.BarrierDiscrete = ext.Discrete; f.BarrierKnockInOutStatus = ext.KnockInOutStatus; f.BarrierKnockInOutDate = ext.KnockInOutDate.OtcFormatDate(); } break; case "双鲨期权": if (td.trade_double_sharkfin_option != null) { var ext = td.trade_double_sharkfin_option; f.DbsharkBarrierLow = ext.BarrierLow.OtcFormatUmPrice(isMoneyness); f.DbsharkBarrierHigh = ext.BarrierHigh.OtcFormatUmPrice(isMoneyness); f.DbsharkStrikeHigh = ext.StrikeHigh.OtcFormatUmPrice(isMoneyness); f.DbsharkCallParticipationRate = ext.CallParticipationRate.OtcFormatPercent(); f.DbsharkPutParticipationRate = ext.PutParticipationRate.OtcFormatPercent(); f.DbsharkRebate = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.RebateRate, ext.Rebate); f.DbsharkRebateHigh = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.RebateHighRate, ext.RebateHigh); f.DbsharkRebateType = TradeHelper.GetRebateTypeCn(ext.RebateType); f.DbsharkDiscrete = ext.Discrete; } break; case "二元期权": if (td.trade_binary_option != null) { var ext = td.trade_binary_option; f.BinaryPayoffType = ext.PayoffType; f.BinaryUpperBarrier = ext.UpperBarrier.OtcFormatUmPrice(isMoneyness); f.BinaryCashOrNothingAmount = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.CashOrNothingAmountRate, ext.CashOrNothingAmount); f.BinaryCashOrNothingAmountHigh = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.CashOrNothingAmountHighRate, ext.CashOrNothingAmountHigh); f.BinaryMonitorType = ext.MonitorType; f.BinaryRebateType = TradeHelper.GetRebateTypeCn(ext.RebateType); } break; case "区间累积期权": if (td.trade_rangeaccrual != null) { var ext = td.trade_rangeaccrual; f.RangeAccrualLowerRange = ext.LowerRange.OtcFormatUmPrice(isMoneyness); f.RangeAccrualUpperRange = ext.UpperRange.OtcFormatUmPrice(isMoneyness); f.RangeAccrualBonusRate = ext.BonusRate.OtcFormatPercent(4); f.CallPut = string.Empty; } break; case "气囊结构": if (td.trade_airbag != null) { var ext = td.trade_airbag; f.AirbagBarrier = ext.Barrier.OtcFormatUmPrice(isMoneyness); f.AirbagIsDiscrete = ext.IsDiscreteMonitored ? "是" : "否"; f.AirbagKIParticipationRate = ext.KIParticipationRate.OtcFormatPercent(); f.AirbagHasPayoffLimit = ext.HasPayoffLimit ? "是" : "否"; f.AirbagHighStrike = ext.HighStrike.OtcFormatUmPrice(isMoneyness); f.CallPut = string.Empty; } break; case "收益增强结构": if (td.trade_underlying_enhance != null) { f.CallPut = string.Empty; f.AnnualizedEnhanceRate = td.trade_underlying_enhance.AnnualizedEnhanceRate.OtcFormatPercent(4); } break; case "凤凰期权": if (td.trade_autocall != null) { var ext = td.trade_autocall; f.AutocallIsFixedCoupon = ext.IsFixedCoupon ? "否" : "是"; f.AutocallCoupon = ext.Coupon.OtcFormatPercent(); f.AutocallCouponBarrier = ext.CouponBarrier.OtcFormatUmPrice(isMoneyness); f.AutocallCouponPayType = ext.CouponPayTypeDesc(); f.AutocallKOBarrier = ext.KOBarrier.OtcFormatUmPrice(isMoneyness); f.AutocallKIBarrier = ext.KIBarrier.OtcFormatUmPrice(isMoneyness); f.AutocallIncludeCouponAfterKI = ext.IncludeCouponAfterKI ? "是" : "否"; f.AutocallKIPayoffType = ext.KIPayoffTypeDesc(); f.AutocallKIStrike1 = ext.SpreadStrike1.OtcFormatUmPrice(isMoneyness); if (ext.KIPayoffType == KIPayoffTypeEnum.ToPutSpreadOption) { f.AutocallKIStrike2 = ext.SpreadStrike.OtcFormatUmPrice(isMoneyness); } var KOObservationDates = ext.KOObservationDates ?? string.Empty; var index = KOObservationDates.IndexOf(';'); f.KOObservationDates = index > 0 ? ext.KOObservationDates.Substring(0, index) : KOObservationDates; f.KIObservationDates = ext.ObservationDates; f.IsAnnualized = ext.IsAnnualized2 ? "是" : "否"; } break; case "雪球期权": if (td.trade_snowball != null) { var ext = td.trade_snowball; f.SnowballKOBarrier = ext.KOBarrier.OtcFormatUmPrice(isMoneyness); switch (ext.KOPayoffType) { case KOPayoffTypeEnum.Rebate: f.SnowballKOPayoffType = "票息补偿"; f.SnowballIsFixedCoupon = ext.IsFixedCoupon ? "否" : "是"; f.SnowballKORebate = ext.KORebate.OtcFormatPercent(); f.SnowballAnnualizedPremiumRate = ext.AnnualizedPremiumRate.OtcFormatPercent(); f.SnowballKOObservationSettleDates = ext.KOObservationSettleDates; break; case KOPayoffTypeEnum.ToOption: f.SnowballKOPayoffType = KOPayoffTypeEnumHelper.GetDesc(ext.KOPayoffType, td.CallPut); f.SnowballKOStrike1 = ext.SpreadStrikeAtKO1.OtcFormatUmPrice(isMoneyness); break; case KOPayoffTypeEnum.ToSpreadOption: f.SnowballKOPayoffType = KOPayoffTypeEnumHelper.GetDesc(ext.KOPayoffType, td.CallPut); f.SnowballKOStrike2 = ext.SpreadStrikeAtKO.OtcFormatUmPrice(isMoneyness); f.SnowballKOStrike1 = ext.SpreadStrikeAtKO1.OtcFormatUmPrice(isMoneyness); break; default: f.SnowballKOPayoffType = ext.KOPayoffType.ToString(); break; } f.SnowballKORebateType = RebateTypeEnumHelper.GetDesc(ext.KORebateType); f.SnowballKIBarrier = ext.KIBarrier.OtcFormatUmPrice(isMoneyness); switch (ext.KIPayoffType) { case KIPayoffTypeEnum.None: f.SnowballKIPayoffType = "无"; break; case KIPayoffTypeEnum.ToPutOption: f.SnowballKIPayoffType = "敲入转看跌"; f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness); break; case KIPayoffTypeEnum.ToPutSpreadOption: f.SnowballKIPayoffType = "敲入转熊市价差"; f.SnowballKIStrike2 = ext.SpreadStrikeAtMaturity.OtcFormatUmPrice(isMoneyness); f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness); break; case KIPayoffTypeEnum.ToCallOption: f.SnowballKIPayoffType = "敲入转看涨"; f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness); break; case KIPayoffTypeEnum.ToCallSpreadOption: f.SnowballKIPayoffType = "敲入转牛市价差"; f.SnowballKIStrike2 = ext.SpreadStrikeAtMaturity.OtcFormatUmPrice(isMoneyness); f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness); break; default: f.SnowballKIPayoffType = ext.KIPayoffType.ToString(); break; } f.SnowballNoKICoupon = ext.Coupon.OtcFormatPercent(); var KOObservationDates = ext.KOObservationDates ?? string.Empty; var index = KOObservationDates.IndexOf(';'); f.KOObservationDates = index > 0 ? ext.KOObservationDates.Substring(0, index) : KOObservationDates; f.KIObservationDates = ext.ObservationDates; f.IsAnnualized = ext.IsAnnualized2 ? "是" : "否"; } break; } if (td.TradeType == "凤凰期权" || td.TradeType == "雪球期权") { f.CallPut = f.ExerciseMode = string.Empty; td.MetaDic.TryGetValue(nameof(OtcOptionTradeFull.AnnualizeFactor2), out var metaValue); f.AnnualizeFactor = metaValue; } else { td.MetaDic.TryGetValue(nameof(OtcOptionTradeFull.AnnualizeFactor), out var metaValue); f.AnnualizeFactor = metaValue; } return f; } //收益互换 private EodPayOffSwapPositionExportFields GetEodPayOffSwapPostionFields(trade td, double PositionTradeAmount, double PositionPnl, double PositionPv) { var swap = td.trade_swap ?? new trade_swap(); var f = new EodPayOffSwapPositionExportFields { TradeNumber = td.TradeNumber, AssetBookName = td.AssetBookName, TraderName = td.TraderName, ClientName = td.ClientName, TradeDate = td.TradeDate.OtcFormatDate(), ExerciseDate = td.ExerciseDate.OtcFormatDate(), StockEqvNotional = td.OriginalStockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional), Comments = td.Comments, GetFixedProfit = swap.GetFixedProfit.OtcFormatMoney(), GetLongShort = swap.GetLongShort, GetMarginRate = swap.GetMarginRate.OtcFormatFlex(minDecimals: 0, percent: true), GetTradePrice = swap.GetTradePrice.OtcFormatMoney(), GetUnderlyingCode = swap.GetUnderlyingCode, GetSpotPrice = swap.GetSpotPrice.OtcFormatUmPrice(), IsGetFloatingProfit = swap.IsGetFloatingProfit ? "是" : "否", IsPayFloatingProfit = swap.IsPayFloatingProfit ? "是" : "否", PayFixedProfit = swap.PayFixedProfit.OtcFormatMoney(), PayLongShort = swap.PayLongShort, PayMarginRate = swap.PayMarginRate.OtcFormatMoney(), PaySpotPrice = swap.PaySpotPrice.OtcFormatUmPrice(), PayTradePrice = swap.PayTradePrice.OtcFormatMoney(), PayUnderlyingCode = swap.PayUnderlyingCode, PositionPnl = Convert.ToDouble(PositionPnl).OtcFormatMoney(), PositionPv = Convert.ToDouble(PositionPv).OtcFormatMoney(), PositionStockEqvNotional = PositionTradeAmount.OtcFormat(OtcFormatFlag.StockEqvNotional) }; f.ClientNumber = ClientDataQueryService.GetClient(td.ClientId)?.Number; return f; } /// /// 查询场内期权持仓列表 /// public IEnumerable SearchExOptionTradeListForExport(DateTime valueDate) { var IsPVRounded = PS.Config.IsPVRounded; var umSource = DataCacheProvider.GetUnderlyingDataSource(); var exOptionSource = DataCacheProvider.GetExchangeListOptionDataSource(); var volFormat = PS.Config.ErpElement.VolMoreAccurate ? "P2" : "P4"; valueDate = valueDate.Date; var query = from etp in DbContext.eod_trade_position join etr in DbContext.eod_trade_risk on etp.TradeId equals etr.TradeId where etp.ValueDate == valueDate && etr.ValueDate == valueDate && etp.TradeType == "场内期权" select new { etp.UnderlyingCode, etp.ExchangeOptionCode, etp.Amount, etp.PositionType, PositionPv = IsPVRounded ? etp.RoundedPv : etp.Pv, PositionPnl = IsPVRounded ? etp.RoundedPositionPnL : etp.PositionPnL, etr.Vol }; var list = new List(); foreach (var item in query) { var exoption = exOptionSource.GetData(item.ExchangeOptionCode); var f = new EodExOptionPositionExportFields { OptionCode = item.ExchangeOptionCode, ExerciseMode = exoption?.ExerciseMode, Strike = (exoption?.Strike)?.ToString("F4"), UnderlyingCode = item.UnderlyingCode, PositionType = item.PositionType, PositionPnl = Convert.ToDouble(item.PositionPnl).OtcFormatMoney(), PositionPv = Convert.ToDouble(item.PositionPv).OtcFormatMoney(), PositionTradeAmount = item.Amount.OtcFormatNotional(), PositionVol = item.Vol.ToString(volFormat) }; list.Add(f); } return list; } /// /// 导出兴证数据中心需要的文件 /// public byte[] ExportXingZhengZipFile(DateTime valueDate, out string zipFileName, IEnumerable clienIds = null) { valueDate = valueDate.Date; if (QdpCalendarHelper.GetNonHoliday(valueDate) != valueDate) { throw new ServiceException($"所选日期'{valueDate:yyyy-MM-dd}'不是交易日!"); } if (!DbContext.eodStatus.Any(n => n.ValueDate == valueDate && n.Status == "已收盘")) { throw new ServiceException($"所选日期'{valueDate:yyyy-MM-dd}'未收盘!"); } SearchOptionTradeListForExport(valueDate, out var listOption, out var listSwap); var listExOption = SearchExOptionTradeListForExport(valueDate); var dateStr = valueDate.ToString("yyyyMMdd"); zipFileName = $"ylotc_position_{dateStr}.zip"; var clients = DbContextFactory.GetClientDbContext(UserInfo).client .Where(d => d.ProcessStatus == "已开户" || d.ProcessStatus == "已休眠" || d.ProcessStatus == "已销户") .Select(n => new InnerClientInfo { id = n.id, ClientNumber = n.Number, ClientName = n.Name, LicenseCode = n.LicenseCode, ClientType = n.ClientType }).ToArray(); #region 新增客户筛选 tw if (clienIds != null) { clients = clients.Where(l => clienIds.Contains(l.id)).ToArray(); } #endregion using (var yldb = DbContextFactory.GetYLDbContext()) { var sumQuery = from t in yldb.trade where t.ValidState != ConsGlobal.InValid && t.IsGroup != 2 && (t.TradeType != "结构化交易" || t.IsGroup == 1) group t by t.ClientId into g select new { clientId = g.Key, sum = g.Sum(n => n.OriginalStockEqvNotional ?? 0) }; var sumDic = sumQuery.ToDictionary(n => n.clientId, m => m.sum); foreach (var c in clients) { if (sumDic.TryGetValue(c.id, out var sum)) { c.StockEqvNotional = sum.ToString("F4"); } } } using (var ms = new MemoryStream()) using (var outStream = new ZipOutputStream(ms)) using (var writer = new StreamWriter(outStream)) { var csvConfig = new CsvConfiguration(System.Globalization.CultureInfo.InvariantCulture) { LeaveOpen = true, Delimiter = "$#$" }; outStream.PutNextEntry(new ZipEntry($"ylotc_position_option_{dateStr}.csv")); using (var csv = new CsvWriter(writer, csvConfig)) { csv.WriteRecords(listOption ?? Enumerable.Empty()); } writer.Flush(); outStream.PutNextEntry(new ZipEntry($"ylotc_position_exoption_{dateStr}.csv")); using (var csv = new CsvWriter(writer, csvConfig)) { csv.WriteRecords(listExOption ?? Enumerable.Empty()); } writer.Flush(); outStream.PutNextEntry(new ZipEntry($"ylotc_position_payoffswap_{dateStr}.csv")); using (var csv = new CsvWriter(writer, csvConfig)) { csv.WriteRecords(listSwap ?? Enumerable.Empty()); } writer.Flush(); outStream.PutNextEntry(new ZipEntry($"ylotc_client_{dateStr}.csv")); using (var csv = new CsvWriter(writer, csvConfig)) { csv.WriteRecords(clients); } writer.Flush(); writer.Close(); return ms.ToArray(); } } public byte[] GetClient() { var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/国投客户数据采集.xlsx"); using (var baseDb = new ClientDBContext()) { //处理客户不属于 内部客户 n.IsInsided!=1 var ClientList = baseDb.client.Where(n => n.ProcessStatus == "已开户"&&n.IsInsided!=1).Select(x => new ClientInfo { ClientType = x.ClientType == "自然人" ? "个人" : x.ClientType, ClientName = x.Name, ClientTypeMemo = x.ClientType == "机构" ? "机构全称" : x.ClientType == "自然人" ? "" : "产品全称", AdminFullName = x.ClientType == "产品" ? x.AdminFullName : "", LicenseType = x.ClientType == "机构" ? "统一社会信用代码" : x.ClientType == "自然人" ? "居民身份证" : "产品编号", AdminFullNameMome = x.ClientType == "产品" ? "产品管理人全称" : "", IdentificationNumber = x.ClientType == "机构" ? x.LicenseCode : x.ClientType == "自然人" ? x.IdentificationNumber : x.ProductNumber, AdminFullNameLicenseType = x.ClientType == "机构" ? "" : x.ClientType == "自然人" ? "" : "统一社会信用代码", AdminRegisteredNum = x.ClientType == "产品" ? x.LicenseCode : "", MainProtocolCode = x.MainProtocolCode }); var buffer = ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = ClientList }).GenerateBytes(); return buffer; } } public byte[] GetEodPosition(Model.EodPositionRisksReq req) { var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/国投数据采集.xlsx"); using (var baseDb = new ClientDBContext()) { req.ValueDate = req.ValueDate; req.EodSettlePriceMode = "收盘价"; req.IsOnlyExport = false; req.IsParentTrade = false; req.needSettleData = false; req.VolType = "持仓"; //处理客户不属于 内部客户 req.ClientIds = baseDb.client.Where(n => n.IsInsided != 1).Select(l => l.id).ToList(); var result = new EodPositionRisksQueryService(UserInfo).SearchList(req); var responEodPositions = new List(); foreach (var item in result.rows) { var responEodPosition = new ResponEodPosition(); var td = DbContext.trade.FirstOrDefault(l => l.id == item.id); responEodPosition.bookName = item.AssetBookName; responEodPosition.tradeId = item.TradeNumber; responEodPosition.positionId = item.trade?.AssetId; responEodPosition.underlyerInstrumentId = item.UnderlyingCode; responEodPosition.underlyerMultiplier = GetunderlyerMultiplier(item.UnderlyingCode); responEodPosition.productType = item.TradeType; responEodPosition.initialNumber = item.TradeOriginalAmount; responEodPosition.unwindNumber = td?.UnWindNotional; responEodPosition.number = item.Notional; responEodPosition.premium = item.TradePrice; responEodPosition.marketValue = item.RoundedPV; responEodPosition.pnl = item.dailyPnl; responEodPosition.delta = item.Delta; responEodPosition.deltaCash = item.DeltaCash; responEodPosition.gamma = item.Gamma; responEodPosition.gammaCash = item.GammaCash; responEodPosition.vega = item.Vega; responEodPosition.theta = item.Theta; responEodPosition.rho = item.Rho; responEodPosition.effectiveDate = td?.TradeDate; responEodPosition.expirationDate = td?.ExerciseDate; responEodPosition.message = ""; responEodPosition.pricingEnvironment = ""; responEodPosition.r = item.RiskFreeRate; responEodPosition.q = item.DividendRate; responEodPosition.vol = item.CurrentVolatility; responEodPosition.listedOption = 0;//! responEodPosition.price = item.UnderlyingPrice; responEodPosition.notional = td?.StockEqvNotionalReal; responEodPosition.initialNotional = item.StockEqvNotional; responEodPosition.initialMargin = item.Margin; responEodPosition.maintenanceMargin = td?.InitialMargin; responEodPosition.initialVol = item.CurrentVolatility; responEodPosition.masterAgreementId = GetmasterAgreement(item.ClientNumber); responEodPosition.direction = td?.BuySell; if (td != null) { responEodPosition.initialQ = GetinitialQ(item.id, req.ValueDate); responEodPosition.initialR = GetinitialR(item.id, req.ValueDate); responEodPosition.term = QdpModule.QdpCalendarHelper.AllBizDays(Convert.ToDateTime(td.TradeDate), Convert.ToDateTime(td.ExerciseDate)).Count; var strike = DbContext.trade_double_sharkfin_option.FirstOrDefault(l => l.TradeId == item.id); responEodPosition.highStrike = strike?.StrikeHigh; responEodPosition.lowStrike = strike?.StrikeLow; } responEodPosition.settlementDate = td?.SettlementDate;//! responEodPosition.tradeStatus = item.TradeStatus; responEodPosition.lcmEventType = item.TradeStatus; responEodPosition.initialSpot = td?.SpotPrice; responEodPosition.highBarrier = item.RebateHigh; responEodPosition.lowBarrier = item.Rebate; responEodPosition.participationRates = item.ParticipationRate; responEodPosition.rebate = item.Rebate; responEodPosition.annualized = td?.IsAnnualized; responEodPosition.specifiedPrice = td?.SettlementType == SettlementTypeEnum.ClosePrice ? "收盘价" : "结算价"; responEodPosition.frontPremium = item.TradeAmount; responEodPosition.minimumPremium = td?.PrincipalRateWrite; responEodPosition.daysInYear = item.InitialSpotPrice;//? responEodPosition.initialPricingValue = item.TradeSinglePrice; responEodPosition.initialUnderlyerPrice = td?.UnderlyingPrice; responEodPosition.portfolioNames = item.TradeType; responEodPosition.trader = td?.TraderName; responEodPosition.tradeConfirmId = item.ContractCode; responEodPosition.underlyerPrice = item.UnderlyingPrice; responEodPosition.callput = item.trade?.CallPut; responEodPositions.Add(responEodPosition); } var buffer = ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list2 = responEodPositions }).GenerateBytes(); return buffer; } } /// /// 获取开仓无风险利率 /// public double? GetinitialQ(int tdId, DateTime dateTime) { return DbContext.TradeHisData.Where(l => l.TradeId == tdId && l.ValueDate == dateTime && l.ValueType == "NoRiskRate").FirstOrDefault()?.Value; } /// /// 获取开仓分红率 /// public double? GetinitialR(int tdId, DateTime dateTime) { return DbContext.TradeHisData.Where(l => l.TradeId == tdId && l.ValueDate == dateTime && l.ValueType == "DividendRate").FirstOrDefault()?.Value; } /// /// 获取 合约乘数 /// /// /// public double? GetunderlyerMultiplier(string UnderlyingCode) { var underlyerMultiplier = DataCacheProvider.GetUnderlyingDataSource().GetData(UnderlyingCode).ContractSize; return underlyerMultiplier; } /// /// 获取sac主协议编号 /// /// /// public string GetmasterAgreement(string ClientNumber) { var clientdb = new ClientDBContext(); if (string.IsNullOrEmpty(ClientNumber)) { return ""; } return clientdb.client.First(l => l.Number == ClientNumber).MainProtocolCode; } // {{item.positionId}} {{item.underlyerInstrumentId}} {{item.underlyerInstrumentIds}} {{item.underlyerMultiplier}} {{item.underlyerMultipliers}} // {{item.productType}} {{item.initialNumber}} {{item.initialNumbers}} {{item.unwindNumber}} {{item.unwindNumbers}} {{item.number}} {{item.numbers}} // {{item.premium}} {{item.unwindAmount}} {{item.marketValue}} {{item.pnl}} {{item.delta}} {{item.deltas}} {{item.deltaCash}} {{item.deltaCashes}} // {{item.deltaDecay}} {{item.deltaDecays}} {{item.deltaWithDecay}} {{item.deltaWithDecays}} {{item.gamma}} {{item.gammas}} {{item.gammaCash}} // {{item.gammaCashes}} {{item.vega}} {{item.vegas}} {{item.theta}} {{item.rho}} {{item.tradeDate}} {{item.effectiveDate}} {{item.expirationDate}} // {{item.message}} {{item.createdAt}} {{item.pricingEnvironment}} {{item.r}} {{item.q}} {{item.qs}} {{item.vol}} {{item.vols}} {{item.listedOption}} // {{item.price}} {{item.correlation}} {{item.notional}} {{item.initialNotional}} {{item.initialMargin}} {{item.initialQ}} {{item.initialR}} {{item.initialVol}} // {{item.maintenanceMargin}} {{item.masterAgreementId}} {{item.direction}} {{item.term}} {{item.settlementDate}} {{item.tradeStatus}} {{item.lcmEventType}} // {{item.initialSpot}} {{item.initialSpots}} {{item.highStrike}} {{item.lowStrike}} {{item.highBarrier}} {{item.lowBarrier}} {{item.participationRates}} // {{item.rebate}} {{item.annualized}} {{item.specifiedPrice}} {{item.frontPremium}} {{item.minimumPremium}} {{item.daysInYear}} {{item.initialPricingValue}} // {{item.initialUnderlyerPrice}} {{item.initialPnl}} {{item.initialStdDelta}} {{item.initialDelta}} {{item.initialDeltaCash}} {{item.initialGamma}} {{item.initialGammaCash}} {{item.initialVega}} {{item.initialTheta}} {{item.initialRhoR}} {{item.initialStdGamma}} {{item.tradeCategory}} {{item.portfolioNames}} {{item.trader}} {{item.tradeConfirmId}} {{item.regulationAssetClass}} {{item.regulationAssetSubClass}} {{item.underlyerPrice}} class ResponEodPosition { public string bookName { get; set; } public string tradeId { get; set; } public int? positionId { get; set; } public string underlyerInstrumentId { get; set; } public string underlyerInstrumentIds { get; set; } public double? underlyerMultiplier { get; set; } public string underlyerMultipliers { get; set; } public string productType { get; set; } public double? initialNumber { get; set; } public double? initialNumbers { get; set; } public double? unwindNumber { get; set; } public double? unwindNumbers { get; set; } public double? number { get; set; } public double? numbers { get; set; } public double? premium { get; set; } public double? unwindAmount { get; set; } public double? marketValue { get; set; } public double? pnl { get; set; } public double? delta { get; set; } public double? deltas { get; set; } public double? deltaCash { get; set; } public double? deltaCashes { get; set; } public double? deltaDecay { get; set; } public double? deltaDecays { get; set; } public double? deltaWithDecay { get; set; } public double? deltaWithDecays { get; set; } public double? gamma { get; set; } public double? gammas { get; set; } public double? gammaCash { get; set; } public double? gammaCashes { get; set; } public double? vega { get; set; } public double? vegas { get; set; } public double? theta { get; set; } public double? rho { get; set; } public string tradeDate { get; set; } public DateTime? effectiveDate { get; set; } public DateTime? expirationDate { get; set; } public string message { get; set; } public string createdAt { get; set; } public string pricingEnvironment { get; set; } public double? r { get; set; } public double? q { get; set; } public double? qs { get; set; } public double? vol { get; set; } public double? vols { get; set; } public double? listedOption { get; set; } public double? price { get; set; } public double? correlation { get; set; } public double? notional { get; set; } public double? initialNotional { get; set; } public double? initialMargin { get; set; } public double? initialQ { get; set; } public double? initialR { get; set; } public double? initialVol { get; set; } public double? maintenanceMargin { get; set; } public string masterAgreementId { get; set; } public string direction { get; set; } public int term { get; set; } public DateTime? settlementDate { get; set; } public string tradeStatus { get; set; } public string lcmEventType { get; set; } public double? initialSpot { get; set; } public double? initialSpots { get; set; } public double? highStrike { get; set; } public double? lowStrike { get; set; } public double? highBarrier { get; set; } public double? lowBarrier { get; set; } public double? participationRates { get; set; } public double? rebate { get; set; } public bool? annualized { get; set; } public string specifiedPrice { get; set; } public double? frontPremium { get; set; } public double? minimumPremium { get; set; } public double? daysInYear { get; set; } public double? initialPricingValue { get; set; } public double? initialUnderlyerPrice { get; set; } public double? initialPnl { get; set; } public double? initialStdDelta { get; set; } public double? initialDelta { get; set; } public double? initialDeltaCash { get; set; } public double? initialGamma { get; set; } public double? initialGammaCash { get; set; } public double? initialVega { get; set; } public double? initialTheta { get; set; } public double? initialRhoR { get; set; } public double? initialStdGamma { get; set; } public double? tradeCategory { get; set; } public string portfolioNames { get; set; } public string trader { get; set; } public string tradeConfirmId { get; set; } public string regulationAssetClass { get; set; } public string regulationAssetSubClass { get; set; } public double? underlyerPrice { get; set; } public string callput { get; set; } } class ClientInfo { /// /// 客户类型 /// public string ClientType { get; set; } /// /// 客户名称 /// public string ClientName { get; set; } /// /// 客户类型备注 机构全称,产品全称,居民身份证 /// public string ClientTypeMemo { get; set; } /// /// 证件类型 /// public string LicenseType { get; set; } /// /// 证件号 /// public string IdentificationNumber { get; set; } /// /// 产品管理人 /// public string AdminFullName { get; set; } /// /// 主协议编号 /// public string MainProtocolCode { get; set; } /// /// 证件类型备注 产品管理人全称 /// public string AdminFullNameMome { get; set; } /// /// 产品管理人证件类型 /// public string AdminFullNameLicenseType { get; set; } /// /// 产品管理人证件号 /// public string AdminRegisteredNum { get; set; } } class InnerClientInfo { internal int id { get; set; } public string ClientNumber { get; set; } public string ClientName { get; set; } public string LicenseCode { get; set; } public string ClientType { get; set; } public string StockEqvNotional { get; set; } } } }