124 lines
4.0 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|