691 lines
28 KiB
C#
691 lines
28 KiB
C#
using System.Data;
|
|
using YieldChain.Helpers;
|
|
using YLErp.BLL;
|
|
using YLErp.DBModels.Helpers;
|
|
using YLErp.Model;
|
|
using YLErp.Models;
|
|
|
|
namespace YLErp.Modules.UnderlyingModule
|
|
{
|
|
/// <summary>
|
|
/// 标的数据操作服务
|
|
/// </summary>
|
|
public class UnderlyingDalService : YLBaseService
|
|
{
|
|
public UnderlyingDalService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取数据详情
|
|
/// </summary>
|
|
public UnderlyingManagerDto GetDetail(int id)
|
|
{
|
|
var um = DbContext.underlying_manager.AsNoTracking().FirstOrDefault(n => n.id == id);
|
|
if (um == null)
|
|
{
|
|
return null;
|
|
}
|
|
var dto = new UnderlyingManagerDto();
|
|
ObjectHelper.MapValues(dto, um);
|
|
dto.HisDataList = DbContext.UnderlyingHisData.Where(n => n.UnderlyingCode == um.UnderlyingCode)
|
|
.OrderBy(n => n.ValueDate)
|
|
.Select(n => new HistoryData { Value = n.Value, ValueDate = n.ValueDate, ValueType = n.ValueType, ValueFlag = n.ValueFlag }).ToArray();
|
|
return dto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有有效的商品期货标的
|
|
/// </summary>
|
|
public IEnumerable<string> GetAllValidCommodityFutureCodes(DateTime minMaturityDate)
|
|
{
|
|
var datas = DbContext.underlying_manager.Where(n => n.MaturityDate >= minMaturityDate &&
|
|
n.UnderlyingInstrumentType == "CommodityFutures" &&
|
|
n.UnderlyingCode != null && n.UnderlyingType != "组合标的")
|
|
.Select(n => n.UnderlyingCode).ToArray();
|
|
Array.Sort(datas);
|
|
return datas;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存组合标的数据
|
|
/// </summary>
|
|
public int SaveSyntheticUnderlying(SyntheticUnderlyingDto reqModel, out SyntheticUnderlying dbModel)
|
|
{
|
|
if (reqModel is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(reqModel));
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(reqModel.Name))
|
|
{
|
|
throw new ServiceException("合成标的代码 不能为空");
|
|
}
|
|
|
|
if (DbContext.synthetic_underlying.Any(n => n.Name == reqModel.Name && n.id != reqModel.id))
|
|
{
|
|
throw new ServiceException("合成标的代码 已经存在");
|
|
}
|
|
|
|
var isAddNew = reqModel.id <= 0;
|
|
|
|
dbModel = null;
|
|
|
|
if (isAddNew)
|
|
{
|
|
DbContext.synthetic_underlying.Add(dbModel = new SyntheticUnderlying());
|
|
}
|
|
else
|
|
{
|
|
dbModel = DbContext.synthetic_underlying.FirstOrDefault(n => n.Name == reqModel.UnderlyingTipsInfo);
|
|
|
|
if (dbModel == null)
|
|
{
|
|
isAddNew = true;
|
|
DbContext.synthetic_underlying.Add(dbModel = new SyntheticUnderlying());
|
|
reqModel.id = 0;
|
|
}
|
|
else if (DbContext.trade.Any(trade => trade.UnderlyingCode == reqModel.UnderlyingTipsInfo && trade.ValidState != ConsGlobal.InValid))
|
|
{
|
|
throw new ServiceException("系统存在使用此组合标的的交易,不能修改");
|
|
}
|
|
}
|
|
if (isAddNew && DbContext.underlying_manager.Any(n => n.UnderlyingCode == reqModel.UnderlyingTipsInfo))
|
|
{
|
|
throw new ServiceException("当前组合标的的标的代码在系统中已经存在,无法重复新增");
|
|
}
|
|
|
|
//复制值
|
|
DbContext.Entry(dbModel).CurrentValues.SetValues(reqModel);
|
|
dbModel.Name = dbModel.UnderlyingTipsInfo;
|
|
|
|
//----------------------------------
|
|
// 获取最小的到期日
|
|
//----------------------------------
|
|
var underlyingCodes = new string[] {
|
|
dbModel.UnderlyingCode1.TrimToNull(),
|
|
dbModel.UnderlyingCode2.TrimToNull(),
|
|
dbModel.UnderlyingCode3.TrimToNull(),
|
|
dbModel.UnderlyingCode4.TrimToNull(),
|
|
};
|
|
|
|
underlyingCodes = underlyingCodes.Where(n => !string.IsNullOrEmpty(n)).ToArray();
|
|
|
|
var underlyings = DbContext.underlying_manager
|
|
.Where(u => underlyingCodes.Contains(u.UnderlyingCode))
|
|
.Select(u => new
|
|
{
|
|
u.UnderlyingCode,
|
|
u.MaturityDate,
|
|
u.TradeUnit,
|
|
u.QuoteUnit,
|
|
u.UnderlyingInstrumentType,
|
|
u.MarketCode,
|
|
u.MarketName
|
|
}).ToArray();
|
|
|
|
if (underlyings.Length != underlyingCodes.Length)
|
|
{
|
|
var missingCode = underlyingCodes.Where(n => !underlyings.Any(m => n.Equals(m.UnderlyingCode, StringComparison.OrdinalIgnoreCase))).ToArray();
|
|
throw new ServiceException("标的数据未找到:" + string.Join(",", missingCode));
|
|
}
|
|
|
|
DateTime? maturityDate = null;
|
|
|
|
var underlying1 = underlyings.FirstOrDefault(n => ConsGlobal.InstrumentType.CalcTypeIsFutures(n.UnderlyingInstrumentType));
|
|
if (underlying1 == null)
|
|
{
|
|
underlying1 = underlyings.First();
|
|
}
|
|
else
|
|
{
|
|
maturityDate = underlyings.Where(n => ConsGlobal.InstrumentType.CalcTypeIsFutures(n.UnderlyingInstrumentType) && n.MaturityDate.HasValue)
|
|
.Min(n => n.MaturityDate);
|
|
}
|
|
|
|
underlying_manager underlying;
|
|
|
|
if (isAddNew)
|
|
{
|
|
underlying = new underlying_manager
|
|
{
|
|
UnderlyingCode = dbModel.UnderlyingTipsInfo,
|
|
|
|
MaturityDate = maturityDate,
|
|
UnderlyingState = "Live",
|
|
UnderlyingDesc = "组合标的",
|
|
OptId = dbModel.OptId,
|
|
OptName = dbModel.OptName,
|
|
OptDate = dbModel.OptDate,
|
|
CommodityCode = "组合标的",
|
|
UnderlyingType = "组合标的",
|
|
|
|
UnderlyingName = reqModel.Name,
|
|
UnderlyingInstrumentType = underlying1.UnderlyingInstrumentType,
|
|
|
|
Price = 0,
|
|
LaunchState = "1",
|
|
LastUpdateTime = dbModel.OptDate,
|
|
UnderlyingStatus = "正常运行",
|
|
|
|
VolatilityRate = reqModel.VolatilityRate,
|
|
UpDownLimit = reqModel.UpDownLimit,
|
|
MarginRate = reqModel.MarginRate,
|
|
ContractSize = reqModel.ContractSize ?? 0,
|
|
|
|
//----------------------------------
|
|
//2020/5/14 使用组合标的的第一个标的为新添加的字段赋值
|
|
//----------------------------------
|
|
TradeUnit = underlying1.TradeUnit,
|
|
QuoteUnit = underlying1.QuoteUnit,
|
|
MarketCode = underlying1.MarketCode,
|
|
MarketName = underlying1.MarketName,
|
|
|
|
OpenDate = DateTime.Today
|
|
};
|
|
|
|
if (string.IsNullOrWhiteSpace(underlying.TradeUnit))
|
|
{
|
|
underlying.TradeUnit = "份";
|
|
}
|
|
|
|
DbContext.underlying_manager.Add(underlying);
|
|
|
|
UpdateHisData(underlying, true);
|
|
}
|
|
else
|
|
{
|
|
var UnderlyingCodestr = dbModel.Name;
|
|
underlying = DbContext.underlying_manager.FirstOrDefault(u => u.UnderlyingCode == UnderlyingCodestr);
|
|
|
|
underlying.MaturityDate = maturityDate;
|
|
underlying.UnderlyingState = "Live";
|
|
underlying.UnderlyingInstrumentType = underlying1.UnderlyingInstrumentType;
|
|
underlying.Price = 0;
|
|
underlying.LaunchState = "1";
|
|
underlying.LastUpdateTime = dbModel.OptDate;
|
|
underlying.UnderlyingStatus = "正常运行";
|
|
|
|
underlying.VolatilityRate = reqModel.VolatilityRate;
|
|
underlying.UpDownLimit = reqModel.UpDownLimit;
|
|
underlying.MarginRate = reqModel.MarginRate;
|
|
underlying.ContractSize = reqModel.ContractSize ?? 0;
|
|
|
|
//----------------------------------
|
|
//2020/5/14 使用组合标的的第一个标的为新添加的字段赋值
|
|
//----------------------------------
|
|
underlying.TradeUnit = underlying1.TradeUnit;
|
|
underlying.QuoteUnit = underlying1.QuoteUnit;
|
|
underlying.MarketCode = underlying1.MarketCode;
|
|
underlying.MarketName = underlying1.MarketName;
|
|
underlying.UnderlyingName = reqModel.Name;
|
|
|
|
if (string.IsNullOrWhiteSpace(underlying.TradeUnit))
|
|
{
|
|
underlying.TradeUnit = "份";
|
|
}
|
|
|
|
UpdateHisData(underlying, false);
|
|
}
|
|
|
|
underlying.UnderlyingTypeId = UnderlyingHelper.GetSyntheticVariety().id;
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
//----------------------------------
|
|
// 新增underlying_parameter
|
|
//----------------------------------
|
|
|
|
var underlying_params = DbContext.underlying_parameter.Where(u => u.UnderlyingId == underlying.id).ToList();
|
|
|
|
//如果没有报价参数,则新增
|
|
if (underlying_params.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 = reqModel.OptId,
|
|
OptName = reqModel.OptName
|
|
};
|
|
DbContext.underlying_parameter.Add(up);
|
|
underlying_params.Add(up);
|
|
});
|
|
}
|
|
|
|
//最后调用保存以保证事物完整性
|
|
return DbContext.SaveChanges();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有有效的组合标的
|
|
/// </summary>
|
|
public IEnumerable<SyntheticUnderlying> GetAllValidSyntheticUnderlyings()
|
|
{
|
|
var queryU = from u in DbContext.underlying_manager
|
|
where u.UnderlyingState != "Matured" && u.LaunchState == "1"
|
|
select new { u.id };
|
|
|
|
var date = DateTime.Today;
|
|
var query = from u in DbContext.underlying_manager
|
|
join su in DbContext.synthetic_underlying on u.UnderlyingCode equals su.Name
|
|
where u.MaturityDate >= date && u.UnderlyingType == "组合标的"
|
|
&& (su.UnderlyingId1 == null || su.UnderlyingId1 == 0 || queryU.Any(n => n.id == su.UnderlyingId1))
|
|
&& (su.UnderlyingId2 == null || su.UnderlyingId2 == 0 || queryU.Any(n => n.id == su.UnderlyingId2))
|
|
&& (su.UnderlyingId3 == null || su.UnderlyingId3 == 0 || queryU.Any(n => n.id == su.UnderlyingId3))
|
|
&& (su.UnderlyingId4 == null || su.UnderlyingId4 == 0 || queryU.Any(n => n.id == su.UnderlyingId4))
|
|
select su;
|
|
return query.ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public SyntheticUnderlyingDto GetSyntheticUnderlyingByName(string name)
|
|
{
|
|
var query = from u in DbContext.underlying_manager
|
|
join su in DbContext.synthetic_underlying on u.UnderlyingCode equals su.Name
|
|
where u.UnderlyingCode == name
|
|
select new SyntheticUnderlyingDto
|
|
{
|
|
id = su.id,
|
|
Coefficient1 = su.Coefficient1,
|
|
Coefficient2 = su.Coefficient2,
|
|
Coefficient3 = su.Coefficient3,
|
|
Coefficient4 = su.Coefficient4,
|
|
Constant = su.Constant,
|
|
ContractSize = su.ContractSize,
|
|
|
|
Name = su.Name,
|
|
OptDate = su.OptDate,
|
|
OptId = su.OptId,
|
|
OptName = su.OptName,
|
|
UnderlyingCode1 = su.UnderlyingCode1,
|
|
UnderlyingCode2 = su.UnderlyingCode2,
|
|
UnderlyingCode3 = su.UnderlyingCode3,
|
|
UnderlyingCode4 = su.UnderlyingCode4,
|
|
UnderlyingId1 = su.UnderlyingId1,
|
|
UnderlyingId2 = su.UnderlyingId2,
|
|
UnderlyingId3 = su.UnderlyingId3,
|
|
UnderlyingId4 = su.UnderlyingId4,
|
|
|
|
MarginRate = u.MarginRate,
|
|
UpDownLimit = u.UpDownLimit,
|
|
VolatilityRate = u.VolatilityRate,
|
|
UnderlyingName = u.UnderlyingName
|
|
};
|
|
|
|
return query.FirstOrDefault();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存标的数据
|
|
/// </summary>
|
|
public underlying_manager SaveUnderlyingData(underlying_manager req)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(req.UnderlyingCode))
|
|
{
|
|
throw new ServiceException("标的资产码 必须填写!");
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(req.UnderlyingName))
|
|
{
|
|
throw new ServiceException("标的名称 必须填写!");
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(req.UnderlyingInstrumentType))
|
|
{
|
|
throw new ServiceException("资产类型 必须填写!");
|
|
}
|
|
|
|
if (req.UnderlyingTypeId < 1)
|
|
{
|
|
throw new ServiceException("资产品种类型 必须填写!");
|
|
}
|
|
|
|
if (req.IsFutures())
|
|
{
|
|
if (!req.MaturityDate.HasValue)
|
|
{
|
|
throw new ServiceException("期货标的到期日期 必须填写!");
|
|
}
|
|
|
|
if (req.MaturityDate.Value.Year < 2000)
|
|
{
|
|
throw new ServiceException("期货标的到期日期 填写错误!");
|
|
}
|
|
|
|
if (req.MaturityDate.Value < DateTime.Today)
|
|
{
|
|
req.UnderlyingState = "Matured";
|
|
}
|
|
}
|
|
|
|
//if (DataCacheProvider.GetStockBlackWhiteDataSource().AsQueryable().Any(
|
|
// n => n.UnderlyingCode == req.UnderlyingCode && n.BlackWhiteState == 0))
|
|
//{
|
|
// throw new ServiceException("此标的存在于黑名单中,无法新增和修改");
|
|
//}
|
|
|
|
//判断是否重复标的
|
|
if (DbContext.underlying_manager.Any(d => d.UnderlyingCode == req.UnderlyingCode && d.id != req.id))
|
|
{
|
|
throw new ServiceException("标的资产码重复");
|
|
}
|
|
|
|
underlying_manager dbModel;
|
|
|
|
var isNew = req.id == 0;
|
|
|
|
if (isNew)
|
|
{
|
|
dbModel = req;
|
|
if (typeof(underlying_manager) != req.GetType())
|
|
{
|
|
dbModel = new underlying_manager();
|
|
ObjectHelper.MapValues(dbModel, req);
|
|
}
|
|
dbModel.Price = underlying_manager.DefaultSpotPrice;
|
|
// 新增标的默认启用
|
|
dbModel.LaunchState = "1";
|
|
DbContext.underlying_manager.Add(dbModel);
|
|
}
|
|
else
|
|
{
|
|
dbModel = DbContext.underlying_manager.Find(req.id);
|
|
if (dbModel == null)
|
|
{
|
|
throw new ServiceException("保存失败,数据不存在");
|
|
}
|
|
UpdateChanges(dbModel, req, new[] {
|
|
nameof(underlying_manager.id) ,
|
|
//nameof(underlying_manager.Price) ,
|
|
nameof(underlying_manager.PrevClosePrice) ,
|
|
nameof(underlying_manager.LaunchState) ,
|
|
nameof(underlying_manager.LastUpdateTime)
|
|
});
|
|
}
|
|
|
|
dbModel.OptId = UserId;
|
|
dbModel.OptName = UserName;
|
|
dbModel.OptDate = DateTime.Now;
|
|
|
|
//更新关联表
|
|
var variety = DbContext.variety.Find(dbModel.UnderlyingTypeId);
|
|
|
|
if (variety != null)
|
|
{
|
|
dbModel.UnderlyingType = variety.VarietyName;
|
|
dbModel.CommodityCode = variety.VarietyCode;
|
|
dbModel.QuoteUnit = variety.QuoteUnitSingleOriginal;
|
|
dbModel.TradeUnit = variety.TradeUnitSingle;
|
|
if (string.IsNullOrWhiteSpace(req.MarketCode))
|
|
{
|
|
dbModel.MarketName = variety.TradingMarket;
|
|
dbModel.MarketCode = string.IsNullOrWhiteSpace(dbModel.MarketName) ? "" :
|
|
DataCacheProvider.GetMarketDataSource().AsQueryable().FirstOrDefault(n => n.MarketName == dbModel.MarketName)?.ExchangeNo;
|
|
}
|
|
if (dbModel.ContractSize <= 1)
|
|
{
|
|
dbModel.ContractSize = variety.TradeUnitValue > 0 ? variety.TradeUnitValue.Value : 1;
|
|
}
|
|
if (dbModel.PriceTick < 1e-5)
|
|
{
|
|
dbModel.PriceTick = VarietyHelper.ParseMinPriceChange(variety.MinPriceChange) ?? 0.01;
|
|
}
|
|
}
|
|
if (!string.IsNullOrWhiteSpace(req.MarketCode))
|
|
{
|
|
dbModel.MarketName = string.IsNullOrWhiteSpace(dbModel.MarketCode) ? "" :
|
|
DataCacheProvider.GetMarketDataSource().AsQueryable().FirstOrDefault(n => n.ExchangeNo == dbModel.MarketCode)?.MarketName;
|
|
}
|
|
if (dbModel.CalcTypeIsStock())
|
|
{
|
|
dbModel.MaturityDate = null;
|
|
}
|
|
|
|
UpdateHisData(req, isNew);
|
|
|
|
DbContext.SaveChanges();
|
|
new DicForTranslationModule.DicForTranslationService(OptUser).SetWordDictionary(req);
|
|
|
|
return dbModel;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存标的数据
|
|
/// </summary>
|
|
public IEnumerable<underlying_manager> SaveUnderlyingData(IEnumerable<underlying_manager> reqs)
|
|
{
|
|
if (reqs.Any(O => string.IsNullOrWhiteSpace(O.UnderlyingCode)))
|
|
{
|
|
throw new ServiceException("标的资产码 必须填写!");
|
|
}
|
|
|
|
if (reqs.Any(O => string.IsNullOrWhiteSpace(O.UnderlyingName)))
|
|
{
|
|
throw new ServiceException("标的名称 必须填写!");
|
|
}
|
|
|
|
if (reqs.Any(O => string.IsNullOrWhiteSpace(O.UnderlyingInstrumentType)))
|
|
{
|
|
throw new ServiceException("资产类型 必须填写!");
|
|
}
|
|
|
|
if (reqs.Any(O => O.UnderlyingTypeId < 1))
|
|
{
|
|
throw new ServiceException("资产品种类型 必须填写!");
|
|
}
|
|
|
|
if (reqs.Any(O => O.IsFutures() && !O.MaturityDate.HasValue))
|
|
{
|
|
throw new ServiceException("期货标的到期日期 必须填写!");
|
|
}
|
|
|
|
if (reqs.Any(O => O.IsFutures() && O.MaturityDate.Value.Year < 2000))
|
|
{
|
|
throw new ServiceException("期货标的到期日期 填写错误!");
|
|
}
|
|
|
|
if (reqs.Where(O => O.IsFutures() && O.MaturityDate.Value < DateTime.Today).ToList() is List<underlying_manager> um)
|
|
{
|
|
um.ForEach(O => O.UnderlyingState = "Matured");
|
|
}
|
|
List<string> underlyingCode_New = reqs.Where(O => O.id < 1).Select(O => O.UnderlyingCode).ToList();
|
|
if (DataCacheProvider.GetStockBlackWhiteDataSource().AsQueryable().Any(
|
|
n => underlyingCode_New.Contains(n.UnderlyingCode) && n.BlackWhiteState == 0))
|
|
{
|
|
throw new ServiceException("此标的存在于黑名单中,无法新增和修改");
|
|
}
|
|
|
|
//判断是否重复标的
|
|
if (underlyingCode_New.Distinct().Count() != underlyingCode_New.Count || DbContext.underlying_manager.Any(d => underlyingCode_New.Contains(d.UnderlyingCode)))
|
|
{
|
|
throw new ServiceException("标的资产码重复");
|
|
}
|
|
foreach (var req in reqs)
|
|
{
|
|
underlying_manager dbModel;
|
|
|
|
var isNew = req.id == 0;
|
|
|
|
if (isNew)
|
|
{
|
|
dbModel = req;
|
|
dbModel.Price = underlying_manager.DefaultSpotPrice;
|
|
DbContext.underlying_manager.Add(dbModel);
|
|
}
|
|
else
|
|
{
|
|
dbModel = DbContext.underlying_manager.Find(req.id);
|
|
if (dbModel == null)
|
|
{
|
|
throw new ServiceException("保存失败,数据不存在");
|
|
}
|
|
UpdateChanges(dbModel, req, new[] {
|
|
nameof(underlying_manager.id) ,
|
|
nameof(underlying_manager.Price) ,
|
|
nameof(underlying_manager.PrevClosePrice) ,
|
|
nameof(underlying_manager.LaunchState) ,
|
|
nameof(underlying_manager.LastUpdateTime)
|
|
});
|
|
}
|
|
|
|
dbModel.OptId = UserId;
|
|
dbModel.OptName = UserName;
|
|
dbModel.OptDate = DateTime.Now;
|
|
dbModel.MarketName = string.IsNullOrWhiteSpace(dbModel.MarketCode) ? "" :
|
|
DataCacheProvider.GetMarketDataSource().AsQueryable().FirstOrDefault(n => n.ExchangeNo == dbModel.MarketCode)?.MarketName;
|
|
|
|
//更新关联表
|
|
var variety = DataCacheProvider.GetVarietyDataSource().GetData(dbModel.UnderlyingTypeId);
|
|
|
|
if (variety != null)
|
|
{
|
|
dbModel.UnderlyingType = variety.VarietyName;
|
|
dbModel.CommodityCode = variety.VarietyCode;
|
|
dbModel.QuoteUnit = variety.QuoteUnitSingleOriginal;
|
|
dbModel.TradeUnit = variety.TradeUnitSingle;
|
|
if (dbModel.ContractSize <= 1)
|
|
{
|
|
dbModel.ContractSize = variety.TradeUnitValue ?? 0;
|
|
}
|
|
if (dbModel.PriceTick < 1e-5)
|
|
{
|
|
dbModel.PriceTick = VarietyHelper.ParseMinPriceChange(variety.MinPriceChange) ?? 0.01;
|
|
}
|
|
}
|
|
|
|
if (dbModel.CalcTypeIsStock())
|
|
{
|
|
dbModel.MaturityDate = null;
|
|
}
|
|
|
|
UpdateHisData(req, isNew);
|
|
}
|
|
DbContext.SaveChanges();
|
|
return reqs;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存标的历史数据
|
|
/// </summary>
|
|
private void UpdateHisData(underlying_manager newData, bool isNewUnderlying)
|
|
{
|
|
var newPara = MarginParamModel.Create(newData.MarginRate, newData.VolatilityRate, newData.UpDownLimit, true);
|
|
|
|
if (!string.IsNullOrWhiteSpace(newData.VolatilityRate) && !newPara.VolatilityRate.HasValue)
|
|
{
|
|
throw new ServiceException("解析Span波动率变动失败:" + newData.VolatilityRate);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(newData.UpDownLimit) && !newPara.UpDownLimit.HasValue)
|
|
{
|
|
throw new ServiceException("解析Span涨跌幅度失败:" + newData.UpDownLimit);
|
|
}
|
|
|
|
if (isNewUnderlying)
|
|
{
|
|
DbContext.BulkDelete<UnderlyingHisData>($"{nameof(UnderlyingHisData.UnderlyingCode)}='{newData.UnderlyingCode}'");
|
|
}
|
|
|
|
var hisdataService = new UnderlyingHisDataService(this);
|
|
var valdate = isNewUnderlying ? new DateTime(2000, 1, 1) : valuedateBLL.ValueDate;
|
|
|
|
hisdataService.AddOrUpdateHisData(new UnderlyingHisDataAddOrUpdateRequest
|
|
{
|
|
UnderlyingCode = newData.UnderlyingCode,
|
|
ValueType = nameof(MarginParamModel.MarginRate),
|
|
Value = newPara.MarginRate,
|
|
ValueDate = valdate,
|
|
ValueFlag = "F"
|
|
}, false);
|
|
|
|
hisdataService.AddOrUpdateHisData(new UnderlyingHisDataAddOrUpdateRequest
|
|
{
|
|
UnderlyingCode = newData.UnderlyingCode,
|
|
ValueType = nameof(MarginParamModel.VolatilityRate),
|
|
Value = newPara.VolatilityRate,
|
|
ValueDate = valdate,
|
|
ValueFlag = "F"
|
|
}, false);
|
|
|
|
hisdataService.AddOrUpdateHisData(new UnderlyingHisDataAddOrUpdateRequest
|
|
{
|
|
UnderlyingCode = newData.UnderlyingCode,
|
|
ValueType = nameof(MarginParamModel.UpDownLimit),
|
|
Value = newPara.UpDownLimit,
|
|
ValueDate = valdate,
|
|
ValueFlag = newPara.IsUpDownLimitFixed ? "F" : "%"
|
|
}, false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新数据
|
|
/// </summary>
|
|
public int UpdateData(string UnderlyingCode, double? MarginRate, string VolatilityRate, string UpDownLimit)
|
|
{
|
|
if (UnderlyingCode is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(UnderlyingCode));
|
|
}
|
|
|
|
var underlying = DbContext.underlying_manager.FirstOrDefault(u => u.UnderlyingCode == UnderlyingCode);
|
|
if (underlying == null)
|
|
{
|
|
throw new ServiceException("系统中没有相关的标的:" + UnderlyingCode);
|
|
}
|
|
if (underlying.IsSynthetic())
|
|
{
|
|
underlying.UnderlyingTypeId = UnderlyingHelper.GetSyntheticVariety().id;
|
|
}
|
|
underlying.MarginRate = MarginRate;
|
|
underlying.VolatilityRate = VolatilityRate;
|
|
underlying.UpDownLimit = UpDownLimit;
|
|
UpdateHisData(underlying, false);
|
|
return DbContext.SaveChanges();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除合成标的
|
|
/// </summary>
|
|
public int RemoveSyntheticUnderlyingByName(string syntheticUnderlyingName)
|
|
{
|
|
if (syntheticUnderlyingName is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(syntheticUnderlyingName));
|
|
}
|
|
|
|
if (DbContext.trade.Any(trade => trade.UnderlyingCode == syntheticUnderlyingName && trade.ValidState != ConsGlobal.InValid))
|
|
{
|
|
throw new ServiceException("系统存在使用此组合标的的交易,不能修改");
|
|
}
|
|
|
|
var synModel = DbContext.synthetic_underlying.FirstOrDefault(n => n.Name == syntheticUnderlyingName);
|
|
var unModel = DbContext.underlying_manager.FirstOrDefault(n => n.UnderlyingCode == syntheticUnderlyingName);
|
|
|
|
if (unModel != null)
|
|
{
|
|
DbContext.underlying_manager.Remove(unModel);
|
|
}
|
|
|
|
if (synModel != null)
|
|
{
|
|
DbContext.synthetic_underlying.Remove(synModel);
|
|
}
|
|
|
|
return DbContext.SaveChanges();
|
|
}
|
|
}
|
|
}
|