159 lines
4.5 KiB
C#
159 lines
4.5 KiB
C#
using YLErp.Abstract;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.Models;
|
|
|
|
namespace YLErp.Modules.DataProviderModule
|
|
{
|
|
/// <summary>
|
|
/// 标的波动率数据提供
|
|
/// </summary>
|
|
class UnderlyingVolProvider : IDataUpdater, IJsonSerializable
|
|
{
|
|
const string KeySeparator = "[|]";
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public DateTime ValueDate { get; }
|
|
|
|
//波动率类型+合约代码做为KEY
|
|
readonly Dictionary<string, InnerVolatility> _dic;
|
|
|
|
static readonly InnerVolatility _removed;
|
|
|
|
public UnderlyingVolProvider(DateTime valueDate)
|
|
{
|
|
ValueDate = valueDate;
|
|
|
|
_dic = new Dictionary<string, InnerVolatility>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
static UnderlyingVolProvider()
|
|
{
|
|
_removed = new InnerVolatility();
|
|
}
|
|
|
|
public string TableName => nameof(volatility);
|
|
|
|
/// <summary>
|
|
/// 根据请求参数获取波动率
|
|
/// </summary>
|
|
public IVolatility GetVolatility(string voltype, string contractCode, string userGroup)
|
|
{
|
|
if (!ConsUserGroup.HasGroup)
|
|
{
|
|
userGroup = string.Empty;
|
|
}
|
|
else if (string.IsNullOrEmpty(userGroup))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(voltype) || string.IsNullOrWhiteSpace(contractCode))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var keyStr = string.Join(KeySeparator, new[] { contractCode, voltype, userGroup });
|
|
|
|
lock (_dic)
|
|
{
|
|
if (_dic.TryGetValue(keyStr, out var dicItem) && dicItem != _removed)
|
|
{
|
|
return dicItem;
|
|
}
|
|
}
|
|
|
|
volatility volData = null;
|
|
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
volData = db.volatility.AsNoTracking()
|
|
.Where(n => n.UserGroup == userGroup && n.ContractCode == contractCode && n.VolType == voltype && n.QuotationDate <= ValueDate)
|
|
.OrderByDescending(n => n.QuotationDate).FirstOrDefault();
|
|
|
|
if (volData == null)
|
|
{
|
|
lock (_dic)
|
|
{
|
|
_dic[keyStr] = null;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
var innerVol = new InnerVolatility
|
|
{
|
|
VolSurfaceMode = volData.VolSurfaceMode,
|
|
InterpolationMethod = volData.InterpolationMethod,
|
|
VolTable = volData.VolTable ?? new List<SingleVol>(0)
|
|
};
|
|
|
|
lock (_dic)
|
|
{
|
|
_dic[keyStr] = innerVol;
|
|
}
|
|
|
|
return innerVol;
|
|
}
|
|
|
|
public string ToJson()
|
|
{
|
|
lock (_dic)
|
|
{
|
|
return new { ValueDate, _dic }.ToJson();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新数据--使用直接删除的方式
|
|
/// </summary>
|
|
public void UpdateData(IEnumerable<string> updateKeyIds)
|
|
{
|
|
lock (_dic)
|
|
{
|
|
var removeArr = _dic.Where(n => n.Value == _removed);
|
|
|
|
foreach (var kv in removeArr)
|
|
{
|
|
_dic.Remove(kv.Key);
|
|
}
|
|
|
|
var set = new HashSet<string>(10, StringComparer.OrdinalIgnoreCase);
|
|
|
|
foreach (var keyId in updateKeyIds)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(keyId))
|
|
{
|
|
var strArr = keyId.Split(','); //id,ContractCode,VolType
|
|
|
|
if (strArr.Length > 2)
|
|
{
|
|
set.Add(string.Concat(strArr[1], KeySeparator, strArr[2]));
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var k in _dic.Keys)
|
|
{
|
|
var index = k.LastIndexOf(KeySeparator);
|
|
|
|
if (index > 0 && set.Contains(k.Substring(0, index)))
|
|
{
|
|
_dic[k] = _removed;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class InnerVolatility : IVolatility
|
|
{
|
|
public string VolSurfaceMode { get; set; }
|
|
|
|
public string InterpolationMethod { get; set; }
|
|
|
|
public List<SingleVol> VolTable { get; set; }
|
|
}
|
|
}
|
|
}
|