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

236 lines
7.9 KiB
C#

using YLErp.Abstract;
using YLErp.Modules.CalculationModule.Abstract;
using YLErp.Modules.DataCacheModule;
using YLErp.Modules.DataProviderModule;
using YLErp.QdpModule;
namespace YLErp.Modules.TradeRiskCalcModule.TaskRunner
{
/// <summary>
/// 实时风险计算数据初始化
/// </summary>
public class DataInitializer : IVolatilityDataProvider
{
public DateTime ValueDate { get; private set; }
public DateTime PreSettleDate { get; private set; }
public TradeDataSource TradeDataSource { get; private set; }
public TradeRiskCalcDataProvider DataProvider { get; private set; }
UnderlyingVolProvider _UnderlyingVolProvider;
UnderlyingVolProvider _UnderlyingVolProviderPre;
OtcPositionVolProvider _OtcPositionVolProvider;
OtcHedgingVolProvider _OtcHedgingVolProvider;
OtcEodOverrideVolProvider _OtcEodOverrideVolProvider;
ExOptionSavedVolProvider _ExOptionSavedVolProvider;
ManualRiskProvider _EodManualRiskProvider;
ManualRiskProvider _EodManualRiskProviderHedge;
IDataTraceSink _dataTraceSink;
readonly IYcLogger _logger;
DateTime? _eodOptTime;
int _initFlag;
public DataInitializer(IYcLogger logger = null)
{
_logger = logger ?? LogFactory.GetLogger("实时风险计算");
}
~DataInitializer()
{
DataCacheManager.UnRegisterDataTraceSink(_dataTraceSink);
}
/// <summary>
/// 特定计算日期(用于测试时可计算历史日期)
/// </summary>
public DateTime? SpecialValueDate { get; set; }
/// <summary>
/// 是否已经准备好
/// </summary>
public bool IsReady => _initFlag == 2;
/// <summary>
/// 初始化(2020-02-20:因为收盘版本改进增加了参数volType用于取最后收盘日期)
/// </summary>
public void Init(out bool blReset)
{
_logger?.Debug("初始化计算数据...");
blReset = false;
//-----------------------------------
// 确定实时风险估值日
//-----------------------------------
var now = SpecialValueDate ?? DateTime.Now;
if (now.TimeOfDay.Ticks > StarTimeTicks)
{
now = now.AddDays(1);
}
var valueDate = QdpCalendarHelper.GetNonHoliday(now.Date);
if (ValueDate != valueDate)
{
_initFlag = 0;
ValueDate = valueDate;
}
_logger?.Debug("计算日期:" + valueDate);
//-----------------------------------
// 检查上个结算日收盘是否发生了变化
// 如果发生了变化,实时风险计算需要重置
//-----------------------------------
var preDate = DateTime.MinValue;
using (var db = DbContextFactory.GetYLDbContext())
{
var lastData = db.eodStatus.Where(t => t.Status == "已收盘" && t.ValueDate < valueDate)
.OrderByDescending(t => t.ValueDate).Select(n => new { n.ValueDate, n.OptDate }).FirstOrDefault();
if (lastData != null)
{
preDate = lastData.ValueDate.Date;
}
else
{
preDate = QdpCalendarHelper.BizDayShift(valueDate, offset: -1);
}
if (PreSettleDate != preDate)
{
_initFlag = 0;
PreSettleDate = preDate;
}
if (lastData?.OptDate != _eodOptTime)
{
_initFlag = 0;
_eodOptTime = lastData?.OptDate;
}
}
_logger?.Debug("上一个结算日:" + preDate);
//-----------------------------------
//更新数据
//-----------------------------------
if (_initFlag == 0)
{
_logger?.Info($"重置数据[valueDate:{ValueDate}][LastSettlementDate:{PreSettleDate}]");
DataCacheManager.UnRegisterDataTraceSink(_dataTraceSink);
//必须重新初始化防止正在进行的计算混淆数据环境
DataProvider = new TradeRiskCalcDataProvider();
TradeDataSource = new TradeDataSource(valueDate, preDate);
var updaters = new List<IDataUpdater>(TradeDataSource.GetDataUpdaters());
updaters.AddRange(new IDataUpdater[] {
AutocallObservationDataSource.Default,
_UnderlyingVolProvider = new UnderlyingVolProvider(valueDate),
_UnderlyingVolProviderPre = new UnderlyingVolProvider(preDate),
_OtcPositionVolProvider = new OtcPositionVolProvider(valueDate),
_OtcHedgingVolProvider = new OtcHedgingVolProvider(valueDate),
_OtcEodOverrideVolProvider = new OtcEodOverrideVolProvider(valueDate),
_ExOptionSavedVolProvider = new ExOptionSavedVolProvider(valueDate),
_EodManualRiskProvider = new ManualRiskProvider(valueDate, "持仓"),
_EodManualRiskProviderHedge = new ManualRiskProvider(valueDate, "对冲")
});
_dataTraceSink = new DataTraceSinkGroup(2, updaters.ToArray());
DataCacheManager.RegisterDataTraceSink(_dataTraceSink);
_dataTraceSink.UpdateCache();
_initFlag = 1;
blReset = true;
}
DataProvider.InitData(preDate, this);
_initFlag = 2;
_logger?.Debug("初始化计算数据完成");
}
/// <summary>
///
/// </summary>
internal InnerRunTaskData GetRunTaskData()
{
return new InnerRunTaskData
{
IsReady = IsReady,
DataProvider = DataProvider,
PreSettleDate = PreSettleDate,
TradeDataSource = TradeDataSource,
ValueDate = ValueDate,
ManualRiskProvider = _EodManualRiskProvider,
ManualRiskProviderHedge = _EodManualRiskProviderHedge
};
}
#region----IVolatilityDataProvider----
/// <summary>
/// 场内期权保存的波动率
/// </summary>
public double? GetExOptionSavedVol(string optionCode, DateTime valueDate)
{
return _ExOptionSavedVolProvider.GetSavedVol(optionCode, valueDate);
}
/// <summary>
/// 场外期权对冲波动率
/// </summary>
public double? GetOtcHedgingVol(int tradeId, DateTime valueDate)
{
return _OtcHedgingVolProvider.GetVol(tradeId, valueDate);
}
/// <summary>
/// 标的波动率
/// </summary>
public IVolatility GetUnderlyingVol(DateTime valueDate, string voltype, string contractCode, string userGroup)
{
return (valueDate == _UnderlyingVolProvider.ValueDate ? _UnderlyingVolProvider : _UnderlyingVolProviderPre)
.GetVolatility(voltype, contractCode, userGroup);
}
/// <summary>
/// 场外期权结算波动率
/// </summary>
public double? GetOtcEodOverrideVol(int tradeId, DateTime valueDate)
{
return _OtcEodOverrideVolProvider.GetVol(tradeId, valueDate);
}
/// <summary>
/// 场外期权交易波动率
/// </summary>
public IOtcTradeVolatility GetOtcPositionVol(int tradeId, DateTime valueDate)
{
return _OtcPositionVolProvider.GetVol(tradeId, valueDate);
}
#endregion
public static readonly long StarTimeTicks;
static DataInitializer()
{
StarTimeTicks = new TimeSpan(20, 35, 0).Ticks;
}
}
}