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

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;
}
}
}