Files
zszq-trs/YLErpDAL/Modules/UnderlyingModule/VarietyDalService.cs
T
2024-05-09 14:06:26 +08:00

502 lines
21 KiB
C#

using System.Data;
using YieldChain.Helpers;
using YLErp.BLL;
using YLErp.Commons;
using YLErp.Models;
namespace YLErp.Modules.UnderlyingModule
{
/// <summary>
/// 标的品种数据操作服务
/// </summary>
public class VarietyDalService : YLBaseService
{
public VarietyDalService(OptUserInfo userInfo) : base(userInfo)
{
}
public void ImportExcel(Stream streamIn, out int totalNum, out int successNum)
{
totalNum = 0;
successNum = 0;
int rowIndex = 0;
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 - rowIndex;
foreach (var row in table.Rows.Cast<DataRow>())
{
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
totalNum--;
continue;
}
reader.SetDataRow(row);
//映射导入数据
var variety = MapVariety(reader, row);
//保存数据
SaveData(variety);
successNum++;
rowIndex++;
}
}
catch (ServiceException se)
{
if (se.Tag != null) throw;
throw new ServiceException($"第{rowIndex + 2}行,发生错误:{se.Message}");
}
}
private Variety MapVariety(DataRowReader reader, DataRow row)
{
var variety = new Variety();
var VarietyCode = reader.GetString("品种代码", true);
variety.VarietyCode = VarietyCode;
bool isnull = VarietyCode != "篮子标的" && VarietyCode != "组合标的";
bool isadd = true;
if (DbContext.variety.FirstOrDefault(o => o.VarietyCode == variety.VarietyCode) != null)
{
variety = DbContext.variety.FirstOrDefault(o => o.VarietyCode == variety.VarietyCode);
isadd = false;
}
string marketCode = null;
string mainCategoryCn = null;
string contractSize = null;
string unit = null;
string VarietyName = null;
string AssetType = null;
string VarietyEnName = null;
string EnUnit = null;
string BBGTicker = null;
string CommissionType = null;
string TradedOptionCommissionType = null;
string CloseTodayCommissionType = null;
string commissionExchange = null;
string commissionDeviation = null;
string tradedOptionCommissionExchange = null;
string tradedOptionCommissionDeviation = null;
string closeTodayCommissionExchange = null;
string closeTodayCommissionDeviation = null;
DataColumnCollection rowx = row.Table.Columns;
foreach (DataColumn col in rowx)
{
switch (col.ColumnName)
{
case "交易所代码":
marketCode = reader.GetString("交易所代码", false);
break;
case "主类型":
mainCategoryCn = reader.GetString("主类型", PS.Config.Company == Configuration.CompanyEnum.中金);
break;
case "合约乘数":
contractSize = reader.GetString("合约乘数", false);
break;
case "单位":
unit = reader.GetString("单位", false);
break;
case "品种名":
VarietyName = reader.GetString("品种名", false);
break;
case "品种类型":
AssetType = reader.GetString("品种类型", false);
break;
case "品种英文名":
VarietyEnName = reader.GetString("品种英文名", false);
break;
case "单位英文描述":
EnUnit = reader.GetString("单位英文描述", false);
break;
case "BBG Ticker":
BBGTicker = reader.GetString("BBG Ticker", false);
break;
case "交易所手续费类型":
CommissionType = reader.GetString("交易所手续费类型", false);
break;
case "场内手续费类型":
TradedOptionCommissionType = reader.GetString("场内手续费类型", false);
break;
case "平今仓手续费类型":
CloseTodayCommissionType = reader.GetString("平今仓手续费类型", false);
break;
case "交易所手续费":
commissionExchange = reader.GetString("交易所手续费", false);
break;
case "手续费偏离值":
commissionDeviation = reader.GetString("手续费偏离值", false);
break;
case "交易所场内手续费":
tradedOptionCommissionExchange = reader.GetString("交易所场内手续费", false);
break;
case "场内手续费偏离值":
tradedOptionCommissionDeviation = reader.GetString("场内手续费偏离值", false);
break;
case "交易所平今仓手续费":
closeTodayCommissionExchange = reader.GetString("交易所平今仓手续费", false);
break;
case "平今仓手续费偏离值":
closeTodayCommissionDeviation = reader.GetString("平今仓手续费偏离值", false);
break;
}
}
var market = DataCacheProvider.GetMarketDataSource().AsQueryable().FirstOrDefault(o => o.ExchangeNo == marketCode);
if (isadd)
{
if (market == null && isnull)
{
throw new ServiceException("未找到交易所代码对应的交易所");
}
if (contractSize == null)
{
throw new ServiceException("未找到合约乘数");
}
if (unit == null)
{
throw new ServiceException("未找到单位");
}
if (VarietyName == null)
{
throw new ServiceException("未找到品种名");
}
if (AssetType == null && PS.Config.Company == Configuration.CompanyEnum.中金)
{
throw new ServiceException("未找到品种类型");
}
if (CommissionType == null)
{
throw new ServiceException("未找到交易所手续费类型");
}
if (TradedOptionCommissionType == null)
{
throw new ServiceException("未找到场内手续费类型");
}
if (CloseTodayCommissionType == null)
{
throw new ServiceException("未找到平今仓手续费类型");
}
}
variety.VarietyName = VarietyName == null ? variety.VarietyName : VarietyName;
variety.AssetType = AssetType == null ? variety.AssetType : AssetType;
variety.VarietyEnName = VarietyEnName == null ? variety.VarietyEnName : VarietyEnName;
variety.TradingMarket = market == null ? variety.TradingMarket : market.MarketName;
variety.TradingMarketId = market == null ? variety.TradingMarketId : market.id;
if (contractSize != null && unit != null)
{
if (double.TryParse(contractSize, out var contractsize))
{
variety.TradeUnit = contractsize + unit + "/手";
}
}
variety.EnUnit = EnUnit == null ? variety.EnUnit : EnUnit;
variety.BBGTicker = BBGTicker == null ? variety.BBGTicker : BBGTicker;
variety.QuoteUnit = unit == null ? variety.QuoteUnit : "元(人民币)/" + unit;
if (mainCategoryCn != null)
{
variety.MainCategory = string.IsNullOrWhiteSpace(mainCategoryCn) ? null : ConsGlobal.MainCategory.GetFromDesc(mainCategoryCn);
}
variety.CommissionType = CommissionType == null ? variety.CommissionType : CommissionType;
variety.TradedOptionCommissionType = VarietyName == null ? variety.TradedOptionCommissionType : TradedOptionCommissionType;
variety.CloseTodayCommissionType = VarietyName == null ? variety.CloseTodayCommissionType : CloseTodayCommissionType;
if (commissionExchange != null)
{
if (double.TryParse(commissionExchange, out var CommissionExchange))
{
variety.CommissionExchange = CommissionExchange;
}
}
if (commissionDeviation != null)
{
if (double.TryParse(commissionDeviation, out var CommissionDeviation))
{
variety.CommissionDeviation = CommissionDeviation;
}
}
if (tradedOptionCommissionExchange != null)
{
if (double.TryParse(tradedOptionCommissionExchange, out var TradedOptionCommissionExchange))
{
variety.TradedOptionCommissionExchange = TradedOptionCommissionExchange;
}
}
if (tradedOptionCommissionDeviation != null)
{
if (double.TryParse(tradedOptionCommissionDeviation, out var TradedOptionCommissionDeviation))
{
variety.TradedOptionCommissionDeviation = TradedOptionCommissionDeviation;
}
}
if (closeTodayCommissionExchange != null)
{
if (double.TryParse(closeTodayCommissionExchange, out var CloseTodayCommissionExchange))
{
variety.CloseTodayCommissionExchange = CloseTodayCommissionExchange;
}
}
if (closeTodayCommissionDeviation != null)
{
if (double.TryParse(closeTodayCommissionDeviation, out var CloseTodayCommissionDeviation))
{
variety.CloseTodayCommissionDeviation = CloseTodayCommissionDeviation;
}
}
using (var db = DbContextFactory.GetErpBaseContext())
{
var dicId = db.Dictionaries.FirstOrDefault(o => o.Name == "品种类型").Id;
if (!db.DictionaryItems.Any(x => x.Name == variety.AssetType && x.DictId == dicId) && AssetType != null)
{
throw new ServiceException("未找到品种类型" + variety.AssetType);
}
}
var currency = DbContext.currency.FirstOrDefault(o => o.CurrencyCode == variety.QuoteCurrency);
if (currency == null && !string.IsNullOrEmpty(variety.QuoteCurrency))
{
throw new ServiceException("计价币种不存在,请先维护货币" + variety.QuoteCurrency);
}
else if (!string.IsNullOrEmpty(variety.QuoteCurrency))
{
if (variety.QuoteCurrency != "CNH" && variety.QuoteCurrency != "CNY")
{
variety.QuoteUnit = currency.CurrencyUnit + "/" + unit;
}
}
return variety;
}
public VarietyDto GetDetail(int id)
{
Variety va = DbContext.variety.AsNoTracking().FirstOrDefault(n => n.id == id);
if (va == null)
{
return null;
}
var dto = new VarietyDto();
ObjectHelper.MapValues(dto, va);
dto.HisDataList = DbContext.VarietyHisData.Where(n => n.VarietyId == id).OrderBy(n => n.ValueDate)
.Select(n => new HistoryData { Value = n.Value, ValueDate = n.ValueDate, ValueType = n.ValueType }).ToArray();
return dto;
}
/// <summary>
/// 保存数据
/// </summary>
public Variety SaveData(Variety reqModel)
{
Variety dbModel;
var isNew = reqModel.id == 0;
if (isNew)
{
dbModel = reqModel;
if (DbContext.variety.Any(o => o.VarietyName == reqModel.VarietyName))
{
throw new ServiceException("保存失败,已存在名为" + reqModel.VarietyName + "的品种");
}
DbContext.variety.Add(dbModel);
}
else
{
dbModel = DbContext.variety.Find(reqModel.id);
if (dbModel == null)
{
throw new ServiceException("保存失败,数据不存在");
}
UpdateChanges(dbModel, reqModel, "id");
}
var currency = DbContext.currency.FirstOrDefault(o => o.CurrencyCode == dbModel.QuoteCurrency);
if (currency == null && !string.IsNullOrEmpty(dbModel.QuoteCurrency))
{
throw new ServiceException("计价币种不存在,请先维护货币" + dbModel.QuoteCurrency);
}
dbModel.VarietyCode = dbModel.VarietyCode;
if (dbModel.CommissionType == ConsCommissionType.Ratio && dbModel.CommissionExchange.HasValue)
{
dbModel.CommissionExchange = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue(dbModel.CommissionExchange.Value / 10000, 8));
}
if (dbModel.CommissionType == ConsCommissionType.Ratio && dbModel.CommissionDeviation.HasValue)
{
dbModel.CommissionDeviation = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue(dbModel.CommissionDeviation.Value / 10000, 8));
}
if (dbModel.TradedOptionCommissionType == ConsCommissionType.Ratio && dbModel.TradedOptionCommissionExchange.HasValue)
{
dbModel.TradedOptionCommissionExchange = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue(dbModel.TradedOptionCommissionExchange.Value / 10000, 8));
}
if (dbModel.TradedOptionCommissionType == ConsCommissionType.Ratio && dbModel.TradedOptionCommissionDeviation.HasValue)
{
dbModel.TradedOptionCommissionDeviation = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue(dbModel.TradedOptionCommissionDeviation.Value / 10000, 8));
}
if (dbModel.CloseTodayCommissionType == ConsCommissionType.Ratio && dbModel.CloseTodayCommissionExchange.HasValue)
{
dbModel.CloseTodayCommissionExchange = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue(dbModel.CloseTodayCommissionExchange.Value / 10000, 8));
}
if (dbModel.CloseTodayCommissionType == ConsCommissionType.Ratio && dbModel.CloseTodayCommissionDeviation.HasValue)
{
dbModel.CloseTodayCommissionDeviation = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue(dbModel.CloseTodayCommissionDeviation.Value / 10000, 8));
}
if (dbModel.CommissionExchange.HasValue || dbModel.CommissionDeviation.HasValue)
{
dbModel.Commission = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue((dbModel.CommissionExchange ?? 0) + (dbModel.CommissionDeviation ?? 0), 8));
}
else
{
dbModel.Commission = null;
}
if (dbModel.TradedOptionCommissionExchange.HasValue || dbModel.TradedOptionCommissionDeviation.HasValue)
{
dbModel.TradedOptionCommission = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue((dbModel.TradedOptionCommissionExchange ?? 0) + (dbModel.TradedOptionCommissionDeviation ?? 0), 8));
}
else
{
dbModel.TradedOptionCommission = null;
}
if (dbModel.CloseTodayCommissionExchange.HasValue || dbModel.CloseTodayCommissionDeviation.HasValue)
{
dbModel.CloseTodayCommission = Convert.ToDouble(OtcFormatExtensions.OtcFormatValue((dbModel.CloseTodayCommissionExchange ?? 0) + (dbModel.CloseTodayCommissionDeviation ?? 0), 8));
}
else
{
dbModel.CloseTodayCommission = null;
}
dbModel.OptId = UserId;
dbModel.OptName = UserName;
dbModel.OptDate = DateTime.Now;
dbModel.DownLimit = dbModel.UpLimit;
//1.修改underlying的单位
var Underlyings = DbContext.underlying_manager.Where(o => o.CommodityCode == dbModel.VarietyCode);
if (Underlyings != null)
{
foreach (var item in Underlyings)
{
item.UnderlyingType = dbModel.VarietyName;
item.QuoteUnit = dbModel.QuoteUnitSingleOriginal;
item.TradeUnit = dbModel.TradeUnitSingle;
}
}
using (var trans = BeginTransaction())
{
DbContext.SaveChanges();
UpdateHisData(reqModel, isNew);
DbContext.SaveChanges();
trans.Commit();
}
new DicForTranslationModule.DicForTranslationService(OptUser).SetWordDictionary(dbModel);
return dbModel;
}
/// <summary>
/// 删除数据
/// </summary>
public void RemoveData(int id)
{
if (DbContext.client_variety_config.Any(x => x.VarietyId == id))
{
throw new ServiceException("收费配置包含该品种信息,不能被删除");
}
if (DbContext.client_variety_marginrate.Any(x => x.VarietyId == id))
{
throw new ServiceException("预付金维护包含该品种信息,不能被删除");
}
var va = DbContext.variety.Find(id);
if (va == null)
{
throw new ServiceException("找不到品种信息");
}
DbContext.variety.Remove(va);
var vvols = DbContext.variety_vol.Where(n => n.VarietyId == id).ToArray();
DbContext.variety_vol.RemoveRange(vvols);
var vhis = DbContext.VarietyHisData.Where(n => n.VarietyId == id).ToArray();
DbContext.VarietyHisData.RemoveRange(vhis);
DbContext.SaveChanges();
}
/// <summary>
/// 保存历史数据
/// </summary>
private void UpdateHisData(Variety newData, bool isNew)
{
var sysDate = valuedateBLL.ValueDate;
var newPara = MarginParamModel.Create(newData.Margin, newData.VolatilityRate, newData.UpLimit, false);
if (!string.IsNullOrWhiteSpace(newData.VolatilityRate) && !newPara.VolatilityRate.HasValue)
{
throw new ServiceException("解析Span波动率变动失败:" + newData.VolatilityRate);
}
if (!string.IsNullOrWhiteSpace(newData.UpLimit) && !newPara.UpDownLimit.HasValue)
{
throw new ServiceException("解析Span涨跌幅度失败:" + newData.UpLimit);
}
if (isNew)
{
DbContext.BulkDelete<VarietyHisData>($"{nameof(VarietyHisData.VarietyId)}='{newData.id}'");
}
var hisdataService = new VarietyHisDataService(this);
var valdate = isNew ? new DateTime(2000, 1, 1) : valuedateBLL.ValueDate;
hisdataService.AddOrUpdateHisData(new VarietyHisDataAddOrUpdateRequest
{
VarietyId = newData.id,
ValueType = nameof(MarginParamModel.MarginRate),
Value = newPara.MarginRate,
ValueDate = valdate
}, false);
hisdataService.AddOrUpdateHisData(new VarietyHisDataAddOrUpdateRequest
{
VarietyId = newData.id,
ValueType = nameof(MarginParamModel.VolatilityRate),
Value = newPara.VolatilityRate,
ValueDate = valdate
}, false);
hisdataService.AddOrUpdateHisData(new VarietyHisDataAddOrUpdateRequest
{
VarietyId = newData.id,
ValueType = nameof(MarginParamModel.UpDownLimit),
Value = newPara.UpDownLimit,
ValueDate = valdate
}, false);
}
}
}