322 lines
14 KiB
C#
322 lines
14 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// 互换成交流水服务
|
|
/// </summary>
|
|
public class SwapFlowImportService : YLBaseService
|
|
{
|
|
public SwapFlowImportService(OptUserInfo optUser) : base(optUser)
|
|
{
|
|
}
|
|
public SwapFlowImportService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
|
|
}
|
|
/// <summary>
|
|
/// 成交流水导入 dbf
|
|
/// </summary>
|
|
/// <param name="filePath">压缩包文件路径</param>
|
|
/// <param name="fileDir">压缩包解压路径</param>
|
|
/// <param name="totalNum">总条数</param>
|
|
/// <param name="successNum">成功条数</param>
|
|
[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));
|
|
});
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 成交流水导入 excel
|
|
/// </summary>
|
|
/// <param name="streamIn">上传的文件</param>
|
|
/// <param name="totalNum">总条数</param>
|
|
/// <param name="successNum">成功条数</param>
|
|
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;
|
|
foreach (var row in table.Rows.Cast<DataRow>().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);
|
|
successNum++;
|
|
}
|
|
DbContext.SaveChanges();
|
|
Task.Run(() =>
|
|
{
|
|
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("导入互换成交流水").Error(ex);
|
|
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取解压路径下所有符合的dbf文件
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
private List<string> GetDbfFiles(string filePath)
|
|
{
|
|
List<string> files = new List<string>();
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// dbf文件中获取流水数据
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <returns></returns>
|
|
private List<swap_flow> GetDbfDatas(List<string> files)
|
|
{
|
|
List<swap_flow> swap_Flows = new List<swap_flow>();
|
|
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<swap_flow>();
|
|
if (dbffile)//SZ
|
|
{
|
|
swapflows = GetSwapFlowData_SZ(dbf);
|
|
}
|
|
else //SH
|
|
{
|
|
swapflows = GetSwapFlowData_SH(dbf);
|
|
}
|
|
swap_Flows.AddRange(swapflows);
|
|
}
|
|
}
|
|
return swap_Flows;
|
|
}
|
|
/// <summary>
|
|
/// 获取SZ流水数据
|
|
/// </summary>
|
|
/// <param name="dbf"></param>
|
|
/// <returns></returns>
|
|
private List<swap_flow> GetSwapFlowData_SZ(DBFReader dbf)
|
|
{
|
|
List<swap_flow> swap_Flows = new List<swap_flow>();
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// 获取SH流水数据
|
|
/// </summary>
|
|
/// <param name="fields"></param>
|
|
/// <returns></returns>
|
|
private List<swap_flow> GetSwapFlowData_SH(DBFReader dbf)
|
|
{
|
|
List<swap_flow> swap_Flows = new List<swap_flow>();
|
|
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;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 6位字符串日期转换
|
|
/// </summary>
|
|
/// <param name="date"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
}
|
|
}
|