feat(bond): 支持债券与股票基金公司行为现金流计算的差异化处理 - init2

- 修改 CalcPayment 方法添加 useBondPriceScale 参数区分债券和股票/基金的金额计算口径
- 债券利息按每100元面值票息通过BondPriceConverter转为入库金额,股票基金分红直接计算
- 在BondPaymentService中添加详细的参数说明文档注释
- 更新SwapDealService中分红计算逻辑,根据标的类型自动选择合适的金额转换方式
- 新增CorporateActionEventLifecycleTest单元测试验证公司行为事件生命周期管理
- 添加SplitCorporateActionTddTest测试验证拆合股功能
- 优化FundCorporateActionRollbackAndUnwindTest扩展到股票类型测试
- 更新前端OperationHistory页面表格列宽和显示格式支持更长的说明信息
This commit is contained in:
张名锐
2026-08-19 17:48:34 +08:00
parent ddf233678d
commit aa3548e77f
19 changed files with 1342 additions and 104 deletions
@@ -119,24 +119,49 @@ namespace YLErp.Modules.EodModule
/// <param name="longRatio">多空方向</param>
/// <param name="payDirection">收支方向</param>
/// <returns></returns>
public decimal CalcPayment(string underlyingCode, DateTime startDate, DateTime endDate, decimal qty, decimal longRatio, decimal payDirection)
public decimal CalcPayment(
string underlyingCode,
DateTime startDate,
DateTime endDate,
decimal qty,
decimal longRatio,
decimal payDirection,
bool useBondPriceScale = true)
{
var payments = GetBondPayments(underlyingCode, startDate, endDate);
return CalcPayment(payments, qty, longRatio, payDirection);
return CalcPayment(payments, qty, longRatio, payDirection, useBondPriceScale);
}
/// <summary>
/// 计算某债券期间付息
/// 计算某标的期间现金流。债券与 Stock/Fund 公司行为共用 bond_payment_info
/// 但通过 useBondPriceScale 明确区分两种入库金额单位。
/// </summary>
/// <param name="payments">期间付息集合</param>
/// <param name="qty">持仓数量</param>
/// <param name="longRatio">多空方向</param>
/// <param name="payDirection">收支方向</param>
/// <param name="useBondPriceScale">
/// 是否按债券报价的百分比口径换算。债券的 payment_interest 是每 100 元面值的票息,
/// 需要继续通过 BondPriceConverter 转成入库金额;Fund/Stock 的公司行为现金分红
/// 在 bond_payment_info 中按每 10 份存储,payment_interest * qty 已经是实际现金,
/// 不能再做一次 /100。默认 true 是为了保持所有历史债券调用方的原有口径。
/// </param>
/// <returns></returns>
public decimal CalcPayment(List<BondPayment> payments, decimal qty, decimal longRatio, decimal payDirection)
public decimal CalcPayment(
List<BondPayment> payments,
decimal qty,
decimal longRatio,
decimal payDirection,
bool useBondPriceScale = true)
{
var interest = payments.Sum(s => s.payment_interest ?? 0);
// interest 为每 100 元面值的票息,×qty 后需 ÷100 转为实际金额(与入库价格 bondPriceMultiple 同口径)
return BondPriceConverter.ToStorage(interest * qty) * longRatio * payDirection;
var paymentAmount = interest * qty;
// 债券:interest 为每 100 元面值的票息,×qty 后需 ÷100 转为实际金额。
// Fund/Stock 公司行为:interest 已由【同步任务】写成 GiveCashAmount/10
// ×qty 就是“每 10 份派现额 × 持仓份额”,必须保留原金额,不能套债券的 /100。
var actualAmount = useBondPriceScale
? BondPriceConverter.ToStorage(paymentAmount)
: paymentAmount;
return actualAmount * longRatio * payDirection;
}
}