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

238 lines
6.4 KiB
C#

using YLErp.Abstract.DataProviders;
using YLErp.Models;
namespace YLErp.Modules.DataProviderModule
{
/// <summary>
/// 日终场内期权价格提供
/// </summary>
public class EodExchangeOptionPriceProvider : IPriceProvider
{
private bool _allInitialized;
private readonly Dictionary<string, EodExchangeOptionPrice> _priceDic;
public EodExchangeOptionPriceProvider(DateTime valueDate, bool useClosePrice)
{
ValueDate = valueDate;
UseClosePrice = useClosePrice;
_priceDic = new Dictionary<string, EodExchangeOptionPrice>(StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// 取值日期
/// </summary>
public DateTime ValueDate { get; }
/// <summary>
/// 使用收盘价
/// </summary>
public bool UseClosePrice { get; }
public EodExchangeOptionPriceProvider InitializeAll()
{
var arr = GetDatasFromDB(null);
foreach (var item in arr)
{
_priceDic[item.OptionCode] = item;
}
_allInitialized = true;
return this;
}
/// <summary>
/// 根据场内期权代码初始化价格数据字典,
/// 调用后提升一定性能,不调用也无关系
/// </summary>
public EodExchangeOptionPriceProvider Initialize(string[] optionCodes)
{
if (_allInitialized)
{
return this;
}
var set = optionCodes.Where(n => !string.IsNullOrWhiteSpace(n)).ToHashSet(StringComparer.OrdinalIgnoreCase);
var list = GetDatasFromDB(set);
if (set.Any())
{
lock (_priceDic)
{
foreach (var code in set)
{
_priceDic[code] = null;
}
foreach (var item in list)
{
_priceDic[item.OptionCode] = item;
}
}
}
return this;
}
/// <summary>
/// 获取当前缓存中是否存在任一笔价格数据
/// </summary>
public bool HasAnyPrice()
{
return _priceDic.Values.Any(n => n != null);
}
/// <summary>
/// 获取价格
/// </summary>
public double GetPrice(string optionCode)
{
var data = InnerGetPrice(optionCode);
return data == null ? 0 : (UseClosePrice ? data.ClosePrice : data.SettlePrice);
}
/// <summary>
/// 尝试获取价格
/// </summary>
public bool TryGetPrice(string optionCode, out double price)
{
var data = InnerGetPrice(optionCode);
if (data != null)
{
price = UseClosePrice ? data.ClosePrice : data.SettlePrice;
return true;
}
else
{
price = 0;
return false;
}
}
/// <summary>
/// 获取价格对象
/// </summary>
public EodExchangeOptionPrice GetPriceModel(string optionCode)
{
return InnerGetPrice(optionCode);
}
/// <summary>
/// 尝试获取价格对象
/// </summary>
public bool TryGetPriceModel(string optionCode, out EodExchangeOptionPrice eodPrice)
{
return null != (eodPrice = InnerGetPrice(optionCode));
}
/// <summary>
/// 获取收盘价或结算价
/// </summary>
private EodExchangeOptionPrice InnerGetPrice(string optionCode)
{
if (string.IsNullOrWhiteSpace(optionCode))
{
return null;
}
lock (_priceDic)
{
if (_priceDic.TryGetValue(optionCode, out var data))
{
return data;
}
}
if (_allInitialized)
{
return null;
}
Initialize(new[] { optionCode });
lock (_priceDic)
{
if (_priceDic.TryGetValue(optionCode, out var data))
{
return data;
}
}
return null;
}
/// <summary>
/// 从数据库中获取初始化数据
/// </summary>
private EodExchangeOptionPrice[] GetDatasFromDB(HashSet<string> optionCodes)
{
var predicate = PredicateBuilder.Create<eod_exchange_option_price>(t => t.ValueDate == ValueDate);
if (optionCodes != null)
{
if (optionCodes.Count > 0)
{
predicate = predicate.And(t => optionCodes.Contains(t.ContractCode));
}
else
{
return Array.Empty<EodExchangeOptionPrice>();
}
}
using var db = DbContextFactory.GetYLDbContext();
return db.eod_exchange_option_price.Where(predicate)
.Select(n => new EodExchangeOptionPrice
{
OptionCode = n.ContractCode,
ClosePrice = n.ClosePrice,
HighPrice = n.HighPrice,
LowPrice = n.LowPrice,
SettlePrice = n.SettlePrice,
ValueDate = n.ValueDate
}).ToArray();
}
}
/// <summary>
/// 日终场内期权结算价
/// </summary>
public class EodExchangeOptionPrice
{
/// <summary>
/// 取值日
/// </summary>
public DateTime ValueDate { get; set; }
/// <summary>
/// 期权代码
/// </summary>
public string OptionCode { get; set; }
/// <summary>
/// 收盘价
/// </summary>
public double ClosePrice { get; set; }
/// <summary>
/// 结算价
/// </summary>
public double SettlePrice { get; set; }
/// <summary>
/// 最高价
/// </summary>
public double? HighPrice { get; set; }
/// <summary>
/// 最低价
/// </summary>
public double? LowPrice { get; set; }
}
}