425 lines
15 KiB
C#
425 lines
15 KiB
C#
using System.Data;
|
|
using System.Text;
|
|
using YLErp.Commons;
|
|
using YLErp.Models;
|
|
|
|
namespace YLErp.Modules.MarginModule
|
|
{
|
|
/// <summary>
|
|
/// 标的预付金计算参数导入服务
|
|
/// </summary>
|
|
public class MarginParamsImportService : YLBaseService
|
|
{
|
|
public MarginParamsImportService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
|
|
}
|
|
|
|
public MarginParamsImportService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导入标的数据(Excel)
|
|
/// </summary>
|
|
public MarginParamsImportResult ImportUnderlying(Stream streamIn)
|
|
{
|
|
var readResult = ReadData(streamIn, false);
|
|
|
|
if (readResult.hasError)
|
|
{
|
|
return new MarginParamsImportResult
|
|
{
|
|
ResultSet = readResult.dataSet,
|
|
ResultMsg = "读取导入数据失败,请检查修改后重新导入"
|
|
};
|
|
}
|
|
|
|
var lists = new[] { readResult.marginHis, readResult.volRateHis, readResult.updownHis };
|
|
|
|
if (!lists.Any(n => n.Count > 0))
|
|
{
|
|
return new MarginParamsImportResult { ResultSet = readResult.dataSet, ResultMsg = "未读取到任何导入数据" };
|
|
}
|
|
|
|
var sqlBuilderList = new List<StringBuilder>(10) { new StringBuilder(5200) };
|
|
var tableName = DbContext.GetTableName<UnderlyingHisData>();
|
|
var result = new MarginParamsImportResult { ResultSet = readResult.dataSet };
|
|
|
|
foreach (var list in lists)
|
|
{
|
|
if (!list.Any())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string valueType = null;
|
|
string sheetName = list[0].dataRow.Table.TableName;
|
|
|
|
switch (sheetName)
|
|
{
|
|
case "预付金比例":
|
|
valueType = nameof(MarginParamModel.MarginRate);
|
|
break;
|
|
case "Span波动率变动":
|
|
valueType = nameof(MarginParamModel.VolatilityRate);
|
|
break;
|
|
case "Span涨跌幅度":
|
|
valueType = nameof(MarginParamModel.UpDownLimit);
|
|
break;
|
|
}
|
|
|
|
var groups = list.GroupBy(n => n.code);
|
|
|
|
foreach (var grp in groups)
|
|
{
|
|
var items = grp.OrderBy(n => n.date).ToArray();
|
|
|
|
var minDate = items[0].date;
|
|
var maxDate = items[items.Length - 1].date;
|
|
|
|
var sqlBuilder = sqlBuilderList.Last();
|
|
if (sqlBuilder.Length > 5000)
|
|
{
|
|
sqlBuilderList.Add(sqlBuilder = new StringBuilder(5200));
|
|
}
|
|
sqlBuilder.AppendFormat("delete from {0} where UnderlyingCode='{1}' and ValueDate>='{2}' and ValueDate<='{3}' and ValueType='{4}';"
|
|
, tableName, grp.Key, minDate.ToShortDateString(), maxDate.ToShortDateString(), valueType).AppendLine();
|
|
|
|
foreach (var item in items)
|
|
{
|
|
DbContext.UnderlyingHisData.Add(new UnderlyingHisData
|
|
{
|
|
UnderlyingCode = grp.Key,
|
|
ValueType = valueType,
|
|
ValueDate = item.date,
|
|
Value = item.dvalue,
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = OptDate,
|
|
ValueFlag = sheetName != "Span涨跌幅度" || item.isPercent ? "%" : "F"
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
using (var trans = BeginTransaction())
|
|
{
|
|
foreach (var sb in sqlBuilderList)
|
|
{
|
|
var sql = sb.ToString();
|
|
if (sql.Length > 0)
|
|
{
|
|
var changes1 = DbContext.Database.ExecuteSqlRaw(sql);
|
|
}
|
|
}
|
|
|
|
result.SuccessSum = DbContext.SaveChanges();
|
|
|
|
UpdateUnderlyingMaringParams(SystemValueDate);
|
|
|
|
trans.Commit();
|
|
}
|
|
|
|
return result.SetMsg($"成功处理{result.SuccessSum}条");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 使用mysql语句执行underlying_manager表中预付金参数的更新
|
|
/// </summary>
|
|
private int UpdateUnderlyingMaringParams(DateTime maxDate)
|
|
{
|
|
var maxDateStr = maxDate.ToString("yyyy-MM-dd");
|
|
|
|
var sql = $@"
|
|
update underlying_manager set
|
|
|
|
MarginRate= (select `Value` end from underlying_hisdata uh
|
|
where uh.UnderlyingCode = underlying_manager.UnderlyingCode and uh.ValueDate <= '{maxDateStr}' && uh.ValueType = 'MarginRate'
|
|
order by ValueDate desc limit 1),
|
|
|
|
VolatilityRate= (select case ValueFlag when '%' then CONCAT(TRUNCATE(`Value`*100,2),'%') else TRUNCATE(`Value`,4) end from underlying_hisdata uh
|
|
where uh.UnderlyingCode = underlying_manager.UnderlyingCode and uh.ValueDate <= '{maxDateStr}' && uh.ValueType = 'VolatilityRate'
|
|
order by ValueDate desc limit 1),
|
|
|
|
UpDownLimit= (select case ValueFlag when '%' then CONCAT(TRUNCATE(`Value`*100,2),'%') else TRUNCATE(`Value`,4) end from underlying_hisdata uh
|
|
where uh.UnderlyingCode = underlying_manager.UnderlyingCode and uh.ValueDate <= '{maxDateStr}' && uh.ValueType = 'UpDownLimit'
|
|
order by ValueDate desc limit 1)";
|
|
|
|
return DbContext.Database.ExecuteSqlRaw(sql);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导入品种数据(Excel)
|
|
/// </summary>
|
|
public MarginParamsImportResult ImportVariety(Stream streamIn)
|
|
{
|
|
var readResult = ReadData(streamIn, true);
|
|
|
|
if (readResult.hasError)
|
|
{
|
|
return new MarginParamsImportResult
|
|
{
|
|
ResultSet = readResult.dataSet,
|
|
ResultMsg = "读取导入数据失败,请检查修改后重新导入"
|
|
};
|
|
}
|
|
|
|
var lists = new[] { readResult.marginHis, readResult.volRateHis, readResult.updownHis };
|
|
|
|
if (!lists.Any(n => n.Count > 0))
|
|
{
|
|
return new MarginParamsImportResult { ResultSet = readResult.dataSet, ResultMsg = "未读取到任何导入数据" };
|
|
}
|
|
|
|
var sysDate = SystemValueDate;
|
|
var vaDic = DbContext.variety.ToDictionary(n => n.VarietyCode);
|
|
|
|
var sqlBuilder = new StringBuilder();
|
|
var tableName = DbContext.GetTableName<VarietyHisData>();
|
|
var result = new MarginParamsImportResult { ResultSet = readResult.dataSet };
|
|
|
|
foreach (var list in lists)
|
|
{
|
|
if (!list.Any())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string valueType = null;
|
|
string sheetName = list[0].dataRow.Table.TableName;
|
|
|
|
switch (sheetName)
|
|
{
|
|
case "预付金比例":
|
|
valueType = nameof(MarginParamModel.MarginRate);
|
|
break;
|
|
case "Span波动率变动":
|
|
valueType = nameof(MarginParamModel.VolatilityRate);
|
|
break;
|
|
case "Span涨跌幅度":
|
|
valueType = nameof(MarginParamModel.UpDownLimit);
|
|
break;
|
|
}
|
|
|
|
var groups = list.GroupBy(n => n.code);
|
|
|
|
foreach (var grp in groups)
|
|
{
|
|
var items = grp.OrderBy(n => n.date).ToArray();
|
|
|
|
if (!vaDic.TryGetValue(grp.Key, out var va))
|
|
{
|
|
foreach (var item in items)
|
|
{
|
|
result.FailSum++;
|
|
item.dataRow["处理结果"] = "品种信息不存在";
|
|
}
|
|
continue;
|
|
}
|
|
|
|
result.SuccessSum++;
|
|
var minDate = items[0].date;
|
|
var maxDate = items[items.Length - 1].date;
|
|
|
|
sqlBuilder.AppendFormat("delete from {0} where VarietyId={1} and ValueDate>='{2}' and ValueDate<='{3}' and ValueType='{4}';"
|
|
, tableName, va.id, minDate.ToShortDateString(), maxDate.ToShortDateString(), valueType).AppendLine();
|
|
|
|
var index = 0;
|
|
|
|
foreach (var item in items)
|
|
{
|
|
if (item.date <= sysDate)
|
|
{
|
|
index++;
|
|
}
|
|
|
|
DbContext.VarietyHisData.Add(new VarietyHisData
|
|
{
|
|
VarietyId = va.id,
|
|
ValueType = valueType,
|
|
ValueDate = item.date,
|
|
Value = item.dvalue,
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = OptDate
|
|
});
|
|
}
|
|
|
|
//更新品种数据
|
|
if (index > 0)
|
|
{
|
|
ReadModel rm = null;
|
|
if (index < items.Length)
|
|
{
|
|
rm = items[index - 1];
|
|
}
|
|
else if (!DbContext.VarietyHisData.Any(n => n.VarietyId == va.id && n.ValueDate > maxDate && n.ValueDate <= sysDate && n.ValueType == valueType))
|
|
{
|
|
rm = items[items.Length - 1];
|
|
}
|
|
|
|
if (rm != null)
|
|
{
|
|
switch (sheetName)
|
|
{
|
|
case "预付金比例":
|
|
va.Margin = rm.dvalue;
|
|
break;
|
|
case "Span波动率变动":
|
|
va.VolatilityRate = rm.dvalue.ToString("P2");
|
|
break;
|
|
case "Span涨跌幅度":
|
|
va.UpLimit = va.DownLimit = rm.dvalue.ToString("P2");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result.SuccessSum < 1)
|
|
{
|
|
return result.SetMsg("所有导入数据都未能成功处理");
|
|
}
|
|
|
|
using (var trans = BeginTransaction())
|
|
{
|
|
var sql = sqlBuilder.ToString();
|
|
var changes = DbContext.Database.ExecuteSqlRaw(sql);
|
|
changes = DbContext.SaveChanges();
|
|
trans.Commit();
|
|
}
|
|
|
|
return result.SetMsg($"成功处理{result.SuccessSum}条,失败{result.FailSum}条");
|
|
}
|
|
|
|
private ReadResult ReadData(Stream streamIn, bool isVariety)
|
|
{
|
|
streamIn.Position = 0;
|
|
|
|
var codePropName = isVariety ? "品种代码" : "标的代码";
|
|
|
|
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn);
|
|
|
|
var readResult = new ReadResult { dataSet = ds };
|
|
|
|
var uniqSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
foreach (DataTable dt in ds.Tables)
|
|
{
|
|
List<ReadModel> list = null;
|
|
|
|
switch (dt.TableName)
|
|
{
|
|
case "预付金比例":
|
|
list = readResult.marginHis;
|
|
break;
|
|
case "Span波动率变动":
|
|
list = readResult.volRateHis;
|
|
break;
|
|
case "Span涨跌幅度":
|
|
list = readResult.updownHis;
|
|
break;
|
|
default: continue;
|
|
}
|
|
|
|
var reader = new DataRowReader(dt);
|
|
|
|
dt.Columns.Add("处理结果");
|
|
|
|
var colCount = dt.Columns.Count;
|
|
|
|
uniqSet.Clear();
|
|
|
|
foreach (DataRow row in dt.Rows.Cast<DataRow>())
|
|
{
|
|
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
reader.SetDataRow(row);
|
|
|
|
try
|
|
{
|
|
var model = new ReadModel
|
|
{
|
|
dataRow = row,
|
|
code = reader.GetString(codePropName, true).ToUpperInvariant(),
|
|
date = reader.GetDate("变动日期", true).Value,
|
|
dvalue = reader.GetPercent(dt.TableName, false) ?? 0
|
|
};
|
|
if (!uniqSet.Add(model.code + "^" + model.date.ToShortDateString()))
|
|
{
|
|
throw new ServiceException("重复设置");
|
|
}
|
|
model.dvalue = Math.Abs(model.dvalue);
|
|
model.isPercent = reader.GetString("绝对值方式", false) != "是";
|
|
list.Add(model);
|
|
}
|
|
catch (ServiceException sex)
|
|
{
|
|
readResult.hasError = true;
|
|
row[colCount - 1] = sex.Message;
|
|
}
|
|
}
|
|
}
|
|
|
|
return readResult;
|
|
}
|
|
|
|
class ReadModel
|
|
{
|
|
public string code;
|
|
|
|
public DateTime date;
|
|
|
|
public double dvalue;
|
|
|
|
public bool isPercent;
|
|
|
|
public DataRow dataRow;
|
|
}
|
|
|
|
class ReadResult
|
|
{
|
|
public bool hasError;
|
|
|
|
public DataSet dataSet;
|
|
|
|
public List<ReadModel> marginHis { get; private set; }
|
|
|
|
public List<ReadModel> volRateHis { get; private set; }
|
|
|
|
public List<ReadModel> updownHis { get; private set; }
|
|
|
|
public ReadResult()
|
|
{
|
|
marginHis = new List<ReadModel>();
|
|
volRateHis = new List<ReadModel>();
|
|
updownHis = new List<ReadModel>();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class MarginParamsImportResult
|
|
{
|
|
public int FailSum { get; set; }
|
|
|
|
public int SuccessSum { get; set; }
|
|
|
|
public string ResultMsg { get; set; }
|
|
|
|
public DataSet ResultSet { get; set; }
|
|
|
|
internal MarginParamsImportResult SetMsg(string msg)
|
|
{
|
|
ResultMsg = msg;
|
|
return this;
|
|
}
|
|
}
|
|
} |