114 lines
3.9 KiB
C#
114 lines
3.9 KiB
C#
namespace YLErp.Modules.VolatilityModule
|
|
{
|
|
/// <summary>
|
|
/// 曲面波动率提供(适用于渤海因为没有考虑UserGroup)
|
|
/// </summary>
|
|
public class UnderlyingVolitalityProvider
|
|
{
|
|
protected readonly DateTime _valueDate;
|
|
protected readonly string[] _volTypes;
|
|
|
|
Dictionary<string, volatility> _dicData;
|
|
|
|
public UnderlyingVolitalityProvider(DateTime valueDate, IEnumerable<string> volTypes)
|
|
{
|
|
if (volTypes == null || !volTypes.Any(n => !string.IsNullOrEmpty(n)))
|
|
{
|
|
_volTypes = new[] { "交易" };
|
|
}
|
|
else
|
|
{
|
|
_volTypes = volTypes.Where(n => !string.IsNullOrEmpty(n)).ToArray();
|
|
}
|
|
_valueDate = valueDate.Date;
|
|
}
|
|
|
|
private void Initialize()
|
|
{
|
|
if (_dicData != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lock (this)
|
|
{
|
|
if (_dicData != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//只取1个月以内的
|
|
var startDate = _valueDate.AddMonths(-3);
|
|
|
|
var predicate = PredicateBuilder.Create<volatility>(
|
|
v => v.QuotationDate >= startDate && v.QuotationDate <= _valueDate && _volTypes.Contains(v.VolType));
|
|
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
//数据量小的表尽量靠前
|
|
var groupQuery = from v in db.volatility.Where(predicate)
|
|
group v by new { v.UserGroup, v.ContractCode, v.VolType } into vg
|
|
select new
|
|
{
|
|
vg.Key.UserGroup,
|
|
vg.Key.ContractCode,
|
|
vg.Key.VolType,
|
|
QuotationDate = vg.Max(n => n.QuotationDate)
|
|
};
|
|
|
|
var volQuery = from vg in groupQuery
|
|
join v in db.volatility.AsNoTracking()
|
|
on vg equals new { v.UserGroup, v.ContractCode, v.VolType, v.QuotationDate }
|
|
select v;
|
|
|
|
_dicData = volQuery.ToDictionary(n =>
|
|
{
|
|
var index = Array.IndexOf(_volTypes, n.VolType);
|
|
return $"{index}^{n.UserGroup}^{n.ContractCode}";
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public volatility GetVol(string volType, string userGroup, string underlyingCode)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(volType) || string.IsNullOrWhiteSpace(underlyingCode))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (userGroup is null)
|
|
{
|
|
userGroup = string.Empty;
|
|
}
|
|
|
|
var index = Array.IndexOf(_volTypes, volType);
|
|
|
|
if (index < 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Initialize();
|
|
|
|
var key = $"{index}^{userGroup}^{underlyingCode}";
|
|
|
|
if (!_dicData.TryGetValue(key, out var unVol))
|
|
{
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var volQuery = from v in db.volatility.AsNoTracking()
|
|
where v.ContractCode == underlyingCode && v.UserGroup == userGroup
|
|
&& v.QuotationDate <= _valueDate && _volTypes.Contains(v.VolType)
|
|
orderby v.QuotationDate descending
|
|
select v;
|
|
|
|
_dicData[key] = unVol = volQuery.FirstOrDefault();
|
|
}
|
|
}
|
|
|
|
return unVol;
|
|
}
|
|
}
|
|
}
|