feat(swaptrade): 添加期末头寸风险表新字段支持

- 在EodSwap实体模型中新增标的类型、期间付息/分红、保证金利息收支字段
- 在前端表格列模型中添加标的类型、期间付息/分红列定义
- 在前端表格分组配置中将新字段归入对应分组显示
- 实现后端服务中对新字段的数据查询和计算逻辑
- 添加保证金利息收入支出的分类汇总功能
- 完善标的类型字段的数据源获取和展示逻辑
This commit is contained in:
张名锐
2026-07-09 15:11:58 +08:00
parent 0bef986e10
commit 358993bedb
3 changed files with 70 additions and 6 deletions
+8
View File
@@ -174,5 +174,13 @@ namespace YLErp.DBModels
public int ClientId { get; set; }
public string SwapTradeTypeStr { get; set; }
public string UnderlyingType { get; set; }
public decimal PeriodAmount { get; set; }
public decimal MarginInterestGain { get; set; }
public decimal MarginInterestLoss { get; set; }
}
}
@@ -2162,10 +2162,40 @@ namespace YLErp.Modules.SwapModule
}
DbContext.SetDebugLog();
var retListResult = query.ToSearchList(req);
var tradeIds = retListResult.rows.Select(x => x.position.SwapTradeId).Distinct().ToList();
var valueDates = retListResult.rows.Select(x => x.position.ValueDate).Distinct().ToList();
var eodPositionDetails = DbContext.eod_swap_position
.Where(x => tradeIds.Contains(x.SwapTradeId) && valueDates.Contains(x.ValueDate) && !x.Invalid)
.ToList();
var underlyingDataSource = DataCacheProvider.GetUnderlyingDataSource();
var varietyDataSource = DataCacheProvider.GetVarietyDataSource();
foreach (var item in retListResult.rows)
{
var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId);
item.SwapTradeTypeStr = client?.SwapTradeTypeStr;
var details = eodPositionDetails
.Where(x => x.SwapTradeId == item.position.SwapTradeId && x.ValueDate == item.position.ValueDate)
.ToList();
var floatingLegs = details.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode)).ToList();
var marginLegs = details.Where(x => marginTypes.Contains(x.InterestMode)).ToList();
item.UnderlyingType = string.Join(",", floatingLegs
.Select(x =>
{
var underlying = underlyingDataSource.GetData(x.UnderlyingCode);
return varietyDataSource.GetData(underlying?.UnderlyingTypeId ?? 0)?.AssetType
?? underlying?.UnderlyingInstrumentTypeCn
?? underlying?.UnderlyingType;
})
.Where(x => !string.IsNullOrWhiteSpace(x))
.Distinct());
item.PeriodAmount = floatingLegs.Sum(x => x.PosiDividendSum); // 分红 - 为实现
item.MarginInterestGain = marginLegs
.Where(x => x.InterestDirection == (int)SwapDirectionEnum.)
.Sum(x => Math.Abs(x.InterestIncomeSum));
item.MarginInterestLoss = marginLegs
.Where(x => x.InterestDirection == (int)SwapDirectionEnum.)
.Sum(x => Math.Abs(x.InterestIncomeSum));
}
var dv01 = query.Sum(O => O.position.dv01??0);
@@ -457,9 +457,7 @@ function colModelGridEodPosition() {
}
//框架合约table
//TODO(估值模块V1-缺失字段): 以下需求字段本轮未实现,待后端确认数据来源后补充:
// - 期间付息/分红(浮动端分组)
// - 付息方式、合约估值(到期轧差口径/期间支付派息口径)(估值与实现收益分组)
// - 标的类型(基本信息分组)
function colModelGridEodSwap() {
//按需求《估值模块V1》2.2 分组定义排列列顺序,确保组内列连续(setGroupHeaders 要求)
var colModelGrid = [{
@@ -526,6 +524,13 @@ function colModelGridEodSwap() {
width: 100,
align: 'center',
sortable: false
}, {
name: 'UnderlyingType',
label: '标的类型',
index: 'UnderlyingType',
width: 100,
align: 'center',
sortable: false
},
//=== 名义本金 ===
{
@@ -574,6 +579,13 @@ function colModelGridEodSwap() {
width: 150,
align: 'center',
formatter: StockEqvNotionalFormat,
}, {
name: 'PeriodAmount',
label: '期间付息/分红',
index: 'PeriodAmount',
width: 150,
align: 'center',
formatter: StockEqvNotionalFormat,
},
//=== 利息端 ===
{
@@ -613,6 +625,20 @@ function colModelGridEodSwap() {
width: 150,
align: 'center',
formatter: StockEqvNotionalFormat,
}, {
name: 'MarginInterestGain',
label: '收取对手方保证金利息',
index: 'MarginInterestGain',
width: 170,
align: 'center',
formatter: StockEqvNotionalFormat,
}, {
name: 'MarginInterestLoss',
label: '支付对手方保证金利息',
index: 'MarginInterestLoss',
width: 170,
align: 'center',
formatter: StockEqvNotionalFormat,
},
//=== 估值与实现收益 ===
{
@@ -657,12 +683,12 @@ function colModelGridEodSwap() {
//框架合约分组配置(对应需求《估值模块V1》2.2 字段定义)
//columns 使用 colModel.name;组内列在 colModel 中必须连续
var eodSwapGroupConfig = [
{ title: '基本信息', columns: ['position.ValueDate', 'AssetBookName', 'ClientName', 'SwapTradeNo', 'StructureType', 'SwapTradeTypeStr'] },
{ title: '基本信息', columns: ['position.ValueDate', 'AssetBookName', 'ClientName', 'SwapTradeNo', 'StructureType', 'SwapTradeTypeStr', 'UnderlyingType'] },
{ title: '名义本金', columns: ['position.NotionalValue', 'position.NotionalValueLong', 'position.NotionalValueShort'] },
{ title: '标的市值', columns: ['position.MarketValueLong', 'position.MarketValueShort'] },
{ title: '浮动端', columns: ['position.FloatingPnL'] },
{ title: '浮动端', columns: ['position.FloatingPnL', 'PeriodAmount'] },
{ title: '利息端', columns: ['position.InterestPnL'] },
{ title: '保证金', columns: ['position.InitMarginGain', 'position.PostionMarginGain', 'position.InitMarginLoss', 'position.PostionMarginLoss'] },
{ title: '保证金', columns: ['position.InitMarginGain', 'position.PostionMarginGain', 'position.InitMarginLoss', 'position.PostionMarginLoss', 'MarginInterestGain', 'MarginInterestLoss'] },
{ title: '估值与实现收益', columns: ['position.PostionValue', 'position.TdRealizedPnL', 'position.RealizedPnL', 'position.dv01'] }
];
@@ -817,4 +843,4 @@ function SearchClick(isSearchclick) {
function showcolumnChooser() {
var jgrid = jQuery('#listGrid');
main.showcolumnChooser(jgrid, cloumnTargetName, page.configcolumn_data);
}
}