using System.Text; using YLErp.Models; using YLErp.Modules.TradeRiskCalcModule.TaskRunner; namespace YLErp.Modules.TradeRiskCalcModule { /// /// 交易风险计算运行器 /// public static class TradeRiskCalcTaskRunner { static readonly IYcLogger _logger; static DataInitializer _initializer; static readonly OtcTradeRiskRunner _hedgingVolRunner; static readonly OtcTradeRiskRunner _positionVolRunner; static readonly OtcTradeRiskRunner _tradeVolSurfaceRunner; static readonly OtcTradeRiskRunner _ZreoDividendRateRunner; static readonly ExchangePositionRunner _exchangePositionRunner; static readonly InnerRunnerBase[] _allRunner; static bool _executing; static bool _reseting; static TradeRiskCalcTaskRunner() { _initializer = new DataInitializer(_logger); _logger = LogFactory.GetLogger(nameof(TradeRiskCalcTaskRunner)); _allRunner = new InnerRunnerBase[] { _hedgingVolRunner = new OtcTradeRiskRunner("对冲"), _positionVolRunner = new OtcTradeRiskRunner("持仓"), _tradeVolSurfaceRunner = new OtcTradeRiskRunner("交易曲面"), _ZreoDividendRateRunner=new OtcTradeRiskRunner("交易曲面分红率0"),//国元特有 _exchangePositionRunner = new ExchangePositionRunner() }; } /// /// 实时风险计算日期 /// public static DateTime ValueDate => _initializer.ValueDate; public static TradeDataSource TradeDataSource => _initializer.TradeDataSource; /// /// 场内实时持仓计算结果 /// public static ExchangePositionCalcResult ExchangePositionResult => _exchangePositionRunner.GetResult(); /// /// 重置风险计算 /// public static void Reset() { _reseting = true; } /// /// 运行实时风险计算 /// public static void Execute(string[] volTypes) { if (_executing) { return; } lock (_allRunner) { if (_executing) { return; } _executing = true; } try { InnerExecuteRiskCalc(volTypes); } catch (Exception ex) { _logger.Error(ex, "实时风险执行出错"); } finally { _executing = false; } } private static void InnerExecuteRiskCalc(string[] volTypes) { if (AppContext.TryGetSwitch("DisableTradeRiskCalcTaskRunner", out var disable) && disable) { AppManager.SetSysInfo("实时风险-定时执行", "停止执行"); return; } AppManager.SetSysInfo("实时风险-定时执行", "执行"); AppContext.TryGetSwitch("场内实时持仓API", out var blHedgePosition); var initializer = _initializer; if (volTypes == null || !volTypes.Any(n => n != null)) { if (blHedgePosition) { initializer.Init(out _); _exchangePositionRunner.StartTask(initializer.GetRunTaskData()); } return; } var voltypeFlag = VolTypeFlagEnum.None; var riskRunners = new List(6); foreach (var type in volTypes) { OtcTradeRiskRunner runner = null; switch (type) { case "对冲": runner = _hedgingVolRunner; voltypeFlag |= VolTypeFlagEnum.HedgeVol; break; case "持仓": runner = _positionVolRunner; voltypeFlag |= VolTypeFlagEnum.PositionVol; break; case "交易曲面": runner = _tradeVolSurfaceRunner; break; } if (runner != null && !riskRunners.Contains(_tradeVolSurfaceRunner)) { riskRunners.Add(runner); } } if (PS.Config.Company == Configuration.CompanyEnum.国元固收) { riskRunners.Add(_ZreoDividendRateRunner); } lock (_allRunner) { var flag = 0; foreach (var runner in riskRunners) { flag |= runner.IsRunning ? runner.IsTimeOut(600) ? 2 : 1 : 0; } if (flag > 0) { if (flag == 1) { if (blHedgePosition) { _exchangePositionRunner.StartTask(initializer.GetRunTaskData()); } return; } //因为有计算严重超时故而重置 foreach (var runner in riskRunners) { runner.CancelTask(0); } _reseting = true; } if (_reseting) { _reseting = false; _initializer = initializer = new DataInitializer(_logger); } } initializer.Init(out var blReset); if (blReset) { LogFactory.GetLogger("实时风险").Info($"重置,计算日:{initializer.ValueDate},前一交易日:{initializer.PreSettleDate}"); AccruedTotalPnlStartingDataSource.Default.Reset(); AccruedTotalPnlStartingDataSource.Default.Reset(); } if (blHedgePosition) { _exchangePositionRunner.StartTask(initializer.GetRunTaskData()); } foreach (var runner in riskRunners) { runner.StartTask(initializer.GetRunTaskData()); } } /// /// 执行价格试算 /// public static TradingRiskResult ExecuteFixedPriceCalc(string volType, IEnumerable underlyingPrices) { if (underlyingPrices == null) { throw new ArgumentNullException(nameof(underlyingPrices)); } var startTime = DateTime.Now; var initializer = _initializer; underlyingPrices = underlyingPrices.Where(n => !string.IsNullOrEmpty(n?.InstrumentCode)).ToArray(); if (!underlyingPrices.Any()) { return new TradingRiskResult { ValueDate = initializer.ValueDate, PreDate = startTime, TradeRiskList = Enumerable.Empty(), CalcStartTime = startTime, CalcEndTime = DateTime.Now }; } var provider = initializer.DataProvider.Clone(new UnderlyingFixedPriceProvider(underlyingPrices)); var context = new TradeRiskCalcContext(volType, false, initializer.ValueDate, initializer.PreSettleDate, provider) { TrialCalclMode = true }; var list = new TradeRiskCalcService(context, skipTradeTypes: null).SetUnderlyingFilter(underlyingPrices.Select(n => n.InstrumentCode).ToArray()) .Calculate(initializer.TradeDataSource, null); return new TradingRiskResult { ValueDate = initializer.ValueDate, PreDate = context.PreSettleDate, TradeRiskList = list, CalcStartTime = startTime, CalcEndTime = DateTime.Now }; } /// /// 获取实时风险运行结果(计算后保存数据的克隆版) /// public static TradingRiskResult GetCalcResult(string volType) { if (volType != null) { foreach (var runner in _allRunner) { if (runner is OtcTradeRiskRunner ts && ts.VolType == volType) { return ts.GetResult();//.Result; } } } return null; } } }