#EQD-6290 日终持仓风险-互换持仓价值和已实现盈亏不正确 ; 未实现的分红到期时未去掉

This commit is contained in:
锦麟 王
2026-06-25 17:55:41 +08:00
parent 25626b845e
commit 90b6692222
4 changed files with 141 additions and 12 deletions
@@ -1,5 +1,6 @@
using BaseOUDAL;
using Newtonsoft.Json;
using NPOI.POIFS.Properties;
using System.Linq.Expressions;
using YLErp.DBModels;
using YLErp.DBModels.Consts;
@@ -471,12 +472,13 @@ namespace YLErp.Modules.SwapModule
eodPosi.TdCloseDividend += eodPosi.PosiDividendSum;
eodPosi.TdPosiDividend = 0;
eodPosi.RealizedDividend += eodPosi.PosiDividendSum;
eodPosi.PosiDividendSum = 0;
eodPosi.PosiProfitSum -= eodPosi.TdCloseDividend;
//互换持仓价值要去掉已实现的
eodPosi.SwapPositionValue -= eodPosi.PosiDividendSum;
//已实现盈亏要加上已实现的
eodPosi.RealizedPnl += eodPosi.PosiDividendSum;
eodPosi.PosiDividendSum = 0;
eodPosi.PosiProfitSum -= eodPosi.TdCloseDividend;
}
UnwindData unwindData = new UnwindData();
@@ -1460,6 +1462,12 @@ namespace YLErp.Modules.SwapModule
int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;
int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum. ? 1 : -1;
var price = UnderlyingCodePrice(eod.UnderlyingCode, dealDate, out decimal vobp);
var todayConsumedDividend = CalcConsumedDividend(curretEod, unwindEvents);
var originNotional = (decimal)td.OriginalStockEqvNotional / swapPosition.PosiNetPrice;
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
decimal totalPayment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, td.StartDate.Value, valueDate, (decimal)originNotional, shortRatio, directionRatio);
decimal tax = um.ValueAddedTax ?? 0;
decimal totalInterest = totalPayment / (1 + tax) * (1 - tax);
SetPriceInfoByFlowEvent(eod, curretEod, unwindEvents, swapPosition);
curretEod.dv01 = Dv01Helper.CalcDv01(eod.UnderlyingCode, curretEod.PosiQuantity, eod.PosiDirection, eod.PositionType, vobp);
curretEod.UnderlyingPrice = price;
@@ -1467,21 +1475,20 @@ namespace YLErp.Modules.SwapModule
curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio;
curretEod.TdPosiDividend = 0;
// 分红与互换无关,只要持仓>0且起始日早于当前日,正常计算当日分红
// 修改,互换事件会影响待实现的分红的,现在要算上
if (valueDate > td.StartDate.Value && (curretEod.PosiQuantity > 0))
{
decimal tax = um.ValueAddedTax ?? 0;
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
decimal payment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, eod.ValueDate, valueDate, curretEod.PosiQuantity, shortRatio, directionRatio);
curretEod.TdPosiDividend = Math.Round(payment / (1 + tax) * (1 - tax), 2);
}
curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl;
// 当日浮动端平仓盈亏·分红(仅来自平仓事件 和 互换 中已实现的分红)
curretEod.TdCloseDividend = unwindEvents.Sum(e => e.DividendIn);
curretEod.RealizedFee = eod.RealizedFee + curretEod.TdCloseFee;
curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl;
curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0;
var closeQty = unwindEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum.).ToList().Sum(s => s.Quantity);
// 当日浮动端平仓盈亏·分红(仅来自平仓事件中已实现的分红)
curretEod.TdCloseDividend = unwindEvents.Sum(e => e.DividendIn);
curretEod.RealizedDividend = curretEod.RealizedDividend + curretEod.TdCloseDividend;
// 分红与互换解耦:持仓>0时从起始日重算待实现分红,不再受互换事件影响
@@ -1490,11 +1497,9 @@ namespace YLErp.Modules.SwapModule
{
//decimal tax = um.ValueAddedTax ?? 0;
//BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
//decimal totalPayment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, td.StartDate.Value, valueDate, td.., shortRatio, directionRatio);
//decimal totalPayment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, td.StartDate.Value, valueDate, (decimal)originNotional, shortRatio, directionRatio);
//var totalInterest = totalPayment / (1 + tax) * (1 - tax);
var consumedDividend = - 1 * CalcConsumedDividend(curretEod, unwindEvents);
curretEod.PosiDividendSum = eod.PosiDividendSum - consumedDividend - curretEod.TdCloseDividend;
curretEod.PosiDividendSum = Math.Round(totalInterest,2) - curretEod.RealizedDividend;
}
else
{