From 1b6c332cf3be652fe17a09bdf1acf252030537b8 Mon Sep 17 00:00:00 2001 From: gongpei Date: Wed, 15 Oct 2025 10:17:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AE=A1=E7=AE=97=E5=99=A8=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YLErpDAL/Helpers/BondCalcHepler.cs | 15 +-- .../SwapModule/SwapTradeAutoService.cs | 107 +++++++++--------- YLErpWeb/Hubs/SwapFlowCombookingHub.cs | 2 +- .../Scripts/app/swaptrade/SwapflowList.js | 4 + 4 files changed, 67 insertions(+), 61 deletions(-) diff --git a/YLErpDAL/Helpers/BondCalcHepler.cs b/YLErpDAL/Helpers/BondCalcHepler.cs index 32113049..9c9ddb7d 100644 --- a/YLErpDAL/Helpers/BondCalcHepler.cs +++ b/YLErpDAL/Helpers/BondCalcHepler.cs @@ -58,16 +58,17 @@ namespace YLErp.Helpers if (!string.IsNullOrEmpty(baseUrl)) { var httpHelper = new HttpHelper(baseUrl, null); - // http 请求 Web项目接口 - var result = httpHelper.PostRequestNoAuth(calculateUrl, request).Result; - if (result != null && !result.success) - { - LogFactory.GetLogger("BondCalcHepler").Info("计算器计算失败:" + result.message); - } - else + try { + // http 请求 Web项目接口 + var result = httpHelper.PostRequestNoAuth(calculateUrl, request).Result; return result.data; } + catch (Exception ex) + { + LogFactory.GetLogger("BondCalcHelper").Error("请求计算器时发生异常", ex); + } + } return null; } diff --git a/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs b/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs index b7c1bf66..c0efa879 100644 --- a/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapTradeAutoService.cs @@ -87,7 +87,7 @@ namespace YLErp.Modules.SwapModule } swapFlow.TradingAmountAvg = (item.deal_full_price ?? 0) * 0.01m; swapFlow.TradingAmountFeeAvg = (item.deal_full_price_include_fee ?? 0) * 0.01m; - swapFlow.TradingAmount = swapFlow.TradingQty * swapFlow.ContractSize*swapFlow.TradingAmountAvg; + swapFlow.TradingAmount = swapFlow.TradingQty * swapFlow.ContractSize * swapFlow.TradingAmountAvg; swapFlow.ClientId = Convert.ToInt32(item.client_id ?? 0); swapFlow.ytm = (item.ytm ?? 0) * 0.01m; swapFlow.TradingAmountNet = (item.deal_price ?? 0) * 0.01m; @@ -182,7 +182,7 @@ namespace YLErp.Modules.SwapModule foreach (var item in groupByClientIdDic) { var clientUms = item.Value.Select(x => x.UnderlyingCode).Distinct().ToList(); - clientUmsDic.Add(item.Key??0, clientUms); + clientUmsDic.Add(item.Key ?? 0, clientUms); } return clientUmsDic; } @@ -194,11 +194,12 @@ namespace YLErp.Modules.SwapModule /// /// /// - public bool CheckFlowAfter(int? clientId, string underlyingCode, DateTime valueDate) { - Expression> expression =x=> x.OccurTime > valueDate && x.DataState == (int)SwapFlowDateStateEnum.完成; + public bool CheckFlowAfter(int? clientId, string underlyingCode, DateTime valueDate) + { + Expression> expression = x => x.OccurTime > valueDate && x.DataState == (int)SwapFlowDateStateEnum.完成; if (clientId.HasValue) { - expression = expression.And(x=>x.ClientId==clientId); + expression = expression.And(x => x.ClientId == clientId); } if (!string.IsNullOrEmpty(underlyingCode)) { @@ -226,7 +227,7 @@ namespace YLErp.Modules.SwapModule { expression = expression.And(x => x.UnderlyingCode == underlyingCode); } - var resetTradeIds = DbContext.trade.Where(expression).Select(s=>s.id).ToList(); + var resetTradeIds = DbContext.trade.Where(expression).Select(s => s.id).ToList(); return resetTradeIds; } /// @@ -236,7 +237,7 @@ namespace YLErp.Modules.SwapModule /// public void CheckFR007Data(DateTime valueDate) { - var existFr007= DbContext.eod_commodity_future_price.Any(s => s.ValueDate==valueDate && s.UnderlyingCode=="FR007"); + var existFr007 = DbContext.eod_commodity_future_price.Any(s => s.ValueDate == valueDate && s.UnderlyingCode == "FR007"); if (!existFr007) { throw new ServiceException($"{valueDate.ToString("yyyy-MM-dd")}没有FR007数据不能进行簿记"); @@ -312,7 +313,7 @@ namespace YLErp.Modules.SwapModule /// 簿记前自动校验 /// /// - public void BookingValidate(List mergeList,DateTime valueDate) + public void BookingValidate(List mergeList, DateTime valueDate) { foreach (var merge in mergeList) { @@ -352,7 +353,7 @@ namespace YLErp.Modules.SwapModule /// 汇总流水 /// /// - public List SummaryFlow(List swapFlows, DateTime valueDate,bool save = true) + public List SummaryFlow(List swapFlows, DateTime valueDate, bool save = true, Action callback = null) { var swapFlowGroup = swapFlows.GroupBy(g => new { g.ClientId, g.OccurTime, g.UnderlyingCode, g.BsType }).ToList(); List list = new List(); @@ -388,14 +389,14 @@ namespace YLErp.Modules.SwapModule swap_flow_summary.TradingAmountNetFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountNetAvg : swap_flow_summary.TradingAmountNetAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty; swap_flow_summary.TradingAmountNetFeeAvg = Math.Round(swap_flow_summary.TradingAmountNetFeeAvg ?? 0, 10); // 计算收益率 - CalBondResult result = BondCalcHepler.BondCalcByDate(gourpItem.Key.UnderlyingCode, swap_flow_summary.TradingAmountAvg * 100, valueDate.ToString("yyyy-MM-dd")); + CalBondResult result = BondCalcHepler.BondCalcByDate(gourpItem.Key.UnderlyingCode, swap_flow_summary.TradingAmountAvg * ConsGlobal.bondShowPriceMultiple, valueDate.ToString("yyyy-MM-dd")); if (result != null) { swap_flow_summary.InitYtm = result.ytm * ConsGlobal.bondPriceMultiple; } else { - // 发送给前端提示 + callback?.Invoke($"请求计算器时发生异常,标的:{gourpItem.Key.UnderlyingCode} 清算日期:{valueDate:yyyy-MM-dd}"); } swap_flow_summary.SetOpt(UserInfo); if (save) @@ -411,7 +412,7 @@ namespace YLErp.Modules.SwapModule /// 汇总流水 /// /// - public List SummaryFlow(List swapFlows) + public List SummaryFlow(List swapFlows1, DateTime tradeDate, List swapFlows) { var swapFlowGroup = swapFlows.GroupBy(g => new { g.ClientId, g.OccurDate, g.UnderlyingCode, g.BsType }).ToList(); List list = new List(); @@ -507,17 +508,17 @@ namespace YLErp.Modules.SwapModule var floatRateQuery = DbContext.swap_float_rate.Where(floatRatePredicate); int dealCount = 0; - Dictionary> clientUmsDic = new Dictionary>(); + Dictionary> clientUmsDic = new Dictionary>(); foreach (var groupItem in flowquery) { - MergeAvgModelItem(groupItem, swaptrades, swapPositions, floatRateQuery, ref dealCount, action); + MergeAvgModelItem(groupItem, swaptrades, swapPositions, floatRateQuery, ref dealCount, action); clientUmsDic.Add(groupItem.Key ?? 0, groupItem.Select(p => p.UnderlyingCode).Distinct().ToList()); } return clientUmsDic; } - + public void UpdateSwapFlowState(List swapFlows) { @@ -604,8 +605,8 @@ namespace YLErp.Modules.SwapModule if (cashNeedAfter) { var flowEvents = DbContext.swap_flow_event.Where(x => x.EventDate == flowMerge.OccurTime && x.PayDate > x.UnwindDate && x.EventType == (int)SwapFlowEventTypeEnum.平仓 && x.DataState == (int)SwapFlowDateStateEnum.完成 && x.ClientId == flowMerge.ClientId && x.PayDirection > 0); - var tradeIds = flowEvents.Select(s=>s.SwapTradeId).Distinct(); - var trades = DbContext.trade.Where(x=> tradeIds.Contains(x.id)&&x.ValidState!=ConsGlobal.InValid); + var tradeIds = flowEvents.Select(s => s.SwapTradeId).Distinct(); + var trades = DbContext.trade.Where(x => tradeIds.Contains(x.id) && x.ValidState != ConsGlobal.InValid); cashNeedAfter = !trades.Any(); } if (!hasPayPosition)//没有持仓 @@ -614,7 +615,7 @@ namespace YLErp.Modules.SwapModule } else { - DealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades,clearingAgency, cashNeedAfter); + DealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clearingAgency, cashNeedAfter); } } @@ -634,7 +635,7 @@ namespace YLErp.Modules.SwapModule private void MergeAvgModelItem(IGrouping groupItem, List swaptrades, List swapPositions, - IQueryable floatRateQuery,ref int dealCount, Action? action) + IQueryable floatRateQuery, ref int dealCount, Action? action) { var clientId = groupItem.Key; var client = DataCacheProvider.GetClientDataSource().GetData(clientId ?? 0); @@ -668,7 +669,7 @@ namespace YLErp.Modules.SwapModule } else { - AvgDealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clearingAgency); + AvgDealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clearingAgency); } } @@ -727,7 +728,7 @@ namespace YLErp.Modules.SwapModule var posi = DbContext.swap_position.FirstOrDefault(x => x.SwapTradeId == trade.id && x.PosiDirection > 0 && !x.IsInitial); SetNewOpenData(flowMergeMin, flowMergeClone, posi); } - var trade2 = swapTradeService.NewSwapTrade(flowMergeClone, client, asset, underlying, floatRate, clearingAgency); + var trade2 = swapTradeService.NewSwapTrade(flowMergeClone, client, asset, underlying, floatRate, clearingAgency); flowMergeMax.SwapTradeNo = trade2.TradeNumber; flowMergeMin.SwapTradeNo = trade2.TradeNumber; } @@ -753,11 +754,11 @@ namespace YLErp.Modules.SwapModule { var negativeFlow = swapFlows.Where(x => x.BsType != byType).FirstOrDefault(); var sameFlow = swapFlows.Where(x => x.BsType == byType).FirstOrDefault(); - if (negativeFlow==null) + if (negativeFlow == null) { - return NewSwapTrade(sameFlow, client, asset, underlying, floatRate,clearingAgency); + return NewSwapTrade(sameFlow, client, asset, underlying, floatRate, clearingAgency); } - return DealTwoDirectionFlows(sameFlow, negativeFlow, client, asset, underlying, floatRate, clearingAgency); + return DealTwoDirectionFlows(sameFlow, negativeFlow, client, asset, underlying, floatRate, clearingAgency); } /// /// 当前无持仓,且有2个方向流水合成簿记 @@ -786,10 +787,10 @@ namespace YLErp.Modules.SwapModule //先开数量大的,再用小的平仓 if (sameQty < negaQty) { - sameFlowClone= DataHelper.DeepCopyObject(negativeFlow); + sameFlowClone = DataHelper.DeepCopyObject(negativeFlow); negaFlowClone = DataHelper.DeepCopyObject(sameFlow); } - var trade = NewSwapTrade(sameFlowClone, client, asset, underlying, floatRate, clearingAgency); + var trade = NewSwapTrade(sameFlowClone, client, asset, underlying, floatRate, clearingAgency); // 平仓 new SwapDealService(UserInfo).AuotoSwapUnwind(trade.id, negaFlowClone.TradingAmountAvg, @@ -911,11 +912,11 @@ namespace YLErp.Modules.SwapModule { if (mergeList.Count == 1)//只有一条流水情况 { - DealSingleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate,clearingAgency); + DealSingleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency); } else { - DealDoubleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency, cashNeedAfter); + DealDoubleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency, cashNeedAfter); } } /// @@ -939,13 +940,13 @@ namespace YLErp.Modules.SwapModule string clearingAgency) { var firstFlow = flowList.First(); - if (flowList.Count==1)//只有一条流水情况 + if (flowList.Count == 1)//只有一条流水情况 { AvgDealSingleFlow(firstFlow, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency); } else { - AvgDealDoubleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate,clearingAgency); + AvgDealDoubleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency); } } /// @@ -1066,18 +1067,18 @@ namespace YLErp.Modules.SwapModule flowMergeFirst.SwapTradeNo = flowMergeFirstClone.SwapTradeNo; //再处理第二条流水的反向持仓 - var lastTrade = DealDoubleFlowDetial(sameTrades, sameDirectionPositions, flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency, false,false); + var lastTrade = DealDoubleFlowDetial(sameTrades, sameDirectionPositions, flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency, false, false); flowMergeLast.SwapTradeNo = flowMergeLastClone.SwapTradeNo; if (flowMergeFirstClone.BsType != flowMergeLastClone.BsType && firstTrade != null) { var trades = new List { firstTrade }; var positions = DbContext.swap_position.Where(x => x.SwapTradeId == firstTrade.id && x.PosiDirection > 0 && !x.IsInitial && !x.Invalid).ToList(); - DealDoubleFlowDetial(trades, positions, flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency, true,false); + DealDoubleFlowDetial(trades, positions, flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency, true, false); flowMergeLast.SwapTradeNo = flowMergeLastClone.SwapTradeNo; } - else if (lastTrade==null) + else if (lastTrade == null) { - swapTradeService.NewSwapTrade(flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency); + swapTradeService.NewSwapTrade(flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency); } } /// @@ -1107,13 +1108,13 @@ namespace YLErp.Modules.SwapModule var flowClone = DataHelper.DeepCopyObject(flow); // 同向新开 - if (flow.BsType== firstPosi.PositionType) + if (flow.BsType == firstPosi.PositionType) { - NewSwapTrade(flowClone, client, asset, underlying, floatRate, clearingAgency); + NewSwapTrade(flowClone, client, asset, underlying, floatRate, clearingAgency); } else //反向先平仓,有剩余开仓 { - AvgDealUnwind(flowClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency); + AvgDealUnwind(flowClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency); } } /// @@ -1142,23 +1143,23 @@ namespace YLErp.Modules.SwapModule var posiQty = swapPositions.Sum(s => s.PosiQuantity); var flowSame = flowList.Where(x => x.BsType == firstPosi.PositionType).First(); var flowNeg = flowList.Where(x => x.BsType != firstPosi.PositionType).First(); - var negaBsType= flowNeg.BsType; + var negaBsType = flowNeg.BsType; var sameQty = posiQty + flowSame.TradingQty; var flowSameClone = DataHelper.DeepCopyObject(flowSame); var flowNegClone = DataHelper.DeepCopyObject(flowNeg); //先平反向 - var trade= AvgDealUnwind(flowNegClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency); + var trade = AvgDealUnwind(flowNegClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency); var newFlowList = new List(); - if (trade!=null) + if (trade != null) { var flowQty = flowSameClone.TradingQty; var currentPosiQty = flowNegClone.TradingQty; var newOpenQty = currentPosiQty - flowQty; var unwindQty = newOpenQty > 0 ? flowQty : currentPosiQty; var unwindFee = flowSameClone.TradingFeePending * unwindQty / currentPosiQty; - unwindFee=Math.Round(unwindFee,ConsGlobal.MoneyRound,MidpointRounding.AwayFromZero); - flowSameClone.TradingFeePending= flowSameClone.TradingFeePending - unwindFee; + unwindFee = Math.Round(unwindFee, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + flowSameClone.TradingFeePending = flowSameClone.TradingFeePending - unwindFee; flowQty = flowQty - unwindQty; // 平仓 new SwapDealService(UserInfo).AuotoSwapUnwind(trade.id, @@ -1169,7 +1170,7 @@ namespace YLErp.Modules.SwapModule flowSameClone.OccurTime, unwindQty, unwindFee); - if (flowQty>0) + if (flowQty > 0) { flowSameClone.TradingQty = flowQty; flowSameClone.TradingAmount = flowSameClone.TradingQty; @@ -1207,7 +1208,7 @@ namespace YLErp.Modules.SwapModule var flowQty = swapFlow.TradingQty; foreach (var posi in swapPositions) { - if (swapFlow==null|| flowQty == 0) + if (swapFlow == null || flowQty == 0) { break; } @@ -1217,9 +1218,9 @@ namespace YLErp.Modules.SwapModule var posiQty = posi.PosiQuantity; var newOpenQty = posiQty - flowQty; var unwindQty = newOpenQty > 0 ? flowQty : posiQty; - var unwindFee = swapFlow.TradingFeePending* unwindQty / flowQty; - unwindFee=Math.Round(unwindFee, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); - flowQty = flowQty - unwindQty; + var unwindFee = swapFlow.TradingFeePending * unwindQty / flowQty; + unwindFee = Math.Round(unwindFee, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + flowQty = flowQty - unwindQty; swapFlow.TradingFeePending = swapFlow.TradingFeePending - unwindFee; // 平仓 new SwapDealService(UserInfo).AuotoSwapUnwind(td.id, @@ -1236,7 +1237,7 @@ namespace YLErp.Modules.SwapModule if (flowQty > 0) //平仓完有剩余流水, { swapFlow.TradingQty = flowQty; - swapFlow.TradingAmount = swapFlow.TradingQty* swapFlow.TradingAmountAvg; + swapFlow.TradingAmount = swapFlow.TradingQty * swapFlow.TradingAmountAvg; return NewSwapTrade(swapFlow, client, asset, underlying, floatRate, clearingAgency); } return null; @@ -1278,7 +1279,7 @@ namespace YLErp.Modules.SwapModule { SetNewOpenData(flowMergeMax, flowMergeSameClone, dealResult.Item4); } - return swapTradeService.NewSwapTrade(flowMergeSameClone, client, asset, underlying, floatRate, clearingAgency); + return swapTradeService.NewSwapTrade(flowMergeSameClone, client, asset, underlying, floatRate, clearingAgency); } return null; @@ -1312,7 +1313,7 @@ namespace YLErp.Modules.SwapModule var first = true; foreach (trade td in negativeTrades) { - if (first&& cashNeedAfter) + if (first && cashNeedAfter) { cashNeedAfter = true; } @@ -1326,7 +1327,7 @@ namespace YLErp.Modules.SwapModule cloneNegativeTrades.Remove(td); if (cloneNegativeTrades.Count > 0) { - return DealNegativeTrade(cloneNegativeTrades, flowMerge, floatPositions, unwindTradeIds, needOpen,false);//继续平下一个簿记 + return DealNegativeTrade(cloneNegativeTrades, flowMerge, floatPositions, unwindTradeIds, needOpen, false);//继续平下一个簿记 } else //交易平完,流水有剩余 { @@ -1340,7 +1341,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; + var unwindFee = newQty > 0 ? flowMerge.TradingFeePending : flowMerge.TradingFeePending * floatPosition.PosiQuantity / flowMerge.TradingQty; unwindFee = Math.Round(unwindFee, 4, MidpointRounding.AwayFromZero); // 全平 new SwapDealService(UserInfo).AuotoSwapUnwind(td.id, @@ -1359,7 +1360,7 @@ namespace YLErp.Modules.SwapModule } else { - flowMerge.TradingFeePending = flowMerge.TradingFeePending- unwindFee; + flowMerge.TradingFeePending = flowMerge.TradingFeePending - unwindFee; } flowMerge.TradingQty = newQtyAbs; if (newQty < 0)//交易不够平,继续平 diff --git a/YLErpWeb/Hubs/SwapFlowCombookingHub.cs b/YLErpWeb/Hubs/SwapFlowCombookingHub.cs index ac9e56e7..7bad26d8 100644 --- a/YLErpWeb/Hubs/SwapFlowCombookingHub.cs +++ b/YLErpWeb/Hubs/SwapFlowCombookingHub.cs @@ -57,7 +57,7 @@ namespace YLErp.Web.Hubs } currentStep = "正在合成流水"; await client.SendAsync("ReceiveMessage", currentStep); - var mergeList = service.SummaryFlow(swapFlows, req.tradeDate); + var mergeList = service.SummaryFlow(swapFlows, req.tradeDate, callback: (str) => { client.SendAsync("WarnMessage", str); }); // 数据校验逻辑 currentStep = "校验上一日是否收盘"; await client.SendAsync("ReceiveMessage", currentStep); diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js index 02d5fdd8..5fe04399 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js @@ -43,6 +43,10 @@ function CombookingHub() { bookconnection.on('ReceiveMessage', function (msg) { $('#msg').text(msg); }); + // 监听服务器发送的消息。 + bookconnection.on('WarnMessage', function (msg) { + $('#msg').messsage(msg); + }); // 监听服务器发送的异常消息。 bookconnection.on('ExceptionMessage', function (msg) { $('#msg').text(msg);