From 688ed0d68218c899e3d20c5bd7973b57212ce3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=96=B9=E6=B5=B7?= Date: Tue, 8 Jul 2025 10:28:28 +0800 Subject: [PATCH] =?UTF-8?q?TRS-ZS-546=20=E8=B5=84=E9=87=91=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E5=A2=9E=E5=8A=A0=E8=B4=B9=E7=94=A8=E5=8F=8A=E5=88=A9?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YLErp.Core/DBModels/Clientbalancedaily.cs | 10 +++ .../YLErp.Core/Models/ClientSettleBalance.cs | 8 ++ .../BLL/EodSettlement/ClientBalanceUtility.cs | 74 +++++++++++++++++- .../RealTimeClientBanlanceService.cs | 5 +- YLErpDAL/Model/clientLinq.cs | 8 ++ .../SettlementModule/EodClientBalanceCalc.cs | 38 +++++++-- .../SettlementReportFotShanXiService.cs | 2 +- .../SwapModule/SwapEodPositionService.cs | 2 +- YLErpWeb/App_Docs/导出模板/结算报告模板.xlsx | Bin 18113 -> 18140 bytes YLErpWeb/App_Docs/导出模板/资金监控模板1.xlsx | Bin 11340 -> 11397 bytes YLErpWeb/Controllers/clientController.cs | 17 ++++ .../Scripts/app/client/clientRiskMonitor.js | 8 +- ...MarketReport_HistoricalPositionSwapFlow.js | 4 +- 13 files changed, 162 insertions(+), 14 deletions(-) diff --git a/Framework/YLErp.Core/DBModels/Clientbalancedaily.cs b/Framework/YLErp.Core/DBModels/Clientbalancedaily.cs index 6cb7fb61..e7150856 100644 --- a/Framework/YLErp.Core/DBModels/Clientbalancedaily.cs +++ b/Framework/YLErp.Core/DBModels/Clientbalancedaily.cs @@ -546,6 +546,16 @@ namespace YLErp.DBModels /// 追保 出金累计 /// public double? vm_out_fund_sum { get; set; } + /// + /// 交易费用 + /// + public double? trade_fee { get; set; } + public double? trade_fee_sum { get; set; } + /// + /// 利息盈亏 + /// + public double? interest_pnl { get; set; } + public double? interest_pnl_sum { get; set; } [NotMapped] public FundObject FundObject { get; set; } diff --git a/Framework/YLErp.Core/Models/ClientSettleBalance.cs b/Framework/YLErp.Core/Models/ClientSettleBalance.cs index ec41df43..3945bafe 100644 --- a/Framework/YLErp.Core/Models/ClientSettleBalance.cs +++ b/Framework/YLErp.Core/Models/ClientSettleBalance.cs @@ -1077,5 +1077,13 @@ namespace YLErp.Models /// 是否需要追保 /// public bool NeedAddMargin { get; set; } + /// + /// 交易费用 + /// + public double TradeFee { get; set; } + /// + /// 利息盈亏 + /// + public double InterestPnl { get; set; } } } diff --git a/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs b/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs index ae83d671..2f14ab3f 100644 --- a/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs +++ b/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs @@ -1,6 +1,9 @@ using BaseOUDAL; +using NPOI.SS.UserModel; using YLErp.BLL.Eod; +using YLErp.DBModels; using YLErp.DBModels.Enums; +using YLErp.Helpers; using YLErp.Model; using YLErp.Models; using YLErp.Modules; @@ -146,7 +149,9 @@ namespace YLErp.BLL.EodSettlement FundJson = t.FundJson, PFE = t.PFE, EAD = t.EAD, - LastSettlemetTime=t.OptDate + LastSettlemetTime=t.OptDate, + TradeFee=t.trade_fee_sum??0, + InterestPnl=t.interest_pnl_sum??0 }; var sumDatas = sumQuery.ToArray(); @@ -171,6 +176,8 @@ namespace YLErp.BLL.EodSettlement balance.Coupon = data.Coupon; balance.CashInCashOutProductChange = data.CashInCashOutProductChange; balance.WinLoss = data.WinLoss; + balance.TradeFee=data.TradeFee; + balance.InterestPnl = data.InterestPnl; //起始时间 有值 和 WinLoss 区分 -- 国投不含当天 balance.WinLossSum = data.WinLoss; balance.FundJson = data.FundJson; @@ -210,6 +217,8 @@ namespace YLErp.BLL.EodSettlement data.Coupon += balance.Coupon; data.CashInCashOutProductChange += balance.CashInCashOutProductChange; data.WinLoss += balance.WinLoss; + data.TradeFee += balance.TradeFee; + data.InterestPnl += balance.InterestPnl; //data.AvailableStockEqvNotional = balance.AvailableStockEqvNotional; data.LastSettlemetTime = balance.LastSettlemetTime; data.LastHTSettlemetTime = balance.LastHTSettlemetTime; @@ -1390,6 +1399,68 @@ namespace YLErp.BLL.EodSettlement } return lastClientBalances; } + + public static void FillClientBalanceHisTradeFee() + { + List marginTypes = new List() { (int)InterestModeEnum.追加预付金, (int)InterestModeEnum.初始预付金 }; + var clients= DataCacheProvider.GetClientDataSource().AsQueryable().Where(x=>x.ProcessStatus=="已开户").ToList(); + using var db = new YLContext(); + var firstEodStatusDate = db.eodStatus.OrderBy(o=>o.ValueDate).FirstOrDefault(); + if (firstEodStatusDate!=null) + { + var firstDate=firstEodStatusDate.ValueDate; + var preBalanceDate = valuedateBLL.GetNonHolidayDefore(valuedateBLL.ValueDate.AddDays(-1)); + while (firstDate < valuedateBLL.ValueDate) + { + foreach (var client in clients) + { + var interestPnl = 0d; + var tradeFee = 0d; + var clientBalance=db.ClientBalanceDaily.FirstOrDefault(x => x.ClientId == client.id && x.BalanceDate == firstDate); + var clientBalancePre = db.ClientBalanceDaily.FirstOrDefault(x => x.ClientId == client.id && x.BalanceDate == preBalanceDate); + if (clientBalance != null) + { + // 互换平仓信息 + var clientEventFlowQuery = from eod in db.swap_flow_event.Where(x => x.EventDate <= firstDate && x.EventDate > preBalanceDate &&x.ClientId== client.id &&x.DataState==(int)SwapFlowDateStateEnum.完成&&x.EventType==(int)SwapFlowEventTypeEnum.平仓) + join t in db.trade.Where(x => x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid ) on eod.SwapTradeId equals t.id + select eod; + var clientEodSwaps = clientEventFlowQuery.ToList(); + foreach (var item in clientEodSwaps.GroupBy(x => x.SwapTradeId)) + { + + var eventPosi = item.FirstOrDefault(t => t.PayDirection > 0); + + var eventInterests = item.Where(t => t.PayDirection == 0).ToList(); + + foreach (var interest in eventInterests) + { + double ratio = interest.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;//收取为正,支付为负 + if (marginTypes.Contains(interest.InterestMode)) + { + ratio = -ratio; + } + interestPnl += Convert.ToDouble(interest.InterestClosePnL) * (-1); + } + + tradeFee += Convert.ToDouble(eventPosi.TradingFee+ eventPosi.TradingFeePending) * (-1); + } + clientBalance.trade_fee = tradeFee; + clientBalance.interest_pnl = interestPnl; + clientBalance.trade_fee_sum = clientBalance.trade_fee; + clientBalance.interest_pnl_sum = clientBalance.interest_pnl; + if (clientBalancePre!=null) + { + clientBalance.trade_fee_sum += clientBalancePre.trade_fee_sum; + clientBalance.interest_pnl_sum += clientBalancePre.interest_pnl_sum; + } + db.SaveChanges(); + } + } + preBalanceDate= firstDate; + firstDate = valuedateBLL.GetNonHoliday(firstDate.AddDays(1)); + } + } + } /// /// 获取预付金率设置 /// @@ -1413,6 +1484,7 @@ namespace YLErp.BLL.EodSettlement } return marinRate; } + class ClientBalanceEx : ClientSettleBalance { public string UnderlyingCode { get; set; } diff --git a/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs b/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs index 2218da49..276ac848 100644 --- a/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs +++ b/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs @@ -1297,7 +1297,10 @@ namespace YLErp.BLL.Eod unwindPercent = posiQty == 0 ? 0 : unwindQty / posiQty; } var tdRealizedPnL = flowEvents.Where(x => x.EventDate > lastSettletDate).ToList().Sum(s => s.InterestClosePnL + s.MarkClosePnl); - var tdRealizedInterestPnL = flowEvents.Where(x => x.EventDate > lastSettletDate).ToList().Sum(s => s.InterestClosePnL * unwindPercent); + var tdRealizedInterestPnL = flowEvents.Where(x => x.EventDate > lastSettletDate).ToList().Sum(s => s.InterestClosePnL); + var tradeFee= flowEvents.Where(x => x.EventDate > lastSettletDate).ToList().Sum(s => s.TradingFee+s.TradingFeePending); + balance.InterestPnl += Convert.ToDouble(tdRealizedInterestPnL)*-1; + balance.TradeFee += Convert.ToDouble(tradeFee) *-1; var currentEvents = flowEvents.Where(x => x.EventDate == startDate).ToList(); var currentRealizedPnl = currentEvents.Sum(s => s.InterestClosePnL + s.MarkClosePnl); //潜在行权收益等于实值额 diff --git a/YLErpDAL/Model/clientLinq.cs b/YLErpDAL/Model/clientLinq.cs index 0f00b7da..7c5809ce 100644 --- a/YLErpDAL/Model/clientLinq.cs +++ b/YLErpDAL/Model/clientLinq.cs @@ -597,5 +597,13 @@ namespace YLErp.Model /// 交易类型 /// public string TypeStr { get { return this.Type == "1" ? "量化高频" : "普通"; } } + /// + /// 交易费用 + /// + public double TradeFee { get; set; } + /// + /// 利息盈亏 + /// + public double InterestPnl { get; set; } } } diff --git a/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs b/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs index f79bd70e..b7968f1a 100644 --- a/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs +++ b/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs @@ -1,10 +1,12 @@ using Newtonsoft.Json; using NPOI.SS.Formula.Functions; +using NPOI.SS.UserModel; using Org.BouncyCastle.Asn1.Ocsp; using YieldChain.Helpers; using YLErp.BLL; using YLErp.BLL.MarginCalculation; using YLErp.Configuration; +using YLErp.DBModels; using YLErp.DBModels.Enums; using YLErp.Helpers; using YLErp.Model; @@ -37,7 +39,7 @@ namespace YLErp.Modules.EodModule.SettlementModule var currencyCodes = _context.CurrencyCodes; var currencyProvider = _context.EodCurrencyProvider; - + List marginTypes = new List() { (int)InterestModeEnum.追加预付金, (int)InterestModeEnum.初始预付金 }; //预付金可取上浮比率 var marginRatio = _context.SystemValue.MarginRatio ?? 0.15; var marginMaxRatio = marginRatio + 0.02; @@ -123,7 +125,7 @@ namespace YLErp.Modules.EodModule.SettlementModule join t in DbContext.trade.Where(x => x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid && ConsTrade.TradeStatusAfterConfirmed.Contains(x.TradeStatus) && x.StartDate <= balanceDate) on eod.SwapTradeId equals t.id select eod; // 互换合约估值持仓信息 - var eodSwapPosiQuery = from eod in DbContext.eod_swap_position.Where(x => x.ValueDate <= balanceDate && x.ValueDate >= preBalanceDate&&x.PosiDirection>0) + var eodSwapPosiQuery = from eod in DbContext.eod_swap_position.Where(x => x.ValueDate <= balanceDate && x.ValueDate >= preBalanceDate) join t in DbContext.trade.Where(x => x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid && ConsTrade.TradeStatusAfterConfirmed.Contains(x.TradeStatus) && x.StartDate <= balanceDate) on eod.SwapTradeId equals t.id select eod; var positionList = DbContext.trade.Where(t => (ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus)||t.UnWindDate> balanceDate) && t.ValidState != "InValid"&&t.TradeType=="收益互换"); @@ -136,7 +138,11 @@ namespace YLErp.Modules.EodModule.SettlementModule StructureType = t.StructureType, marin = s.InterestPrincipalFix * (s.InterestDirection == 1 ? -1m : 1m) }; - + // 互换平仓信息 + var clientEventFlowQuery = from eod in DbContext.swap_flow_event.Where(x => x.EventDate <= balanceDate && x.EventDate > preBalanceDate && x.DataState == (int)SwapFlowDateStateEnum.完成 && x.EventType == (int)SwapFlowEventTypeEnum.平仓) + join t in DbContext.trade.Where(x => x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid && ConsTrade.TradeStatusAfterConfirmed.Contains(x.TradeStatus) && x.TradeDate <= balanceDate) on eod.SwapTradeId equals t.id + select eod; + var clientEventFlows = clientEventFlowQuery.ToList(); var eodSwaps = eodSwapQuery.ToList(); var eodSwapPosis = eodSwapPosiQuery.ToList(); if (reqClientIds != null && reqClientIds.Any()) @@ -144,6 +150,7 @@ namespace YLErp.Modules.EodModule.SettlementModule eodSwaps = eodSwaps.Where(t => reqClientIds.Contains(t.ClientId)).ToList(); eodSwapPosis= eodSwapPosis.Where(t => reqClientIds.Contains(t.ClientId)).ToList(); marignQuery = marignQuery.Where(t => reqClientIds.Contains(t.ClientId)); + clientEventFlows.Where(t => reqClientIds.Contains(t.ClientId??0)); } var swapIds = eodSwaps.Select(s => s.SwapTradeId); var todaySwapTrades = DbContext.trade.Where(t => swapIds.Contains(t.id)).ToList(); @@ -297,6 +304,10 @@ namespace YLErp.Modules.EodModule.SettlementModule var PFE = 0d; //互换存续预付金 var SwapMarinAmount = 0d; + //交易费用 + var tradeFee= 0d; + //利息盈亏 + var interestPnl= 0d; // ClientBalanceDaily clientbalancedaily = null; #endregion @@ -807,11 +818,9 @@ namespace YLErp.Modules.EodModule.SettlementModule foreach (var item in clientEodSwapsLast) { var lastEodSwap = eodSwaps.FirstOrDefault(t => t.SwapTradeId == item.SwapTradeId && t.ValueDate == preBalanceDate); - var lastEodSwapPosition = eodSwapPosis.FirstOrDefault(t => t.SwapTradeId == item.SwapTradeId && t.ValueDate == preBalanceDate&&t.PosiStartDate<= preBalanceDate); - var eodSwapPosition = clientEodSwapPositionLast.FirstOrDefault(t => t.SwapTradeId == item.SwapTradeId && t.ValueDate == balanceDate && t.PosiStartDate <= balanceDate); item.PostionValue=Math.Round(item.PostionValue, ConsGlobal.MoneyRound,MidpointRounding.AwayFromZero); PotentialSurpluses += Convert.ToDouble(item.PostionValue) * (-1); - // WinLoss += Convert.ToDouble(item.TdRealizedPnL) * (-1); + // WinLoss += Convert.ToDouble(item.TdRealizedPnL) * (-1); var lastPv = lastEodSwap != null ? Convert.ToDouble(lastEodSwap.PostionValue) * (-1) : 0; eodPnlSum.LastPvSum = eodPnlSum.LastPvSum.HasValue ? eodPnlSum.LastPvSum + lastPv : lastPv; var pnl = item.PostionValue; @@ -827,6 +836,17 @@ namespace YLErp.Modules.EodModule.SettlementModule DailyPnl += Convert.ToDouble(pnl - lastPnl + item.TdRealizedPnL) * (-1); //PayableMargin += Convert.ToDouble(item.InitMarginLoss + item.InitMarginGain+ item.PostionMarginLoss + item.PostionMarginGain); } + var clientEventFlowList = clientEventFlows.Where(x=>x.ClientId== client.id); + foreach (var item in clientEventFlowList.GroupBy(x => x.SwapTradeId)) + { + var eventPosi = item.FirstOrDefault(t => t.PayDirection > 0); + + var eventInterests = item.Where(t => t.PayDirection == 0).ToList(); + + interestPnl += Convert.ToDouble(eventInterests.Sum(x=>x.InterestClosePnL)) * (-1); + + tradeFee += Convert.ToDouble(eventPosi.TradingFee + eventPosi.TradingFeePending) * (-1); + } var clientmarignQuery = marignQuery.Where(x => x.ClientId == client.id&&x.StructureType!="多空组合"); SwapMarinAmount = Convert.ToDouble(clientmarignQuery.Sum(s => s.marin)); #endregion @@ -963,6 +983,8 @@ namespace YLErp.Modules.EodModule.SettlementModule clientbalancedaily.ExerciseBalance = ExerciseBalance; clientbalancedaily.AdvisableMargin = AdvisableMargin; clientbalancedaily.TotalNominal = TotalNominal; + clientbalancedaily.trade_fee = tradeFee; + clientbalancedaily.interest_pnl = interestPnl; clientbalancedaily.Pv = clientPv ?? 0; clientbalancedaily.RoundedPv = roundedClientPv ?? 0; clientbalancedaily.SellPv = clientSellPv ?? 0; @@ -1067,6 +1089,8 @@ namespace YLErp.Modules.EodModule.SettlementModule clientbalancedaily.CouponSum = clientbalancedaily.Coupon; clientbalancedaily.SwapBalanceSum = clientbalancedaily.SwapBalance; clientbalancedaily.WinLossSum = clientbalancedaily.WinLoss; + clientbalancedaily.trade_fee_sum = clientbalancedaily.trade_fee; + clientbalancedaily.interest_pnl_sum = clientbalancedaily.interest_pnl; clientbalancedaily.EndPremiumSum = clientbalancedaily.EndPremium; clientbalancedaily.CashInCashOutProductChangeSum = clientbalancedaily.CashInCashOutProductChange; @@ -1134,6 +1158,8 @@ namespace YLErp.Modules.EodModule.SettlementModule clientbalancedaily.CouponSum += clientbalancedailyPre.CouponSum; clientbalancedaily.SwapBalanceSum += clientbalancedailyPre.SwapBalanceSum; clientbalancedaily.WinLossSum += clientbalancedailyPre.WinLossSum; + clientbalancedaily.trade_fee_sum += clientbalancedailyPre.trade_fee_sum??0; + clientbalancedaily.interest_pnl_sum += clientbalancedailyPre.interest_pnl_sum??0; clientbalancedaily.EndPremiumSum += (clientbalancedailyPre.EndPremiumSum ?? 0); clientbalancedaily.CashInCashOutProductChangeSum += clientbalancedailyPre.CashInCashOutProductChangeSum; } diff --git a/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs b/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs index 35430716..5517fc74 100644 --- a/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs +++ b/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs @@ -258,7 +258,7 @@ namespace YLErp.Modules.ReportModule.SettlementReportModule TradingFeeSum= report.clientSwapPositions.Sum(x => x.TradingFee), PosiPnlSum = report.clientSwapPositions.Sum(x => x.PosiPnl), DividendInSum= report.clientSwapPositions.Sum(x => x.FlowEvent.DividendIn), - InterestAmountSum= report.clientSwapPositions.Sum(x => x.FlowEvent.InterestAmount), + InterestAmountSum= report.clientSwapPositions.Sum(x => x.FlowEvent.InterestClosePnL), InterestFeeSum= report.clientSwapPositions.Sum(x => x.FlowEvent.InterestFee), NetSettmentAmountSum = report.clientSwapPositions.Sum(x => x.NetSettmentAmount), }); diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index bb65c7be..20d6c497 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -1297,7 +1297,7 @@ namespace YLErp.Modules.SwapModule curretEod.PosiNotionalValue = curretEod.PosiGrossPrice * curretEod.PosiQuantity * curretEod.ContractSize; curretEod.PosiNotionalValue= Math.Round(curretEod.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); curretEod.TdPosiDividend = unwindEvents.Sum(x => x.DividendIn) * directionRatio; - curretEod.TdCloseFee = unwindEvents.Sum(x => x.TradingFee); + curretEod.TdCloseFee = unwindFlowEvents.Sum(x => x.TradingFee+x.TradingFeePending); curretEod.TdCloseQty = unwindQty; curretEod.TdCloseMtmPnl = unwindEvents.Sum(x => x.MarkClosePnl); } diff --git a/YLErpWeb/App_Docs/导出模板/结算报告模板.xlsx b/YLErpWeb/App_Docs/导出模板/结算报告模板.xlsx index 46178bc5ba97bc10cb6116008a179e0c918984d9..94662a2f96dcb6ca0d9c5d2a4fa9ac4d7b1de706 100644 GIT binary patch delta 9525 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 delta 9517 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 LCX`Cne_!|)Rzc|H delta 5249 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 bQ6qXDCX1tiX5f>-AxE3?aS{6P{73LVh4;a4 diff --git a/YLErpWeb/Controllers/clientController.cs b/YLErpWeb/Controllers/clientController.cs index fa8739f6..bfa0da81 100644 --- a/YLErpWeb/Controllers/clientController.cs +++ b/YLErpWeb/Controllers/clientController.cs @@ -1,5 +1,6 @@ using Dapper; using DocumentFormat.OpenXml.Drawing.Charts; +using Microsoft.AspNetCore.Authorization; using OfficeOpenXml; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using Org.BouncyCastle.Crypto.Tls; @@ -726,6 +727,8 @@ namespace YLErp.Web.Controllers x.LastHTSettlemetTime = clientBalance.LastHTSettlemetTime; x.LastSettlemetTime = clientBalance.LastSettlemetTime; + x.InterestPnl = clientBalance.InterestPnl; + x.TradeFee = clientBalance.TradeFee; //拼装标签值 if (clientTagList.ContainsKey(x.id)) @@ -3433,5 +3436,19 @@ namespace YLErp.Web.Controllers new ClientProcessLogService(CurUser).revertBankDutyFile(clientId); return JsonSuccess(); } + + /// + /// 填充客户收盘的历史交易费用、利息金额 + /// + /// + [AllowAnonymous] + public JsonResult FillClientBalanceHisData() + { + Task.Run(() => + { + ClientBalanceUtility.FillClientBalanceHisTradeFee(); + }); + return JsonSuccess(); + } } } \ No newline at end of file diff --git a/YLErpWeb/wwwroot/Scripts/app/client/clientRiskMonitor.js b/YLErpWeb/wwwroot/Scripts/app/client/clientRiskMonitor.js index e437b0ec..b57963d6 100644 --- a/YLErpWeb/wwwroot/Scripts/app/client/clientRiskMonitor.js +++ b/YLErpWeb/wwwroot/Scripts/app/client/clientRiskMonitor.js @@ -166,6 +166,10 @@ function getColModelGrid() { name: 'CurrentHoldingPenNumber', label: '持仓笔数', index: 'CurrentHoldingPenNumber', width: 80, align: 'center', formatter: main.toInt, sorttype: 'number' }, { name: 'WinLoss', label: '实现盈亏', index: 'WinLoss', width: 120, align: 'right', value: '0', formatter: 'number', sorttype: 'number' + }, { + name: 'InterestPnl', label: '利息', index: 'InterestPnl', width: 120, align: 'right', value: '0', formatter: 'number', sorttype: 'number' + }, { + name: 'TradeFee', label: '费用', index: 'TradeFee', width: 120, align: 'right', value: '0', formatter: 'number', sorttype: 'number' }, { name: 'PositionPnl', label: '持仓盈亏', index: 'PositionPnl', width: 120, align: 'right', value: '0', formatter: 'number', optionHide: page.isPvRounded, hidden: page.isPvRounded, sorttype: 'number' }, { @@ -263,7 +267,7 @@ function gridComplete() { Number: "合计", TotalTradeCount: sum.TotalTradeCountSum, TotalNotionalPrincipal: sum.TotalNotionalPrincipalSum, TransactionPenNumber: sum.TransactionPenNumberSum, TodayNotionalPrincipal: sum.TodayNotionalPrincipalSum, PositionNotionalPrincipal: sum.PositionNotionalPrincipalSum, CurrentHoldingPenNumber: sum.CurrentHoldingPenNumberSum, - WinLoss: sum.WinLossSum, PositionPv: sum.PositionPvSum, PositionPnl: sum.PositionPnlSum, RoundedPositionPnl: sum.RoundedPositionPnlSum, + WinLoss: sum.WinLossSum, InterestPnl: sum.InterestPnlSum, TradeFee: sum.TradeFeeSum, PositionPv: sum.PositionPvSum, PositionPnl: sum.PositionPnlSum, RoundedPositionPnl: sum.RoundedPositionPnlSum, NetFund: sum.NetFundSum, OtherFund: sum.OtherFundSum, AmountFund: sum.AmountFundSum, TotalAmount: sum.TotalAmountSum, RoundedTotalAmount: sum.RoundedTotalAmountSum, AvailableAmount: sum.AvailableAmountSum, InsuredAmount: sum.InsuredAmountSum, @@ -314,7 +318,7 @@ function LoadGrid() { useColSpanStyle: true, groupHeaders: [ { startColumnName: 'Number', numberOfColumns: 2, titleText: '客户信息' }, - { startColumnName: 'TotalTradeCount', numberOfColumns: 9, titleText: '交易信息 ' }, + { startColumnName: 'TotalTradeCount', numberOfColumns: 11, titleText: '交易信息 ' }, { startColumnName: 'LastDayRemainFund', numberOfColumns: 13, titleText: '账户状况' } ] }); diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/TradeMarketReport_HistoricalPositionSwapFlow.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/TradeMarketReport_HistoricalPositionSwapFlow.js index 548b7656..2bf64007 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/TradeMarketReport_HistoricalPositionSwapFlow.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/TradeMarketReport_HistoricalPositionSwapFlow.js @@ -307,9 +307,9 @@ var colModelGrid = [ width: 140, align: 'center' }, { - name: 'FlowEvent.InterestAmount', + name: 'FlowEvent.InterestClosePnL', label: '利息端平仓盈亏·利息', - index: 'FlowEvent.InterestAmount', + index: 'FlowEvent.InterestClosePnL', width: 220, align: 'center', formatter: StockEqvNotionalFormat