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

124 lines
4.0 KiB
C#

using YLErp.Abstract.DataProviders;
namespace YLErp.Modules.DataProviderModule
{
/// <summary>
/// 日终参考价数据提供(这个类只有特殊情况下用到)
/// </summary>
public class EodReferencePriceProvider : IPriceProvider
{
bool _initialized;
Dictionary<string, double?> _priceDic;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="valueDate">结算价取值日</param>
public EodReferencePriceProvider(DateTime valueDate)
{
ValueDate = valueDate.Date;
}
/// <summary>
/// 结算价取值日
/// </summary>
public DateTime ValueDate { get; }
/// <summary>
/// 初始化数据字典
/// (提前初始化可在大批量标的取结算价时提高一定性能)
/// </summary>
public EodReferencePriceProvider Initialize(string[] underlyingCodes = null)
{
//多线程时只初始化一次
if (!_initialized)
{
lock (this)
{
if (!_initialized)
{
InnerInitialize(underlyingCodes);
}
_initialized = true;
}
}
return this;
}
private void InnerInitialize(string[] underlyingCodes)
{
using (var db = DbContextFactory.GetYLDbContext())
{
var predicate1 = PredicateBuilder.Create<eod_commodity_future_price>(t => t.ValueDate == ValueDate);
var predicate2 = PredicateBuilder.Create<eod_stock_price>(t => t.ValueDate == ValueDate);
if (underlyingCodes != null && underlyingCodes.Any(n => !string.IsNullOrEmpty(n)))
{
predicate1 = predicate1.And(n => underlyingCodes.Contains(n.UnderlyingCode));
predicate2 = predicate2.And(n => underlyingCodes.Contains(n.UnderlyingCode));
}
var eodFutureQuery = db.eod_commodity_future_price.Where(predicate1).Select(n => new { n.UnderlyingCode, n.ReferencePrice });
var eodStockQuery = db.eod_stock_price.Where(predicate2).Select(n => new { n.UnderlyingCode, n.ReferencePrice });
//数据加载到字典中
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
_priceDic = eodFutureQuery.Concat(eodStockQuery).ToArray()
.Where(n => n.UnderlyingCode != null && set.Add(n.UnderlyingCode))
.ToDictionary(n => n.UnderlyingCode, m => m.ReferencePrice, StringComparer.OrdinalIgnoreCase);
}
}
public double GetPrice(string instrumentCode)
{
return InnerTryGetPrice(instrumentCode, out var price) ? price : 0d;
}
public bool TryGetPrice(string instrumentCode, out double price)
{
return InnerTryGetPrice(instrumentCode, out price);
}
private bool InnerTryGetPrice(string instrumentCode, out double price)
{
price = 0;
if (string.IsNullOrWhiteSpace(instrumentCode))
{
return false;
}
lock (this)
{
if (_priceDic == null)
{
_priceDic = new Dictionary<string, double?>(StringComparer.OrdinalIgnoreCase);
}
else if (_priceDic.TryGetValue(instrumentCode, out var nPrice))
{
price = nPrice ?? 0;
return nPrice.HasValue;
}
else if (_initialized)
{
return false;
}
}
var exists = EodPriceQueryService.TryGetReferencePrice(ValueDate, instrumentCode, out price);
lock (this)
{
_priceDic[instrumentCode] = exists ? (double?)price : null;
}
return exists;
}
}
}