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

323 lines
12 KiB
C#

using Newtonsoft.Json;
using System.Data;
using YLErp.BLL;
namespace YLErp.Modules.UnderlyingModule
{
/// <summary>
/// 篮子标的信息管理服务
/// </summary>
public class BasketUnderlyingService : YLBaseService
{
public BasketUnderlyingService(YLBaseService baseService) : base(baseService)
{
}
public BasketUnderlyingService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 组合标的导入xlsx数据
/// </summary>
public BasketUnderlyingDto ImportBasketDatasFromExcel(Stream stream)
{
var result = new BasketUnderlyingDto();
try
{
//当前编码支持ansi和utf with bom
var ds = Office.ExcelHelper.ReadExcelAsDataSet(stream);
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1)
{
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
}
var table = ds.Tables[0];
List<BasketUnderlyingItem> list = new List<BasketUnderlyingItem>();
if (table.Rows.Count < 1)
{
throw new ServiceException("导入数据不能为空!");
}
var useWhiteCode = new StockBlackWhiteService(UserInfo).GetStockBlackWhiteList(Configuration.Enums.LimitRangeEnum.Swap, out var Codes);
foreach (DataRow row in table.Rows)
{
if (row.IsNull("标的代码") || row.IsNull("标的权重"))
{
throw new ServiceException("导入标的代码或标的权重不能为空!");
}
double price = 0;
BasketUnderlyingItem importModel = new BasketUnderlyingItem();
importModel.code = (string)row["标的代码"];
double.TryParse((row["标的权重"]?.ToString() ?? ""), out var weight);
importModel.weight = weight;
double.TryParse((row["标的份额"]?.ToString() ?? ""), out var notional);
importModel.notional = notional;
DataCacheProvider.GetUnderlyingDataSource().TryGetPrice(importModel.code, out price);
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(importModel.code);
if (underlying == null)
{
throw new ServiceException("标的代码不存在: " + importModel.code);
}
if (ConsGlobal.InstrumentType.IsStock(underlying.UnderlyingInstrumentType) && Codes != null && useWhiteCode == Codes.Contains(importModel.code))
{
throw new ServiceException($"标的代码:{importModel.code} {(useWhiteCode ? "存在于黑名单中" : "不在白名单中")}");
}
importModel.Price = price;
list.Add(importModel);
}
result.Items = list;
}
catch (Exception ex)
{
throw (ex.InnerException as ServiceException) ?? ex;
}
if (!result.Items.Any())
{
throw new ServiceException("没有可导入的数据");
}
return result;
}
/// <summary>
/// 保存篮子标的数据
/// </summary>
public int SaveBasketUnderlying(BasketUnderlyingDto model)
{
if (model is null)
{
throw new ArgumentNullException(nameof(model));
}
if (string.IsNullOrWhiteSpace(model.UnderlyingCode))
{
throw new ServiceException("别名不能为空");
}
if (DbContext.underlying_manager.Any(n => n.UnderlyingCode == model.UnderlyingCode))
{
throw new ServiceException("系统中已有重名的组合标的");
}
if (model.Items == null || !model.Items.Any())
{
throw new ServiceException("篮子标的列表没有任何数据");
}
if (model.Items.Any(n => string.IsNullOrWhiteSpace(n.code)))
{
throw new ServiceException("篮子标的列表中不应存在空白标的");
}
var isAddNew = model.id <= 0;
//----------------------------------
// 存入underlying_manager表
//----------------------------------
var variety = UnderlyingHelper.GetBasketVariety();
//----------------------------------
// 2020/5/14 获取组合标的的第一个标的
//----------------------------------
var underlyingCode1 = model.Items.First().code;
var underlying1 = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode1);
if (underlying1 == null)
{
throw new ServiceException("标的数据未找到:" + underlyingCode1);
}
// 篮子标的到期日
DateTime? MaturityDate = DateTime.MaxValue;
foreach (var item in model.Items)
{
DateTime? Date = DataCacheProvider.GetUnderlyingDataSource().GetData(item.code).MaturityDate;
MaturityDate = Date < MaturityDate ? Date : MaturityDate;
item.Price = null;
}
//----------------------------------
// 新增variety 如果没有该品种 则新增
//-------------
if (variety.id == 0)
{
variety = new Variety()
{
VarietyCode = "篮子标的",
VarietyName = "篮子标的",
OptId = model.OptId,
OptName = model.OptName,
OptDate = model.OptDate,
TradingMarketId = 0,
TradeUnit = "100股/手",
QuoteUnit = "元(人民币)/股",
DeliveryType = "",
HasNightMarket = false,
ShortName = "篮子标的",
CommissionType = "固定",
CloseTodayCommissionType = "固定",
//UnderlyingInstrumentType = "Stock",
VolatilityRate = "",
VolatilityAdjust = 0
};
DbContext.variety.Add(variety);
DbContext.SaveChanges();
}
underlying_manager underlying;
if (isAddNew)
{
underlying = new underlying_manager
{
UnderlyingCode = model.UnderlyingCode,
UnderlyingType = variety.VarietyName,
UnderlyingTypeId = variety.id,
UnderlyingName = model.UnderlyingCode,
CommodityCode = variety.VarietyCode,
OpenDate = DateTime.Today
};
DbContext.underlying_manager.Add(underlying);
}
else
{
underlying = DbContext.underlying_manager.FirstOrDefault(u => u.UnderlyingCode == model.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException("数据不存在:" + model.UnderlyingCode);
}
underlying.LaunchState = "1";
underlying.LastUpdateTime = OptDate;
}
underlying.SubData = JsonHelper.Stringify(model.Items);
underlying.OptId = UserId;
underlying.OptName = UserName;
underlying.OptDate = OptDate;
underlying.Price = 0;
underlying.MaturityDate = MaturityDate == DateTime.MaxValue ? null : MaturityDate;
underlying.UnderlyingState = "Live";
underlying.UnderlyingStatus = "正常运行";
underlying.MarketCode = underlying1.MarketCode;
underlying.UnderlyingInstrumentType = underlying1.UnderlyingInstrumentType;
//----------------------------------
//2020/5/14 使用组合标的的第一个标的为新添加的字段赋值
//----------------------------------
underlying.TradeUnit = underlying1.TradeUnit;
underlying.QuoteUnit = underlying1.QuoteUnit;
underlying.MarketName = underlying1.MarketName;
if (string.IsNullOrEmpty(underlying.TradeUnit))
{
underlying.TradeUnit = "份";
}
DbContext.SaveChanges();
//----------------------------------
// 新增underlying_parameter
//----------------------------------
var underlyingParams = DbContext.underlying_parameter.Where(u => u.UnderlyingId == underlying.id).ToList();
//如果没有报价参数,则新增
if (underlyingParams.Count == 0)
{
underlying_parameter.defaultQuoteTypes.ForEach(t =>
{
var up = new underlying_parameter()
{
NoRiskRate = valuedateBLL.SystemDate.RiskFreeRate * 0.01,
Price = 0,
Gamma = 0,
Rho = 0,
Vega = 0,
Theta = 0,
Delta = 0,
UnderlyingId = underlying.id,
Type = t,
OptDate = DateTime.Now,
OptId = model.OptId,
OptName = model.OptName
};
DbContext.underlying_parameter.Add(up);
underlyingParams.Add(up);
});
}
//最后调用保存以保证事物完整性
return DbContext.SaveChanges();
}
/// <summary>
/// 篮子标的查看
/// </summary>
public BasketUnderlyingDto GetBasketUnderlyingByName(string name)
{
var query = from u in DbContext.underlying_manager.AsEnumerable()
where u.UnderlyingCode == name
select new BasketUnderlyingDto
{
Items = JsonConvert.DeserializeObject<List<BasketUnderlyingItem>>(u.SubData),
};
var res = query.FirstOrDefault();
double price = 0;
foreach (var item in res.Items)
{
DataCacheProvider.GetUnderlyingDataSource().TryGetPrice(item.code, out price);
item.Price = price;
}
return res;
}
}
/// <summary>
///
/// </summary>
public class BasketUnderlyingDto : UnderlyingManagerDto
{
/// <summary>
/// 篮子标的项目
/// </summary>
public IEnumerable<BasketUnderlyingItem> Items { get; set; }
}
/// <summary>
/// 篮子标的合成项
/// </summary>
public class BasketUnderlyingItem
{
public double? Price { get; set; }
/// <summary>
/// 权重
/// </summary>
public double weight { get; set; }
/// <summary>
/// 份额
/// </summary>
public double notional { get; set; }
/// <summary>
/// 标的代码
/// </summary>
public string code { get; set; }
}
}