refactor(swap): 优化基金公司行为处理逻辑 - finished001

- 修改 FindFundCorporateActions 方法以支持查询跨日期范围的公司行为记录
- 实现按生效日期和ID顺序稳定排序的多条公司行为记录处理
- 更新平仓时基金基线恢复逻辑以正确处理跨多个生效日的场景
- 在测试类中重写 FindFundCorporateActions 方法以支持单元测试验证
- 添加完整的跨非交易日公司行为恢复功能测试用例
This commit is contained in:
张名锐
2026-08-20 16:10:56 +08:00
parent b2f4e16782
commit ff7e540084
4 changed files with 78 additions and 6 deletions
+27 -5
View File
@@ -310,6 +310,29 @@ namespace YLErp.Modules.SwapModule
&& x.EffectiveDate.Value == valueDate.Date);
}
/// <summary>
/// 查询从最近 EOD 之后到平仓日已经生效的 Stock/Fund 公司行为。
/// 平仓可能跨越登记日、生效日和多个非交易日,因此不能只按 valueDate 命中一条记录。
/// 调用方已限定为 Stock/Fund 浮动腿;同日多条记录按生效日、主键稳定排序后逐条应用。
/// </summary>
protected virtual List<ex_dividend_info> FindFundCorporateActions(
string underlyingCode,
DateTime eodDate,
DateTime valueDate)
{
var fromDate = eodDate.Date;
var toDate = valueDate.Date;
return DbContext.ex_dividend_info
.Where(x => x.ValidStatus
&& x.UnderlyingCode == underlyingCode
&& x.EffectiveDate.HasValue
&& x.EffectiveDate.Value.Date > fromDate
&& x.EffectiveDate.Value.Date <= toDate)
.OrderBy(x => x.EffectiveDate)
.ThenBy(x => x.id)
.ToList();
}
/// <summary>
/// Stock/Fund 公司行为系数仍使用登记日收盘价,而不是生效日盘中/收盘价。
/// 测试可用 EOD 快照价格作为回退值;生产从登记日行情表取真实收盘价。
@@ -387,13 +410,12 @@ namespace YLErp.Modules.SwapModule
}
// 最近 EOD 已经处于生效日或更晚时,说明该快照本身已经是除权后基线,
// 不能再次套系数。只有“最近 EOD < EffectiveDate <= valueDate”时,
// 才在盘中恢复后补一次公司行为。
var corporateAction = FindFundCorporateAction(
// 不能再次套系数。若平仓跨过多个生效日,则按生效日、id 顺序逐条补齐。
var corporateActions = FindFundCorporateActions(
position.UnderlyingCode,
eodPosition.ValueDate,
valueDate);
if (corporateAction?.EffectiveDate > eodPosition.ValueDate.Date
&& corporateAction.EffectiveDate.Value.Date <= valueDate.Date)
foreach (var corporateAction in corporateActions ?? new List<ex_dividend_info>())
{
var closePrice = GetFundCorporateActionClosePrice(
corporateAction,