fix(swap): 单利路径扣除历史已结利息consumedInterest
复利路径已由c6adb3bb修复(加consumedInterest扣除),单利路径 CalcDailySimpleInterest未同步。互换结清后再平仓默认值偏大。 改动(SwapDealService.cs 3处): - cs:437 去掉InterestType==复利条件,单利也取GetConsumedInterest - cs:707 单利调用传入consumedInterest参数 - cs:802/856 CalcDailySimpleInterest签名加consumedInterest+末尾扣除 验证(Step1_SimpleInterestRedTest): 1813单利样本 34203偏大量8271→0✅, 34204预付金偏大量58→0✅(修正测试口径漏乘ratio) 复利回归(1889): 6-30默认值仍6.44✅无退化
This commit is contained in:
@@ -231,7 +231,7 @@ namespace YLErp.Modules.SwapModule
|
||||
|
||||
// 4. 对每个单利腿,对比"默认值"vs"应计基数(待实现-已结利息)"
|
||||
Console.WriteLine($"\n[3] 单利路径诊断:默认值 vs 应计基数");
|
||||
Console.WriteLine($" {"PositionId",10} {"InterestMode",14} {"默认值",14} {"eod待实现IPS",14} {"历史已结CI",14} {"应计(IPS-CI)",14} {"偏大量",14} {"红灯",6}");
|
||||
Console.WriteLine($" {"PositionId",10} {"InterestMode",14} {"方向",6} {"默认ClosePnL",14} {"InterestAmt",14} {"eod待实现IPS",14} {"历史已结CI",14} {"ratio",6} {"应计(IPS-CI)",14} {"偏大量",14} {"红灯",6}");
|
||||
|
||||
int redCount = 0;
|
||||
foreach (var d in defaults.Where(x => x.InterestDirection > 0))
|
||||
@@ -248,31 +248,36 @@ namespace YLErp.Modules.SwapModule
|
||||
// 历史已结利息(复利路径用的 GetConsumedInterest,单利路径没用)
|
||||
decimal ci = service.GetConsumedInterest(tradeId, d.PositionId, testDate);
|
||||
|
||||
// 应计基数 = 待实现 - 已结(这才是正确的"未实现利息")
|
||||
decimal expected = ips - ci;
|
||||
// InterestClosePnL = InterestAmount × interestRatio(方向系数)
|
||||
// interestRatio = InterestDirection==收取(1) ? 1 : -1
|
||||
decimal interestRatio = d.InterestDirection == (int)SwapDirectionEnum.收取 ? 1m : -1m;
|
||||
// 应计基数 = (待实现 - 已结) × ratio(与 InterestClosePnL 同口径)
|
||||
decimal expected = (ips - ci) * interestRatio;
|
||||
decimal actual = d.InterestClosePnL;
|
||||
decimal diff = actual - expected;
|
||||
bool isRed = Math.Abs(ci) > 0.01m && Math.Abs(diff) > Math.Abs(ci) * 0.5m;
|
||||
|
||||
if (isRed) redCount++;
|
||||
string modeName = ((InterestModeEnum)d.InterestMode).ToString();
|
||||
Console.WriteLine($" {d.PositionId,10} {modeName,14} {actual,14:F4} {ips,14:F4} {ci,14:F4} {expected,14:F4} {diff,14:F4} {(isRed ? "⚠红灯" : "绿灯"),6}");
|
||||
string dirName = ((SwapDirectionEnum)d.InterestDirection).ToString();
|
||||
Console.WriteLine($" {d.PositionId,10} {modeName,14} {dirName,6} {actual,14:F4} {d.InterestAmount,14:F4} {ips,14:F4} {ci,14:F4} {interestRatio,6} {expected,14:F4} {diff,14:F4} {(isRed ? "⚠红灯" : "绿灯"),6}");
|
||||
}
|
||||
|
||||
Console.WriteLine($"\n[结论]");
|
||||
if (redCount > 0)
|
||||
{
|
||||
Console.WriteLine($" ⚠ 坐实单利路径 bug:{redCount} 条单利腿默认值偏大(含历史已结利息)。");
|
||||
Console.WriteLine($" 根因:CalcDailySimpleInterest(cs:802) 未加 consumedInterest 扣除(复利 cs:793 已加)。");
|
||||
Console.WriteLine($" ⚠ 单利路径仍存在偏大:{redCount} 条单利腿默认值含历史已结利息。");
|
||||
Console.WriteLine($" 根因:CalcDailySimpleInterest 未加 consumedInterest 扣除。");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($" 单利路径未检测到偏大(可能已修或样本无历史互换)。");
|
||||
Console.WriteLine($" ✅ 单利路径已修复:默认值正确扣除历史已结利息,无偏大。");
|
||||
}
|
||||
|
||||
// 红灯断言:单利路径应存在偏大
|
||||
Assert.IsTrue(redCount > 0,
|
||||
"红灯:单利路径应存在默认值偏大(含历史已结利息)。修复后此断言应反转。");
|
||||
// 绿灯断言(修复后):单利路径不应再存在偏大
|
||||
Assert.AreEqual(0, redCount,
|
||||
$"绿灯:单利路径默认值应正确扣除历史已结利息(consumedInterest)," +
|
||||
$"但仍有 {redCount} 条腿偏大。");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user