feat新增规则

This commit is contained in:
ruisu
2026-08-06 17:08:20 +08:00
parent 8d58ef15e8
commit 4b15445507
+94 -40
View File
@@ -2180,17 +2180,16 @@ WHERE t.id = @TradeId;
## 19. 规则 8 查询结果排查 SQL
规则 8:支付日为银行间交易日(本地)。用于核对交易平仓窗口的支付日期是否为银行间交易日;若支付日期未落在 IB 日历的非交易日列表中,则命中。
规则 8:支付日为银行间交易日(本地)。用于核对互换交易-交易查看-交易平仓窗口中本次提交的支付日期是否为银行间交易日;若支付日期未落在 IB 日历的非交易日列表中,则命中。
取数流程:
```text
1. 根据 TradeId 查 swap_flow_event
2. 限定 SwapTradeId = TradeId、EventType = 2、DataState <> 0,取平仓事件
3. 取 swap_flow_event.PayDate,作为交易平仓窗口的支付日期
4. 根据 PayDate.Value.Year 查询 calendar 表中 Country = 'IB' 的银行间日历
5. calendar.HolidayJson 存储该年非交易日,格式为 yyyy,MM,dd
6. 若 HolidayJson 不包含支付日期对应的 yyyy,MM,dd,则说明支付日期是银行间交易日,命中规则。
1. 用户从互换交易-交易查看进入交易平仓窗口
2. 取交易平仓窗口本次提交的支付日期,即 UnwindData.PayDate
3. 根据 PayDate.Value.Year 查询 calendar 表中 Country = 'IB' 的银行间日历
4. calendar.HolidayJson 存储该年非交易日,格式为 yyyy,MM,dd
5. HolidayJson 不包含支付日期对应的 yyyy,MM,dd,则说明支付日期是银行间交易日,命中规则
```
规则公式:
@@ -2202,10 +2201,9 @@ WHERE t.id = @TradeId;
规则字段口径:
```text
支付日期:swap_flow_event.PayDate,对应交易平仓窗口的支付日期
平仓事件:swap_flow_event.EventType = 2
支付日期:UnwindData.PayDate,对应互换交易-交易查看-交易平仓窗口的支付日期
银行间日历:calendar.Country = 'IB'
日历年份:calendar.Year = swap_flow_event.PayDate.Year
日历年份:calendar.Year = UnwindData.PayDate.Year
非交易日:calendar.HolidayJson
```
@@ -2216,6 +2214,17 @@ WHERE t.id = @TradeId;
<vue-datepicker :mindate="minStartDate" :holiday="1" v-model="deal.PayDate" />
```
变量 Roslyn 示例:变量名为“平仓支付日期为银行间交易日”,DataType 为 Bool;规则前端配置“平仓支付日期为银行间交易日 == true”。该变量必须使用本次平仓请求中的 PayDate,不能查询 swap_flow_event 历史平仓事件,否则首次提交和修改支付日期后的试算会取不到当前页面值。
```csharp
if (!PayDate.HasValue)
throw new Exception("平仓支付日期为空");
return new RiskVariableValueDetail(
RiskCalendarHelper.IsInterbankTradingDay(DbContext, PayDate.Value),
$"交易ID {TradeId},本次平仓支付日期为{PayDate.Value:yyyy-MM-dd}");
```
注释规则定义:
```csharp
@@ -2223,8 +2232,8 @@ WHERE t.id = @TradeId;
//{
// Id = 1000008,
// RuleName = "支付日为银行间交易日(本地)",
// RuleText = "取值字段:通过 DbContext.swap_flow_event 按 SwapTradeId=TradeId、EventType=2、DataState<>0 取平仓事件的 PayDatePayDate 对应交易平仓窗口的支付日期;通过 DbContext.calendar 按 Country='IB' 且 Year=PayDate.Year 取银行间日历,HolidayJson 存储该年非交易日。计算逻辑:若支付日期对应的 yyyy,MM,dd 不存在于 IB 日历 HolidayJson 中,则说明支付日期是银行间交易日,触发审批。",
// RuleExpr = "DbContext.swap_flow_event.Any(e => e.SwapTradeId == TradeId && e.EventType == 2 && e.DataState != 0 && e.PayDate.HasValue) && !DbContext.calendar.First(c => c.Country == \"IB\" && c.Year == DbContext.swap_flow_event.Where(e => e.SwapTradeId == TradeId && e.EventType == 2 && e.DataState != 0 && e.PayDate.HasValue).OrderByDescending(e => e.id).First().PayDate.Value.Year && c.ValidState != \"InValid\").HolidayJson.Contains(DbContext.swap_flow_event.Where(e => e.SwapTradeId == TradeId && e.EventType == 2 && e.DataState != 0 && e.PayDate.HasValue).OrderByDescending(e => e.id).First().PayDate.Value.ToString(\"yyyy,MM,dd\"))",
// RuleText = "取值字段:取互换交易-交易查看-交易平仓窗口本次提交的 UnwindData.PayDatePayDate 对应页面支付日期;通过 DbContext.calendar 按 Country='IB' 且 Year=PayDate.Year 取银行间日历,HolidayJson 存储该年非交易日。计算逻辑:若支付日期对应的 yyyy,MM,dd 不存在于 IB 日历 HolidayJson 中,则说明支付日期是银行间交易日,触发审批。",
// RuleExpr = "PayDate.HasValue && RiskCalendarHelper.IsInterbankTradingDay(DbContext, PayDate.Value)",
// Version = 1,
// Status = RiskRuleStatus.Active,
// OptId = 0,
@@ -2236,6 +2245,8 @@ WHERE t.id = @TradeId;
//});
```
变量值核对 SQL:用于核对已落库平仓事件的支付日期是否为银行间交易日;首次提交前的页面值应以请求中的 UnwindData.PayDate 为准,不能只依赖该 SQL。
```sql
SET @TradeId = 3001699;
@@ -2274,33 +2285,54 @@ WHERE t.id = @TradeId;
## 20. 规则 9 查询结果排查 SQL
规则 9:到期日为银行间交易日(本地)。用于核对互换交易界面的到期日是否为银行间交易日;若到期日未落在 IB 日历的非交易日列表中,则命中。
规则 9:到期日为银行间交易日(本地)。用于核对新增互换交易的到期日是否为银行间交易日;若到期日未落在 IB 日历的非交易日列表中,则命中。
取数流程:
```text
1. 根据 TradeId 查当前 trade
2. 取 trade.ExerciseDate,作为互换交易界面的到期日
3. 根据 ExerciseDate.Value.Year 查询 calendar 表中 Country = 'IB' 的银行间日历
4. calendar.HolidayJson 存储该年非交易日,格式为 yyyy,MM,dd
5. HolidayJson 不包含到期日对应的 yyyy,MM,dd,则说明到期日是银行间交易日,命中规则
1. 根据 TradeId 查 swap_position
2. 限定 SwapTradeId = TradeId、IsInitial = 1,取新增互换交易生成的期初持仓
3. 取 swap_position.PosiMatuirityDate,作为新增互换交易的到期日期
4. 根据 PosiMatuirityDate.Value.Year 查询 calendar 表中 Country = 'IB' 的银行间日历
5. calendar.HolidayJson 存储该年非交易日,格式为 yyyy,MM,dd
6. 若 HolidayJson 不包含到期日期对应的 yyyy,MM,dd,则说明到期日期是银行间交易日,命中规则。
```
规则公式:
```text
到期日 ∉ IB 日历非交易日
到期日 ∉ IB 日历非交易日
```
规则字段口径:
```text
到期日trade.ExerciseDate,对应互换交易界面的到期日
到期日期:swap_position.PosiMatuirityDate,对应新增互换交易的到期日
期初持仓:swap_position.IsInitial = 1
银行间日历:calendar.Country = 'IB'
日历年份:calendar.Year = trade.ExerciseDate.Year
日历年份:calendar.Year = swap_position.PosiMatuirityDate.Year
非交易日:calendar.HolidayJson
```
变量 Roslyn 示例:变量名为“互换到期日期为银行间交易日”,DataType 为 Bool;规则前端配置“互换到期日期为银行间交易日 == true”。该变量取新增互换交易生成的期初持仓到期日期,即 swap_position.PosiMatuirityDate。
```csharp
var maturityDate = DbContext.swap_position
.Where(p => p.SwapTradeId == TradeId
&& p.IsInitial
&& p.PosiMatuirityDate.HasValue)
.OrderBy(p => p.id)
.Select(p => p.PosiMatuirityDate)
.FirstOrDefault();
if (!maturityDate.HasValue)
throw new Exception("互换到期日期为空");
return new RiskVariableValueDetail(
RiskCalendarHelper.IsInterbankTradingDay(DbContext, maturityDate.Value),
$"交易ID {TradeId},互换到期日期为{maturityDate.Value:yyyy-MM-dd}");
```
注释规则定义:
```csharp
@@ -2308,8 +2340,8 @@ WHERE t.id = @TradeId;
//{
// Id = 1000009,
// RuleName = "到期日为银行间交易日(本地)",
// RuleText = "取值字段:通过 DbContext.tradeTradeId 取当前交易的 ExerciseDateExerciseDate 对应互换交易界面的到期日;通过 DbContext.calendar 按 Country='IB' 且 Year=ExerciseDate.Year 取银行间日历,HolidayJson 存储该年非交易日。计算逻辑:若到期日对应的 yyyy,MM,dd 不存在于 IB 日历 HolidayJson 中,则说明到期日是银行间交易日,触发审批。",
// RuleExpr = "DbContext.trade.First(t => t.id == TradeId).ExerciseDate.HasValue && !DbContext.calendar.First(c => c.Country == \"IB\" && c.Year == DbContext.trade.First(t => t.id == TradeId).ExerciseDate.Value.Year && c.ValidState != \"InValid\").HolidayJson.Contains(DbContext.trade.First(t => t.id == TradeId).ExerciseDate.Value.ToString(\"yyyy,MM,dd\"))",
// RuleText = "取值字段:通过 DbContext.swap_position 按 SwapTradeId=TradeId、IsInitial=true 取新增互换交易生成的期初持仓 PosiMatuirityDatePosiMatuirityDate 对应新增互换交易的到期日;通过 DbContext.calendar 按 Country='IB' 且 Year=PosiMatuirityDate.Year 取银行间日历,HolidayJson 存储该年非交易日。计算逻辑:若到期日对应的 yyyy,MM,dd 不存在于 IB 日历 HolidayJson 中,则说明到期日是银行间交易日,触发审批。",
// RuleExpr = "DbContext.swap_position.Any(p => p.SwapTradeId == TradeId && p.IsInitial && p.PosiMatuirityDate.HasValue) && RiskCalendarHelper.IsInterbankTradingDay(DbContext, DbContext.swap_position.Where(p => p.SwapTradeId == TradeId && p.IsInitial && p.PosiMatuirityDate.HasValue).OrderBy(p => p.id).First().PosiMatuirityDate.Value)",
// Version = 1,
// Status = RiskRuleStatus.Active,
// OptId = 0,
@@ -2327,19 +2359,30 @@ SET @TradeId = 3001699;
SELECT
t.id AS TradeId,
t.TradeType,
t.ExerciseDate AS MaturityDate,
sp.id AS SwapPositionId,
sp.IsInitial,
sp.PosiMatuirityDate AS MaturityDate,
c.Country AS CalendarCountry,
c.Year AS CalendarYear,
DATE_FORMAT(t.ExerciseDate, '%Y,%m,%d') AS MaturityDateText,
DATE_FORMAT(sp.PosiMatuirityDate, '%Y,%m,%d') AS MaturityDateText,
CASE
WHEN t.ExerciseDate IS NOT NULL
AND c.HolidayJson NOT LIKE CONCAT('%', DATE_FORMAT(t.ExerciseDate, '%Y,%m,%d'), '%') THEN 1
WHEN sp.PosiMatuirityDate IS NOT NULL
AND c.HolidayJson NOT LIKE CONCAT('%', DATE_FORMAT(sp.PosiMatuirityDate, '%Y,%m,%d'), '%') THEN 1
ELSE 0
END AS IsMaturityDateIBTradingDay
FROM trade t
LEFT JOIN (
SELECT *
FROM swap_position
WHERE SwapTradeId = @TradeId
AND IsInitial = 1
AND PosiMatuirityDate IS NOT NULL
ORDER BY id
LIMIT 1
) sp ON sp.SwapTradeId = t.id
LEFT JOIN calendar c
ON c.Country = 'IB'
AND c.Year = YEAR(t.ExerciseDate)
AND c.Year = YEAR(sp.PosiMatuirityDate)
AND c.ValidState <> 'InValid'
WHERE t.id = @TradeId;
```
@@ -2348,17 +2391,16 @@ WHERE t.id = @TradeId;
## 21. 规则 10 查询结果排查 SQL
规则 10:平仓日为银行间交易日(本地)。用于核对交易平仓窗口的平仓日期是否为银行间交易日;若平仓日期未落在 IB 日历的非交易日列表中,则命中。
规则 10:平仓日为银行间交易日(本地)。用于核对互换交易-交易查看-交易平仓窗口中本次提交的平仓日期是否为银行间交易日;若平仓日期未落在 IB 日历的非交易日列表中,则命中。
取数流程:
```text
1. 根据 TradeId 查 swap_flow_event
2. 限定 SwapTradeId = TradeId、EventType = 2、DataState <> 0,取平仓事件
3. 取 swap_flow_event.UnwindDate,作为交易平仓窗口的平仓日期
4. 根据 UnwindDate.Value.Year 查询 calendar 表中 Country = 'IB' 的银行间日历
5. calendar.HolidayJson 存储该年非交易日,格式为 yyyy,MM,dd
6. 若 HolidayJson 不包含平仓日期对应的 yyyy,MM,dd,则说明平仓日期是银行间交易日,命中规则。
1. 用户从互换交易-交易查看进入交易平仓窗口
2. 取交易平仓窗口本次提交的平仓日期,即 UnwindData.UnwindDate
3. 根据 UnwindDate.Value.Year 查询 calendar 表中 Country = 'IB' 的银行间日历
4. calendar.HolidayJson 存储该年非交易日,格式为 yyyy,MM,dd
5. HolidayJson 不包含平仓日期对应的 yyyy,MM,dd,则说明平仓日期是银行间交易日,命中规则
```
规则公式:
@@ -2370,10 +2412,9 @@ WHERE t.id = @TradeId;
规则字段口径:
```text
平仓日期:swap_flow_event.UnwindDate,对应交易平仓窗口的平仓日期
平仓事件:swap_flow_event.EventType = 2
平仓日期:UnwindData.UnwindDate,对应互换交易-交易查看-交易平仓窗口的平仓日期
银行间日历:calendar.Country = 'IB'
日历年份:calendar.Year = swap_flow_event.UnwindDate.Year
日历年份:calendar.Year = UnwindData.UnwindDate.Year
非交易日:calendar.HolidayJson
```
@@ -2384,6 +2425,17 @@ WHERE t.id = @TradeId;
<vue-datepicker :mindate="minStartDate" :holiday="1" v-model="deal.UnwindDate" v-on:input="setUnwindDate" />
```
变量 Roslyn 示例:变量名为“平仓日期为银行间交易日”,DataType 为 Bool;规则前端配置“平仓日期为银行间交易日 == true”。该变量必须使用本次平仓请求中的 UnwindDate,不能查询 swap_flow_event 历史平仓事件,否则首次提交和修改平仓日期后的试算会取不到当前页面值。
```csharp
if (!UnwindDate.HasValue)
throw new Exception("平仓日期为空");
return new RiskVariableValueDetail(
RiskCalendarHelper.IsInterbankTradingDay(DbContext, UnwindDate.Value),
$"交易ID {TradeId},本次平仓日期为{UnwindDate.Value:yyyy-MM-dd}");
```
注释规则定义:
```csharp
@@ -2391,8 +2443,8 @@ WHERE t.id = @TradeId;
//{
// Id = 1000010,
// RuleName = "平仓日为银行间交易日(本地)",
// RuleText = "取值字段:通过 DbContext.swap_flow_event 按 SwapTradeId=TradeId、EventType=2、DataState<>0 取平仓事件的 UnwindDateUnwindDate 对应交易平仓窗口的平仓日期;通过 DbContext.calendar 按 Country='IB' 且 Year=UnwindDate.Year 取银行间日历,HolidayJson 存储该年非交易日。计算逻辑:若平仓日期对应的 yyyy,MM,dd 不存在于 IB 日历 HolidayJson 中,则说明平仓日期是银行间交易日,触发审批。",
// RuleExpr = "DbContext.swap_flow_event.Any(e => e.SwapTradeId == TradeId && e.EventType == 2 && e.DataState != 0 && e.UnwindDate.HasValue) && !DbContext.calendar.First(c => c.Country == \"IB\" && c.Year == DbContext.swap_flow_event.Where(e => e.SwapTradeId == TradeId && e.EventType == 2 && e.DataState != 0 && e.UnwindDate.HasValue).OrderByDescending(e => e.id).First().UnwindDate.Value.Year && c.ValidState != \"InValid\").HolidayJson.Contains(DbContext.swap_flow_event.Where(e => e.SwapTradeId == TradeId && e.EventType == 2 && e.DataState != 0 && e.UnwindDate.HasValue).OrderByDescending(e => e.id).First().UnwindDate.Value.ToString(\"yyyy,MM,dd\"))",
// RuleText = "取值字段:取互换交易-交易查看-交易平仓窗口本次提交的 UnwindData.UnwindDateUnwindDate 对应页面平仓日期;通过 DbContext.calendar 按 Country='IB' 且 Year=UnwindDate.Year 取银行间日历,HolidayJson 存储该年非交易日。计算逻辑:若平仓日期对应的 yyyy,MM,dd 不存在于 IB 日历 HolidayJson 中,则说明平仓日期是银行间交易日,触发审批。",
// RuleExpr = "UnwindDate.HasValue && RiskCalendarHelper.IsInterbankTradingDay(DbContext, UnwindDate.Value)",
// Version = 1,
// Status = RiskRuleStatus.Active,
// OptId = 0,
@@ -2404,6 +2456,8 @@ WHERE t.id = @TradeId;
//});
```
变量值核对 SQL:用于核对已落库平仓事件的平仓日期是否为银行间交易日;首次提交前的页面值应以请求中的 UnwindData.UnwindDate 为准,不能只依赖该 SQL。
```sql
SET @TradeId = 3001699;