修复平仓时计息使用事件日期

This commit is contained in:
gongpei
2025-10-23 22:42:27 +08:00
parent de184dfdd6
commit 1bbdd47497
2 changed files with 32 additions and 33 deletions
@@ -137,7 +137,7 @@ namespace YLErp.Modules.SwapModule
}
var flowEvents = new List<swap_flow_event>();
Expression<Func<swap_flow_event, bool>> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum.;
eventExpression = eventExpression.And(x => x.EventDate == settleDate );
eventExpression = eventExpression.And(x => x.EventDate == settleDate);
//if (settleDate == td.TradeDate)
//{
// eventExpression = eventExpression.And(x => x.EventDate == settleDate);
@@ -443,7 +443,7 @@ namespace YLErp.Modules.SwapModule
decimal allPosiNotionalValue = 0;
decimal longNotionalValue = realPositions.Where(s => s.PositionType == (int)PositionTypeFlag.Long).Sum(s => s.PosiNotionalValue);//剩余多头名义本金规模
decimal shortNotionalValue = realPositions.Where(s => s.PositionType == (int)PositionTypeFlag.Short).Sum(s => s.PosiNotionalValue);//剩余空头名义本金规模
foreach (var eventGroup in eventQuery.GroupBy(g => g.PositionId))//持仓标的腿合成持仓
{
var eventList = eventGroup.ToList();
@@ -562,7 +562,7 @@ namespace YLErp.Modules.SwapModule
unwindData.CloseNotionalValue = tdCloseNotionalValue;
swapEvent.EventData = JsonHelper.Serialize(unwindData);
DbContext.SaveChanges();
SaveEodSwap(td, tradeDate,preSettleDate);
SaveEodSwap(td, tradeDate, preSettleDate);
DbContext.SaveChanges();
trans?.Commit();
}
@@ -717,7 +717,7 @@ namespace YLErp.Modules.SwapModule
var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, posiNotionalValue, closePercent, (int)SwapEventTypeEnum., false, true, grossPrice, orginPv, true);
decimal InterestAmount = interests.Sum(x => x.InterestAmount);
decimal TdInterestAmount = interests.Sum(x => x.TdInterestAmount);
newEodPayPosition.ValueDate = valueDate;
newEodPayPosition.PositionId = position.id;
UpdateDbOption(newEodPayPosition);
@@ -750,7 +750,7 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition.InterestFeeSum = eodPayPosition.InterestFeeSum + newEodPayPosition.TdInterestFee - newEodPayPosition.TdCloseInterestFee;
newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum;
//持仓价值
newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum + newEodPayPosition.PosiProfitSum;
newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum + newEodPayPosition.PosiProfitSum;
//累计已实现
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio;
@@ -824,7 +824,7 @@ namespace YLErp.Modules.SwapModule
preEodPositions.Add(eodPayPosition);
var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, closeNational, 1, eventType, false, true, grossPrice, orginPv, true);
decimal TdInterestAmount = interests.Sum(x => x.TdInterestAmount);
newEodPayPosition.ValueDate = valueDate;
newEodPayPosition.PositionId = position.id;
UpdateDbOption(newEodPayPosition);
@@ -970,7 +970,7 @@ namespace YLErp.Modules.SwapModule
}
var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNational, posiShortNational, posiNotionalValue, closePercent, 0, false, needPrice, grossPrice, orginPv);
UpdateDbOption(newEodPayPosition);
newEodPayPosition.PosiStatus = 0;
newEodPayPosition.Invalid = false;
newEodPayPosition.ValueDate = valueDate;
@@ -1137,7 +1137,7 @@ namespace YLErp.Modules.SwapModule
{
return curretEod;
}
var dealDate = curretEod.ValueDate;
var dealDate = curretEod.ValueDate;
int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;
int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum. ? 1 : -1;
curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0;
@@ -1148,9 +1148,9 @@ namespace YLErp.Modules.SwapModule
{
decimal payment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, eod.ValueDate, valueDate, curretEod.PosiQuantity, shortRatio, directionRatio);
// 考虑增值税
curretEod.TdPosiDividend = payment / (1 - tax) * (1 + tax);
curretEod.TdPosiDividend = payment / (1 + tax) * (1 - tax);
}
curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend;
curretEod.PosiDividendSum = eod.PosiQuantity > 0 ? (eod.PosiDividendSum + curretEod.TdPosiDividend) : 0;
curretEod.PosiQuantity = eod.PosiQuantity;
if (curretEod.PosiStatus == 1)
{
@@ -1161,7 +1161,7 @@ namespace YLErp.Modules.SwapModule
curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio;
//curretEod.TdPosiDividend = 0;
//curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum+ curretEod.PosiFeePending;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.PosiFeePending;
curretEod.TdCloseFee = 0;
curretEod.TdCloseQty = 0;
curretEod.TdCloseMtmPnl = 0;
@@ -1218,7 +1218,7 @@ namespace YLErp.Modules.SwapModule
{
return curretEod;
}
var dealDate = curretEod.ValueDate;
var dealDate = curretEod.ValueDate;
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);
@@ -1231,20 +1231,19 @@ namespace YLErp.Modules.SwapModule
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
decimal payment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, eod.ValueDate, valueDate, curretEod.PosiQuantity, shortRatio, directionRatio);
// 考虑增值税
curretEod.TdPosiDividend = payment / (1 - tax) * (1 + tax);
curretEod.TdPosiDividend = payment / (1 + tax) * (1 - tax);
curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl;
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 = closeQty / eod.PosiQuantity * eod.PosiDividendSum;
curretEod.TdCloseDividend = unwindEvents.Sum(e => e.DividendIn);
curretEod.RealizedDividend = curretEod.RealizedDividend + curretEod.TdCloseDividend;
// 浮动端待实现收益·分红 = 昨日 + 当日浮动端分红 - 当日浮动端平仓盈亏·分红
curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend - curretEod.TdCloseDividend;
curretEod.RealizedDividend = eod.RealizedDividend + curretEod.TdCloseDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.PosiFeePending;
if (curretEod.PosiStatus == 1)
{
@@ -1320,13 +1319,13 @@ namespace YLErp.Modules.SwapModule
curretEod.PosiNetFeePrice = Math.Round(curretEod.PosiNetFeePrice ?? 0, 10, MidpointRounding.AwayFromZero);
}
curretEod.PosiNotionalValue = curretEod.PosiGrossPrice * curretEod.PosiQuantity * curretEod.ContractSize;
curretEod.PosiNotionalValue= Math.Round(curretEod.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
curretEod.PosiNotionalValue = Math.Round(curretEod.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
curretEod.TdPosiDividend = unwindEvents.Sum(x => x.DividendIn) * directionRatio;
curretEod.TdCloseFee = unwindFlowEvents.Sum(x => x.TradingFee+x.TradingFeePending);
curretEod.TdCloseFee = unwindFlowEvents.Sum(x => x.TradingFee + x.TradingFeePending);
curretEod.TdCloseQty = unwindQty;
curretEod.TdCloseMtmPnl = unwindEvents.Sum(x => x.MarkClosePnl);
}
if (curretEod.PosiQuantity==0)
if (curretEod.PosiQuantity == 0)
{
curretEod.PosiFeePending = 0;
}
@@ -1347,7 +1346,7 @@ namespace YLErp.Modules.SwapModule
{
return curretEod;
}
var dealDate = settleDate;
var dealDate = settleDate;
curretEod.ValueDate = settleDate;
curretEod.PosiStartDate = position.PosiStartDate;
curretEod.PosiMatuirityDate = td.ExerciseDate.Value;
@@ -1457,11 +1456,11 @@ namespace YLErp.Modules.SwapModule
/// </summary>
/// <param name="td">互换交易</param>
/// <param name="settleDate">收盘日</param>
private void SaveEodSwap(trade td, DateTime settleDate,DateTime preSettleDate)
private void SaveEodSwap(trade td, DateTime settleDate, DateTime preSettleDate)
{
var eod_Swaps = DbContext.eod_swap.Where(x => x.SwapTradeId == td.id && x.ValueDate >= preSettleDate && x.ValueDate<= settleDate).ToList();
var eod_Swap = eod_Swaps.FirstOrDefault(x => x.ValueDate == settleDate);
var preEodSwap= eod_Swaps.FirstOrDefault(x => x.ValueDate == preSettleDate);
var eod_Swaps = DbContext.eod_swap.Where(x => x.SwapTradeId == td.id && x.ValueDate >= preSettleDate && x.ValueDate <= settleDate).ToList();
var eod_Swap = eod_Swaps.FirstOrDefault(x => x.ValueDate == settleDate);
var preEodSwap = eod_Swaps.FirstOrDefault(x => x.ValueDate == preSettleDate);
if (eod_Swap == null)
{
eod_Swap = new eod_swap();
@@ -1918,14 +1917,14 @@ namespace YLErp.Modules.SwapModule
{
eventDate = QdpCalendarHelper.GetNonHoliday(eventDate.AddDays(tradeExtend.ExtendObj.SettlementRules));
}
item.DayCount = (eventDate - item.position.PosiStartDate).Days+1;
item.DayCount = (eventDate - item.position.PosiStartDate).Days + 1;
//item.position.PosiProfitSum += item.position.VTradingFee-item.position.PosiFeePending;
SetClientEodPosition(item.position);
//item.position.PosiProfitSum += item.TradingFee;
var posiProfitSum= item.position.PosiProfitSum;
var posiProfitSum = item.position.PosiProfitSum;
//item.position.PosiProfitSum 不需要加交易费用
item.position.PosiProfitSum = item.position.PosiProfitSum - item.position.PosiFeePending-item.position.PosiDividendSum;
item.NetSettmentAmount = item.position.PosiProfitSum+ item.position.PosiDividendSum+ item.position.PosiFeePending;
item.position.PosiProfitSum = item.position.PosiProfitSum - item.position.PosiFeePending - item.position.PosiDividendSum;
item.NetSettmentAmount = item.position.PosiProfitSum + item.position.PosiDividendSum + item.position.PosiFeePending;
item.PeriodAmount = item.position.PosiDividendSum;
var margins = positions.Where(x => x.SwapTradeId == item.position.SwapTradeId);
var interests = eodPositions.Where(x => x.SwapTradeId == item.position.SwapTradeId && x.ValueDate == item.position.ValueDate);
@@ -1933,14 +1932,14 @@ namespace YLErp.Modules.SwapModule
var eodInterests = interests.Where(x => !marginTypes.Contains(x.InterestMode));
var floatRateInterest = eodInterests.Where(x => !string.IsNullOrEmpty(x.FloatRateUnderlyingCode)).FirstOrDefault();
item.position.FloatRateUnderlyingCode = floatRateInterest?.FloatRateUnderlyingCode;
item.position.FloatRate= floatRateInterest?.FloatRate??0;
item.position.FloatRate = floatRateInterest?.FloatRate ?? 0;
item.OpenMarginAmount = margins.Sum(s => s.InterestPrincipalFix * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.OpenMarginRate = margins.Sum(s => s.InterestRateDefault * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.MarginInterestAmount = eodMargins.Sum(s => s.InterestIncomeSum * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.InterestAmount = eodInterests.Sum(s => s.InterestIncomeSum * (s.InterestDirection == (int)SwapDirectionEnum. ? -1 : 1));
item.InterestRate = eodInterests.Sum(s => s.InterestRateDefault);
item.NetSettmentAmount += item.InterestAmount + item.MarginInterestAmount + eodMargins.Sum(s => s.InterestPrincipalFix * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.NetSettmentAmount = Math.Round(item.NetSettmentAmount, ConsGlobal.MoneyRound,MidpointRounding.AwayFromZero);
item.NetSettmentAmount = Math.Round(item.NetSettmentAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
if (item.position.PosiNotionalValue != 0 && item.position.PosiNetPrice != 0)
{
item.FloatRateAbs = item.position.PosiNotionalValue == 0 ? 0 : item.InterestAmount / item.position.PosiNotionalValue;
@@ -1986,7 +1985,7 @@ namespace YLErp.Modules.SwapModule
return;
}
}
/// <summary>
/// 获取客户互换持仓信息
/// </summary>
@@ -2011,7 +2010,7 @@ namespace YLErp.Modules.SwapModule
foreach (var item in eodSwaps)
{
var tradeOrigin = trades.First(x => x.id == item.SwapTradeId);
var realizedPnL = item.RealizedMtmPnL + item.RealizedInterest;
var realizedPnL = item.RealizedMtmPnL + item.RealizedInterest;
var tdExtend = tradeExtends.First(x => x.TradeId == item.SwapTradeId);
eod_position model = new eod_position()
{