From f0ed2058bf413ffc09b9ae049d024471226a3b80 Mon Sep 17 00:00:00 2001 From: ruisu Date: Wed, 5 Aug 2026 16:45:27 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=9B=B4=E6=96=B0=E8=A7=84?= =?UTF-8?q?=E5=88=9914=EF=BC=8C=E5=AD=97=E6=AE=B5=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=B9=98=E4=BB=A5100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YLErpDAL/Modules/RiskEngine/测试用例.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/YLErpDAL/Modules/RiskEngine/测试用例.md b/YLErpDAL/Modules/RiskEngine/测试用例.md index cd706142..2eb3b5fe 100644 --- a/YLErpDAL/Modules/RiskEngine/测试用例.md +++ b/YLErpDAL/Modules/RiskEngine/测试用例.md @@ -3090,13 +3090,13 @@ ORDER BY DiffAbs DESC, sp.id ASC; 3. 根据 TradeId 查所有符合条件的浮动支付端,取 PosiGrossPrice 和 UnderlyingCode。 4. 用 swap_position.UnderlyingCode 关联 eod_commodity_future_price.UnderlyingCode;该模型属性映射数据库列 FutureContractId。 5. 每个标的优先取开始日期上一交易日的 ClosePrice;该日无数据时,改取成交日期上一交易日的数据;两日均无数据才报错。 -6. 逐条计算 ABS(PosiGrossPrice * 100 - ClosePrice),变量返回全部记录中的最大偏离值,命中说明只展示产生最大偏离值的记录。 +6. 逐条计算 ABS(PosiGrossPrice - ClosePrice),变量返回全部记录中的最大偏离值,命中说明只展示产生最大偏离值的记录。 ``` 规则公式: ```text -ABS(浮动支付端.PosiGrossPrice * 100 - 上一日行情.ClosePrice) > 5 +ABS(浮动支付端.PosiGrossPrice - 上一日行情.ClosePrice) > 5 ``` 变量形式: @@ -3170,14 +3170,14 @@ var deviationItems = selectedItems { x.Position.id, x.Position.UnderlyingCode, - PositionValue = x.Position.PosiGrossPrice * 100m, + PositionValue = x.Position.PosiGrossPrice, MarketDate = x.Market.ValueDate, MarketDateSource = startPreviousTradingDay.HasValue && x.Market.ValueDate.Date == startPreviousTradingDay.Value ? "开始日期上一交易日" : "成交日期上一交易日", MarketValue = Convert.ToDecimal(x.Market.ClosePrice), - DiffAbs = Math.Abs(x.Position.PosiGrossPrice * 100m - Convert.ToDecimal(x.Market.ClosePrice)) + DiffAbs = Math.Abs(x.Position.PosiGrossPrice - Convert.ToDecimal(x.Market.ClosePrice)) }) .OrderByDescending(x => x.DiffAbs) .ThenBy(x => x.id) @@ -3196,9 +3196,9 @@ return new RiskVariableValueDetail(maxDeviationItem.DiffAbs, detailMessage); //{ // Id = 1000014, // RuleName = "非债券类价格偏离(本地)", -// RuleText = "取值字段:通过 DbContext.swap_position 按 TradeId 取 IsInitial=true、Invalid=false、PosiDirection=2 且有标的代码的浮动支付端 PosiGrossPrice 和 UnderlyingCode,PosiGrossPrice 对应普通收益互换页面填写的期初标的价格,库内为 1 左右原值;通过 DbContext.eod_commodity_future_price 按该浮动支付端标的和交易日前日期取上一日收盘价 ClosePrice。注意:eod_commodity_future_price 模型属性 UnderlyingCode 实际映射数据库列 FutureContractId,数据库排查时应使用 FutureContractId 与 swap_position.UnderlyingCode 关联。计算逻辑:按 ABS(PosiGrossPrice×100-ClosePrice) 计算绝对价差,价差大于 5 时触发审批。", +// RuleText = "取值字段:通过 DbContext.swap_position 按 TradeId 取 IsInitial=true、Invalid=false、PosiDirection=2 且有标的代码的浮动支付端 PosiGrossPrice 和 UnderlyingCode,PosiGrossPrice 对应普通收益互换页面填写的期初标的价格,库内为原值;通过 DbContext.eod_commodity_future_price 按该浮动支付端标的和交易日前日期取上一日收盘价 ClosePrice。注意:eod_commodity_future_price 模型属性 UnderlyingCode 实际映射数据库列 FutureContractId,数据库排查时应使用 FutureContractId 与 swap_position.UnderlyingCode 关联。计算逻辑:按 ABS(PosiGrossPrice-ClosePrice) 计算绝对价差,价差大于 5 时触发审批。", // 字段映射:RuleExpr 中 eod_commodity_future_price.UnderlyingCode 是 C# 模型属性,实际数据库列为 FutureContractId;SQL 排查时应写 e.FutureContractId。 -// RuleExpr = "Math.Abs(DbContext.swap_position.First(p => p.SwapTradeId == TradeId && p.IsInitial && !p.Invalid && p.PosiDirection == 2 && !string.IsNullOrEmpty(p.UnderlyingCode)).PosiGrossPrice * 100m - Convert.ToDecimal(DbContext.eod_commodity_future_price.Where(e => e.UnderlyingCode == DbContext.swap_position.First(p => p.SwapTradeId == TradeId && p.IsInitial && !p.Invalid && p.PosiDirection == 2 && !string.IsNullOrEmpty(p.UnderlyingCode)).UnderlyingCode && e.ValueDate < DbContext.trade.First(t => t.id == TradeId).TradeDate.Value.Date).OrderByDescending(e => e.ValueDate).First().ClosePrice)) > 5m", +// RuleExpr = "Math.Abs(DbContext.swap_position.First(p => p.SwapTradeId == TradeId && p.IsInitial && !p.Invalid && p.PosiDirection == 2 && !string.IsNullOrEmpty(p.UnderlyingCode)).PosiGrossPrice - Convert.ToDecimal(DbContext.eod_commodity_future_price.Where(e => e.UnderlyingCode == DbContext.swap_position.First(p => p.SwapTradeId == TradeId && p.IsInitial && !p.Invalid && p.PosiDirection == 2 && !string.IsNullOrEmpty(p.UnderlyingCode)).UnderlyingCode && e.ValueDate < DbContext.trade.First(t => t.id == TradeId).TradeDate.Value.Date).OrderByDescending(e => e.ValueDate).First().ClosePrice)) > 5m", // Version = 1, // Status = RiskRuleStatus.Active, // OptId = 0, @@ -3211,7 +3211,7 @@ return new RiskVariableValueDetail(maxDeviationItem.DiffAbs, detailMessage); ``` ```sql -SET @TradeId = 3001699; +SET @TradeId = 3001749; SET @Threshold = 5; WITH RECURSIVE trade_dates AS ( @@ -3264,7 +3264,7 @@ market_ranked AS ( SELECT sp.id AS SwapPositionId, e.*, - CASE WHEN rd.StartPreviousTradingDay IS NOT NULL AND DATE(e.ValueDate) = rd.StartPreviousTradingDay THEN '开始日期上一交易日' ELSE '成交日期上一交易日' END AS DataSource, + CASE WHEN rd.StartPreviousTradingDay IS NOT NULL AND DATE(e.ValueDate) = rd.StartPreviousTradingDay THEN '开始日期上一交易日' ELSE '成交日期上一交易日' END AS PriceDateSource, ROW_NUMBER() OVER ( PARTITION BY sp.id ORDER BY @@ -3292,14 +3292,13 @@ SELECT sp.id AS SwapPositionId, sp.UnderlyingCode AS SwapPositionUnderlyingCode, sp.PosiGrossPrice, - sp.PosiGrossPrice * 100 AS PosiGrossPrice_100, e.id AS EodPriceId, e.FutureContractId AS EodFutureContractId, e.ValueDate, e.ClosePrice, - e.DataSource, - ABS(sp.PosiGrossPrice * 100 - e.ClosePrice) AS DiffAbs, - CASE WHEN ABS(sp.PosiGrossPrice * 100 - e.ClosePrice) > @Threshold THEN 1 ELSE 0 END AS IsGreaterThanThreshold + e.PriceDateSource, + ABS(sp.PosiGrossPrice - e.ClosePrice) AS DiffAbs, + CASE WHEN ABS(sp.PosiGrossPrice - e.ClosePrice) > @Threshold THEN 1 ELSE 0 END AS IsGreaterThanThreshold FROM trade_dates td CROSS JOIN reference_days rd INNER JOIN position_items sp ON 1 = 1