using YLErp.Abstract; using YLErp.DBModels.Consts; using YLErp.Models; namespace YLErp.Modules.DataProviderModule { /// /// 标的波动率数据提供 /// class UnderlyingVolProvider : IDataUpdater, IJsonSerializable { const string KeySeparator = "[|]"; /// /// /// public DateTime ValueDate { get; } //波动率类型+合约代码做为KEY readonly Dictionary _dic; static readonly InnerVolatility _removed; public UnderlyingVolProvider(DateTime valueDate) { ValueDate = valueDate; _dic = new Dictionary(StringComparer.OrdinalIgnoreCase); } static UnderlyingVolProvider() { _removed = new InnerVolatility(); } public string TableName => nameof(volatility); /// /// 根据请求参数获取波动率 /// 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(0) }; lock (_dic) { _dic[keyStr] = innerVol; } return innerVol; } public string ToJson() { lock (_dic) { return new { ValueDate, _dic }.ToJson(); } } /// /// 更新数据--使用直接删除的方式 /// public void UpdateData(IEnumerable updateKeyIds) { lock (_dic) { var removeArr = _dic.Where(n => n.Value == _removed); foreach (var kv in removeArr) { _dic.Remove(kv.Key); } var set = new HashSet(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 VolTable { get; set; } } } }