diff --git a/Framework/YLErp.Core/ConsGlobal.cs b/Framework/YLErp.Core/ConsGlobal.cs index 049817e7..f2c8181f 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 BondYield = "BondYield"; //债券收益率 + 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 BondYield: return "债券收益率"; + case BondIndex: return "债券指数"; default: return instType; } } @@ -204,6 +209,8 @@ namespace YLErp //case "其他标的": return OtherUnderlying; case "信用债": return CreditBonds; case "其它债券": return OtherBonds; + case "债券收益率": return BondYield; + 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 = BondYield}, + 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, BondYield, 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 BondYield: + 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,BondYield,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/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/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..3a5bf504 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.net_price ?? 0) / 100, + SettlePrice = (double)(eodprice.dirty_price_close ?? 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, diff --git a/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs b/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs index 9acddd70..821f5ae2 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); 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); 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..4385923a --- /dev/null +++ b/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using YLErp.Model; + +namespace YLErp.Modules.EodModule +{ + /// + /// 国联民生 希腊字母计算 + /// + public class GLMSGreeksHandleService + { + + public void InitData(DateTime valueDate,List underlyingCodes) + { + + } + + + public void Handle(EodPositionRisksDTO dto) + { + //对Delta_r Delta_r_1bp Dv01 Gamma_r Gamma_r_1bp Vega_r Vega_r_1bp + + } + } +} 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/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..437f62a6 100644 --- a/YLErpDAL/YLErpDAL.csproj +++ b/YLErpDAL/YLErpDAL.csproj @@ -41,7 +41,7 @@ - + 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/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.国联 }; }