using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; using YLErp.Helpers; using YLErp.DBModels; using Org.BouncyCastle.Ocsp; using YLErp.BLL.Eod; using CsvHelper; using YLErp.BLL; namespace YLErp.Modules.SwapModule { /// /// 互换成交流水服务 /// public class SwapFlowImportService : YLBaseService { public SwapFlowImportService(OptUserInfo optUser) : base(optUser) { } public SwapFlowImportService(YLBaseService baseService) : base(baseService) { } /// /// 成交流水导入 excel /// /// 上传的文件 /// 总条数 /// 成功条数 public void ImportSwapTradesFromExcel(Stream streamIn, out int totalNum, out int successNum) { totalNum = 0; successNum = 0; var rowIndex = 0; try { var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0); if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2) { throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" }; } var table = ds.Tables[0]; var reader = new DataRowReaderHelper(table); rowIndex = 1; totalNum = table.Rows.Count - rowIndex; Dictionary> clientUmsDic = new Dictionary>(); foreach (var row in table.Rows.Cast().Skip(rowIndex)) { rowIndex++; if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString()))) { totalNum--; continue; } reader.SetDataRow(row,rowIndex); var swap_flow = new swap_flow(); swap_flow.FundAccount = reader.GetString("资金账号"); var uPattern = "^[0 - 9]{6,20}$"; Regex regex = new Regex(uPattern); if (!string.IsNullOrEmpty(swap_flow.FundAccount)&®ex.IsMatch(swap_flow.FundAccount)) { throw new ServiceException($"第{rowIndex}行资金账号应为20位以内的数字"); } swap_flow.UnderlyingCode = reader.GetString("标的代码", true); var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(swap_flow.UnderlyingCode); swap_flow.UnderlyingName = underlying?.UnderlyingName; var clientName = reader.GetString("交易对手方", true); swap_flow.OccurTime = reader.GetDate("交易日期", true); swap_flow.SettleDate = valuedateBLL.GetNonHoliday(swap_flow.OccurTime.Value).Date; swap_flow.BsType = reader.GetString("买卖方向", true) == "B" ? (int)EnumDirection.Long : (int)EnumDirection.Short; swap_flow.TradingAmount = reader.GetDecimal("成交金额") ?? 0; swap_flow.TradingFee = reader.GetDecimal("交易费用") ?? 0; swap_flow.TradingQty = reader.GetDecimal("成交数量") ?? 0; if (swap_flow.TradingQty<=0) { throw new ServiceException($"第{rowIndex}行成交数量必须大于0"); } swap_flow.DataState = (int)SwapFlowDateStateEnum.等待完成; swap_flow.ContractSize= reader.GetDecimal("乘数") ?? 0; swap_flow.TradingAmountAvg = reader.GetDecimal("成交全价") ?? 0; swap_flow.TradingAmountFeeAvg = TradeFeeHelper.CalcPriceWithFee(swap_flow.TradingFee, swap_flow.TradingAmountAvg, swap_flow.TradingQty, swap_flow.BsType); swap_flow.ytm = reader.GetDecimalOrPercent("成交收益率",false,true) ?? 0; swap_flow.TradingAmountNet = reader.GetDecimal("成交净价") ?? 0; swap_flow.TradingAmountNetFee = TradeFeeHelper.CalcPriceWithFee(swap_flow.TradingFee, swap_flow.TradingAmountNet??0, swap_flow.TradingQty, swap_flow.BsType); var isBond = underlying != null && underlying.IsBond(); if (isBond) { // 成交流水债券报价(×100形式)转入库小数(×0.01),统一走 BondPriceConverter swap_flow.TradingAmountAvg = BondPriceConverter.ToStorage(swap_flow.TradingAmountAvg); swap_flow.TradingAmountFeeAvg = BondPriceConverter.ToStorage(swap_flow.TradingAmountFeeAvg); // TradingAmountNet/NetFee 可空,null 时保持 null 语义(与原 *= 一致) if (swap_flow.TradingAmountNet.HasValue) swap_flow.TradingAmountNet = BondPriceConverter.ToStorage(swap_flow.TradingAmountNet.Value); if (swap_flow.TradingAmountNetFee.HasValue) swap_flow.TradingAmountNetFee = BondPriceConverter.ToStorage(swap_flow.TradingAmountNetFee.Value); } swap_flow.TradingAmountAvg = Math.Round( swap_flow.TradingAmountAvg, isBond ? ConsGlobal.PriceRound : ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero); if (!string.IsNullOrEmpty(clientName)) { var client = DataCacheProvider.GetClientDataSource().AsQueryable(x=>x.Name== clientName).FirstOrDefault(); swap_flow.ClientId = client?.id; swap_flow.ClientName = clientName; } swap_flow.OptId = UserId; swap_flow.OptName = UserName; swap_flow.OptTime = DateTime.Now; DbContext.swap_flow.Add(swap_flow); if (!clientUmsDic.ContainsKey(swap_flow.ClientId ?? 0)) { clientUmsDic.Add(swap_flow.ClientId ?? 0, new List { swap_flow.UnderlyingCode }); } else { if (!clientUmsDic[swap_flow.ClientId ?? 0].Contains(swap_flow.UnderlyingCode)) { clientUmsDic[swap_flow.ClientId ?? 0].Add(swap_flow.UnderlyingCode); } } successNum++; } DbContext.SaveChanges(); Task.Run(() => { RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service)); }); new RiskCacheService().refreshRiskCache(clientUmsDic); } catch (Exception ex) { LogFactory.GetLogger("导入互换成交流水").Error(ex); throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex); } } } }