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;
}
}
}