namespace YLErp.Modules.VolatilityModule { /// /// 曲面波动率提供(适用于渤海因为没有考虑UserGroup) /// public class UnderlyingVolitalityProvider { protected readonly DateTime _valueDate; protected readonly string[] _volTypes; Dictionary _dicData; public UnderlyingVolitalityProvider(DateTime valueDate, IEnumerable 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( 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; } } }