diff --git a/Framework/YLErp.Core/ConsGlobal.cs b/Framework/YLErp.Core/ConsGlobal.cs index 049817e7..8e078bdf 100644 --- a/Framework/YLErp.Core/ConsGlobal.cs +++ b/Framework/YLErp.Core/ConsGlobal.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using YLErp.Models; namespace YLErp @@ -135,6 +135,9 @@ namespace YLErp public const string Shibor = "Shibor"; public const string FixingRepoRate = "FixingRepoRate"; public const string OtherRate = "OtherRate"; + public const string RateYield = "RateYield"; //利率收益率 + public const string BondIndex = "BondIndex"; // 债券指数 + //public const string OtherUnderlying = "OtherUnderlying"; @@ -169,6 +172,8 @@ namespace YLErp //case OtherUnderlying: return "其他标的"; case CreditBonds: return "信用债"; case OtherBonds: return "其它债券"; + case RateYield: return "利率收益率"; + case BondIndex: return "债券指数"; default: return instType; } } @@ -204,6 +209,8 @@ namespace YLErp //case "其他标的": return OtherUnderlying; case "信用债": return CreditBonds; case "其它债券": return OtherBonds; + case "利率收益率": return RateYield; + case "债券指数": return BondIndex; default: throw new ServiceException("资产类型不存在"); } } @@ -264,6 +271,8 @@ namespace YLErp new SelectItem { Text = "汇率" ,Value = ExRate }, new SelectItem { Text = "Shibor" ,Value = Shibor}, new SelectItem { Text = "银行间回购定盘" ,Value = FixingRepoRate}, + new SelectItem { Text = "利率收益率" ,Value = RateYield}, + new SelectItem { Text = "债券指数" ,Value = BondIndex}, //new SelectItem { Text = "其他利率" ,Value = OtherRate}, //new SelectItem { Text = "其他标的" ,Value = OtherUnderlying} }; @@ -271,7 +280,7 @@ namespace YLErp public static IEnumerable FutureTypes() { - return new[] { CommodityFutures, StockIF, GoldFutures, TBFutures, OtherFutures, AbroadFutures }; + return new[] { CommodityFutures, StockIF, GoldFutures, TBFutures, OtherFutures, AbroadFutures, RateYield, BondIndex }; } /// @@ -371,8 +380,12 @@ namespace YLErp /// 类型转换为计算所用类型 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string ConvertCalcType(string instType) + public static string ConvertCalcType(string instType,bool pringScene = false) { + if (pringScene && PS.Config.Company == Configuration.CompanyEnum.国联) + { + return Bonds; + } switch (instType) { case Stock: @@ -390,6 +403,8 @@ namespace YLErp case TBFutures: case OtherFutures: case AbroadFutures: + case RateYield: + case BondIndex: return CommodityFutures; case CommoditySpot: case GoldSpot: @@ -414,7 +429,7 @@ namespace YLErp public static string[] GetFutureTypes() { return new[] { CommodityFutures, StockIF, - GoldFutures, TBFutures, AbroadFutures, OtherFutures }; + GoldFutures, TBFutures, AbroadFutures, OtherFutures,RateYield,BondIndex }; } /// @@ -458,7 +473,7 @@ namespace YLErp Bonds, TBonds, CreditBonds, - OtherBonds + OtherBonds, }; } } diff --git a/Framework/YLErp.Core/YLErp.Core.csproj b/Framework/YLErp.Core/YLErp.Core.csproj index f33b22cb..2677280c 100644 --- a/Framework/YLErp.Core/YLErp.Core.csproj +++ b/Framework/YLErp.Core/YLErp.Core.csproj @@ -13,7 +13,7 @@ - + diff --git a/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs b/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs index 21aceac3..ec57f41b 100644 --- a/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs +++ b/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs @@ -1,4 +1,4 @@ -using Qdp.ComputeService.Data.CommonModels.ValuationParams.Equity; +using Qdp.ComputeService.Data.CommonModels.ValuationParams.Equity; using Qdp.ComputeService.Data.CommonModels.ValuationParams.FixedIncome; using Qdp.ComputeServiceV2.Data.CommonModels.TradeInfos; using Qdp.ComputeServiceV2.Data.CommonModels.TradeInfos.Options; @@ -59,7 +59,7 @@ namespace YLErp.BLL.Calculation.V2 { underlying = underlying.Clone(); - underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType); + underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType,true); switch (trade.TradeType) { diff --git a/YLErpDAL/Model/EodPositionRisks.cs b/YLErpDAL/Model/EodPositionRisks.cs index 7f124449..3669e15c 100644 --- a/YLErpDAL/Model/EodPositionRisks.cs +++ b/YLErpDAL/Model/EodPositionRisks.cs @@ -1,4 +1,4 @@ -using BaseOUDAL; +using BaseOUDAL; using YLErp.Commons; using YLErp.Helpers; using YLErp.Modules; @@ -211,6 +211,27 @@ namespace YLErp.Model public double DividendRate { get; set; } + + /// + /// Delta_R + /// + public double? Delta_r { get; set; } + + public double? Delta_r_1bp { get; set; } + + + public double? Dv01 { get; set; } + + public double? Gamma_r { get; set; } + + public double? Gamma_r_1bp { get; set; } + + public double? Vega_r { get; set; } + + public double? Vega_r_1bp { get; set; } + + + /// /// 维持预付金 /// diff --git a/YLErpDAL/Modules/CalcPriceShowConfigModule/CalcPriceShowConfigService.cs b/YLErpDAL/Modules/CalcPriceShowConfigModule/CalcPriceShowConfigService.cs index c81b4093..c021ef8a 100644 --- a/YLErpDAL/Modules/CalcPriceShowConfigModule/CalcPriceShowConfigService.cs +++ b/YLErpDAL/Modules/CalcPriceShowConfigModule/CalcPriceShowConfigService.cs @@ -1,4 +1,4 @@ -using MoreLinq; +using MoreLinq; using System; using System.Collections.Generic; using System.Linq; @@ -248,7 +248,14 @@ namespace YLErp.Modules.CalcPriceShowConfigModule new CalcQuotaDto{Name="Vegacash",Tip=""}, new CalcQuotaDto{Name="PV*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"}, new CalcQuotaDto{Name="Delta*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"}, - new CalcQuotaDto{Name="Gamma*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"} + new CalcQuotaDto{Name="Gamma*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"}, + new CalcQuotaDto{Name="Delta_r",Tip=""}, + new CalcQuotaDto{Name="Delta_r(1bp)",Tip=""}, + new CalcQuotaDto{Name="Dv01",Tip=""}, + new CalcQuotaDto{Name="Gamma_r",Tip=""}, + new CalcQuotaDto{Name="Gamma_r(1bp)",Tip=""}, + new CalcQuotaDto{Name="Vega_r",Tip=""}, + new CalcQuotaDto{Name="Vega_r(1bp)",Tip=""}, }; } diff --git a/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs b/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs index 93b9fac1..2c4d6c45 100644 --- a/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs +++ b/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs @@ -1,4 +1,4 @@ -using Qdp.Foundation.Implementations; +using Qdp.Foundation.Implementations; using Qdp.Pricing.Base.Enums; using Qdp.Pricing.Base.Implementations; using YLErp.Enums; @@ -105,7 +105,7 @@ namespace YLErp.Modules.CalculationModule public string underlyingInstrumentType { get => _underlyingInstrumentType; - set => _underlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(value); + set => _underlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(value,true); } /// diff --git a/YLErpDAL/Modules/CalculationModule/Models/TradeValueResult.cs b/YLErpDAL/Modules/CalculationModule/Models/TradeValueResult.cs index f28cd464..d7df7d83 100644 --- a/YLErpDAL/Modules/CalculationModule/Models/TradeValueResult.cs +++ b/YLErpDAL/Modules/CalculationModule/Models/TradeValueResult.cs @@ -1,4 +1,4 @@ -using Qdp.Pricing.Base.Interfaces; +using Qdp.Pricing.Base.Interfaces; namespace YLErp.Modules.CalculationModule { @@ -495,6 +495,26 @@ namespace YLErp.Modules.CalculationModule /// Theta(轧差) /// public double ThetaNet { get; set; } + + + + /// + /// Delta_R + /// + public double? Delta_r { get; set; } + + public double? Delta_r_1bp { get; set; } + + + public double? Dv01 { get; set; } + + public double? Gamma_r { get; set; } + + public double? Gamma_r_1bp { get; set; } + + public double? Vega_r { get; set; } + + public double? Vega_r_1bp { get; set; } } public class TradeValueResultExtend diff --git a/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs b/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs index 531afaed..add6c39d 100644 --- a/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs +++ b/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs @@ -1,4 +1,4 @@ -using Qdp.Foundation.Implementations; +using Qdp.Foundation.Implementations; using Qdp.Pricing.Base.Implementations; using Qdp.Pricing.Base.Interfaces; using Qdp.Pricing.Base.Utilities; @@ -570,7 +570,7 @@ namespace YLErp.Modules.CalculationModule { underlying = underlying.Clone(); - underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType); + underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType,true); switch (trade.TradeType) { diff --git a/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs b/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs index c59eca99..b053c521 100644 --- a/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs +++ b/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs @@ -1,4 +1,4 @@ -using YLErp.Abstract.DataProviders; +using YLErp.Abstract.DataProviders; using YLErp.Helpers; using YLErp.Models; using YLErp.Modules.TradeModule.DealModule; @@ -118,13 +118,13 @@ namespace YLErp.Modules.DataProviderModule ValueDate = ValueDate, UnderlyingId = um.id, UnderlyingCode = um.UnderlyingCode, - ClosePrice = 0, - SettlePrice = 0, + ClosePrice = (double)(eodprice.dirty_price_close ?? 0) / 100, + SettlePrice = (double)(eodprice.net_price ?? 0) / 100, HighPrice = 0, LowPrice = 0, UnderlyingStatus = "正常运行", UnderlyingInstrumentType = "Bonds", - ReferencePrice = 0, + ReferencePrice = (double)(eodprice.yield ?? 0), DeciSettlePrice = eodprice.dirty_price_close, DeciClosePrice = eodprice.net_price, DeciReferencePrice = eodprice.yield, @@ -138,15 +138,15 @@ namespace YLErp.Modules.DataProviderModule { if (item.UnderlyingCode != null) { - if (item.UnderlyingInstrumentType == "Bonds") - { - // [Layer2-待统一] 债券映射口径:SettlePrice=全价(dirty_price_close),ClosePrice=净价(net_price)。 - // 注意:这与 EodPriceQueryService.GetBondPrice 的映射【完全相反】(GetBondPrice: ClosePrice=全价,SettlePrice=净价)。 - // 两处对"债券收盘价/结算价"的净全价定义不一致属历史遗留,请勿随意改动单侧,需业务先定调后统一(见 TryGetSettlementEodPrice 注释)。 - item.SettlePrice = Convert.ToDouble(BondPriceConverter.ToStorage(item.DeciSettlePrice)); - item.ClosePrice = Convert.ToDouble(BondPriceConverter.ToStorage(item.DeciClosePrice)); - item.ReferencePrice = Convert.ToDouble(BondPriceConverter.ToStorage(item.DeciReferencePrice)); - } + //if (item.UnderlyingInstrumentType == "Bonds") + //{ + // // [Layer2-待统一] 债券映射口径:SettlePrice=全价(dirty_price_close),ClosePrice=净价(net_price)。 + // // 注意:这与 EodPriceQueryService.GetBondPrice 的映射【完全相反】(GetBondPrice: ClosePrice=全价,SettlePrice=净价)。 + // // 两处对"债券收盘价/结算价"的净全价定义不一致属历史遗留,请勿随意改动单侧,需业务先定调后统一(见 TryGetSettlementEodPrice 注释)。 + // item.SettlePrice = Convert.ToDouble(BondPriceConverter.ToStorage(item.DeciSettlePrice)); + // item.ClosePrice = Convert.ToDouble(BondPriceConverter.ToStorage(item.DeciClosePrice)); + // item.ReferencePrice = Convert.ToDouble(BondPriceConverter.ToStorage(item.DeciReferencePrice)); + //} _priceDic[item.UnderlyingCode] = item; } } diff --git a/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs b/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs index 9acddd70..e9a3286e 100644 --- a/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs +++ b/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs @@ -1,4 +1,4 @@ -using BaseOUDAL; +using BaseOUDAL; using System; using System.Data; using System.Diagnostics; @@ -339,7 +339,9 @@ namespace YLErp.Modules.EodModule var tcActions = new[] { ClientCashInCashOut.系统操作_平仓费, ClientCashInCashOut.系统操作_行权费,ClientCashInCashOut.系统操作_票息,ClientCashInCashOut.系统操作_互换,ClientCashInCashOut.人工操作_其他}; - + var underlyingCodes = searchResult.rows.Select(O => O.UnderlyingCode).Distinct().ToList(); + var greeksHandleService = new GLMSGreeksHandleService(); + greeksHandleService.InitData(req.ValueDate, underlyingCodes); foreach (var r in searchResult.rows) { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode); @@ -470,6 +472,7 @@ namespace YLErp.Modules.EodModule r.DeltaLots = (r.Delta ?? 0) / um.ContractSize; } r.Rho *= 100; + greeksHandleService.Handle(r,um); if (r.trade == null) { r.TradeSinglePrice = r.etcTradePrice / r.TradeAmount; @@ -1118,6 +1121,9 @@ namespace YLErp.Modules.EodModule .AsEnumerable() .GroupBy(O => O.ParentTradeId) .ToDictionary(K => K.Key, V => V.Select(O => new xodTradeBase() { TradeJson = O.TradeJson })); + var underlyingCodes = searchResult.rows.Select(O => O.UnderlyingCode).Distinct().ToList(); + var greeksHandleService = new GLMSGreeksHandleService(); + greeksHandleService.InitData(req.ValueDate, underlyingCodes); foreach (var r in searchResult.rows) { @@ -1200,6 +1206,7 @@ namespace YLErp.Modules.EodModule } r.Rho *= 100; + greeksHandleService.Handle(r,um); r.CountRatio = um.CountRatio; r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio; r.etcTradePrice = ConsTrade.TradeTypesForHedge.Contains(r.TradeType) @@ -1706,10 +1713,10 @@ namespace YLErp.Modules.EodModule var results = GetEodPositionRisksDataHandle(req); var list2 = results.Select(n => new ExpandoDictionary(n)).ToArray(); - var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险.xlsx"); + var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险_国联.xlsx"); if (PS.Config.ErpElement.NeedShowSpv) { - templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险-Spv.xlsx"); + templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx"); } return ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = list2 }).GenerateBytes(); @@ -2016,6 +2023,17 @@ namespace YLErp.Modules.EodModule dic.Add("Spv3", item.PnLDelta.OtcFormat(OtcFormatFlag.greek)); } + if (PS.Config.Company == Configuration.CompanyEnum.国联) + { + dic.Add("Delta_r", OtcFormatExtensions.OtcFormat(item.Delta_r, OtcFormatFlag.greek)); + dic.Add("Delta_r_1bp", OtcFormatExtensions.OtcFormat(item.Delta_r_1bp, OtcFormatFlag.greek)); + dic.Add("Dv01", OtcFormatExtensions.OtcFormat(item.Dv01, OtcFormatFlag.greek)); + dic.Add("Gamma_r", OtcFormatExtensions.OtcFormat(item.Gamma_r, OtcFormatFlag.greek)); + dic.Add("Gamma_r_1bp", OtcFormatExtensions.OtcFormat(item.Gamma_r_1bp, OtcFormatFlag.greek)); + dic.Add("Vega_r", OtcFormatExtensions.OtcFormat(item.Vega_r, OtcFormatFlag.greek)); + dic.Add("Vega_r_1bp", OtcFormatExtensions.OtcFormat(item.Vega_r_1bp, OtcFormatFlag.greek)); + } + dic.Add("备注", item.Comments); @@ -2115,6 +2133,17 @@ namespace YLErp.Modules.EodModule dic.Add("Spv2", ""); dic.Add("Spv3", ""); } + + if (PS.Config.Company == Configuration.CompanyEnum.国联) + { + dic.Add("Delta_r", ""); + dic.Add("Delta_r_1bp", ""); + dic.Add("Dv01", ""); + dic.Add("Gamma_r", ""); + dic.Add("Gamma_r_1bp", ""); + dic.Add("Vega_r", ""); + dic.Add("Vega_r_1bp", ""); + } results.Add(dic); } return results; diff --git a/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs b/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs new file mode 100644 index 00000000..97020691 --- /dev/null +++ b/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using YLErp.Model; +using YLErp.Modules.CalculationModule; + +namespace YLErp.Modules.EodModule +{ + /// + /// 国联民生 希腊字母计算 + /// + public class GLMSGreeksHandleService + { + + public void InitData(DateTime valueDate,List underlyingCodes) + { + + } + + + public void Handle(EodPositionRisksDTO dto,underlying_manager um) + { + //对Delta_r Delta_r_1bp Dv01 Gamma_r Gamma_r_1bp Vega_r Vega_r_1bp + + if ("GB10".Equals(um.UnderlyingCode)) + { + dto.Delta_r = dto.Delta * -1; + } + + + } + + + public void Handle(trade td,TradeValueResult calRes) + { + calRes.Delta_r = calRes.Delta * -1; + } + } +} diff --git a/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs b/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs index e071bb88..87af919a 100644 --- a/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs +++ b/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Linq.Dynamic.Core; using YLErp.Modules.DataProviderModule; @@ -48,7 +48,7 @@ namespace YLErp.Modules.EodModule.SettlementModule if (request.IsSettleOtcTrades) { var tradePredicate = _context.PredicateBuilder.GetOtcTradePredicate() - .And(t => t.TradeType != "自定义交易" && t.TradeType != "收益互换" && t.UnderlyingCode != null); + .And(t => t.TradeType != "自定义交易" && t.UnderlyingCode != null); //新增客户筛选 tw if (clienIds != null) @@ -58,6 +58,11 @@ namespace YLErp.Modules.EodModule.SettlementModule allQuery = DbContext.trade.Where(tradePredicate).Select(n => n.UnderlyingCode).Distinct(); + if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD) + { + allQuery = allQuery.Union(DbContext.trade.Where(tradePredicate).Where(x => x.BasisUnderlyingCode != null && x.BasisUnderlyingCode != "").Select(n => n.BasisUnderlyingCode).Distinct()); + } + var clientProductPredicate = _context.PredicateBuilder.GetClientProductPredicate(); //新增客户筛选 tw @@ -74,26 +79,28 @@ namespace YLErp.Modules.EodModule.SettlementModule } //检查场内标的 - //if (request.IsSettleExchangeTrades) - //{ - // var exTradePredicate = _context.PredicateBuilder.GetExchangeTradePredicate(); + if (request.IsSettleExchangeTrades) + { + var exTradePredicate = _context.PredicateBuilder.GetExchangeTradePredicate(); - // var exTradeQuery = DbContext.ExchangeTrade.Where(exTradePredicate).Select(n => n.UnderlyingCode); + var exTradeQuery = DbContext.ExchangeTrade.Where(exTradePredicate).Select(n => n.UnderlyingCode); - // allQuery = allQuery == null ? exTradeQuery.Distinct() : allQuery.Union(exTradeQuery.Distinct()); + allQuery = allQuery == null ? exTradeQuery.Distinct() : allQuery.Union(exTradeQuery.Distinct()); - // var preSettleDate = _context.PreSettleDate; - // //最后一个交易日持仓信息 - // var futureTypes = ConsGlobal.InstrumentType.GetFutureTypes(); - // var positionQuery = from t in DbContext.eod_trade_position - // join um in DbContext.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode - // where t.ValueDate == preSettleDate && t.Amount != 0 - // && ConsTrade.TradeTypesForHedge.Contains(t.TradeType) - // && (!futureTypes.Contains(um.UnderlyingInstrumentType) || um.MaturityDate >= settleDate) - // select t.UnderlyingCode; + var preSettleDate = _context.PreSettleDate; + //最后一个交易日持仓信息 + var futureTypes = ConsGlobal.InstrumentType.GetFutureTypes(); + var positionQuery = from t in DbContext.eod_trade_position + join um in DbContext.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode + where t.ValueDate == preSettleDate && t.Amount != 0 + && ConsTrade.TradeTypesForHedge.Contains(t.TradeType) + && (!futureTypes.Contains(um.UnderlyingInstrumentType) || um.MaturityDate >= settleDate) + select t.UnderlyingCode; - // allQuery = allQuery.Union(positionQuery.Distinct()); - //} + allQuery = allQuery.Union(positionQuery.Distinct()); + } + + if (allQuery == null) { @@ -103,12 +110,10 @@ namespace YLErp.Modules.EodModule.SettlementModule //检查是否所有标的都在结算日有结算价格 var umCodeArr = allQuery.ToArray(); - var swapUmCodeArr = GetSwapUnderlyingCodes(); - var codeArr = umCodeArr.Union(swapUmCodeArr); - var eodPriceProvider = _context.GetEodPriceProvider().Initialize(codeArr); - // var preEodPriceProvidaer = _context.GetPreEodPriceProvider().Initialize(swapUmCodeArr); - var umCodes = codeArr.Where(n => !string.IsNullOrEmpty(n) && !eodPriceProvider.HasValue(n)).ToHashSet(StringComparer.OrdinalIgnoreCase); - //var swapUmCodes= swapUmCodeArr.Where(n => !string.IsNullOrEmpty(n) && !preEodPriceProvidaer.HasValue(n)).ToHashSet(StringComparer.OrdinalIgnoreCase); + + var eodPriceProvider = _context.GetEodPriceProvider().Initialize(umCodeArr); + var umCodes = umCodeArr.Where(n => !string.IsNullOrEmpty(n) && !eodPriceProvider.HasValue(n)).ToHashSet(StringComparer.OrdinalIgnoreCase); + //排除掉节假日不需要结算的交易 foreach (var t in _context.HolidayTrades) { diff --git a/YLErpDAL/Modules/PricingModule/PriceCalcService.cs b/YLErpDAL/Modules/PricingModule/PriceCalcService.cs index 4be94b0a..5e59a00c 100644 --- a/YLErpDAL/Modules/PricingModule/PriceCalcService.cs +++ b/YLErpDAL/Modules/PricingModule/PriceCalcService.cs @@ -1,4 +1,4 @@ -using Qdp.Pricing.Base.Implementations; +using Qdp.Pricing.Base.Implementations; using System.Text.RegularExpressions; using YLErp.BLL; using YLErp.BLL.Calculation.V2; @@ -11,6 +11,7 @@ using YLErp.Enums; using YLErp.Model; using YLErp.Modules.CalculationModule; using YLErp.Modules.DataProviderModule; +using YLErp.Modules.EodModule; using YLErp.Modules.PricingModule.Models; using YLErp.Modules.TradeModule; using YLErp.QdpModule; @@ -500,7 +501,7 @@ namespace YLErp.Modules.PricingModule } } } - + var greeksHandleService = new GLMSGreeksHandleService(); foreach (var item in tdList) { var td = item.tdConv; @@ -529,6 +530,9 @@ namespace YLErp.Modules.PricingModule } } + + greeksHandleService.Handle(td, calcResult); + results.Add(new CalcOptionPriceResult { BuySell = td.BuySell, diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs index 4a2bc9a5..822f4c2e 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs @@ -117,12 +117,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] public class SacDescriptionAttribute : Attribute { - // Attribute.TypeId 本质是 System.Type,Newtonsoft 序列化会触发 - // "Method may only be called on a Type for which Type.IsGenericParameter is true." - // 预览页用 ToJson() 序列化 SacInfo/List 时崩溃,故显式跳过该成员。 - // (13.0.1 安全版对 Type 成员序列化行为变更后暴露此问题) - public bool ShouldSerializeTypeId() => false; - /// /// 字段名 /// diff --git a/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs b/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs index 4980ca9a..699a1dd4 100644 --- a/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs +++ b/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs @@ -1,4 +1,4 @@ -using BaseOUDAL; +using BaseOUDAL; using YLErp.BLL; using YLErp.Configuration; using YLErp.Configuration.Enums; @@ -993,10 +993,10 @@ namespace YLErp.Modules.TradeModule.OrderModule throw new ServiceException($"客户'{client.Name}'为非高风险客户,没有卖出权限"); } - if (_underlying != null && _underlying.CalcTypeIsStock() && ((client.TradingInstType & TradingInstTypeEnum.Equity) != TradingInstTypeEnum.Equity)) - { - throw new ServiceException($"客户'{client.Name}'的'交易资产'属性不包括'权益',不能进行权益类的期权交易"); - } + //if (_underlying != null && _underlying.CalcTypeIsStock() && ((client.TradingInstType & TradingInstTypeEnum.Equity) != TradingInstTypeEnum.Equity)) + //{ + // throw new ServiceException($"客户'{client.Name}'的'交易资产'属性不包括'权益',不能进行权益类的期权交易"); + //} if (PS.Config.ErpElement.SecuritiesEnvironment) { diff --git a/YLErpDAL/YLErpDAL.csproj b/YLErpDAL/YLErpDAL.csproj index 8b50f99f..07cbcda8 100644 --- a/YLErpDAL/YLErpDAL.csproj +++ b/YLErpDAL/YLErpDAL.csproj @@ -40,10 +40,10 @@ - - - - + + + + diff --git a/YLErpWeb/App/ExceptionMiddleware.cs b/YLErpWeb/App/ExceptionMiddleware.cs index 5163baaa..a0c469d2 100644 --- a/YLErpWeb/App/ExceptionMiddleware.cs +++ b/YLErpWeb/App/ExceptionMiddleware.cs @@ -37,15 +37,13 @@ namespace YLErp.Web.App try { - // 暴露完整异常(类型 + 所有内层 message + 堆栈),不再只取最内层 message, - // 便于定位根因(如 SacInfo 序列化 TypeId 触发的 IsGenericParameter 反射异常)。 - message = exception.ToString(); + message = GetInnerExceptionMessage(exception); if (serviceExpcetion == null || serviceExpcetion.IsFaultError) { var result = await request.BodyReader.ReadAsync(); var reqBody = ConvertBufferToString(result.Buffer); - LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}\r\n{message}"); + LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}"); } } catch (Exception ex) @@ -79,5 +77,16 @@ namespace YLErp.Web.App ReadOnlySpan span = readOnlySequence.IsSingleSegment ? readOnlySequence.First.Span : readOnlySequence.ToArray().AsSpan(); return System.Text.Encoding.UTF8.GetString(span); } + + private static string GetInnerExceptionMessage(Exception ex) + { + var exceptionStr = ex.Message; + while (ex.InnerException != null) + { + exceptionStr = ex.InnerException.Message; + ex = ex.InnerException; + } + return exceptionStr; + } } } \ No newline at end of file diff --git a/YLErpWeb/App_Data/FunctionRight.xml b/YLErpWeb/App_Data/FunctionRight.xml index 397e458d..eccba1c4 100644 --- a/YLErpWeb/App_Data/FunctionRight.xml +++ b/YLErpWeb/App_Data/FunctionRight.xml @@ -7,12 +7,13 @@ + - + diff --git a/YLErpWeb/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx b/YLErpWeb/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx new file mode 100644 index 00000000..827586a1 Binary files /dev/null and b/YLErpWeb/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx differ diff --git a/YLErpWeb/App_Docs/导出模板/日终持仓风险_国联.xlsx b/YLErpWeb/App_Docs/导出模板/日终持仓风险_国联.xlsx new file mode 100644 index 00000000..9b440137 Binary files /dev/null and b/YLErpWeb/App_Docs/导出模板/日终持仓风险_国联.xlsx differ diff --git a/YLErpWeb/Common/UserInfoRight.cs b/YLErpWeb/Common/UserInfoRight.cs index 5db38dd8..cf0989bd 100644 --- a/YLErpWeb/Common/UserInfoRight.cs +++ b/YLErpWeb/Common/UserInfoRight.cs @@ -407,9 +407,9 @@ namespace YLErp.Web public bool 交易管理_交易新增 => HasRight("交易管理-交易新增"); /// - /// 交易管理-交易续做 + /// 交易管理-交易续作 /// - public bool 交易管理_交易续做 => HasRight("交易管理-交易续做"); + public bool 交易管理_交易续作 => HasRight("交易管理-交易续作"); /// /// 交易管理-交易编辑 diff --git a/YLErpWeb/Controllers/SwapTrade2Controller.cs b/YLErpWeb/Controllers/SwapTrade2Controller.cs index c8c78e65..699e370a 100644 --- a/YLErpWeb/Controllers/SwapTrade2Controller.cs +++ b/YLErpWeb/Controllers/SwapTrade2Controller.cs @@ -48,9 +48,9 @@ namespace YLErp.Web.Controllers public ActionResult TradeEdit(string enid, string renewEnid = null, bool isUseApproval = false) { ViewBag.isUseApproval = isUseApproval; - if (!string.IsNullOrWhiteSpace(renewEnid) && !CurUser.交易管理_交易续做) + if (!string.IsNullOrWhiteSpace(renewEnid) && !CurUser.交易管理_交易续作) { - return ShowError("没有续做交易权限"); + return ShowError("没有续作交易权限"); } // The new/renew flow uses the literal "0" to indicate that no trade exists yet. var intid = enid == "0" ? 0 : DecryptInt(enid); diff --git a/YLErpWeb/Controllers/tradeController.cs b/YLErpWeb/Controllers/tradeController.cs index 827bc8a6..f0f5728e 100644 --- a/YLErpWeb/Controllers/tradeController.cs +++ b/YLErpWeb/Controllers/tradeController.cs @@ -7055,6 +7055,10 @@ namespace YLErp.Web.Controllers public JsonResult BatchDownloadEodPositionRisks(EodPositionRisksReq req) { + req.BookIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.BookIds).ToList(); + req.UserAssets = CurUser.GetAssetUnitIds(); + req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); + if (CurUser.交易管理_查看所有交易) { req.UserClients.Clear(); } if (!new EodPositionRisksQueryService(CurUser).BatchDownloadEodPositionRisks(req)) { return JsonError("线程正在被占用"); diff --git a/YLErpWeb/Views/Pricing/_PricingItemTpl.cshtml b/YLErpWeb/Views/Pricing/_PricingItemTpl.cshtml index fd3809ad..6d565236 100644 --- a/YLErpWeb/Views/Pricing/_PricingItemTpl.cshtml +++ b/YLErpWeb/Views/Pricing/_PricingItemTpl.cshtml @@ -1,4 +1,4 @@ -@using YLErp.Modules.CalcPriceShowConfigModule +@using YLErp.Modules.CalcPriceShowConfigModule @*定价模板*@ @model PricingModel @{ @@ -1199,6 +1199,55 @@ {{calcResult.GammaContainsKnockOut}} } + else if ("Delta_r".Equals(quta.Name)) + { + + Delta_r + {{calcResult.Delta_r}} + + } + else if ("Delta_r(1bp)".Equals(quta.Name)) + { + + Delta_r(1bp) + {{calcResult.Delta_r_1bp}} + + } + else if ("Dv01".Equals(quta.Name)) + { + + Dv01 + {{calcResult.Dv01}} + + } + else if ("Gamma_r".Equals(quta.Name)) + { + + Gamma_r + {{calcResult.Gamma_r}} + + } + else if ("Gamma_r(1bp)".Equals(quta.Name)) + { + + Gamma_r(1bp) + {{calcResult.Gamma_r_1bp}} + + } + else if ("Vega_r".Equals(quta.Name)) + { + + Vega_r + {{calcResult.Vega_r}} + + } + else if ("Vega_r(1bp)".Equals(quta.Name)) + { + + Vega_r(1bp) + {{calcResult.Vega_r_1bp}} + + } } } diff --git a/YLErpWeb/Views/SwapTrade2/header.cshtml b/YLErpWeb/Views/SwapTrade2/header.cshtml index 333c8915..54a70d94 100644 --- a/YLErpWeb/Views/SwapTrade2/header.cshtml +++ b/YLErpWeb/Views/SwapTrade2/header.cshtml @@ -157,7 +157,7 @@ { @MyControls.Btn("收益结算", string.Format("unWindLongShortSwap('{0}')", tradeModel.EncryptId)) } - @if (CurUser.交易管理_交易续做) + @if (CurUser.交易管理_交易续作) { @MyControls.Btn("续作", string.Format("renewTrade('{0}')", tradeModel.EncryptId)) } diff --git a/YLErpWeb/Views/trade/EodPositionRisks.cshtml b/YLErpWeb/Views/trade/EodPositionRisks.cshtml index d6831d6f..89b1e8b8 100644 --- a/YLErpWeb/Views/trade/EodPositionRisks.cshtml +++ b/YLErpWeb/Views/trade/EodPositionRisks.cshtml @@ -1,4 +1,4 @@ -@{ +@{ ViewBag.Title = "日终持仓风险"; Layout = "~/Views/Shared/_MainLayout.cshtml"; var settleConfig = PS.Config.GetSettlementConfig(); @@ -19,7 +19,8 @@ IsUseDisplayNotional = PS.Config.IsUseDisplayNotional, showGuohai = PS.Config.Is国海, isGuoyuan = PS.Config.Company==CompanyEnum.国元固收, - isGuoJun = PS.Config.IsGuoJun + isGuoJun = PS.Config.IsGuoJun, + isGLMS = PS.Config.Company == CompanyEnum.国联 }; }