using YLErp.Abstract; using YLErp.Modules.CalculationModule.Abstract; using YLErp.Modules.DataCacheModule; using YLErp.Modules.DataProviderModule; using YLErp.QdpModule; namespace YLErp.Modules.TradeRiskCalcModule.TaskRunner { /// /// 实时风险计算数据初始化 /// 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); } /// /// 特定计算日期(用于测试时可计算历史日期) /// public DateTime? SpecialValueDate { get; set; } /// /// 是否已经准备好 /// public bool IsReady => _initFlag == 2; /// /// 初始化(2020-02-20:因为收盘版本改进增加了参数volType用于取最后收盘日期) /// 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(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("初始化计算数据完成"); } /// /// /// internal InnerRunTaskData GetRunTaskData() { return new InnerRunTaskData { IsReady = IsReady, DataProvider = DataProvider, PreSettleDate = PreSettleDate, TradeDataSource = TradeDataSource, ValueDate = ValueDate, ManualRiskProvider = _EodManualRiskProvider, ManualRiskProviderHedge = _EodManualRiskProviderHedge }; } #region----IVolatilityDataProvider---- /// /// 场内期权保存的波动率 /// public double? GetExOptionSavedVol(string optionCode, DateTime valueDate) { return _ExOptionSavedVolProvider.GetSavedVol(optionCode, valueDate); } /// /// 场外期权对冲波动率 /// public double? GetOtcHedgingVol(int tradeId, DateTime valueDate) { return _OtcHedgingVolProvider.GetVol(tradeId, valueDate); } /// /// 标的波动率 /// public IVolatility GetUnderlyingVol(DateTime valueDate, string voltype, string contractCode, string userGroup) { return (valueDate == _UnderlyingVolProvider.ValueDate ? _UnderlyingVolProvider : _UnderlyingVolProviderPre) .GetVolatility(voltype, contractCode, userGroup); } /// /// 场外期权结算波动率 /// public double? GetOtcEodOverrideVol(int tradeId, DateTime valueDate) { return _OtcEodOverrideVolProvider.GetVol(tradeId, valueDate); } /// /// 场外期权交易波动率 /// 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; } } }