/// <summary> /// Initializes a new instance of the <see cref="ChartingInsightManagerExtension"/> class /// </summary> /// <param name="algorithm">The algorithm instance. This is only used for adding the charts /// to the algorithm. We purposefully do not save a reference to avoid potentially inconsistent reads</param> /// <param name="statisticsManager">Statistics manager used to access mean population scores for charting</param> public ChartingInsightManagerExtension(IAlgorithm algorithm, StatisticsInsightManagerExtension statisticsManager) { _statisticsManager = statisticsManager; _liveMode = algorithm.LiveMode; // chart for average scores over sample period var scoreChart = new Chart("Alpha"); foreach (var scoreType in InsightManager.ScoreTypes) { var series = new Series($"{scoreType} Score", SeriesType.Line, "%"); scoreChart.AddSeries(series); _insightScoreSeriesByScoreType[scoreType] = series; } // chart for insight count over sample period var insightCount = new Chart("Insight Count"); insightCount.AddSeries(_totalInsightCountSeries); algorithm.AddChart(scoreChart); algorithm.AddChart(insightCount); algorithm.AddChart(_totalInsightCountPerSymbolChart); // removing this for now, not sure best way to display this data //Algorithm.AddChart(_dailyInsightCountPerSymbolChart); }
/// <summary> /// Invokes the manager at the end of the time step. /// Samples and plots insight counts and population score. /// </summary> /// <param name="frontierTimeUtc">The current frontier time utc</param> public void Step(DateTime frontierTimeUtc) { // Only add our charts to the algorithm when we actually have an insight // We will still update our internal charts anyways, but this keeps Alpha charts out of // algorithms that don't use the framework. if (!_chartsAdded && _dailyInsightCount > 0) { _algorithm.AddChart(_insightScoreChart); _algorithm.AddChart(_totalInsightCountChart); _algorithm.AddChart(_totalInsightCountPerSymbolChart); _chartsAdded = true; } // sample insight/symbol counts each utc day change if (frontierTimeUtc.Date > _lastInsightCountSampleDateUtc) { _lastInsightCountSampleDateUtc = frontierTimeUtc.Date; // add sum of daily insight counts to the total insight count series _totalInsightCountSeries.AddPoint(frontierTimeUtc.Date, _dailyInsightCount); // Create the pie chart every minute or so PopulateChartWithSeriesPerSymbol(_totalInsightCountPerSymbol, _totalInsightCountPerSymbolChart, SeriesType.Treemap, frontierTimeUtc); // Resetting our storage _dailyInsightCount = 0; } // sample average population scores if (frontierTimeUtc >= _nextChartSampleAlgorithmTimeUtc) { try { // verify these scores have been computed before taking the first sample if (_statisticsManager.RollingAverageIsReady) { // sample the rolling averaged population scores foreach (var scoreType in InsightManager.ScoreTypes) { var score = 100 * _statisticsManager.Statistics.RollingAveragedPopulationScore.GetScore(scoreType); _insightScoreSeriesByScoreType[scoreType].AddPoint(frontierTimeUtc, score.SafeDecimalCast()); } _nextChartSampleAlgorithmTimeUtc = frontierTimeUtc + SampleInterval; } } catch (Exception err) { Log.Error(err); } } }
/// <summary> /// Initializes this alpha handler to accept alphas from the specified algorithm /// </summary> /// <param name="job">The algorithm job</param> /// <param name="algorithm">The algorithm instance</param> /// <param name="messagingHandler">Handler used for sending alphas</param> /// <param name="api">Api instance</param> public virtual void Initialize(AlgorithmNodePacket job, IAlgorithm algorithm, IMessagingHandler messagingHandler, IApi api) { // initializing these properties just in case, doens't hurt to have them populated Job = job; Algorithm = algorithm; _messagingHandler = messagingHandler; _isNotFrameworkAlgorithm = !algorithm.IsFrameworkAlgorithm; if (_isNotFrameworkAlgorithm) { return; } AlphaManager = CreateAlphaManager(); RuntimeStatistics = new AlphaRuntimeStatistics(); // wire events to update runtime statistics at key moments in alpha life cycle (new/period end/analysis end) AlphaManager.AlphaReceived += (sender, context) => StatisticsUpdater.OnAlphaReceived(RuntimeStatistics, context); AlphaManager.AlphaClosed += (sender, context) => StatisticsUpdater.OnAlphaClosed(RuntimeStatistics, context); AlphaManager.AlphaAnalysisCompleted += (sender, context) => StatisticsUpdater.OnAlphaAnalysisCompleted(RuntimeStatistics, context); algorithm.AlphasGenerated += (algo, collection) => OnAlphasGenerated(collection); // chart for average scores over sample period var scoreChart = new Chart("Alpha"); foreach (var scoreType in ScoreTypes) { var series = new Series($"{scoreType} Score", SeriesType.Line, "%"); scoreChart.AddSeries(series); _alphaScoreSeriesByScoreType[scoreType] = series; } // chart for prediction count over sample period var predictionCount = new Chart("Alpha Count"); predictionCount.AddSeries(_totalAlphaCountSeries); Algorithm.AddChart(scoreChart); Algorithm.AddChart(predictionCount); Algorithm.AddChart(_totalAlphaCountPerSymbolChart); // removing this for now, not sure best way to display this data //Algorithm.AddChart(_dailyAlphaCountPerSymbolChart); }
/// <summary> /// Add a Chart object to algorithm collection /// </summary> /// <param name="chart">Chart object to add to collection.</param> public void AddChart(Chart chart) => _baseAlgorithm.AddChart(chart);