feat(bond): 支持股票和基金现金分红纳入债券支付计算 - 收紧过度开发行为

- 实现股票/基金现金分红数据从 ex_dividend_info 同步到 BondPayment
- 新增公司行为去重机制,避免镜像任务完成后重复计息
- 统一现金分红存储口径为"每 10 份派现金额",保持与同步任务一致性
- 修改 CalcPayment 方法,股票/基金分红需除以 10 转换实际现金金额
- 添加单元测试验证债券票息和股票/基金分红的不同计算方式
- 更新文档注释说明"每 10 份派现金额"存储规范
- 修复公司行为生效日处理逻辑,确保正确应用除权系数
- 扩展测试覆盖股票类证券的公司行为处理场景
This commit is contained in:
张名锐
2026-08-20 13:30:36 +08:00
parent aa3548e77f
commit b2f4e16782
13 changed files with 384 additions and 368 deletions
@@ -113,7 +113,7 @@ namespace YLErp.Modules.SwapModule
}
[TestMethod]
public void OperationHistory_FiltersPendingCorporateActionOnly()
public void OperationHistory_PreservesPendingCorporateActionForAudit()
{
var info = CreateAction(80, ConsGlobal.InstrumentType.Stock);
var pendingData = SwapEodPositionService.BuildCorporateActionEventData(
@@ -133,12 +133,12 @@ namespace YLErp.Modules.SwapModule
new swap_event { id = 3, EventType = (int)SwapEventTypeEnum., EventData = "{}" }
};
var visible = SwapEventService.FilterOperationHistory(events);
Assert.AreEqual(2, visible.Count);
CollectionAssert.DoesNotContain(visible.Select(x => x.id).ToList(), 1L);
CollectionAssert.Contains(visible.Select(x => x.id).ToList(), 2L);
CollectionAssert.Contains(visible.Select(x => x.id).ToList(), 3L);
// 操作历史不再隐藏登记日待生效事件;Applied=false 是事件状态,不是展示过滤条件。
Assert.AreEqual(3, events.Count);
Assert.IsTrue(SwapEventService.TryDeserializeCorporateActionEventData(events[0], out var pendingSnapshot));
Assert.IsFalse(pendingSnapshot.Applied);
Assert.IsTrue(SwapEventService.TryDeserializeCorporateActionEventData(events[1], out var appliedSnapshot));
Assert.IsTrue(appliedSnapshot.Applied);
}
[TestMethod]
@@ -158,7 +158,7 @@ namespace YLErp.Modules.SwapModule
var info = CreateAction(81, ConsGlobal.InstrumentType.Stock);
info.GiveShareAmount = 10m;
var applied = SwapEodPositionService.ApplyFundCorporateActionToPosition(
var applied = SwapEodPositionService.ApplyCorporateActionToPosition(
position,
info,
100m,