using YieldChain.Commons; using YLErp.Abstract.DataProviders; using YLErp.Models; namespace YLErp.Modules.DataProviderModule { /// /// 期权现价提供 /// public class ExchangeOptionPriceProvider : IPriceProvider { readonly bool _initializeAll; readonly IDictionary _priceDic; /// /// /// /// 是否初始化全部数据 public ExchangeOptionPriceProvider(bool initializeAll = true) { _initializeAll = initializeAll; _priceDic = initializeAll ? InnerDataProvider.Default.GetPriceDic() : new Dictionary(StringComparer.OrdinalIgnoreCase); } /// /// /// public double GetPrice(string optionCode) { return (InnerGetPrice(optionCode)?.Price) ?? 0; } /// /// /// public bool TryGetPrice(string optionCode, out double price) { var data = InnerGetPrice(optionCode); if (data != null) { price = data.Price; return true; } price = 0; return false; } /// /// /// public bool TryGetPriceModel(string optionCode, out PriceModel priceModel) { return null != (priceModel = InnerGetPrice(optionCode)); } private PriceModel InnerGetPrice(string optionCode) { if (string.IsNullOrEmpty(optionCode)) { return null; } if (_priceDic.TryGetValue(optionCode, out var data)) { return data; } if (_initializeAll) { return null; } using var db = DbContextFactory.GetYLDbContext(); data = db.exchange_list_option.Where(n => n.ContractCode == optionCode) .Select(n => new PriceModel { InstrumentCode = n.ContractCode, Price = n.Price ?? 0, PriceTime = n.PriceTime }).FirstOrDefault(); _priceDic[optionCode] = data; return data; } /// /// 内部数据提供以保证行情可以及时更新 /// class InnerDataProvider { readonly ThrottleAction _updateThrottle; readonly Dictionary _priceDic; private InnerDataProvider() { _updateThrottle = new ThrottleAction(UpdatePrice, 10); _priceDic = new Dictionary(); } private void UpdatePrice() { using var db = DbContextFactory.GetYLDbContext(); var date = DateTime.Today.AddDays(-10); var arr = db.exchange_list_option.Where(n => n.MaturityDate > date && n.ContractCode != null) .Select(n => new PriceModel { InstrumentCode = n.ContractCode, Price = n.Price ?? 0, PriceTime = n.PriceTime }).ToArray(); foreach (var item in arr) { _priceDic[item.InstrumentCode] = item; } } public IDictionary GetPriceDic() { _updateThrottle.Execute(); return new Dictionary(_priceDic); } /// /// 单例 /// public static readonly InnerDataProvider Default; static InnerDataProvider() { Default = new InnerDataProvider(); } } } }