using System.Data; using YLErp.Commons; namespace YLErp.Modules.EodModule { public class EodSwapPositionMannualImportService : YLBaseService { public EodSwapPositionMannualImportService(OptUserInfo userInfo) : base(userInfo) { } /// /// 导入交易 /// /// /// 当前文件中的目标期权总条数 /// 成功入库的数量 public void ImportEodSwapPositionMannualFromExcel(Stream streamIn, DateTime valuedate, out int totalNum, out int successNum) { totalNum = 0; successNum = 0; var rowIndex = 1; try { var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 1); if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1) { throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" }; } var table = ds.Tables[0]; var reader = new DataRowReader(table); totalNum = table.Rows.Count; using (var trans = BeginTransaction()) { List eod_Trade_Position_Swap_Mannuals = new List(); foreach (var row in table.Rows.Cast()) { rowIndex++; if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString()))) { totalNum--; continue; } reader.SetDataRow(row); //映射导入数据到交易对象 var tradeFlow = MapSwapTrade(reader, valuedate); eod_Trade_Position_Swap_Mannuals.Add(tradeFlow); successNum++; } var valuedates = eod_Trade_Position_Swap_Mannuals.Select(x => x.ValueDate).ToHashSet(); List remove = new List(); foreach (var date in valuedates) { if (DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == date).Any()) { var clientNumbers = eod_Trade_Position_Swap_Mannuals.Where(x => x.ValueDate == date).Select(x => x.ClientNumber).ToHashSet(); foreach (var number in clientNumbers) { if (DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == date && x.ClientNumber == number).Any()) { var underlys = eod_Trade_Position_Swap_Mannuals.Where(x => x.ValueDate == date && x.ClientNumber == number).Select(x => x.UnderlyingCode).ToHashSet(); var list = DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == date && x.ClientNumber == number && underlys.Contains(x.UnderlyingCode)).ToList(); remove.AddRange(list); } } } } if (remove.Any()) { DbContext.eod_trade_position_swap_mannual.RemoveRange(remove); } DbContext.eod_trade_position_swap_mannual.AddRange(eod_Trade_Position_Swap_Mannuals); DbContext.SaveChanges(); trans.Commit(); } } catch (ServiceException se) { if (se.Tag != null) { throw; } throw new ServiceException($"第{rowIndex}行,{se.Message}"); } catch (Exception ex) { LogFactory.GetLogger("导入互换交易").Error(ex); throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex); } } private eod_trade_position_swap_mannual MapSwapTrade(DataRowReader reader, DateTime valuedate) { var eod_Swap = new eod_trade_position_swap_mannual(); eod_Swap.ValueDate = reader.GetDate("估值日期", false) ?? valuedate; eod_Swap.ClientNumber = reader.GetString("客户编号", false); eod_Swap.ClientName = reader.GetString("客户名称", false); eod_Swap.UnderlyingCode = reader.GetString("标的代码", false); eod_Swap.UnderlyingName = reader.GetString("标的名称", false); eod_Swap.Notional = reader.GetDouble("持仓数量", true) ?? 0; eod_Swap.SpotPrice = reader.GetDouble("开仓均价", true) ?? 0; eod_Swap.CurrentPrice = reader.GetDouble("标的现价", true) ?? 0; eod_Swap.TotalFee = reader.GetDouble("交易总费用", true) ?? 0; eod_Swap.AnnualFee = reader.GetDouble("固定收益", true) ?? 0; eod_Swap.FloatingWinLoss = reader.GetDouble("浮动收益", true) ?? 0; eod_Swap.Margin = reader.GetDouble("预付金占用", true) ?? 0; eod_Swap.PositionPnl = reader.GetDouble("持仓盈亏", true) ?? 0; eod_Swap.Strategy = reader.GetString("策略", false); CheckAssignmentSwapTradeFlow(eod_Swap); eod_Swap.OptId = UserId; eod_Swap.OptName = UserName; eod_Swap.OptDate = DateTime.Now; return eod_Swap; } /// /// 互换流水api导入 /// /// /// /// public int EodTradeSwap(EodSwapTradeRequestDate data) { List add = new List(); List remove = new List(); using (var trans = BeginTransaction()) { foreach (var model in data.models) { CheckNotNullSwapTradeFlow(model); var eod_Swap = new eod_trade_position_swap_mannual(); eod_Swap.ValueDate = model.ValueDate ?? DateTime.Today; ; eod_Swap.ClientNumber = model.ClientNumber; eod_Swap.ClientName = model.ClientName; eod_Swap.UnderlyingCode = model.UnderlyingCode; eod_Swap.UnderlyingName = model.UnderlyingName; eod_Swap.Notional = model.Notional ?? 0; eod_Swap.SpotPrice = model.SpotPrice ?? 0; eod_Swap.CurrentPrice = model.CurrentPrice ?? 0; eod_Swap.TotalFee = model.TotalFee ?? 0; eod_Swap.AnnualFee = model.AnnualFee ?? 0; eod_Swap.FloatingWinLoss = model.FloatingWinLoss ?? 0; eod_Swap.Margin = model.Margin ?? 0; eod_Swap.PositionPnl = model.PositionPnl ?? 0; eod_Swap.Strategy = model.Strategy; CheckAssignmentSwapTradeFlow(eod_Swap); eod_Swap.OptId = UserId; eod_Swap.OptName = UserName; eod_Swap.OptDate = DateTime.Now; if (DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == eod_Swap.ValueDate && x.ClientNumber == eod_Swap.ClientNumber && x.UnderlyingCode == eod_Swap.UnderlyingCode).Any()) { var list = DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == eod_Swap.ValueDate && x.ClientNumber == eod_Swap.ClientNumber && x.UnderlyingCode == eod_Swap.UnderlyingCode); remove.AddRange(list); } add.Add(eod_Swap); } DbContext.eod_trade_position_swap_mannual.RemoveRange(remove); DbContext.eod_trade_position_swap_mannual.AddRange(add); DbContext.SaveChanges(); trans.Commit(); } return add.Count; } private void CheckNotNullSwapTradeFlow(EodSwapTradeRequestModel model) { if (!model.ValueDate.HasValue) { throw new ServiceException($"估值日期 不能为空"); } if (!model.SpotPrice.HasValue) { throw new ServiceException($"开仓均价 不能为空"); } if (!model.CurrentPrice.HasValue) { throw new ServiceException($"标的现价 不能为空"); } if (!model.TotalFee.HasValue) { throw new ServiceException($"交易总费用 不能为空"); } if (!model.AnnualFee.HasValue) { throw new ServiceException($"固定收益 不能为空"); } if (!model.FloatingWinLoss.HasValue) { throw new ServiceException($"浮动收益 不能为空"); } if (!model.Margin.HasValue) { throw new ServiceException($"预付金占用 不能为空"); } if (!model.PositionPnl.HasValue) { throw new ServiceException($"持仓盈亏 不能为空"); } if (model.Strategy != "套利" && model.Strategy != "非套利") { throw new ServiceException($"策略 只能填充【套利】和【非套利】"); } } private void CheckAssignmentSwapTradeFlow(eod_trade_position_swap_mannual model) { string clientNumber = model.ClientNumber; string clientName = model.ClientName; if (!string.IsNullOrWhiteSpace(clientNumber)) { var client = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(n => clientNumber.Equals(n.Number, StringComparison.OrdinalIgnoreCase)); if (client == null) { throw new ServiceException($"该客户编号[{clientNumber}]在系统中不存在"); } model.ClientNumber = client.Number; model.ClientId = client.id; } else if (!string.IsNullOrWhiteSpace(clientName)) { var client = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(n => clientName.Equals(n.Name, StringComparison.OrdinalIgnoreCase)); if (client == null) { throw new ServiceException($"该客户名称[{clientName}]在系统中不存在"); } model.ClientNumber = client.Number; model.ClientId = client.id; } else { throw new ServiceException($"客户编号和客户名称不能同时为空"); } string underlyingCode = model.UnderlyingCode; string underlyingName = model.UnderlyingName; if (!string.IsNullOrWhiteSpace(underlyingCode)) { var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode); if (underlying == null) { throw new ServiceException($"该标的代码[{underlyingCode}]在系统中不存在"); } model.UnderlyingCode = underlying.UnderlyingCode; } else if (!string.IsNullOrWhiteSpace(underlyingName)) { var underlying = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().FirstOrDefault(n => underlyingName.Equals(n.UnderlyingName, StringComparison.OrdinalIgnoreCase)); if (underlying == null) { throw new ServiceException($"该标的名称[{underlyingName}]在系统中不存在"); } model.UnderlyingCode = underlying.UnderlyingCode; } else { throw new ServiceException($"标的代码和标的名称不能同时为空"); } if (model.Notional == 0) { throw new ServiceException($"持仓数量不能为0"); } if (model.Strategy != "套利" && model.Strategy != "非套利") { throw new ServiceException($"策略 只能填充【套利】和【非套利】"); } } } }