feat(swap-trade): 新增收益互换交易功能

- 实现了收入互换交易的前端界面和交互逻辑
- 添加了平仓日期、标的价格、交易费用等字段的处理
- 集成了价格格式化和数值精度控制功能
- 实现了浮动端平仓盈亏计算逻辑
- 添加了利息端信息获取和平仓金额计算
- 集成了审批流程和复核机制
- 实现了后端服务层的平仓初始化和利息计算功能
- 添加了多空组合平仓和收益互换的业务逻辑
- 集成了底层数据库模型和服务类
- 实现了价格缓存和数据验证机制
This commit is contained in:
hjhan
2026-04-14 09:09:18 +08:00
parent e0d4f247f6
commit 6708878d6a
3 changed files with 40 additions and 26 deletions
+35 -22
View File
@@ -181,8 +181,8 @@ namespace YLErp.Modules.SwapModule
unwindData.StartDate = preDealDate.Value;
}
unwindData.ValueDate = dealDate;
unwindData.UnwindDate = unwindData.UnwindDate;
unwindData.PayDate = QdpCalendarHelper.GetNonHoliday(unwindData.UnwindDate.Value.AddDays(td.trade_extend.ExtendObj.SettlementRules));
unwindData.UnwindDate = dealDate;
unwindData.PayDate = QdpCalendarHelper.GetNonHoliday(dealDate.AddDays(td.trade_extend.ExtendObj.SettlementRules));
unwindData.SwapTradeId = tradeId;
unwindData.NotionalValue = Convert.ToDecimal(td.OriginalStockEqvNotional ?? 0);
unwindData.NotionalQty = positions.Sum(s => s.PosiQuantity);
@@ -610,17 +610,17 @@ namespace YLErp.Modules.SwapModule
DateTime lastSwapDate = preEodPosition.ValueDate;
decimal interestProfitSum = preEodPosition.InterestProfitSum;
var TdInterestPrincipal = preEodPosition.TdInterestPrincipal;
decimal interest = 0;
decimal tdinterest = 0;
decimal interest = interestProfitSum * closePercent;
decimal tdinterest = interestProfitSum * closePercent;
int interestPeriod = position.interest_rest_days ?? 1;
decimal dynomicPrincipal = principal;
decimal tdDynomicPrincipal = posiPrincipal;
var calcDays = (endDate - tradeDate).Days;
var calcDays = (endDate - lastSwapDate).Days;
double floatRate = Convert.ToDouble(floateRate);
for (int i = 0; i <= calcDays; i++)
{
var rateDate = tradeDate.AddDays(i);
if (rateDate > lastSwapDate || endDate == tradeDate)
var rateDate = lastSwapDate.AddDays(i);
if (rateDate > lastSwapDate || endDate == lastSwapDate)
{
if (i % interestPeriod == 0)
{
@@ -663,11 +663,6 @@ namespace YLErp.Modules.SwapModule
tdinterest += tdinterest1;
}
else if (lastSwapDate >= rateDate)
{
interest = interestProfitSum * closePercent;
tdinterest = interestProfitSum * closePercent;
}
}
InterestAmount = Math.Round(interest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
@@ -1150,8 +1145,8 @@ namespace YLErp.Modules.SwapModule
});
}
unwindData.SwapCloseAmount = decimal.Parse(unwindData.SwapCloseAmount.ToString("0.00"));
unwindData.SwapRealizedPnL = unwindData.SwapCloseAmount;
unwindData.SwapCloseAmount = Math.Round(unwindData.SwapCloseAmount, 2, MidpointRounding.AwayFromZero);
unwindData.SwapRealizedPnL = Math.Round(unwindData.SwapRealizedPnL, 2, MidpointRounding.AwayFromZero);
}
/// <summary>
/// 多空组合平仓
@@ -1188,7 +1183,7 @@ namespace YLErp.Modules.SwapModule
catch (Exception ex)
{
trans.Rollback();
throw ex;
throw;
}
finally
{
@@ -1214,12 +1209,20 @@ namespace YLErp.Modules.SwapModule
{
int clientCashId = AddClientCashInCashOut(td, Convert.ToDouble(unwindData.SwapCloseAmount), ClientCashInCashOut._互换, unwindData.ValueDate);
SaveSwapDeal(unwindData, (int)SwapEventTypeEnum., clientCashId, "系统操作_互换");
td.UnWindDate = unwindData.UnwindDate;
if (td.ExerciseDate <= unwindData.ValueDate)
{
td.Notional = 0;
td.StockEqvNotional = 0;
td.TradeStatus = "已到期";
}
DbContext.SaveChanges();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
throw;
}
finally
{
@@ -1267,7 +1270,7 @@ namespace YLErp.Modules.SwapModule
catch (Exception ex)
{
trans.Rollback();
throw ex;
throw;
}
finally
{
@@ -1345,7 +1348,7 @@ namespace YLErp.Modules.SwapModule
catch (Exception ex)
{
trans.Rollback();
throw ex;
throw;
}
finally
{
@@ -1412,10 +1415,20 @@ namespace YLErp.Modules.SwapModule
{
if (!string.IsNullOrEmpty(position.UnderlyingCode))
{
position.PosiQuantity -= unwindData.CloseQty;
position.PosiNotionalValue = unwindData.PosiNotionalValue - unwindData.CloseNotionalValue;
position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent;
position.PosiTradingFeePending -= position.PosiTradingFeePending * unwindData.ClosePercent;
// 收益结算(互换)不改变持仓数量和名义本金,只更新费用
if (eventType == (int)SwapEventTypeEnum.)
{
position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent;
position.PosiTradingFeePending -= position.PosiTradingFeePending * unwindData.ClosePercent;
}
else
{
// 平仓时才扣减持仓
position.PosiQuantity -= unwindData.CloseQty;
position.PosiNotionalValue -= unwindData.CloseNotionalValue;
position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent;
position.PosiTradingFeePending -= position.PosiTradingFeePending * unwindData.ClosePercent;
}
}
else
{