using System.Collections.Concurrent;
using YLErp.Abstract;
using YLErp.Models;
namespace YLErp.Modules.DataProviderModule
{
///
/// 场外期权开仓平仓波动率提供
///
public class OtcPositionVolProvider : IDataUpdater, IJsonSerializable
{
readonly DateTime _valueDate;
//使用tradeid做为主键,为当日取波动率提供服务
readonly ConcurrentDictionary _dic;
//业务操作上来说,旧的波动率不会再变更,为上一交易日取波动率提供服务
readonly ConcurrentDictionary _dicOld;
///
/// 构造函数
///
/// 当前结算日期
public OtcPositionVolProvider(DateTime valueDate)
{
_valueDate = valueDate;
_dic = new ConcurrentDictionary();
_dicOld = new ConcurrentDictionary();
}
public string TableName => nameof(TradeVolatility);
///
/// 获取交易波动率
///
public IOtcTradeVolatility GetVol(int tradeId, DateTime valueDate)
{
var dic = valueDate < _valueDate ? _dicOld : _dic;
if (!dic.TryGetValue(tradeId, out var vol))
{
var tradVol = DbContextFactory.GetYLDbContext().TradeVolatility
.Where(n => n.TradeId == tradeId && n.ValueDate <= valueDate)
.OrderByDescending(n => n.ValueDate)
.Select(n => new
{
n.NumOfSmoothingDays,
n.TradePositionVolatility,
n.TradeCloseVolatility,
n.IsFromTradeAdd,
n.ValueDate
}).FirstOrDefault();
if (tradVol != null)
{
vol = new OtcTradeVolatility
{
ValueDate = tradVol.ValueDate,
OpenVol = tradVol.TradePositionVolatility ?? 0,
CloseVol = tradVol.TradeCloseVolatility ?? 0,
SmoothingDays = tradVol.NumOfSmoothingDays ?? 0,
IsFirst = tradVol.IsFromTradeAdd == true
};
}
dic.AddOrUpdate(tradeId, vol, (n, m) => vol);
}
return vol;
}
public string ToJson()
{
return new { _valueDate, _dic, _dicOld }.ToJson();
}
///
/// 更新数据
///
public void UpdateData(IEnumerable updateKeyIds)
{
var tradeIds = DataConvert.ConvertToInt32Array(updateKeyIds);
foreach (var tradeId in tradeIds)
{
_dic.TryRemove(tradeId, out IOtcTradeVolatility vol);
}
}
}
}