using DotNetDBF; using ICSharpCode.SharpZipLib.Zip; 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) { } /// /// 成交流水导入 dbf /// /// 压缩包文件路径 /// 压缩包解压路径 /// 总条数 /// 成功条数 [Obsolete] public void ImportSwapTradesFromZip(string filePath, string fileDir, out int totalNum, out int successNum) { totalNum = 0; successNum = 0; var fileDirPath = ZipHelper.unZipFile(filePath, fileDir, out var msg); var dbfFiles = GetDbfFiles(fileDirPath); var swapFlowList = GetDbfDatas(dbfFiles); if (swapFlowList.Count > 0) { DbContext.swap_flow.AddRange(swapFlowList); DbContext.SaveChanges(); new SysJobService(UserInfo).UpdateJob("互换流水合成持仓", 11, "互换流水导入完成"); Task.Run(() => { RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service)); }); } } /// /// 成交流水导入 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); if (underlying != null && underlying.IsBond()) { swap_flow.TradingAmountAvg *= ConsGlobal.bondPriceMultiple; swap_flow.TradingAmountFeeAvg *= ConsGlobal.bondPriceMultiple; swap_flow.TradingAmountNet *= ConsGlobal.bondPriceMultiple; swap_flow.TradingAmountNetFee *= ConsGlobal.bondPriceMultiple; } 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); } } /// /// 获取解压路径下所有符合的dbf文件 /// /// /// private List GetDbfFiles(string filePath) { List files = new List(); var allFiles = Directory.GetFiles(filePath, ".", SearchOption.AllDirectories); foreach (var file in allFiles) { FileInfo _file = new FileInfo(file); var fileName = _file.Name.ToLower(); //SZ:SJSMX20518.DBF SH:jsmx03_jsx73.518 if ((fileName.StartsWith("sjsmx") && fileName.Contains(".dbf")) || fileName.StartsWith("jsmx")) { files.Add(file); } } return files; } /// /// dbf文件中获取流水数据 /// /// /// private List GetDbfDatas(List files) { List swap_Flows = new List(); for (var i = 0; i < files.Count; i++) { using (var dbf = new DBFReader(files[i])) { var columnCount = dbf.Fields.Length; if (columnCount != 48) { continue; } bool dbffile = dbf.Fields[0].Name == "MXJSZH"; var swapflows = new List(); if (dbffile)//SZ { swapflows = GetSwapFlowData_SZ(dbf); } else //SH { swapflows = GetSwapFlowData_SH(dbf); } swap_Flows.AddRange(swapflows); } } return swap_Flows; } /// /// 获取SZ流水数据 /// /// /// private List GetSwapFlowData_SZ(DBFReader dbf) { List swap_Flows = new List(); var count = dbf.RecordCount; for (var j = 0; j < count; j++) { var dbfRecord = dbf.NextRecord(); if (dbfRecord != null) { string MXZQLB = dbfRecord[18].ToString().Trim();//证券类别 if (MXZQLB != "00")//A股 { continue; } decimal.TryParse(dbfRecord[12].ToString().Trim(), out decimal tradingQty);//成交数量(MXCJSL) decimal.TryParse(dbfRecord[23].ToString().Trim(), out decimal tradingAmount);//清算本金(MXQSBJ) decimal.TryParse(dbfRecord[33].ToString().Trim(), out decimal tradingFee);//收付净额(MXSXF) var underlyingCode = dbfRecord[4].ToString().Trim() + ".SZ";// 证券代码(MXSFJE) var date = dbfRecord[34].ToString().Trim();//成交日期MXCJRQ var bstype = dbfRecord[17].ToString().Trim();//平仓标识(MXPCBS) var bsType = 0; if (bstype == "2" || bstype == "3")//2平仓 3强制平仓 { bsType = 2; } else if (bstype == "1")//开仓 { bsType = 1; } var tradeDate = ConvertDateTime(date); swap_Flows.Add(new swap_flow() { FundAccount = dbfRecord[7].ToString().Trim(),//证券账户号码(MXZQZH) OccurTime = tradeDate, UnderlyingCode = underlyingCode, BsType = bsType, TradingQty = tradingQty, TradingAmount = tradingAmount, TradingFee = tradingFee - tradingAmount,//收付净额-清算本金 DataState = 1 }); } } return swap_Flows; } /// /// 获取SH流水数据 /// /// /// private List GetSwapFlowData_SH(DBFReader dbf) { List swap_Flows = new List(); var count = dbf.RecordCount; for (var j = 0; j < count; j++) { var dbfRecord = dbf.NextRecord(); if (dbfRecord != null) { string SCDM = dbfRecord[0].ToString().Trim();//市场代码 if (SCDM != "01")//A股 { continue; } var bstype = dbfRecord[29].ToString().Trim();//买卖标识(MMBZ) decimal.TryParse(dbfRecord[31].ToString().Trim(), out decimal tradingQty);//成交数量(CJSL) decimal.TryParse(dbfRecord[36].ToString().Trim(), out decimal tradingAmount);//清算金额(QSJE) decimal.TryParse(dbfRecord[45].ToString().Trim(), out decimal tradingPay);//实际收付(SJSF) var underlyingCode = dbfRecord[23].ToString().Trim() + ".SH";// 证券代码1(ZQDM1) var date = dbfRecord[11].ToString().Trim();//交易日期(JYRQ) var tradeDate = ConvertDateTime(date); var bsType = 0; if (bstype == "B") { bsType = 1; } else if (bstype == "S") { bsType = 2; } swap_Flows.Add(new swap_flow() { FundAccount = dbfRecord[32].ToString().Trim(),//资金账号(ZJZH) OccurTime = tradeDate, UnderlyingCode = underlyingCode, BsType = bsType, TradingQty = tradingQty, TradingAmount = tradingAmount, TradingFee = tradingPay - tradingAmount, DataState = 1 }); } } return swap_Flows; } /// /// 6位字符串日期转换 /// /// /// private DateTime? ConvertDateTime(string date) { if (date.Length != 8) { return null; } DateTime.TryParse(date.Substring(0, 4) + "-" + date.Substring(4, 2) + "-" + date.Substring(6), out DateTime tradeDate); return tradeDate; } } }