diff --git a/UnitTestProject/Modules/CalcModules/CalculationTest.cs b/UnitTestProject/Modules/CalcModules/CalculationTest.cs index 5a153d49..013454d1 100644 --- a/UnitTestProject/Modules/CalcModules/CalculationTest.cs +++ b/UnitTestProject/Modules/CalcModules/CalculationTest.cs @@ -135,7 +135,16 @@ namespace YLErp.Modules.CalcModules Assert.AreEqual(date20190708, QdpCalendarHelper.GetNonHolidayDefore(date20190708)); #endregion } - + [TestMethod] + public void CalendarBLLGetNonHolidayDeforeTest() + { + var date20250421 = new DateTime(2025, 04, 21); + var date20250418 = new DateTime(2025, 04, 18); + var cudate = QdpCalendarHelper.GetNonHolidayDefore(date20250421.AddDays(0)); + var preDate = QdpCalendarHelper.GetNonHolidayDefore(date20250421.AddDays(-1)); + Assert.AreEqual(date20250421, cudate); + Assert.AreEqual(date20250418, preDate); + } [TestMethod] public void GetObservationDateStringTest() { diff --git a/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs b/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs index 4d27ed92..f224b024 100644 --- a/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs +++ b/YLErpDAL/BLL/EodSettlement/ClientBalanceUtility.cs @@ -357,8 +357,8 @@ namespace YLErp.BLL.EodSettlement balance.NeedAddMargin = balance.SwapMarketAmount < balance.MaintenanceMargin; // 追保金额=初始保证金金额-盯市金额 balance.MarginByPayableMarginTotal = balance.NeedAddMargin ? (balance.MySideMargin - balance.SwapMarketAmount):0; - // 可取资金=期末结存-min(持仓盈亏,0)-初始保证金 - balance.DesirableFund = balance.MarginBalance + Math.Min(balance.RoundedPositionPnl, 0); + // 可取资金=Math.Max(期末结存-min(持仓盈亏,0)-初始保证金,0) + balance.DesirableFund = Math.Max(balance.MarginBalance + Math.Min(balance.RoundedPositionPnl, 0),0); } } @@ -582,14 +582,7 @@ namespace YLErp.BLL.EodSettlement DicTotal.TotalMarginTotal = DicTotal.TotalMargin; DicTotal.RoundedTotalAmountTotal = DicTotal.RoundedTotalAmount; DicTotal.TotalAmountTotal = DicTotal.TotalAmount; - if (PS.Config.Is湘财) - { - DicTotal.MarginByPayableMarginTotal = Math.Max(-DicTotal.AvailableAmount, 0); - } - else - { - DicTotal.MarginByPayableMarginTotal = DicTotal.MarginByPayableMargin; - } + DicTotal.MarginByPayableMarginTotal = DicTotal.MarginByPayableMarginTotal; //if (PS.Config.Is广期资本) //{ // DicTotal.MarginByPayableMarginTotal = Math.Max(-DicTotal.AvailableAmount, 0); @@ -637,18 +630,7 @@ namespace YLErp.BLL.EodSettlement DicTotal.RoundedTotalAmountTotal += dc.Value.RoundedTotalAmount; DicTotal.TotalAmountTotal += dc.Value.TotalAmount; - if (PS.Config.Is湘财) - { - DicTotal.MarginByPayableMarginTotal += Math.Max(-dc.Value.AvailableAmount, 0); - } - else - { - DicTotal.MarginByPayableMarginTotal += dc.Value.MarginByPayableMargin; - } - //if (PS.Config.Is广期资本) - //{ - // DicTotal.MarginByPayableMarginTotal = Math.Max(-DicTotal.AvailableAmount, 0); - //} + DicTotal.MarginByPayableMarginTotal += dc.Value.MarginByPayableMarginTotal; DicTotal.ClosedTradePayableFundTotal += dc.Value.ClosedTradePayableFund; DicTotal.PositionTradePayableFundTotal += dc.Value.PositionTradePayableFund; diff --git a/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs b/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs index 63b18f1a..f13ec384 100644 --- a/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs +++ b/YLErpDAL/BLL/EodSettlement/RealTimeClientBanlanceService.cs @@ -259,7 +259,7 @@ namespace YLErp.BLL.Eod item.LastDayRemainFundWithProduct = item.LastDayRemainFund + item.LastGuaranteesTotalAmount; //当前账号资金 - item.AmountFund = item.AmountFund + item.NetFund + item.OtherFund + item.OptionPremium + item.OptionPremiumSwap + item.SwapBalance + item.SettlementBalance; + item.AmountFund = item.AmountFund + item.NetFund + item.OtherFund + item.OptionPremium + item.OptionPremiumSwap + item.SwapBalance + item.SettlementBalance+item.VmFundSum; item.WinLoss += item.WinLoss2; @@ -279,8 +279,8 @@ namespace YLErp.BLL.Eod item.NeedAddMargin = item.SwapMarketAmount < item.MaintenanceMargin; // 追保金额=初始保证金金额-盯市金额 item.MarginByPayableMarginTotal = item.NeedAddMargin ? (item.MySideMargin - item.SwapMarketAmount) : 0; - // 可取资金=期末结存-min(持仓盈亏,0)-初始保证金 - item.DesirableFund = item.MarginBalance + Math.Min(item.RoundedPositionPnl, 0); + // 可取资金=max(期末结存+min(持仓盈亏,0)-初始保证金,0) + item.DesirableFund =Math.Max( item.MarginBalance - item.FrozenMarginMoney + Math.Min(item.RoundedPositionPnl, 0),0); } return _clientBalanceDic.Values; @@ -1314,8 +1314,8 @@ namespace YLErp.BLL.Eod balance.UpdateDate = balance.UpdateDate > lastEodSwap.OptTime ? balance.UpdateDate : lastEodSwap.OptTime; } balance.WinLoss += Convert.ToDouble(tdRealizedPnL) * -1; - balance.PositionPnl += Convert.ToDouble(pnl); - balance.RoundedPositionPnl += Math.Round(Convert.ToDouble(pnl), 2); + balance.PositionPnl += Convert.ToDouble(pnl) * -1; + balance.RoundedPositionPnl += Math.Round(Convert.ToDouble(pnl), 2) * -1; //期权空头浮动盈利=∑max(期权空头持仓*(期权合约成本价-期权合约现价), 0) 从客户角度看的 balance.ClientSellPositionPnl += Convert.ToDouble(lastEodSwap.FloatingPnL) * -1; } diff --git a/YLErpDAL/Modules/ClientModule/ClientBlackService.cs b/YLErpDAL/Modules/ClientModule/ClientBlackService.cs index 5c5e085a..894dec2a 100644 --- a/YLErpDAL/Modules/ClientModule/ClientBlackService.cs +++ b/YLErpDAL/Modules/ClientModule/ClientBlackService.cs @@ -1,6 +1,10 @@ using BaseOUDAL; +using Microsoft.Extensions.DependencyInjection; +using Org.BouncyCastle.Crypto.Tls; using Qdp.Foundation.Utilities; using System.Data; +using YieldChain.Commons; +using YLErp.Abstract; using YLErp.Commons; using YLErp.Model; using YLErp.Models.Tag; @@ -14,9 +18,10 @@ namespace YLErp.Modules.ClientModule /// public class ClientBlackService : ClientBaseService { + private IKafkaProduce _kafkaProduce; public ClientBlackService(OptUserInfo userInfo) : base(userInfo) { - + _kafkaProduce = YLServiceLocator.ServiceProvider.GetService(); } /// @@ -188,6 +193,8 @@ namespace YLErp.Modules.ClientModule throw new ServiceException(msg); } } + // 在外部定义列表来保存需要通知的客户对 + var clientsToNotify = new List<(Client oldClient, Client newClient)>(); foreach (var item in list) { if (string.IsNullOrWhiteSpace(item.Name)) @@ -205,6 +212,7 @@ namespace YLErp.Modules.ClientModule var dt = DateTime.Now; if (clientexistence.ProcessStatus == "已开户") { + var oldClient= clientexistence.Clone(); clientexistence.ProcessOrderId = -4; clientexistence.ProcessStatus = "已休眠"; clientexistence.OptId = UserId; @@ -221,6 +229,11 @@ namespace YLErp.Modules.ClientModule OptName = UserName, OptDate = dt }); + // 如果原有状态是已开户,添加到通知列表 + if (oldClient != null) + { + clientsToNotify.Add((oldClient, clientexistence)); + } } ///日志记录 DbContext.ClientAuditLog.Add(new ClientAuditLog @@ -242,7 +255,11 @@ namespace YLErp.Modules.ClientModule } DbContext.client_black.AddRange(list); DbContext.SaveChanges(); - + // 发送Kafka消息 + foreach (var (oldClient, newClient) in clientsToNotify) + { + new ClientKafkaService(_kafkaProduce).Send(newClient, oldClient); + } var importHasTagClientNames = list.Where(p => p.Tags != null && p.Tags.Count > 0).Select(p => p.Name).Distinct().ToList(); if (importHasTagClientNames != null && importHasTagClientNames.Count > 0) { diff --git a/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSwapFlow.cs b/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSwapFlow.cs index e46b4202..14878b57 100644 --- a/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSwapFlow.cs +++ b/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSwapFlow.cs @@ -20,8 +20,12 @@ namespace YLErp.Modules.EodModule.SettlementModule public void Execute() { var settleDate = _context.SettleDate; + var clienIds = _context.Request.ClientIds; var swapFlowList = DbContext.swap_flow.Where(x=>x.OccurTime==settleDate&&x.DataState==(int)SwapFlowDateStateEnum.等待完成); - + if (clienIds != null && clienIds.Any()) + { + swapFlowList = swapFlowList.Where(x => clienIds.Contains(x.ClientId ?? 0)); + } if (swapFlowList.Any()) { _context.RaiseError(Step, $"{settleDate:yyyy-MM-dd}有未簿记的流水未处理"); diff --git a/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs b/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs index 5946909d..2298e3fb 100644 --- a/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs +++ b/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotShanXiService.cs @@ -317,7 +317,7 @@ namespace YLErp.Modules.ReportModule.SettlementReportModule WinLoss = clientBalance?.WinLoss ?? 0, ClosedTradeFundGap = clientBalance?.ClosedTradeFundGap ?? 0, ClosedTradePayableFund = clientBalance?.ClosedTradePayableFundTotal ?? 0, - PositionTradePayableFund = clientBalance?.PositionTradePayableFundTotal ?? 0, + PositionTradePayableFund = clientBalance?.MarginByPayableMarginTotal ?? 0, DesirableFund = clientBalance?.DesirableFundTotal ?? 0, PayableFund = emailData.PayableFund >= 0 ? emailData.PayableFund : (clientBalance?.PayableFundTotal ?? 0), PositionPv = PS.Config.IsPVRounded ? (clientBalance?.RoundedPositionPv ?? 0) : (clientBalance?.PositionPv ?? 0), diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index 34ac96d9..f07f15f8 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -135,19 +135,17 @@ namespace YLErp.Modules.SwapModule { throw new Exception($"交易【{td.TradeNumber}】到期扔有持仓信息"); } - //实际自动互换数据开头已删除 - var longEventTypes = eventTyps; - longEventTypes.Add((int)SwapFlowEventTypeEnum.开仓); var flowEvents = new List(); - Expression> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum.完成 && longEventTypes.Contains(x.EventType); - if (settleDate == td.TradeDate) - { - eventExpression = eventExpression.And(x => x.EventDate == settleDate); - } - else - { - eventExpression = eventExpression.And(x => x.UnwindDate == settleDate); - } + Expression> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum.完成; + eventExpression = eventExpression.And(x => (x.EventDate == settleDate && x.EventType == (int)SwapFlowEventTypeEnum.开仓) || (x.UnwindDate == settleDate && eventTyps.Contains(x.EventType))); + //if (settleDate == td.TradeDate) + //{ + // eventExpression = eventExpression.And(x => x.EventDate == settleDate); + //} + //else + //{ + // eventExpression = eventExpression.And(x => x.UnwindDate == settleDate); + //} flowEvents = DbContext.swap_flow_event.Where(eventExpression).ToList(); var preDealDate = GetPreDealDate(td.id, settleDate, eventTyps);//上一次平仓/互换/自动互换处理日期 List autoInterests = new List();//自动互换利息腿信息 @@ -1349,16 +1347,15 @@ namespace YLErp.Modules.SwapModule curretEod.PosiTradingFee = position.PosiTradingFee; curretEod.UnderlyingPrice = UnderlyingCodePrice(position.UnderlyingCode, dealDate, out decimal vobp); SetPriceInfoByFlowEvent(eod, curretEod, unwindEvents, position); + if (settleDate == td.TradeDate) + { + curretEod.UnderlyingPrice = curretEod.PosiGrossPrice; + curretEod.TdCloseMtmPnl = 0; + curretEod.TdCloseFee = 0; + } curretEod.TdCloseDividend = curretEod.TdPosiDividend; curretEod.UnderlyingMarketValue = curretEod.UnderlyingPrice * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio; curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio; - if (settleDate == td.TradeDate) - { - curretEod.PosiMtmPnL = 0; - //curretEod.TdCloseMtmPnl = 0; - //curretEod.TdCloseFee = 0; - } - curretEod.PosiDividendSum = curretEod.TdPosiDividend; curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.VTradingFee; curretEod.RealizedMtmPnL = curretEod.TdCloseMtmPnl; curretEod.RealizedDividend = curretEod.TdCloseDividend; diff --git a/YLErpDAL/Modules/SwapModule/SwapFlowService.cs b/YLErpDAL/Modules/SwapModule/SwapFlowService.cs index 9ddecf0f..dff60649 100644 --- a/YLErpDAL/Modules/SwapModule/SwapFlowService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapFlowService.cs @@ -28,6 +28,101 @@ namespace YLErp.Modules.SwapModule { } + /// + /// 查询今天是否有FR007的数据 + /// + /// + + public eod_commodity_future_price SearchTodayFRData(DateTime dateTime) + { + var data = DbContext.eod_commodity_future_price.Where(a => a.ValueDate == dateTime).FirstOrDefault(); + if (data == null) + { + data = new eod_commodity_future_price(); + } + return data; + } + + /// + /// 查询选择的时间是否拥有FR007的数据 + /// + /// + + public List SearchdateFRData(List date) + { + var datafr007 = DbContext.eod_commodity_future_price.Where(a => date.Contains(a.ValueDate)).ToList(); + return datafr007; + } + + /// + /// 删除的RF007数据 + /// + /// 要删除的RF007数据Id + /// + public bool DeleteFRData(int id) + { + + var frdata = DbContext.eod_commodity_future_price.Find(id); + if (frdata == null) + { + throw new ServiceException("未找到FR007流水"); + } + DbContext.eod_commodity_future_price.Remove(frdata); + DbContext.SaveChanges(); + return true; + } + /// + /// 新增或者修改FR007数据 + /// + /// FR007价格 + /// 新增或者修改时间 + /// + public bool AddOrUpdateFRdata(Double price, DateTime dateTime) + { + string beforedate = ""; + var frdata = DbContext.eod_commodity_future_price.Where(a => a.ValueDate == dateTime).FirstOrDefault(); + if (frdata == null) + { + frdata = new eod_commodity_future_price(); + } + //修改 + if (frdata != null && frdata?.UnderlyingCode != null) + { + frdata.ValueDate = dateTime; + frdata.HighPrice = 0; + frdata.LowPrice = 0; + beforedate = JsonHelper.Serialize(frdata); + } + else + { + //新增 + var newestdata = DbContext.eod_commodity_future_price.OrderByDescending(a => a.ValueDate).FirstOrDefault(); + if (newestdata == null) + { + var underlyingCode = DbContext.underlying_manager.Where(a => a.UnderlyingCode == "FR007").FirstOrDefault(); + if (underlyingCode == null) + { + throw new ServiceException("找不到FR007的标的"); + } + newestdata = new eod_commodity_future_price(); + newestdata.UnderlyingId = underlyingCode.id; + } + frdata.ValueDate = dateTime; + frdata.UnderlyingCode = "FR007"; + frdata.UnderlyingId = newestdata.UnderlyingId; + frdata.DataSource = "人工"; + DbContext.Add(frdata); + } + frdata.ClosePrice = Math.Round(price, 4); + frdata.SettlePrice = Math.Round(price, 4); + frdata.ReferencePrice = Math.Round(price, 4); + frdata.OptId = UserInfo.UserId; + frdata.OptName = UserInfo.UserName; + frdata.OptDate = DateTime.Now; + DbContext.SaveChanges(); + return true; + } + /// /// 查询互换流水导入 /// diff --git a/YLErpDAL/Modules/SwapModule/SwapRateService.cs b/YLErpDAL/Modules/SwapModule/SwapRateService.cs index 26184c06..3b6ac440 100644 --- a/YLErpDAL/Modules/SwapModule/SwapRateService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapRateService.cs @@ -107,8 +107,8 @@ namespace YLErp.Modules.SwapModule swapRate.DiscountRateIsPercent = req.DiscountRateIsPercent; swapRate.DiscountRate = req.DiscountRate; swapRate.FrontDeskCharge = req.FrontDeskCharge; - swapRate.FrontDeskChargeIsPercent=req.FrontDeskChargeIsPercent; - swapRate.BackDeskCharge=req.BackDeskCharge; + swapRate.FrontDeskChargeIsPercent = req.FrontDeskChargeIsPercent; + swapRate.BackDeskCharge = req.BackDeskCharge; swapRate.BackDeskChargeIsPercent = req.BackDeskChargeIsPercent; swapRate.SetOpt(UserId, UserName); } @@ -227,34 +227,55 @@ namespace YLErp.Modules.SwapModule var tempRate = reader.GetString("临时费率"); if (!string.IsNullOrEmpty(tempRate)) { + decimal rate = 0; if (tempRate.EndsWith("%")) { swapRate.TempRateIsPercent = true; tempRate = tempRate.Replace("%", ""); + decimal.TryParse(tempRate, out rate); + rate = rate / 100; + } + else + { + swapRate.TempRateIsPercent = false; + decimal.TryParse(tempRate, out rate); } - decimal.TryParse(tempRate, out var rate); swapRate.TempRate = rate; } var baseRate = reader.GetString("基础费率"); if (!string.IsNullOrEmpty(baseRate)) { + decimal rate = 0; if (baseRate.EndsWith("%")) { swapRate.BaseRateIsPercent = true; baseRate = baseRate.Replace("%", ""); + decimal.TryParse(baseRate, out rate); + rate = rate / 100; + } + else + { + swapRate.BaseRateIsPercent = false; + decimal.TryParse(baseRate, out rate); } - decimal.TryParse(baseRate, out var rate); swapRate.BaseRate = rate; } var disAccRate = reader.GetString("优惠费率"); if (!string.IsNullOrEmpty(disAccRate)) { + decimal rate = 0; if (disAccRate.EndsWith("%")) { swapRate.DiscountRateIsPercent = true; disAccRate = disAccRate.Replace("%", ""); + decimal.TryParse(disAccRate, out rate); + rate = rate / 100; + } + else + { + swapRate.DiscountRateIsPercent = false; + decimal.TryParse(disAccRate, out rate); } - decimal.TryParse(disAccRate, out var rate); swapRate.DiscountRate = rate; } var frontRate = reader.GetString("现券对冲交易费用"); @@ -265,7 +286,8 @@ namespace YLErp.Modules.SwapModule swapRate.FrontDeskChargeIsPercent = true; frontRate = frontRate.Replace("‱", ""); } - decimal.TryParse(frontRate, out var rate); + + decimal.TryParse(frontRate, out var rate); swapRate.FrontDeskCharge = rate * 0.0001m; } var backRate = reader.GetString("现券对冲结算费用"); @@ -277,7 +299,7 @@ namespace YLErp.Modules.SwapModule backRate = backRate.Replace("‱", ""); } decimal.TryParse(backRate, out var rate); - swapRate.BackDeskCharge = rate*0.0001m; + swapRate.BackDeskCharge = rate * 0.0001m; } swapRate.DiscountAccDown = reader.GetDecimal("优惠累计量下限"); ValidateSwapRate(swapRate); @@ -321,7 +343,7 @@ namespace YLErp.Modules.SwapModule exportModel.TempRate = item.TempRateIsPercent ? item.TempRate.OtcFormatPercent(4) : item.TempRate.OtcFormatMoney(true); exportModel.DiscountRate = item.DiscountRateIsPercent ? item.DiscountRate.OtcFormatPercent(4) : item.DiscountRate.OtcFormatMoney(true); exportModel.DiscountAccDown = item.DiscountAccDown.OtcFormatMoney(true); - exportModel.FrontDeskCharge= item.FrontDeskChargeIsPercent==true ? item.FrontDeskCharge.OtcFormatTenThousandsPercent(4) : item.FrontDeskCharge.OtcFormatMoney(true); + exportModel.FrontDeskCharge = item.FrontDeskChargeIsPercent == true ? item.FrontDeskCharge.OtcFormatTenThousandsPercent(4) : item.FrontDeskCharge.OtcFormatMoney(true); exportModel.BackDeskCharge = item.BackDeskChargeIsPercent == true ? item.BackDeskCharge.OtcFormatTenThousandsPercent(4) : item.BackDeskCharge.OtcFormatMoney(true); list.Add(exportModel); } @@ -363,11 +385,11 @@ namespace YLErp.Modules.SwapModule var posiNotionalValueGroup = DbContext.trade.Where(x => x.TradeDate >= monthStart && x.ValidState != ConsGlobal.InValid && x.TradeType == "收益互换" - && ConsTrade.TradeStatusCustomexport.Contains(x.TradeStatus)).ToList().GroupBy(x=>x.ClientId); + && ConsTrade.TradeStatusCustomexport.Contains(x.TradeStatus)).ToList().GroupBy(x => x.ClientId); foreach (var swapRate in swapRates) { - var clientPosiNotional = posiNotionalValueGroup.FirstOrDefault(x=>x.Key== swapRate.ClientId).ToList().Sum(s=>s.OriginalStockEqvNotional??0); - SendToKafka(swapRate, clientPosiNotional); + var clientPosiNotional = posiNotionalValueGroup.FirstOrDefault(x => x.Key == swapRate.ClientId).ToList().Sum(s => s.OriginalStockEqvNotional ?? 0); + SendToKafka(swapRate, clientPosiNotional); } } /// @@ -398,13 +420,13 @@ namespace YLErp.Modules.SwapModule swapRateKafkaModel.isRate = swapRate.BaseRateIsPercent; swapRateKafkaModel.rate = swapRate.BaseRate ?? 0; swapRateKafkaModel.disRateDown = swapRate.DiscountAccDown ?? 0; - if (swapRate.DiscountAccDown.HasValue&&Convert.ToDecimal(clientPosiNotional)>= swapRateKafkaModel.disRateDown) + if (swapRate.DiscountAccDown.HasValue && Convert.ToDecimal(clientPosiNotional) >= swapRateKafkaModel.disRateDown) { swapRateKafkaModel.isDisRate = swapRate.DiscountRateIsPercent; - swapRateKafkaModel.disRate= swapRate.DiscountRate ?? 0; + swapRateKafkaModel.disRate = swapRate.DiscountRate ?? 0; swapRateKafkaModel.rate = swapRateKafkaModel.disRate; } - + } kafkaProduceHelper.Produce(Environment.GetEnvironmentVariable("KafkaConfig_ClientRateTopic"), JsonConvert.SerializeObject(swapRateKafkaModel)); } diff --git a/YLErpDAL/Modules/SwapModule/SwapTradeService.cs b/YLErpDAL/Modules/SwapModule/SwapTradeService.cs index 10845c4e..51f308c6 100644 --- a/YLErpDAL/Modules/SwapModule/SwapTradeService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapTradeService.cs @@ -1350,8 +1350,11 @@ namespace YLErp.Modules.SwapModule position.UnderlyingInstrumentType = swap.UnderlyingInstrumentType; position.PosiDirection = swap.PosiDirection; position.PosiGrossPrice = swap.PosiGrossPrice; - position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiGrossPrice + (position.PosiTradingFee / swap.PosiQuantity) * ratio); + position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiGrossPrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio); position.PosiNetPrice = Math.Round(position.PosiNetPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero); + position.PosiNetNoFeePrice = swap.PosiNetNoFeePrice; + position.PosiNetFeePrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiNetNoFeePrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio); + position.PosiNetFeePrice = Math.Round(position.PosiNetFeePrice??0, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero); position.PosiNotionalValue = position.PosiGrossPrice * swap.PosiQuantity * swap.ContractSize; position.PosiQuantity = swap.PosiQuantity; position.InterestDirection = swap.InterestDirection; diff --git a/YLErpWeb/App_Docs/导入模板/阶梯费率导入模板.xlsx b/YLErpWeb/App_Docs/导入模板/阶梯费率导入模板.xlsx index d7ffdcec..fd6df59c 100644 Binary files a/YLErpWeb/App_Docs/导入模板/阶梯费率导入模板.xlsx and b/YLErpWeb/App_Docs/导入模板/阶梯费率导入模板.xlsx differ diff --git a/YLErpWeb/Controllers/SwapTrade2Controller.cs b/YLErpWeb/Controllers/SwapTrade2Controller.cs index ce01c9a2..0a3b05f8 100644 --- a/YLErpWeb/Controllers/SwapTrade2Controller.cs +++ b/YLErpWeb/Controllers/SwapTrade2Controller.cs @@ -2,6 +2,7 @@ using BaseOUDAL; using CsvHelper; using DocumentFormat.OpenXml.Spreadsheet; +using Microsoft.AspNetCore.Authorization; using System.Collections.Concurrent; using System.Linq; using System.Web.Mvc; @@ -712,6 +713,44 @@ namespace YLErp.Web.Controllers } #endregion #endregion + #region fr007 + /// + /// 查询最新一条FR007数据 + /// + /// + public JsonResult SearchTodayWhetherFRData(DateTime dateTime) + { + var service = new SwapFlowService(CurUser); + var data = service.SearchTodayFRData(dateTime); + return Json(data); + } + + /// + /// 删除FR007数据 + /// + /// 要删除的RF007数据Id + /// + public JsonResult DeleteFRData(int id) + { + var service = new SwapFlowService(CurUser); + bool flag = service.DeleteFRData(id); + return Json(flag); + } + + /// + /// 新增或者修改FR007数据 + /// + /// 新增为空 修改时是要修改的FR007数据 + /// FR007价格 + /// 新增或者修改时间 + [AllowAnonymous] + public JsonResult AddOrUpdateFRData(double price, DateTime dateTime) + { + var service = new SwapFlowService(CurUser); + bool flag = service.AddOrUpdateFRdata(price, dateTime); + return Json(flag); + } + #endregion #endregion #region 估值 #region 风险控制-日终持仓 @@ -1039,5 +1078,7 @@ namespace YLErp.Web.Controllers var result = service.SendConfirmEamil(contractCode); return JsonSuccess(result); } + + } } \ No newline at end of file diff --git a/YLErpWeb/Controllers/clientController.cs b/YLErpWeb/Controllers/clientController.cs index 85a8f946..c770f1d9 100644 --- a/YLErpWeb/Controllers/clientController.cs +++ b/YLErpWeb/Controllers/clientController.cs @@ -625,7 +625,7 @@ namespace YLErp.Web.Controllers x.HoldingDepositB = -clientBalance.PayableMarginB; x.SwapPayableMargin = -clientBalance.SwapPayableMargin; x.AvailableAmount = clientBalance.AvailableAmount; - x.InsuredAmount = clientBalance.PositionTradePayableFundTotal; + x.InsuredAmount = clientBalance.MarginByPayableMarginTotal; x.MarginMonitoringTime = clientBalance.UpdateDate ?? DateTime.Now; x.FreezePremium = clientBalance.FreezePremium; x.ReceivablesPremium = clientBalance.ReceivablesPremium; diff --git a/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml b/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml index d3899a20..5961c843 100644 --- a/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml +++ b/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml @@ -15,6 +15,7 @@ @section CSS{ } @section JS{ @@ -72,34 +111,87 @@
-
- 刷新交易端流水 - @if (CurUser.结算管理_成交簿记流水新增) - { - - - } - - @**@ -
- @Html.MyAceDropdownInput("SearchClientId", "客户名称", ClientDataModel.GetAllOpenClient(),multiple:false,appendEmptyAll:false) - - - - - @if (CurUser.结算管理_成交簿记流水重置) +
+ +
+ + 刷新交易端流水 + + @if (CurUser.结算管理_成交簿记流水新增) { - - } - @if (CurUser.结算管理_成交簿记流水簿记) - { - + + } + +
+ + +
+ +
+ FR007 +
+ + % +
+ + +
+ + +
+ 日期 + + 客户名称 + +
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+ @if (CurUser.结算管理_成交簿记流水重置) + { + + } + @if (CurUser.结算管理_成交簿记流水簿记) + { + + } +
- @* - *@
+
@Html.Raw(JqGridSimple.OutTable())
diff --git a/YLErpWeb/Views/clientbalance/TradeMarketReport.cshtml b/YLErpWeb/Views/clientbalance/TradeMarketReport.cshtml index b7b6b937..7778d0b9 100644 --- a/YLErpWeb/Views/clientbalance/TradeMarketReport.cshtml +++ b/YLErpWeb/Views/clientbalance/TradeMarketReport.cshtml @@ -130,7 +130,7 @@ 其他收支 追保金额 - + diff --git a/YLErpWeb/Views/entryexit/entryexitList.cshtml b/YLErpWeb/Views/entryexit/entryexitList.cshtml index 1f2c7aff..d34f3ac2 100644 --- a/YLErpWeb/Views/entryexit/entryexitList.cshtml +++ b/YLErpWeb/Views/entryexit/entryexitList.cshtml @@ -675,28 +675,14 @@ } -
+@*
-
+
*@
@Html.SearchDateRange("HappenDate", "发生时间") @@ -743,10 +729,6 @@ @MyControls.Btn("拒绝", "setReject()") } } - @if (PS.Config.Company == CompanyEnum.中金) - { - @MyControls.Btn("南向资金全量", "downloadCashInfo()") - }
diff --git a/YLErpWeb/Views/variety/varietyList.cshtml b/YLErpWeb/Views/variety/varietyList.cshtml index db3a086e..d74c4da7 100644 --- a/YLErpWeb/Views/variety/varietyList.cshtml +++ b/YLErpWeb/Views/variety/varietyList.cshtml @@ -18,11 +18,6 @@ @MyControls.Btn("导入", "importVariety()") } @MyControls.Btn("导出", "downloadExcel()") - @if (CurUser.基础参数管理.标的品种编辑) - { - @MyControls.Btn("预付金参数导入", "importMarginParams()") - } - 预付金参数导出 @Html.Raw(JqGridSimple.OutTable()) diff --git a/YLErpWeb/appsettings.local.json b/YLErpWeb/appsettings.local.json index 8da1e8bb..308bb4f5 100644 --- a/YLErpWeb/appsettings.local.json +++ b/YLErpWeb/appsettings.local.json @@ -67,7 +67,7 @@ "YiLian_SwapFlowGroup": "YiLian_SwapFlowGroup1" //交易端同步流水消费组 }, "BondOmsInterface": { - "BaseUrl": "http://git.yiliantech.com:8887" + "BaseUrl": "http://trs.yiliantech.com:8080/trs_hub_api" }, "OrcaleDatabaseConfig": { "Schema": "APEX_040000" diff --git a/YLErpWeb/wwwroot/Scripts/app/client/tradeMarketReport.js b/YLErpWeb/wwwroot/Scripts/app/client/tradeMarketReport.js index 78a069af..4a910002 100644 --- a/YLErpWeb/wwwroot/Scripts/app/client/tradeMarketReport.js +++ b/YLErpWeb/wwwroot/Scripts/app/client/tradeMarketReport.js @@ -312,7 +312,7 @@ function SearchClientBalance() { $("#VmFundSum").text(numFormart(data.VmFundSum)); $("#AvailableFund").text(numFormart(data.AvailableAmount)); $("#OtherFund").text(numFormart(data.OtherFund)); - $("#PositionTradePayableFund").text(numFormart(data.PositionTradePayableFundTotal)); + $("#MarginByPayableMargin").text(numFormart(data.MarginByPayableMarginTotal)); $("#ToDayRemainFund").text(numFormart(data.AmountFund)); $("#DesirableFund").text(numFormart(data.DesirableFundTotal)); }); diff --git a/YLErpWeb/wwwroot/Scripts/app/risk/quotaMonitor.js b/YLErpWeb/wwwroot/Scripts/app/risk/quotaMonitor.js index 5daabaef..3beb5396 100644 --- a/YLErpWeb/wwwroot/Scripts/app/risk/quotaMonitor.js +++ b/YLErpWeb/wwwroot/Scripts/app/risk/quotaMonitor.js @@ -1537,16 +1537,6 @@ var colModel_client = [ formatter: function (cellvalue, options, rowObject) { return !cellvalue || cellvalue == "NaN" ? "" : cellvalue.toLocaleString(); } - }, { - name: 'Credit', - label: '授信额度', - index: 'Credit', - width: 120, - align: 'right', - sortable: false, - formatter: function (cellvalue, options, rowObject) { - return !cellvalue || cellvalue == "NaN" ? "" : cellvalue.toLocaleString(); - } } ]; diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js index 339a1f60..3d51053f 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js @@ -2,6 +2,7 @@ const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.precision, negative: true, append: '' }); const inputFormatTradeAmount = Object.freeze({ precision: otcformat.trading.notional.precision, append: '' }); const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' }); +var clients = ylotc.clients; const consUnderlyingFlag = (function () { let unSelFlag = tradeHelper.UnderlyingSelectFlag; return unSelFlag.UseForTrading | unSelFlag.IncludeMatured | unSelFlag.UsePinYinFilter | unSelFlag.IncludeBasket | unSelFlag.IncludeSynthetic | unSelFlag.CheckLaunch; @@ -186,6 +187,9 @@ $(function () { document.onkeydown = keyEnter; let underlyingCtrl = new tradeHelper.UnderlyingSelectCtrl('#UnderlyingCode', { UseCodeAsId: true }).setFlag(tradeHelper.UnderlyingSelectFlag.OtcTrade); + let autoClientNumber_0 = FastVue.autocomplete(document.getElementById('SearchClientId'), { + nameField: 'Name', valueField: 'id', searchField: ['Number', 'Name'], lookup: clients + }); CombookingHub(); ResetHub(); }); @@ -868,7 +872,16 @@ var vue = new Vue({ step: 1, tradeDate: "", UnderlyingCode: "", - ClientId:null + ClientId: null, + isAddOrEditFRData: false, + isShowWarning: true, + isFromArtifical: false, + FRData: { + oldValue: null, + value: "", + id: "", + date: "" + }, }, mounted: function () { autoClient = FastVue.autocomplete(document.getElementById('ClientId'), { @@ -881,12 +894,17 @@ var vue = new Vue({ this.initStep(this.step); //intiGrid(this.step) this.refreshTradeFlow(false); + this.FRData.date = this.getToday() + this.getFRData(); }, computed: { maxTradeDate() { var now = this.getCurrentDate(); return now; }, + frTips() { + return `${this.FRData.date}无FR007,请补充。`; + } }, methods: { initStep(index) { @@ -903,6 +921,87 @@ var vue = new Vue({ intiGrid(thisObj.step) }); }, + getToday() { + const today = new Date(); + const year = today.getFullYear(); + const month = today.getMonth() + 1; // getMonth() 返回的月份是从 0 开始的 + const day = today.getDate(); + + // 如果需要格式化为 YYYY-MM-DD 字符串 + const formattedToday = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; + return formattedToday + }, + getFRData() { + const thisObj = this; + main.post(`/swapTrade2/SearchTodayWhetherFRData?dateTime=${this.FRData.date}`).done(function (resp) { + if (resp.UnderlyingCode) { // 如果这天有fr007获取值和id,隐藏警告 + thisObj.FRData.value = (resp.ReferencePrice * 100).toFixed(4); + thisObj.FRData.oldValue = (resp.ReferencePrice * 100).toFixed(4); + thisObj.FRData.id = resp.id; + thisObj.isShowWarning = false + thisObj.isFromArtifical = resp.DataSource === "人工" + } else { + thisObj.FRData.value = ""; + thisObj.FRData.id = ""; + thisObj.isShowWarning = true; + thisObj.isFromArtifical = true;// 如果没有fr007,fr007来源默认设置为人工,用于新增 + } + }); + }, + editFRData() { + this.isAddOrEditFRData = true + this.isShowWarning = false + }, + cancelEditFRData() { + this.FRData.value = ""; + this.isAddOrEditFRData = false + const today = this.getToday(); + if (this.FRData.date !== today) { + this.isShowWarning = true; + } else { + this.isShowWarning = false + } + }, + commitFRData() { + if (this.FRData.value) { + const value = Number(this.FRData.value) + if (!Number.isNaN(value)) { + // 用字符串四舍五入 + const price = main.toNumber(value / 100, 6); + // 新增时不传id + const url = this.FRData.date ? `/swapTrade2/AddOrUpdateFRData?dateTime=${this.FRData.date}&price=${price}` : `/swapTrade2/AddOrUpdateFRData?price=${price}` + const thisObj = this; + main.post(url).done(function (resp) { + if (resp) { + thisObj.isAddOrEditFRData = false + thisObj.getFRData() + } + }); + } + } else if (this.isShowWarning) { // 当日无fr007不做改动 + this.isAddOrEditFRData = false + this.getFRData() + } else if (this.FRData.id) { // 当日有fr007删除fr007 + const thisObj = this; + main.post(`/swapTrade2/DeleteFRData?id=${thisObj.FRData.id}`).done(function (resp) { + if (resp) { + thisObj.isAddOrEditFRData = false + thisObj.getFRData() + } + }); + } else { + this.isAddOrEditFRData = false + this.isShowWarning = true; + } + }, + deleteFRData() { + if (this.FRData.id) { + this.FRData.value = this.FRData.oldValue + this.isAddOrEditFRData = false + } else { + this.cancelEditFRData() + } + }, setStep(st) { this.step = st; }, diff --git a/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js b/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js index d53a8933..3b34f24d 100644 --- a/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js +++ b/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js @@ -47,7 +47,7 @@ var app = new Vue({ { text: '客户开户', value: '1' }, { text: '客户信息修改', value: '5' }, { text: '交易', value: '2' }, - { text: '资信与授信', value: '3' }, + /* { text: '资信与授信', value: '3' },*/ { text: '出金', value: '4' } ],