From 829334a4fd653424949eff88c8a5012af00c3e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=96=B9=E6=B5=B7?= Date: Fri, 30 May 2025 13:08:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AF=8F=E6=97=A5=E4=BC=B0=E5=80=BCbug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RealTimeClientBanlanceService.cs | 2 +- .../SettlementModule/EodClientBalanceCalc.cs | 4 +-- .../Modules/SwapModule/SwapDealService.cs | 10 ++++--- .../SwapModule/SwapEodPositionService.cs | 26 +++++++++++-------- .../SwapModule/SwapFlowEventService.cs | 2 +- .../SwapModule/SwapTradeAutoService.cs | 20 +++++++++----- YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml | 4 +-- 7 files changed, 41 insertions(+), 27 deletions(-) diff --git a/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs b/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs index 13e40b66..096f7cff 100644 --- a/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs +++ b/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs @@ -1276,7 +1276,7 @@ namespace YLErp.BLL.Eod foreach (var item in clientEodSwaps) { var lastEodSwap = item.First(); - var eodPosi = eodSwapPositions.FirstOrDefault(x => x.ValueDate == lastEodSwap.ValueDate && x.SwapTradeId == lastEodSwap.SwapTradeId); + var eodPosi = eodSwapPositions.FirstOrDefault(x => x.ValueDate == lastEodSwap.ValueDate && x.SwapTradeId == lastEodSwap.SwapTradeId &&x.PosiStartDate<= lastEodSwap.ValueDate); var posiQty = eodPosi?.PosiQuantity ?? 0; var flowEvents = swapFlowEvents.Where(x => x.SwapTradeId == item.Key).ToList(); var unwindQty = flowEvents.Sum(s => s.Quantity); diff --git a/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs b/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs index 6d7ed87a..e620f40c 100644 --- a/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs +++ b/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs @@ -847,8 +847,8 @@ 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); - var eodSwapPosition = clientEodSwapPositionLast.FirstOrDefault(t => t.SwapTradeId == item.SwapTradeId && t.ValueDate == balanceDate); + 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); PotentialSurpluses += Convert.ToDouble(item.PostionValue) * (-1); WinLoss += Convert.ToDouble(item.TdRealizedPnL) * (-1); var lastPv = lastEodSwap != null ? Convert.ToDouble(lastEodSwap.PostionValue- lastEodSwapPosition?.VTradingFee+lastEodSwapPosition?.PosiFeePending) * (-1) : 0; diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index 49d04b1e..7e731add 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -812,7 +812,7 @@ namespace YLErp.Modules.SwapModule /// /// /// - public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty) + public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty,decimal closeFee) { unwindPriceFee = decimal.Parse(unwindPriceFee.ToString("F10")); var td = DbContext.trade.Find(tradeid); @@ -878,9 +878,9 @@ namespace YLErp.Modules.SwapModule floatEvent.TradingAmountNetAvg = unwindNet; floatEvent.TradingFeePending = position.PosiTradingFeePending * unwindData.ClosePercent; floatEvent.TradingFeePending = Math.Round(floatEvent.TradingFeePending, 2, MidpointRounding.AwayFromZero); - floatEvent.TradingFee = floatEvent.TradingFeePending; + floatEvent.TradingFee = closeFee; floatEvent.MarkClosePnl = (unwindPrice - position.PosiGrossPrice) * unwindQty * floatRatio * longRatio; - floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + (floatEvent.TradingFeePending*2 * floatRatio * -1), ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + ((floatEvent.TradingFeePending+ closeFee) * floatRatio * -1), ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); floatEvent.TradingAmount = unwindPrice * floatEvent.Quantity * floatEvent.ContractSize; floatEvent.OptLog = "流水自动"; floatEvent.ClientId = td.ClientId; @@ -1073,6 +1073,9 @@ namespace YLErp.Modules.SwapModule td.StockEqvNotional -= Convert.ToDouble(unwindData.CloseNotionalValue); td.TradeAmount -= Convert.ToDouble(unwindData.CloseQty); td.Notional = td.TradeAmount; + td.OptDate = DateTime.Now; + td.OptId= UserId; + td.OptName = UserName; DbContext.SaveChanges(); } /// @@ -1369,6 +1372,7 @@ namespace YLErp.Modules.SwapModule position.PosiQuantity -= unwindData.CloseQty; position.PosiNotionalValue = position.PosiGrossPrice * position.PosiQuantity * position.ContractSize; position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent; + position.PosiTradingFeePending -= position.PosiTradingFeePending * unwindData.ClosePercent; } else { diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index c0b00f33..faf75da7 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -755,7 +755,7 @@ namespace YLErp.Modules.SwapModule //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; - newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee; + newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest; var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate , seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); @@ -878,7 +878,7 @@ namespace YLErp.Modules.SwapModule //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; - newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee; + newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest; var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate , seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); @@ -995,7 +995,7 @@ namespace YLErp.Modules.SwapModule //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; - newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee; + newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest; var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate , seekPreday: true, currencyRateType: eodPayPosition.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); @@ -1092,7 +1092,7 @@ namespace YLErp.Modules.SwapModule newEodPayPosition.RealizedFee = closeFee; newEodPayPosition.RealizedMtmPnL = newEodPayPosition.TdCloseMtmPnl; newEodPayPosition.RealizedDividend = newEodPayPosition.TdCloseDividend; - newEodPayPosition.RealizedPnl = newEodPayPosition.TdCloseMtmPnl + newEodPayPosition.TdCloseDividend + newEodPayPosition.TdCloseFee; + newEodPayPosition.RealizedPnl = newEodPayPosition.TdCloseMtmPnl; newEodPayPosition.PosiStatus = payQty == 0 ? 1 : 0; UpdateDbOption(newEodPayPosition); @@ -1159,7 +1159,7 @@ namespace YLErp.Modules.SwapModule curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl; curretEod.RealizedDividend = eod.RealizedDividend + curretEod.TdCloseDividend; curretEod.RealizedFee = eod.RealizedFee + curretEod.TdCloseFee; - curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl + curretEod.TdCloseDividend + curretEod.TdCloseFee; + curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl; var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, td.StartDate.Value , seekPreday: true, currencyRateType: curretEod.PosiDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); curretEod.TdCurrency = Convert.ToDecimal(currencyRate); @@ -1219,7 +1219,7 @@ namespace YLErp.Modules.SwapModule curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl; curretEod.RealizedDividend = eod.RealizedDividend + curretEod.TdCloseDividend; curretEod.RealizedFee = eod.RealizedFee + curretEod.TdCloseFee; - curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl + curretEod.TdCloseDividend + curretEod.TdCloseFee; + curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl; curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0; if (curretEod.PosiStatus == 1) { @@ -1296,10 +1296,14 @@ namespace YLErp.Modules.SwapModule } curretEod.PosiNotionalValue = curretEod.PosiGrossPrice * curretEod.PosiQuantity * curretEod.ContractSize; curretEod.TdPosiDividend = unwindEvents.Sum(x => x.DividendIn) * directionRatio; - //curretEod.TdCloseFee = unwindEvents.Sum(x => x.TradingFee); + curretEod.TdCloseFee = unwindEvents.Sum(x => x.TradingFee); curretEod.TdCloseQty = unwindQty; curretEod.TdCloseMtmPnl = unwindEvents.Sum(x => x.MarkClosePnl); } + if (curretEod.PosiQuantity==0) + { + curretEod.PosiFeePending = 0; + } UpdateVTradingFee(curretEod); } @@ -1350,8 +1354,8 @@ namespace YLErp.Modules.SwapModule if (settleDate == td.TradeDate) { curretEod.UnderlyingPrice = curretEod.PosiGrossPrice; - curretEod.TdCloseMtmPnl = 0; - curretEod.TdCloseFee = 0; + //curretEod.TdCloseMtmPnl = 0; + //curretEod.TdCloseFee = 0; } curretEod.TdCloseDividend = curretEod.TdPosiDividend; curretEod.UnderlyingMarketValue = curretEod.UnderlyingPrice * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio; @@ -1360,7 +1364,7 @@ namespace YLErp.Modules.SwapModule curretEod.RealizedMtmPnL = curretEod.TdCloseMtmPnl; curretEod.RealizedDividend = curretEod.TdCloseDividend; curretEod.RealizedFee = curretEod.TdCloseFee; - curretEod.RealizedPnl = curretEod.TdCloseMtmPnl + curretEod.TdCloseDividend + curretEod.TdCloseFee; + curretEod.RealizedPnl = curretEod.TdCloseMtmPnl; curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0; if (curretEod.PosiStatus == 1) { @@ -1981,7 +1985,7 @@ namespace YLErp.Modules.SwapModule foreach (var item in eodSwaps) { var tradeOrigin = trades.First(x => x.id == item.SwapTradeId); - var realizedPnL = item.RealizedMtmPnL + item.RealizedDividend + item.RealizedFee + item.RealizedInterest + item.RealizedInterestFee; + var realizedPnL = item.RealizedMtmPnL + item.RealizedInterest; var tdExtend = tradeExtends.First(x => x.TradeId == item.SwapTradeId); eod_position model = new eod_position() { diff --git a/YLErpDAL/Modules/SwapModule/SwapFlowEventService.cs b/YLErpDAL/Modules/SwapModule/SwapFlowEventService.cs index 3ad368ef..dbc00b68 100644 --- a/YLErpDAL/Modules/SwapModule/SwapFlowEventService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapFlowEventService.cs @@ -519,7 +519,7 @@ namespace YLErp.Modules.SwapModule { item.TradeFee = item.FlowEvent.TradingFee; item.TradingFee = item.FlowEvent.TradingFeePending; - item.PosiPnl= item.FlowEvent.MarkClosePnl- item.FlowEvent.CloseFee-item.FlowEvent.DividendIn; + item.PosiPnl= item.FlowEvent.MarkClosePnl- item.TradeFee-item.FlowEvent.DividendIn - item.TradingFee; item.NetSettmentAmount = item.FlowEvent.MarkClosePnl + item.FlowEvent.InterestClosePnL; item.Days = (item.FlowEvent.UnwindDate - item.StartDate).Value.Days; } diff --git a/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs b/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs index b220a92f..90eddc20 100644 --- a/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs @@ -685,7 +685,8 @@ namespace YLErp.Modules.SwapModule flowMergeMin.TradingAmountNetFeeAvg ?? 0, flowMergeMin.TradingAmountNetAvg ?? 0, flowMergeMin.OccurTime, - flowMergeMax.TradingQtyAbs); + flowMergeMax.TradingQtyAbs, + flowMergeMin.TradingFeePending); var amount = qty * flowMergeMax.ContractSize;//平仓剩余金额=(平仓流水的成交均价-平仓对象的期初价格不含费)*平仓流水的成交数量*合约乘数 if (qty != 0)//平仓有剩余,开仓 { @@ -775,7 +776,8 @@ namespace YLErp.Modules.SwapModule negaFlowClone.TradingAmountNetFeeAvg ?? 0, negaFlowClone.TradingAmountNetAvg ?? 0, negaFlowClone.OccurTime, - negaFlowClone.TradingQty); + negaFlowClone.TradingQty, + negaFlowClone.TradingFeePending); return trade; } /// @@ -1150,7 +1152,8 @@ namespace YLErp.Modules.SwapModule flowSameClone.TradingAmountNetFeeAvg ?? 0, flowSameClone.TradingAmountNetAvg ?? 0, flowSameClone.OccurTime, - unwindQty); + unwindQty, + unwindFee); if (flowQty>0) { var unwindPercent = 1 - (flowQty / flowSameClone.TradingQty); @@ -1214,7 +1217,8 @@ namespace YLErp.Modules.SwapModule swapFlow.TradingAmountNetFeeAvg ?? 0, swapFlow.TradingAmountNetAvg ?? 0, swapFlow.OccurTime, - unwindQty); + unwindQty, + unwindFee); } } if (flowQty > 0) //平仓完有剩余流水, @@ -1328,6 +1332,7 @@ namespace YLErp.Modules.SwapModule var newQty = floatPosition.PosiQuantity - flowMerge.TradingQtyAbs; var newQtyAbs = Math.Abs(newQty); flowMerge.SwapTradeNo = td.TradeNumber; + var unwindFee= newQty>0? flowMerge.TradingFeePending: flowMerge.TradingFeePending* floatPosition.PosiQuantity / flowMerge.TradingQty; // 全平 new SwapDealService(UserInfo).AuotoSwapUnwind(td.id, flowMerge.TradingAmountAvg, @@ -1335,16 +1340,17 @@ namespace YLErp.Modules.SwapModule flowMerge.TradingAmountNetFeeAvg ?? 0, flowMerge.TradingAmountNetAvg ?? 0, flowMerge.OccurTime, - floatPosition.PosiQuantity); + floatPosition.PosiQuantity, + unwindFee); unwindTradeIds.Add(td.id); flowMerge.TradingAmount = newQtyAbs * flowMerge.ContractSize; if (newQty > 0) { - flowMerge.TradingFeePending = floatPosition.PosiTradingFeePending * newQtyAbs / floatPosition.PosiQuantity; + flowMerge.TradingFeePending = 0; } else { - flowMerge.TradingFeePending = flowMerge.TradingFeePending * newQtyAbs / flowMerge.TradingQty; + flowMerge.TradingFeePending = flowMerge.TradingFeePending- unwindFee; } flowMerge.TradingQty = newQtyAbs; if (newQty < 0)//交易不够平,继续平 diff --git a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml index 771c1ac3..51641ed9 100644 --- a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml +++ b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml @@ -20,8 +20,8 @@ var currencys = CurrencyController.getList(); List places = new List(); List agencys = new List(); - var tradingPlaceMap = YLErp.DBModels.Consts.ConsReport.TradingPlaceMap; - var clearingAgencyMap = YLErp.DBModels.Consts.ConsReport.ClearingAgencyMap; + var tradingPlaceMap = YLErp.DBModels.Consts.ConsReport.TradingPlaceMapDisplay; + var clearingAgencyMap = YLErp.DBModels.Consts.ConsReport.ClearingAgencyMapDisplay; foreach (var item in tradingPlaceMap) { places.Add(item.Key);