Files
zszq-trs/项目文档/数据库/排查SQL/互换分红损益_数据导出与验证.sql
T
hjhan ee1e8487d7 docs(swap): 排查SQL新增第2.5步-分红重复计算完整证明
4段查询还原证据链(含事件/价格/费用/付息明细):
段1事件拆解 MarkClosePnl=价差+费+分红;段2 EOD逐日盯市vs分红列;
段3累计对照;段4一句话结论。已连库实测:1875重复302400、1891重复-18.66。

修正段1列名: PosiNetPrice/PosiGrossPrice 在swap_flow_event是[NotMapped]
不入库,改用 TradingAmountNetAvg/TradingAmountNetFeeAvg。
2026-06-26 09:55:19 +08:00

436 lines
24 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
SELECT sfe.SwapTradeId,
MAX(sfe.SwapTradeNo) AS SwapTradeNo,
SUM(sfe.DividendIn) AS 分红合计,
SUM(sfe.MarkClosePnl) AS 盯市合计,
-- 关键:必须有 eod 归档才算"走完EOD的有效样本"
(SELECT COUNT(*) FROM eod_swap_position esp
WHERE esp.SwapTradeId = sfe.SwapTradeId) AS eod持仓快照数,
(SELECT COUNT(*) FROM eod_swap es
WHERE es.SwapTradeId = sfe.SwapTradeId) AS eod汇总数
FROM swap_flow_event sfe
WHERE sfe.EventType IN (3,4) AND sfe.DividendIn <> 0 AND sfe.DataState = 100
GROUP BY sfe.SwapTradeId
HAVING eod持仓快照数 > 0 AND eod汇总数 > 0 -- ← 这道过滤保证种子完整
ORDER BY ABS(SUM(sfe.DividendIn)) DESC, MAX(sfe.SwapTradeNo) DESC;
-- ============================================================================
-- 互换分红损益:数据导出与重复计算验证 SQL 工具箱
-- ----------------------------------------------------------------------------
-- ⚠ 本脚本所有列名均取自真实库 DDLglms_yltrs_ylcms.sql),非实体类属性名。
-- 实体类属性名与库列名存在差异(如 swap_flow_event.EventDate、
-- bond_payment_info.paying_interest、swap_position.IsInitial 等)。
--
-- 目的:
-- 1) 定位并导出一笔"带分红的互换交易"完整数据,作 golden source 种子;
-- 2) 用真实库数据验证"分红被重复计算 2 次"
-- 3) 生命周期守恒校验。
--
-- 涉及表与关键列(取自 DDL,列名以反引号为准):
-- swap_event 事件主表(窄列)id,SwapTradeId,ValueDate,EventType,
-- EventReason,EventData(json),Invalid,BackId,OptId,OptTime,ClientCashId
-- ※ 无 SwapTradeNo/UnderlyingCode/金额,这些在 EventData 或流水表
-- swap_position 持仓:PositionId,SwapTradeId,UnderlyingCode,PosiQuantity,
-- PosiNotionalValue,PosiNetPrice,PosiGrossPrice,IsInitial(0实时/1期初),
-- PosiDividendIncome,PosiTradingFeePending,Invalid
-- swap_flow_event 流水(分红核心)EventDate(非ValueDate!),SwapTradeId,SwapTradeNo,
-- EventType,PositionId,Quantity,MarkClosePnl,DividendIn,DividendPending,
-- CloseFee,DataState(0废弃/1等待/100完成)
-- eod_swap_position 日终归档:ValueDate,SwapTradeId,PositionId,TdCloseMtmPnl,TdCloseDividend,
-- RealizedMtmPnL,RealizedDividend,RealizedFee,RealizedInterest,
-- RealizedInterestFee,RealizedPnl,DV01(大写),PosiDividendSum,Invalid
-- eod_swap 日终汇总:ValueDate,SwapTradeId,SwapTradeNo,TdRealizedPnL,RealizedPnL,
-- PostionValue
-- bond_payment_info 债券付息:underlying_code,pay_date_PL,paying_interest(非payment_interest!),
-- paying_principal,paying_price
--
-- EventType 枚举(注意 swap_event 与 swap_flow_event 取值不同!):
-- swap_event.EventType (SwapEventTypeEnum): 展期1/平仓2/互换3/自动互换4/回退5/合成持仓6...
-- swap_flow_event.EventType (SwapFlowEventTypeEnum): 开仓1/平仓2/互换3/自动互换4
-- → 分红型互换在两表均为 EventType IN (3,4)
-- ============================================================================
-- ============================================================================
-- 第 0 步:定位一笔"带分红的互换交易"作为样本
-- ============================================================================
-- 思路:互换/自动互换事件(EventType in 3,4) 的 DividendIn != 0,即发生过分红型互换。
-- swap_flow_event 自带 SwapTradeNo(人类可读),无需关联 swap_event。
-- DataState=100 仅取已完成流水。
SELECT SwapTradeId,
MAX(SwapTradeNo) AS SwapTradeNo,
COUNT(*) AS 互换事件数,
SUM(DividendIn) AS 互换事件分红合计,
SUM(MarkClosePnl) AS 互换事件盯市合计,
MAX(EventDate) AS 最近事件日
FROM swap_flow_event
WHERE EventType IN (3, 4) -- 互换 / 自动互换
AND DividendIn <> 0 -- 真正发生过分红
AND DataState = 100 -- 仅完成的
GROUP BY SwapTradeId
ORDER BY SUM(DividendIn) DESC, MAX(EventDate) DESC
LIMIT 20;
-- 选定其中一行 SwapTradeId,填入下面 @TargetTradeId。
-- ============================================================================
-- 第 1 步:单笔交易完整数据导出(golden source 种子)
-- ============================================================================
-- 用法:把 @TargetTradeId 改为第 0 步选出的值,逐段执行。
SET @TargetTradeId := 1874; -- ← 替换为实际样本 SwapTradeId
-- 1.1 互换事件主表(窄列;EventData 是 json,含详细快照)
SELECT id, SwapTradeId, ValueDate, EventType, EventReason,
Invalid, BackId, OptId, OptName, OptTime, ClientCashId
FROM swap_event
WHERE SwapTradeId = @TargetTradeId
ORDER BY ValueDate, id;
-- 1.2 互换持仓(区分期初/实时:IsInitial 1=期初, 0=实时)
SELECT PositionId, SwapTradeId, UnderlyingCode, PosiDirection, PositionType,
PosiQuantity, PosiNotionalValue, PosiNetPrice, PosiGrossPrice,
ContractSize, CountRatio, PosiTradingFee, PosiTradingFeePending,
PosiDividendIncome, IsInitial, Invalid
FROM swap_position
WHERE SwapTradeId = @TargetTradeId
ORDER BY IsInitial DESC, PositionId;
-- 说明:IsInitial=1 是期初开仓腿;=0 是实时持仓(会随平仓/互换变动)。
-- 1.3 流水事件(分红核心表,导出全字段便于复盘)
SELECT id, EventDate, SwapTradeId, SwapTradeNo, EventType, EventReason,
PositionId, PayDirection, PositionType, UnderlyingCode, Quantity,
TradingAmount, TradingAmountAvg, TradingAmountFeeAvg,
TradingFee, TradingFeePending, DividendPending,
MarkClosePnl, DividendIn, CloseFee, DataState, ClientCashId
FROM swap_flow_event
WHERE SwapTradeId = @TargetTradeId
ORDER BY EventDate, EventType, id;
-- 1.4 日终持仓归档(按日快照,含所有 TdClose* / Realized* 字段)
SELECT id, ValueDate, SwapTradeId, PositionId, PosiDirection, PositionType,
UnderlyingCode, PosiQuantity, PosiNotionalValue,
PosiNetPrice, PosiGrossPrice, UnderlyingPrice, UnderlyingMarketValue,
TdPosiDividend, PosiMtmPnL, PosiDividendSum, PosiFeePending, PosiProfitSum,
TdCloseQty, TdCloseMtmPnl, TdCloseDividend, TdCloseFee,
RealizedMtmPnL, RealizedDividend, RealizedFee, RealizedInterest, RealizedInterestFee,
RealizedPnl, DV01, PosiStatus, Invalid
FROM eod_swap_position
WHERE SwapTradeId = @TargetTradeId
ORDER BY PositionId, ValueDate;
-- 1.5 日终互换层汇总
SELECT id, ValueDate, SwapTradeId, SwapTradeNo, TdCloseQty,
TdRealizedPnL, RealizedPnL, PostionValue
FROM eod_swap
WHERE SwapTradeId = @TargetTradeId
ORDER BY ValueDate;
-- 1.6 债券付息明细(理论应付分红来源)
-- 先从 swap_position 取该交易挂钩的标的代码:
SELECT DISTINCT UnderlyingCode
FROM swap_position
WHERE SwapTradeId = @TargetTradeId
AND UnderlyingCode IS NOT NULL;
-- 再用取到的 UnderlyingCode 查付息明细(替换 @BondCode):
SET @BondCode := 'PUT_UNDERLYING_CODE_HERE';
SELECT id, underlying_code, inner_code,
pay_date_PL, pay_date_act, paying_interest, paying_principal, paying_price,
interest_tax_rate, event_type, info_source, insert_time
FROM bond_payment_info
WHERE underlying_code = @BondCode
ORDER BY pay_date_PL;
-- ============================================================================
-- 第 2 步:分红重复计算验证(证明"分红被算 2 次"
-- ============================================================================
-- 根因链路(SwapEodPositionService.cs):
-- SetPriceInfoByFlowEvent:1610 TdCloseMtmPnl = Σ unwindEvents.MarkClosePnl
-- (互换/平仓事件的 MarkClosePnl 已含分红)
-- UpdateEodPosition:1486 RealizedMtmPnL += TdCloseMtmPnl ← 分红第1次进"盯市"列
-- UpdateEodPosition:1488/1607 TdCloseDividend = Σ DividendIn
-- UpdateEodPosition:1494 RealizedDividend += TdCloseDividend ← 分红第2次进"分红"列
-- SaveEodSwap:1869 eod_swap.RealizedPnL = Σ(RealizedMtmPnL + RealizedDividend + ...)
-- → 分红在盯市列和分红列各计一次 = 2 次
--
-- 验证思路:若 MarkClosePnl 含分红,则同一事件日同一持仓满足:
-- 该日"盯市列中扣除纯平仓价差后的余额" ≈ "分红列",且两者都进了 RealizedPnL → 重复。
SET @TargetTradeId := 1874; -- ← 替换为实际样本
-- 2.1 逐日核对:盯市列 vs 分红列
-- 关键比对:盯市列里扣除"纯平仓事件(EventType=2)的价差"后,剩余是否≈分红列。
-- 若是,说明互换/自动互换事件(EventType in 3,4)的 MarkClosePnl 含分红。
SELECT esp.ValueDate,
esp.PositionId,
esp.TdCloseMtmPnl AS 当日盯市列,
esp.TdCloseDividend AS 当日分红列,
-- 当日纯平仓事件(EventType=2)的盯市价差合计(理论上=纯价差,不含分红)
(SELECT COALESCE(SUM(sfe2.MarkClosePnl), 0)
FROM swap_flow_event sfe2
WHERE sfe2.SwapTradeId = esp.SwapTradeId
AND sfe2.PositionId = esp.PositionId
AND sfe2.EventType = 2
AND sfe2.DataState = 100
AND sfe2.EventDate = esp.ValueDate) AS 纯平仓盯市价差,
-- 盯市列 - 纯平仓价差 = 互换/自动互换事件贡献的盯市成分(若≈分红列→含分红)
(esp.TdCloseMtmPnl - (
SELECT COALESCE(SUM(sfe2.MarkClosePnl), 0)
FROM swap_flow_event sfe2
WHERE sfe2.SwapTradeId = esp.SwapTradeId
AND sfe2.PositionId = esp.PositionId
AND sfe2.EventType = 2
AND sfe2.DataState = 100
AND sfe2.EventDate = esp.ValueDate
)) AS 盯市列扣除纯平仓后余额,
esp.TdCloseDividend AS 分红列,
esp.RealizedMtmPnL AS 累计盯市已实现,
esp.RealizedDividend AS 累计分红已实现,
esp.RealizedPnl AS 持仓层累计已实现
FROM eod_swap_position esp
WHERE esp.SwapTradeId = @TargetTradeId
AND (esp.TdCloseDividend <> 0 OR esp.TdCloseMtmPnl <> 0)
ORDER BY esp.PositionId, esp.ValueDate;
-- 2.2 全生命周期汇总:盯市列累计 + 分红列累计 vs RealizedPnL
-- 若 MarkClosePnl 含分红:盯市累计里多算了一份分红,导致
-- RealizedMtmPnL + RealizedDividend > 真实盯市价差 + 分红 (多出 ≈ 分红金额)
SELECT esp.PositionId,
MAX(esp.RealizedMtmPnL) AS 最终累计盯市已实现,
MAX(esp.RealizedDividend) AS 最终累计分红已实现,
MAX(esp.RealizedPnl) AS 最终持仓层累计已实现,
-- 互换层汇总公式(SaveEodSwap:1869)的口径:
(MAX(esp.RealizedMtmPnL) + MAX(esp.RealizedDividend)
+ COALESCE(MAX(esp.RealizedFee),0)
+ COALESCE(MAX(esp.RealizedInterest),0)
+ COALESCE(MAX(esp.RealizedInterestFee),0))
AS 按互换层公式重算,
-- 理论上不含费的纯盯市价差(用纯平仓 EventType=2 的 MarkClosePnl 估算):
(SELECT COALESCE(SUM(sfe.MarkClosePnl), 0)
FROM swap_flow_event sfe
WHERE sfe.SwapTradeId = esp.SwapTradeId
AND sfe.PositionId = esp.PositionId
AND sfe.EventType = 2
AND sfe.DataState = 100) AS 纯平仓盯市价差合计
FROM eod_swap_position esp
WHERE esp.SwapTradeId = @TargetTradeId
GROUP BY esp.PositionId;
-- 2.3 一句话诊断:互换/自动互换分红事件的 MarkClosePnl 是否含分红
-- 对每个 EventType in (3,4) 且 DividendIn<>0 的事件日,
-- 检查当日 eod 盯市列是否也包含了等额成分。
SELECT sfe.EventDate,
sfe.PositionId,
sfe.EventType,
sfe.DividendIn AS 事件分红流入,
sfe.MarkClosePnl AS 事件盯市含费,
esp.TdCloseMtmPnl AS 当日盯市列,
esp.TdCloseDividend AS 当日分红列,
CASE
-- 同一互换事件自身:若 MarkClosePnl≈DividendIn,则该事件盯市就含分红
WHEN ABS(sfe.MarkClosePnl - sfe.DividendIn) < 0.01 AND sfe.DividendIn <> 0
THEN '⚠该事件MarkClosePnl≈DividendIn→盯市含分红(根因)'
-- 当日整列:盯市列≈分红列
WHEN esp.TdCloseMtmPnl <> 0
AND ABS(esp.TdCloseMtmPnl - esp.TdCloseDividend) < 0.01
THEN '⚠当日盯市列≈分红列→重复'
ELSE '需人工核对'
END AS 诊断
FROM swap_flow_event sfe
JOIN eod_swap_position esp
ON esp.SwapTradeId = sfe.SwapTradeId
AND esp.PositionId = sfe.PositionId
AND esp.ValueDate = sfe.EventDate
WHERE sfe.SwapTradeId = @TargetTradeId
AND sfe.EventType IN (3, 4)
AND sfe.DividendIn <> 0
AND sfe.DataState = 100
ORDER BY sfe.EventDate;
-- ============================================================================
-- 第 2.5 步:分红被计算两次的完整证明(含事件/价格/费用/付息明细)
-- ============================================================================
-- 本节用 4 个查询把"分红重复计算"的证据链完整还原:
-- 段1事件明细:每条平仓/互换事件,把 MarkClosePnl 拆成 价差+费+分红 三成分。
-- 若"价差"残差~0 且 DividendIn<>0,证明 MarkClosePnl 里装的就是分红。
-- 段2 EOD逐日:盯市列(TdCloseMtmPnl) 与 分红列(TdCloseDividend) 同日出现等额分红。
-- 段3 累计对照:盯市列累计 RealizedMtmPnL 含了分红成分,分红列累计 RealizedDividend 又含一份。
-- 段4 一句话结论:重复金额 = 盯市列里的分红成分(按 PositionId 汇总避免双向腿抵消)。
--
-- 已用 golden 数据(1875纯分红型重复302400、1891混合型重复-18.66)校验本 SQL 结果正确。
SET @TargetTradeId := 1875; -- 替换为实际样本(1875=纯分红型 / 1891=混合型)
-- 段1 事件明细拆解:MarkClosePnl = 价差 + 费(CloseFee) + 分红(DividendIn)
-- 价差残差 = MarkClosePnl - DividendIn - CloseFee
-- 纯分红型:价差残差~0MarkClosePnl 全是分红)
-- 混合型 :价差残差<>0MarkClosePnl 含真实价差 + 少量分红)
SELECT sfe.id,
sfe.EventDate,
CASE sfe.EventType WHEN 1 THEN '开仓' WHEN 2 THEN '平仓'
WHEN 3 THEN '互换' WHEN 4 THEN '自动互换' END AS 事件类型,
sfe.PositionId,
sfe.UnderlyingCode,
sfe.Quantity,
sfe.TradingAmountAvg AS 成交均价不含费,
sfe.TradingAmountFeeAvg AS 含费均价,
sfe.TradingAmountNetAvg AS 成交净价不含费,
sfe.TradingAmountNetFeeAvg AS 成交净价含费,
sfe.TradingAmount AS 成交金额,
sfe.TradingFee AS 交易佣金,
sfe.TradingFeePending AS 待结算后付费用,
sfe.CloseFee AS 平仓费用_费成分,
sfe.DividendPending AS 待结算分红,
sfe.DividendIn AS 分红流入_分红成分,
sfe.MarkClosePnl AS 盯市盈亏_总额,
(sfe.MarkClosePnl - sfe.DividendIn - sfe.CloseFee) AS 价差残差,
CASE WHEN sfe.EventType IN (2,3,4)
AND ABS(sfe.MarkClosePnl - sfe.DividendIn - sfe.CloseFee) < 0.01
AND sfe.DividendIn <> 0
THEN '根因:价差~0->MarkClosePnl全是分红'
WHEN sfe.EventType IN (2,3,4) AND sfe.DividendIn <> 0
THEN '混合:价差+分红(分红成分进盯市列)'
ELSE '' END AS 事件诊断
FROM swap_flow_event sfe
WHERE sfe.SwapTradeId = @TargetTradeId
AND sfe.DataState = 100
AND sfe.EventType IN (2,3,4)
ORDER BY sfe.PositionId, sfe.EventDate, sfe.EventType;
-- 段2 EOD逐日:盯市列 vs 分红列(同日同腿,分红同时出现在两列)
SELECT esp.ValueDate,
esp.PositionId,
esp.TdCloseQty,
esp.UnderlyingPrice AS 当日盯市价,
esp.PosiGrossPrice AS 期初成本价,
esp.TdCloseMtmPnl AS 当日盯市列,
esp.RealizedMtmPnL AS 累计盯市列,
esp.TdCloseDividend AS 当日分红列,
esp.RealizedDividend AS 累计分红列,
esp.TdCloseFee AS 当日费用列,
esp.TdCloseInterest AS 当日利息列,
esp.RealizedPnl AS 持仓层累计已实现,
CASE WHEN esp.TdCloseMtmPnl <> 0 AND esp.TdCloseDividend <> 0
THEN CONCAT('分红', esp.TdCloseDividend, '同时进盯市列和分红列')
ELSE '' END AS 当日诊断
FROM eod_swap_position esp
WHERE esp.SwapTradeId = @TargetTradeId
AND (esp.TdCloseMtmPnl <> 0 OR esp.TdCloseDividend <> 0)
ORDER BY esp.PositionId, esp.ValueDate;
-- 段3 累计对照:按 PositionId 取最终累计,算出盯市列里的分红成分
-- 盯市列里的分红成分 = 该腿所有平仓/互换事件的 DividendIn 之和
SELECT fin.PositionId,
fin.RealizedMtmPnL AS 最终累计盯市列,
fin.RealizedDividend AS 最终累计分红列,
fin.RealizedFee AS 最终累计费用列,
fin.RealizedInterest AS 最终累计利息列,
fin.RealizedPnl AS 最终持仓层已实现,
dv.盯市列分红成分,
(fin.RealizedMtmPnL - dv.盯市列分红成分 - fin.RealizedFee) AS 盯市列纯价差成分
FROM (SELECT PositionId, RealizedMtmPnL, RealizedDividend, RealizedFee, RealizedInterest, RealizedPnl
FROM eod_swap_position esp
WHERE esp.SwapTradeId = @TargetTradeId
AND esp.id IN (SELECT MAX(id) FROM eod_swap_position
WHERE SwapTradeId = @TargetTradeId GROUP BY PositionId)
) fin
LEFT JOIN (SELECT PositionId, SUM(DividendIn) AS 盯市列分红成分
FROM swap_flow_event
WHERE SwapTradeId = @TargetTradeId AND DataState = 100 AND EventType IN (2,3,4)
GROUP BY PositionId) dv ON dv.PositionId = fin.PositionId
ORDER BY fin.PositionId;
-- 段4 一句话结论:重复金额合计 = 盯市列里的分红成分之和
SELECT @TargetTradeId AS SwapTradeId,
SUM(盯市列分红成分) AS 重复计入分红金额,
(SELECT SUM(RealizedPnl) FROM eod_swap_position
WHERE SwapTradeId = @TargetTradeId
AND id IN (SELECT MAX(id) FROM eod_swap_position
WHERE SwapTradeId = @TargetTradeId GROUP BY PositionId)) AS 当前RealizedPnl合计,
CASE WHEN ABS(SUM(盯市列分红成分)) > 0.01
THEN CONCAT('坐实重复计算: 分红 ', SUM(盯市列分红成分),
' 既在 RealizedMtmPnL(盯市列) 又在 RealizedDividend(分红列)',
', 修复后 RealizedPnl 应减少 ', SUM(盯市列分红成分))
ELSE '未检测到重复(可能已修复或无分红平仓/互换事件)' END AS 结论
FROM (SELECT PositionId, SUM(DividendIn) AS 盯市列分红成分
FROM swap_flow_event
WHERE SwapTradeId = @TargetTradeId AND DataState = 100 AND EventType IN (2,3,4)
GROUP BY PositionId) t;
-- 预期结果:
-- 1875(纯分红型) -> 重复计入 302400.00MarkClosePnl 全是分红,价差=0
-- 1891(混合型) -> 重复计入 -18.66 MarkClosePnl 含价差395604 + 分红-18.66
-- ============================================================================
-- 第 3 步:生命周期守恒校验(累计已实现分红 vs 理论应付分红)
-- ============================================================================
-- 含义:一笔互换交易从开仓到全部平仓,"已实现分红收益总额"应等于持仓期间
-- 该债券应付分红(税后)的累加。任何偏差说明核算有误。
-- 若存在第 2 步的重复计算,累计已实现分红会被放大,本步量化偏差作修复后回归基线。
SET @TargetTradeId := 1874;
-- 3.1 实际已实现分红(从事件流水 DividendIn 累加)
SELECT
SUM(CASE WHEN EventType IN (2,3,4) THEN DividendIn ELSE 0 END) AS 事件流水已实现分红合计,
SUM(CASE WHEN EventType IN (3,4) THEN DividendIn ELSE 0 END) AS 其中互换事件分红,
SUM(CASE WHEN EventType = 2 THEN DividendIn ELSE 0 END) AS 其中平仓事件分红
FROM swap_flow_event
WHERE SwapTradeId = @TargetTradeId
AND DataState = 100;
-- 3.2 日终表口径的最终累计已实现分红(应与 3.1 一致)
SELECT PositionId,
MAX(RealizedDividend) AS 日终表累计已实现分红,
MAX(RealizedPnl) AS 日终表累计已实现盈亏
FROM eod_swap_position
WHERE SwapTradeId = @TargetTradeId
GROUP BY PositionId;
-- 3.3 理论应付分红(税后)—— 需人工带入持仓区间与标的
-- 业务口径(BondPaymentService.CalcPayment):
-- totalPayment = CalcPayment(UnderlyingCode, StartDate, EndDate, Qty, shortRatio, dirRatio)
-- 理论税后分红 = totalPayment / (1 + tax) * (1 - tax)
-- 这里给出从 bond_payment_info 直接估算的简化版(仅供量级对照):
SET @BondCode := 'PUT_UNDERLYING_CODE_HERE';
SET @StartDate := '2024-01-01';
SET @EndDate := '2024-12-31';
SELECT underlying_code,
SUM(COALESCE(paying_interest, 0)) * 0.01 AS 区间每张利息合计_相对值,
COUNT(*) AS 付息次数
FROM bond_payment_info
WHERE underlying_code = @BondCode
AND pay_date_PL BETWEEN @StartDate AND @EndDate
GROUP BY underlying_code;
-- 说明:paying_interest 为"每张兑付利息额",×0.01 转相对价后还需 ×持仓数量 ×方向,
-- 再做税后调整,才能与 3.1/3.2 对齐。精确口径见 BondPaymentService.CalcPayment。
-- ============================================================================
-- 附录:导出为 json / csv 的方式
-- ============================================================================
-- 【方式A:MySQL 客户端导出(推荐,最简单)】
-- 在 Navicat / DBeaver / MySQL Workbench 中执行上述任一 SELECT,结果区右键
-- "导出" → 选 JSON / CSV / Excel。推荐把 1.1~1.6 各导一份,按表名命名:
-- swap_event.json / swap_position.json / swap_flow_event.json /
-- eod_swap_position.json / eod_swap.json / bond_payment_info.json
--
-- 【方式B:命令行 mysqldump(整表+DDL,含 CREATE)】
-- mysqldump -h<host> -u<user> -p<db> swap_flow_event \
-- --where="SwapTradeId=1874 AND DataState=100" \
-- --skip-add-drop-table --no-create-info > sfe_1874.sql
--
-- 【方式CSELECT ... INTO OUTFILE(服务端导 csv,需 FILE 权限)】
-- SELECT ... FROM swap_flow_event WHERE SwapTradeId=1874
-- INTO OUTFILE '/tmp/sfe_1874.csv'
-- FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
--
-- golden source 种子建议:用方式A导出 1.1~1.6 共 6 个 json
-- 连同 trade 主记录,作为"一笔带分红互换交易"的完整快照纳入版本库。