502 lines
21 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|