/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="packet">Algorithm job packet for this result handler</param> /// <param name="messagingHandler"></param> /// <param name="api"></param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket packet, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { // we expect one of two types here, the backtest node packet or the live node packet var job = packet as BacktestNodePacket; if (job != null) { _algorithmNode = new BacktestConsoleStatusHandler(job); } else { var live = packet as LiveNodePacket; if (live == null) { throw new ArgumentException("Unexpected AlgorithmNodeType: " + packet.GetType().Name); } _algorithmNode = new LiveConsoleStatusHandler(live); } _resamplePeriod = _algorithmNode.ComputeSampleEquityPeriod(); var time = DateTime.Now.ToString("yyyy-MM-dd-HH-mm"); _chartDirectory = Path.Combine("../../../Charts/", packet.AlgorithmId, time); if (Directory.Exists(_chartDirectory)) { foreach (var file in Directory.EnumerateFiles(_chartDirectory, "*.csv", SearchOption.AllDirectories)) { File.Delete(file); } Directory.Delete(_chartDirectory, true); } Directory.CreateDirectory(_chartDirectory); _messagingHandler = messagingHandler; }
public override void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { _job = job; }
/// <summary> /// Initializes this alpha handler to accept insights 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 insights</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, doesn't hurt to have them populated Job = job; Algorithm = algorithm; MessagingHandler = messagingHandler; _fitnessScore = new FitnessScoreManager(); _insights = new List <Insight>(); _securityValuesProvider = new AlgorithmSecurityValuesProvider(algorithm); InsightManager = CreateInsightManager(); var statistics = new StatisticsInsightManagerExtension(algorithm); RuntimeStatistics = statistics.Statistics; InsightManager.AddExtension(statistics); AddInsightManagerCustomExtensions(statistics); // when insight is generated, take snapshot of securities and place in queue for insight manager to process on alpha thread algorithm.InsightsGenerated += (algo, collection) => { lock (_insights) { _insights.AddRange(collection.Insights); } }; }
public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { }
/// <summary> /// Initializes this alpha handler to accept insights 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 insights</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; _fitnessScore = new FitnessScoreManager(); _securityValuesProvider = new AlgorithmSecurityValuesProvider(algorithm); InsightManager = CreateInsightManager(); // send scored insights to messaging handler InsightManager.AddExtension(CreateAlphaResultPacketSender()); var statistics = new StatisticsInsightManagerExtension(algorithm); RuntimeStatistics = statistics.Statistics; InsightManager.AddExtension(statistics); _charting = new ChartingInsightManagerExtension(algorithm, statistics); InsightManager.AddExtension(_charting); // when insight is generated, take snapshot of securities and place in queue for insight manager to process on alpha thread algorithm.InsightsGenerated += (algo, collection) => InsightManager.Step(collection.DateTimeUtc, CreateSecurityValuesSnapshot(), collection); }
/// <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; } _securityValuesProvider = new AlgorithmSecurityValuesProvider(algorithm); AlphaManager = CreateAlphaManager(); var statistics = new StatisticsAlphaManagerExtension(); RuntimeStatistics = statistics.Statistics; AlphaManager.AddExtension(statistics); _charting = new ChartingAlphaManagerExtension(algorithm, statistics); AlphaManager.AddExtension(_charting); // when alpha is generated, take snapshot of securities and place in queue for alpha manager to process on alpha thread algorithm.AlphasGenerated += (algo, collection) => _alphaQueue.Enqueue(new AlphaQueueItem(collection.DateTimeUtc, CreateSecurityValuesSnapshot(), collection)); }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler"></param> /// <param name="api"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { //Redirect the log messages here: _job = job; var desktopLogging = new FunctionalLogHandler(DebugMessage, DebugMessage, ErrorMessage); Log.LogHandler = new CompositeLogHandler(desktopLogging, Log.LogHandler); }
public void Setup() { _geolocator = CrossGeolocator.Geolocator = Substitute.For <IGeolocator>(); _permissionValidator = Substitute.For <IPermissionValidator>(); _messagingHandler = Substitute.For <IMessagingHandler>(); _trackerService = new TrackerService(_permissionValidator, _messagingHandler); }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="transactionHandler">The transaction handler used to get the algorithms <see cref="Order"/> information</param> public override void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { _algorithmId = job.AlgorithmId; _projectId = job.ProjectId; _job = (BacktestNodePacket)job; if (_job == null) throw new Exception("BacktestingResultHandler.Constructor(): Submitted Job type invalid."); base.Initialize(job, messagingHandler, api, transactionHandler); }
public override void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { base.Initialize(job, messagingHandler, api, transactionHandler); PreviousUtcSampleTime = InitialSampleTime; }
/// <summary> /// Form launcher method for thread. /// </summary> static void LaunchUX(IMessagingHandler messaging, AlgorithmNodePacket job) { //Launch the UX //var form = Composer.Instance.GetExportedValueByTypeName<Form>("desktop-ux-classname"); var form = new Views.WinForms.LeanWinForm(messaging, job); Application.Run(form); }
/// <summary> /// Create the UX. /// </summary> /// <param name="notificationHandler">Messaging system</param> /// <param name="job">Job to use for URL generation</param> public LeanWinForm(IMessagingHandler notificationHandler, AlgorithmNodePacket job) { InitializeComponent(); //Form Setup: CenterToScreen(); WindowState = FormWindowState.Maximized; Text = "QuantConnect Lean Algorithmic Trading Engine: v" + Globals.Version; //Save off the messaging event handler we need: _job = job; _liveMode = job is LiveNodePacket; _messaging = (EventMessagingHandler)notificationHandler; var url = GetUrl(job, _liveMode); //GECKO WEB BROWSER: Create the browser control // https://www.nuget.org/packages/GeckoFX/ // -> If you don't have IE. #if !__MonoCS__ Gecko.Xpcom.Initialize(); _geckoBrowser = new GeckoWebBrowser { Dock = DockStyle.Fill, Name = "browser" }; _geckoBrowser.DOMContentLoaded += BrowserOnDomContentLoaded; _geckoBrowser.Navigate(url); splitPanel.Panel1.Controls.Add(_geckoBrowser); #else // MONO WEB BROWSER: Create the browser control // Default shipped with VS and Mono. Works OK in Windows, and compiles in linux. _monoBrowser = new WebBrowser() { Dock = DockStyle.Fill, Name = "Browser" }; _monoBrowser.DocumentCompleted += MonoBrowserOnDocumentCompleted; _monoBrowser.Navigate(url); splitPanel.Panel1.Controls.Add(_monoBrowser); #endif //Setup Event Handlers: _messaging.DebugEvent += MessagingOnDebugEvent; _messaging.LogEvent += MessagingOnLogEvent; _messaging.RuntimeErrorEvent += MessagingOnRuntimeErrorEvent; _messaging.HandledErrorEvent += MessagingOnHandledErrorEvent; _messaging.BacktestResultEvent += MessagingOnBacktestResultEvent; _logging = Log.LogHandler as QueueLogHandler; //Show warnings if the API token and UID aren't set. if (_job.UserId == 0) { MessageBox.Show("Your user id is not set. Please check your config.json file 'job-user-id' property.", "LEAN Algorithmic Trading", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (_job.Channel == "") { MessageBox.Show("Your API token is not set. Please check your config.json file 'api-access-token' property.", "LEAN Algorithmic Trading", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public Ping(AlgorithmManager algorithmManager, IApi api, IResultHandler resultHandler, IMessagingHandler messagingHandler, AlgorithmNodePacket job) { _api = api; _job = job; _resultHandler = resultHandler; _messagingHandler = messagingHandler; _algorithmManager = algorithmManager; _exitEvent = new ManualResetEventSlim(false); }
public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _job = job; }
/// <summary> /// Creates an instance of the <see cref="Ping"/> class /// </summary> public Ping(AlgorithmManager algorithmManager, IApi api, IResultHandler resultHandler, IMessagingHandler messagingHandler, AlgorithmNodePacket job) { _api = api; _job = job; _resultHandler = resultHandler; _messagingHandler = messagingHandler; _algorithmManager = algorithmManager; _exitEvent = new ManualResetEventSlim(false); }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="transactionHandler">The transaction handler used to get the algorithms <see cref="Order"/> information</param> public virtual void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { MessagingHandler = messagingHandler; TransactionHandler = transactionHandler; CompileId = job.CompileId; AlgorithmId = job.AlgorithmId; _updateRunner = new Thread(Run, 0) { IsBackground = true, Name = "Result Thread" }; _updateRunner.Start(); }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public virtual void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _messagingHandler = messagingHandler; _transactionHandler = transactionHandler; _setupHandler = setupHandler; _job = (BacktestNodePacket)job; if (_job == null) { throw new Exception("BacktestingResultHandler.Constructor(): Submitted Job type invalid."); } _compileId = _job.CompileId; _backtestId = _job.BacktestId; }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="transactionHandler">The transaction handler used to get the algorithms <see cref="Order"/> information</param> public virtual void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { _algorithmId = job.AlgorithmId; _projectId = job.ProjectId; MessagingHandler = messagingHandler; TransactionHandler = transactionHandler; _job = (BacktestNodePacket)job; if (_job == null) { throw new Exception("BacktestingResultHandler.Constructor(): Submitted Job type invalid."); } JobId = _job.BacktestId; CompileId = _job.CompileId; }
//private GeckoWebBrowser _geckoBrowser; /// <summary> /// Create the UX. /// </summary> /// <param name="notificationHandler">Messaging system</param> /// <param name="job">Job to use for URL generation</param> public LeanWinForm(IMessagingHandler notificationHandler, AlgorithmNodePacket job) { InitializeComponent(); //Form Setup: CenterToScreen(); WindowState = FormWindowState.Maximized; Text = "QuantConnect Lean Algorithmic Trading Engine: v" + Globals.Version; //Save off the messaging event handler we need: _job = job; _liveMode = job is LiveNodePacket; _messaging = (EventMessagingHandler)notificationHandler; var url = GetUrl(job, _liveMode); //GECKO WEB BROWSER: Create the browser control // https://www.nuget.org/packages/GeckoFX/ // -> If you don't have IE. //_geckoBrowser = new GeckoWebBrowser { Dock = DockStyle.Fill, Name = "browser" }; //_geckoBrowser.DOMContentLoaded += BrowserOnDomContentLoaded; //_geckoBrowser.Navigate(url); //splitPanel.Panel1.Controls.Add(_geckoBrowser); // MONO WEB BROWSER: Create the browser control // Default shipped with VS and Mono. Works OK in Windows, and compiles in linux. _monoBrowser = new WebBrowser() {Dock = DockStyle.Fill, Name = "Browser"}; _monoBrowser.DocumentCompleted += MonoBrowserOnDocumentCompleted; _monoBrowser.Navigate(url); splitPanel.Panel1.Controls.Add(_monoBrowser); //Setup Event Handlers: _messaging.DebugEvent += MessagingOnDebugEvent; _messaging.LogEvent += MessagingOnLogEvent; _messaging.RuntimeErrorEvent += MessagingOnRuntimeErrorEvent; _messaging.HandledErrorEvent += MessagingOnHandledErrorEvent; _messaging.BacktestResultEvent += MessagingOnBacktestResultEvent; _logging = Log.LogHandler as QueueLogHandler; //Show warnings if the API token and UID aren't set. if (_job.UserId == 0) { MessageBox.Show("Your user id is not set. Please check your config.json file 'job-user-id' property.", "LEAN Algorithmic Trading", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (_job.Channel == "") { MessageBox.Show("Your API token is not set. Please check your config.json file 'api-access-token' property.", "LEAN Algorithmic Trading", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler"></param> /// <param name="api"></param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _api = api; _dataFeed = dataFeed; _messagingHandler = messagingHandler; _setupHandler = setupHandler; _transactionHandler = transactionHandler; _job = (LiveNodePacket)job; if (_job == null) { throw new Exception("LiveResultHandler.Constructor(): Submitted Job type invalid."); } _deployId = _job.DeployId; _compileId = _job.CompileId; }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="transactionHandler">The transaction handler used to get the algorithms <see cref="Order"/> information</param> public virtual void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { MessagingHandler = messagingHandler; TransactionHandler = transactionHandler; CompileId = job.CompileId; AlgorithmId = job.AlgorithmId; ProjectId = job.ProjectId; RamAllocation = job.RamAllocation.ToStringInvariant(); OrderEventJsonConverter = new OrderEventJsonConverter(AlgorithmId); _updateRunner = new Thread(Run, 0) { IsBackground = true, Name = "Result Thread" }; _updateRunner.Start(); }
public AlphaResultPacketSender(AlgorithmNodePacket job, IMessagingHandler messagingHandler, TimeSpan interval, int maximumNumberOfInsightsPerPacket) { _job = job; _interval = interval; _messagingHandler = messagingHandler; _insights = new ConcurrentQueue <Insight>(); _maximumNumberOfInsightsPerPacket = maximumNumberOfInsightsPerPacket; _timer = new Timer(MessagingUpdateIntervalElapsed); _timer.Change(interval, interval); // don't bother holding on more than makes sense. this makes the maximum // number of insights we'll hold in the queue equal to one hour's worth of // processing. For 50 insights/message @ 1message/sec this is 90K _maximumQueueLength = (int)(TimeSpan.FromMinutes(30).Ticks / interval.Ticks * maximumNumberOfInsightsPerPacket); }
/// <summary> /// Initializes a new instance of the <see cref="LeanEngineSystemHandlers"/> class with the specified handles /// </summary> /// <param name="jobQueue">The job queue used to acquire algorithm jobs</param> /// <param name="api">The api instance used for communicating limits and status</param> /// <param name="notify">The messaging handler user for passing messages from the algorithm to listeners</param> public LeanEngineSystemHandlers(IJobQueueHandler jobQueue, IApi api, IMessagingHandler notify) { if (jobQueue == null) { throw new ArgumentNullException("jobQueue"); } if (api == null) { throw new ArgumentNullException("api"); } if (notify == null) { throw new ArgumentNullException("notify"); } _api = api; _jobQueue = jobQueue; _notify = notify; }
/// <summary> /// Initializes a new instance of the <see cref="LeanEngineSystemHandlers"/> class with the specified handles /// </summary> /// <param name="jobQueue">The job queue used to acquire algorithm jobs</param> /// <param name="api">The api instance used for communicating limits and status</param> /// <param name="notify">The messaging handler user for passing messages from the algorithm to listeners</param> public LeanEngineSystemHandlers(IJobQueueHandler jobQueue, IApi api, IMessagingHandler notify) { if (jobQueue == null) { throw new ArgumentNullException("jobQueue"); } if (api == null) { throw new ArgumentNullException("api"); } if (notify == null) { throw new ArgumentNullException("notify"); } _api = api; _jobQueue = jobQueue; _notify = notify; }
/// <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> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _api = api; _messagingHandler = messagingHandler; _transactionHandler = transactionHandler; _job = (BacktestNodePacket)job; if (_job == null) { throw new Exception("BacktestingResultHandler.Constructor(): Submitted Job type invalid."); } _compileId = _job.CompileId; _backtestId = _job.BacktestId; //Get the resample period: var totalMinutes = (_job.PeriodFinish - _job.PeriodStart).TotalMinutes; var resampleMinutes = (totalMinutes < (_minimumSamplePeriod * _samples)) ? _minimumSamplePeriod : (totalMinutes / _samples); // Space out the sampling every _resamplePeriod = TimeSpan.FromMinutes(resampleMinutes); Log.Trace("BacktestingResultHandler(): Sample Period Set: " + resampleMinutes.ToString("00.00")); }
/// <summary> /// Initializes this alpha handler to accept insights 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 insights</param> /// <param name="api">Api instance</param> /// <param name="transactionHandler">Algorithms transaction handler</param> public virtual void Initialize(AlgorithmNodePacket job, IAlgorithm algorithm, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { // initializing these properties just in case, doesn't hurt to have them populated Job = job; Algorithm = algorithm; MessagingHandler = messagingHandler; _fitnessScore = new FitnessScoreManager(); _insights = new List <Insight>(); _securityValuesProvider = new AlgorithmSecurityValuesProvider(algorithm); InsightManager = CreateInsightManager(); var statistics = new StatisticsInsightManagerExtension(algorithm); RuntimeStatistics = statistics.Statistics; InsightManager.AddExtension(statistics); AddInsightManagerCustomExtensions(statistics); var baseDirectory = Config.Get("results-destination-folder", Directory.GetCurrentDirectory()); var directory = Path.Combine(baseDirectory, AlgorithmId); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } _alphaResultsPath = Path.Combine(directory, "alpha-results.json"); // when insight is generated, take snapshot of securities and place in queue for insight manager to process on alpha thread algorithm.InsightsGenerated += (algo, collection) => { lock (_insights) { _insights.AddRange(collection.Insights); } }; }
static void LaunchUX(IMessagingHandler messaging, AlgorithmNodePacket job) { var form = new Views.WinForms.LeanWinForm(messaging, job); Application.Run(form); }
public void Initialize(AlgorithmNodePacket job, IAlgorithm algorithm, IMessagingHandler messagingHandler, IApi api) { }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler">The handler responsible for communicating messages to listeners</param> /// <param name="api">The api instance used for handling logs</param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _api = api; _messagingHandler = messagingHandler; _transactionHandler = transactionHandler; _job = (BacktestNodePacket)job; if (_job == null) throw new Exception("BacktestingResultHandler.Constructor(): Submitted Job type invalid."); _compileId = _job.CompileId; _backtestId = _job.BacktestId; //Get the resample period: var totalMinutes = (_job.PeriodFinish - _job.PeriodStart).TotalMinutes; var resampleMinutes = (totalMinutes < (_minimumSamplePeriod * _samples)) ? _minimumSamplePeriod : (totalMinutes / _samples); // Space out the sampling every _resamplePeriod = TimeSpan.FromMinutes(resampleMinutes); Log.Trace("BacktestingResultHandler(): Sample Period Set: " + resampleMinutes.ToString("00.00")); }
public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { _shadow.Initialize(job, messagingHandler, api, transactionHandler); }
public TrackerService(IPermissionValidator permissionValidator, IMessagingHandler messagingHandler) { _permissionValidator = permissionValidator; _messagingHandler = messagingHandler; _geolocator.DesiredAccuracy = 1; }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="packet">Algorithm job packet for this result handler</param> /// <param name="messagingHandler"></param> /// <param name="api"></param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket packet, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { // we expect one of two types here, the backtest node packet or the live node packet var job = packet as BacktestNodePacket; if (job != null) { _algorithmNode = new BacktestConsoleStatusHandler(job); } else { var live = packet as LiveNodePacket; if (live == null) { throw new ArgumentException("Unexpected AlgorithmNodeType: " + packet.GetType().Name); } _algorithmNode = new LiveConsoleStatusHandler(live); } _resamplePeriod = _algorithmNode.ComputeSampleEquityPeriod(); var time = DateTime.Now.ToString("yyyy-MM-dd-HH-mm"); _chartDirectory = Path.Combine("../../../Charts/", packet.AlgorithmId, time); if (Directory.Exists(_chartDirectory)) { foreach (var file in Directory.EnumerateFiles(_chartDirectory, "*.csv", SearchOption.AllDirectories)) { File.Delete(file); } Directory.Delete(_chartDirectory, true); } Directory.CreateDirectory(_chartDirectory); _messagingHandler = messagingHandler; }
public void Initialize(AlgorithmNodePacket job, IAlgorithm algorithm, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler) { //HACK: needed to set id prior to initialize algorithm.SetAlgorithmId(((BacktestNodePacket)job).AlgorithmId); }
public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _shadow.Initialize(job, messagingHandler, api, dataFeed, setupHandler, transactionHandler); }
/******************************************************** * CLASS METHODS *********************************************************/ /// <summary> /// Primary Analysis Thread: /// </summary> public static void Main(string[] args) { //Initialize: var algorithmPath = ""; string mode = "RELEASE"; AlgorithmNodePacket job = null; var algorithm = default(IAlgorithm); var startTime = DateTime.Now; Log.LogHandler = Composer.Instance.GetExportedValueByTypeName<ILogHandler>(Config.Get("log-handler", "CompositeLogHandler")); #if DEBUG mode = "DEBUG"; #endif //Name thread for the profiler: Thread.CurrentThread.Name = "Algorithm Analysis Thread"; Log.Trace("Engine.Main(): LEAN ALGORITHMIC TRADING ENGINE v" + Constants.Version + " Mode: " + mode); Log.Trace("Engine.Main(): Started " + DateTime.Now.ToShortTimeString()); Log.Trace("Engine.Main(): Memory " + OS.ApplicationMemoryUsed + "Mb-App " + +OS.TotalPhysicalMemoryUsed + "Mb-Used " + OS.TotalPhysicalMemory + "Mb-Total"); //Import external libraries specific to physical server location (cloud/local) try { // grab the right export based on configuration Api = Composer.Instance.GetExportedValueByTypeName<IApi>(Config.Get("api-handler")); Notify = Composer.Instance.GetExportedValueByTypeName<IMessagingHandler>(Config.Get("messaging-handler")); JobQueue = Composer.Instance.GetExportedValueByTypeName<IJobQueueHandler>(Config.Get("job-queue-handler")); } catch (CompositionException compositionException) { Log.Error("Engine.Main(): Failed to load library: " + compositionException); } //Setup packeting, queue and controls system: These don't do much locally. Api.Initialize(); Notify.Initialize(); JobQueue.Initialize(); //Start monitoring the backtest active status: var statusPingThread = new Thread(StateCheck.Ping.Run); statusPingThread.Start(); try { //Reset algo manager internal variables preparing for a new algorithm. AlgorithmManager.ResetManager(); //Reset thread holders. var initializeComplete = false; Thread threadFeed = null; Thread threadTransactions = null; Thread threadResults = null; Thread threadRealTime = null; do { //-> Pull job from QuantConnect job queue, or, pull local build: job = JobQueue.NextJob(out algorithmPath); // Blocking. // if the job version doesn't match this instance version then we can't process it // we also don't want to reprocess redelivered live jobs if (job.Version != Constants.Version || (LiveMode && job.Redelivered)) { Log.Error("Engine.Run(): Job Version: " + job.Version + " Deployed Version: " + Constants.Version); //Tiny chance there was an uncontrolled collapse of a server, resulting in an old user task circulating. //In this event kill the old algorithm and leave a message so the user can later review. JobQueue.AcknowledgeJob(job); Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, _collapseMessage); Notify.SetChannel(job.Channel); Notify.RuntimeError(job.AlgorithmId, _collapseMessage); job = null; } } while (job == null); //-> Initialize messaging system Notify.SetChannel(job.Channel); //-> Create SetupHandler to configure internal algorithm state: SetupHandler = GetSetupHandler(job.SetupEndpoint); //-> Set the result handler type for this algorithm job, and launch the associated result thread. ResultHandler = GetResultHandler(job); threadResults = new Thread(ResultHandler.Run, 0) {Name = "Result Thread"}; threadResults.Start(); try { // Save algorithm to cache, load algorithm instance: algorithm = SetupHandler.CreateAlgorithmInstance(algorithmPath); //Initialize the internal state of algorithm and job: executes the algorithm.Initialize() method. initializeComplete = SetupHandler.Setup(algorithm, out _brokerage, job); //If there are any reasons it failed, pass these back to the IDE. if (!initializeComplete || algorithm.ErrorMessages.Count > 0 || SetupHandler.Errors.Count > 0) { initializeComplete = false; //Get all the error messages: internal in algorithm and external in setup handler. var errorMessage = String.Join(",", algorithm.ErrorMessages); errorMessage += String.Join(",", SetupHandler.Errors); ResultHandler.RuntimeError(errorMessage); Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError); } } catch (Exception err) { var runtimeMessage = "Algorithm.Initialize() Error: " + err.Message + " Stack Trace: " + err.StackTrace; ResultHandler.RuntimeError(runtimeMessage, err.StackTrace); Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, runtimeMessage); } //-> Using the job + initialization: load the designated handlers: if (initializeComplete) { //-> Reset the backtest stopwatch; we're now running the algorithm. startTime = DateTime.Now; //Set algorithm as locked; set it to live mode if we're trading live, and set it to locked for no further updates. algorithm.SetAlgorithmId(job.AlgorithmId); algorithm.SetLiveMode(LiveMode); algorithm.SetLocked(); //Load the associated handlers for data, transaction and realtime events: ResultHandler.SetAlgorithm(algorithm); DataFeed = GetDataFeedHandler(algorithm, job); TransactionHandler = GetTransactionHandler(algorithm, _brokerage, ResultHandler, job); RealTimeHandler = GetRealTimeHandler(algorithm, _brokerage, DataFeed, ResultHandler, job); //Set the error handlers for the brokerage asynchronous errors. SetupHandler.SetupErrorHandler(ResultHandler, _brokerage); //Send status to user the algorithm is now executing. ResultHandler.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Running); //Launch the data, transaction and realtime handlers into dedicated threads threadFeed = new Thread(DataFeed.Run) {Name = "DataFeed Thread"}; threadTransactions = new Thread(TransactionHandler.Run) {Name = "Transaction Thread"}; threadRealTime = new Thread(RealTimeHandler.Run) {Name = "RealTime Thread"}; //Launch the data feed, result sending, and transaction models/handlers in separate threads. threadFeed.Start(); // Data feed pushing data packets into thread bridge; threadTransactions.Start(); // Transaction modeller scanning new order requests threadRealTime.Start(); // RealTime scan time for time based events: // Result manager scanning message queue: (started earlier) ResultHandler.DebugMessage(string.Format("Launching analysis for {0} with LEAN Engine v{1}", job.AlgorithmId, Constants.Version)); try { // Execute the Algorithm Code: var complete = Isolator.ExecuteWithTimeLimit(SetupHandler.MaximumRuntime, AlgorithmManager.TimeLoopWithinLimits, () => { try { //Run Algorithm Job: // -> Using this Data Feed, // -> Send Orders to this TransactionHandler, // -> Send Results to ResultHandler. AlgorithmManager.Run(job, algorithm, DataFeed, TransactionHandler, ResultHandler, SetupHandler, RealTimeHandler); } catch (Exception err) { //Debugging at this level is difficult, stack trace needed. Log.Error("Engine.Run", err); } Log.Trace("Engine.Run(): Exiting Algorithm Manager"); }, job.UserPlan == UserPlan.Free ? 1024 : MaximumRamAllocation); if (!complete) { Log.Error("Engine.Main(): Failed to complete in time: " + SetupHandler.MaximumRuntime.ToString("F")); throw new Exception("Failed to complete algorithm within " + SetupHandler.MaximumRuntime.ToString("F") + " seconds. Please make it run faster."); } // Algorithm runtime error: if (algorithm.RunTimeError != null) { throw algorithm.RunTimeError; } } catch (Exception err) { //Error running the user algorithm: purge datafeed, send error messages, set algorithm status to failed. Log.Error("Engine.Run(): Breaking out of parent try-catch: " + err.Message + " " + err.StackTrace); if (DataFeed != null) DataFeed.Exit(); if (ResultHandler != null) { var message = "Runtime Error: " + err.Message; Log.Trace("Engine.Run(): Sending runtime error to user..."); ResultHandler.LogMessage(message); ResultHandler.RuntimeError(message, err.StackTrace); Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, message + " Stack Trace: " + err.StackTrace); } } //Send result data back: this entire code block could be rewritten. // todo: - Split up statistics class, its enormous. // todo: - Make a dedicated Statistics.Benchmark class. // todo: - Move all creation and transmission of statistics out of primary engine loop. // todo: - Statistics.Generate(algorithm, resulthandler, transactionhandler); try { var charts = new Dictionary<string, Chart>(ResultHandler.Charts); var orders = new Dictionary<int, Order>(algorithm.Transactions.Orders); var holdings = new Dictionary<string, Holding>(); var statistics = new Dictionary<string, string>(); var banner = new Dictionary<string, string>(); try { //Generates error when things don't exist (no charting logged, runtime errors in main algo execution) const string strategyEquityKey = "Strategy Equity"; const string equityKey = "Equity"; const string dailyPerformanceKey = "Daily Performance"; // make sure we've taken samples for these series before just blindly requesting them if (charts.ContainsKey(strategyEquityKey) && charts[strategyEquityKey].Series.ContainsKey(equityKey) && charts[strategyEquityKey].Series.ContainsKey(dailyPerformanceKey)) { var equity = charts[strategyEquityKey].Series[equityKey].Values; var performance = charts[strategyEquityKey].Series[dailyPerformanceKey].Values; var profitLoss = new SortedDictionary<DateTime, decimal>(algorithm.Transactions.TransactionRecord); statistics = Statistics.Statistics.Generate(equity, profitLoss, performance, SetupHandler.StartingPortfolioValue, algorithm.Portfolio.TotalFees, 252); } } catch (Exception err) { Log.Error("Algorithm.Node.Engine(): Error generating statistics packet: " + err.Message); } //Diagnostics Completed, Send Result Packet: var totalSeconds = (DateTime.Now - startTime).TotalSeconds; ResultHandler.DebugMessage(string.Format("Algorithm Id:({0}) completed in {1} seconds at {2}k data points per second. Processing total of {3} data points.", job.AlgorithmId, totalSeconds.ToString("F2"), ((AlgorithmManager.DataPoints / (double)1000) / totalSeconds).ToString("F0"), AlgorithmManager.DataPoints.ToString("N0"))); ResultHandler.SendFinalResult(job, orders, algorithm.Transactions.TransactionRecord, holdings, statistics, banner); } catch (Exception err) { Log.Error("Engine.Main(): Error sending analysis result: " + err.Message + " ST >> " + err.StackTrace); } //Before we return, send terminate commands to close up the threads TransactionHandler.Exit(); DataFeed.Exit(); RealTimeHandler.Exit(); } //Close result handler: ResultHandler.Exit(); StateCheck.Ping.Exit(); //Wait for the threads to complete: var ts = Stopwatch.StartNew(); while ((ResultHandler.IsActive || (TransactionHandler != null && TransactionHandler.IsActive) || (DataFeed != null && DataFeed.IsActive)) && ts.ElapsedMilliseconds < 30 * 1000) { Thread.Sleep(100); Log.Trace("Waiting for threads to exit..."); } //Terminate threads still in active state. if (threadFeed != null && threadFeed.IsAlive) threadFeed.Abort(); if (threadTransactions != null && threadTransactions.IsAlive) threadTransactions.Abort(); if (threadResults != null && threadResults.IsAlive) threadResults.Abort(); if (statusPingThread != null && statusPingThread.IsAlive) statusPingThread.Abort(); if (_brokerage != null) { _brokerage.Disconnect(); } if (SetupHandler != null) { SetupHandler.Dispose(); } Log.Trace("Engine.Main(): Analysis Completed and Results Posted."); } catch (Exception err) { Log.Error("Engine.Main(): Error running algorithm: " + err.Message + " >> " + err.StackTrace); } finally { //No matter what for live mode; make sure we've set algorithm status in the API for "not running" conditions: if (LiveMode && AlgorithmManager.State != AlgorithmStatus.Running && AlgorithmManager.State != AlgorithmStatus.RuntimeError) Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmManager.State); //Delete the message from the job queue: JobQueue.AcknowledgeJob(job); Log.Trace("Engine.Main(): Packet removed from queue: " + job.AlgorithmId); //Attempt to clean up ram usage: GC.Collect(); } //Final disposals. Api.Dispose(); // Make the console window pause so we can read log output before exiting and killing the application completely if (IsLocal) { Log.Trace("Engine.Main(): Analysis Complete. Press any key to continue."); Console.Read(); } Log.LogHandler.Dispose(); }
/******************************************************** * CLASS METHODS *********************************************************/ /// <summary> /// Primary Analysis Thread: /// </summary> public static void Main(string[] args) { //Initialize: AlgorithmNodePacket job = null; var timer = Stopwatch.StartNew(); var algorithm = default(IAlgorithm); _version = DateTime.ParseExact(Config.Get("version", DateTime.Now.ToString(DateFormat.UI)), DateFormat.UI, CultureInfo.InvariantCulture); //Name thread for the profiler: Thread.CurrentThread.Name = "Algorithm Analysis Thread"; Log.Trace("Engine.Main(): LEAN ALGORITHMIC TRADING ENGINE v" + _version); Log.Trace("Engine.Main(): Started " + DateTime.Now.ToShortTimeString()); Log.Trace("Engine.Main(): Memory " + OS.ApplicationMemoryUsed + "Mb-App " + +OS.TotalPhysicalMemoryUsed + "Mb-Used " + OS.TotalPhysicalMemory + "Mb-Total"); //Import external libraries specific to physical server location (cloud/local) var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(@"../../Extensions")); var container = new CompositionContainer(catalog); try { // grab the right export based on configuration Notify = container.GetExportedValueByTypeName <IMessagingHandler>(Config.Get("messaging-handler")); Queue = container.GetExportedValueByTypeName <IQueueHandler>(Config.Get("queue-handler")); Api = container.GetExportedValueByTypeName <IApi>(Config.Get("api-handler")); } catch (CompositionException compositionException) { Log.Error("Engine.Main(): Failed to load library: " + compositionException); } //Setup packeting, queue and controls system: These don't do much locally. Api.Initialize(); Notify.Initialize(); Queue.Initialize(_liveMode); //Start monitoring the backtest active status: var statusPingThread = new Thread(StateCheck.Ping.Run); statusPingThread.Start(); do { try { //Reset algo manager internal variables preparing for a new algorithm. AlgorithmManager.ResetManager(); //Reset thread holders. var initializeComplete = false; Thread threadFeed = null; Thread threadTransactions = null; Thread threadResults = null; Thread threadRealTime = null; //-> Pull job from QuantConnect job queue, or, pull local build: var algorithmPath = ""; job = Queue.NextJob(out algorithmPath); // Blocking. //-> Initialize messaging system Notify.SetChannel(job.Channel); //-> Reset the backtest stopwatch; we're now running the algorithm. timer.Restart(); //-> Create SetupHandler to configure internal algorithm state: SetupHandler = GetSetupHandler(job.SetupEndpoint); //-> Set the result handler type for this algorithm job, and launch the associated result thread. ResultHandler = GetResultHandler(job); threadResults = new Thread(ResultHandler.Run, 0) { Name = "Result Thread" }; threadResults.Start(); try { // Save algorithm to cache, load algorithm instance: algorithm = SetupHandler.CreateAlgorithmInstance(algorithmPath); //Initialize the internal state of algorithm and job: executes the algorithm.Initialize() method. initializeComplete = SetupHandler.Setup(algorithm, out _brokerage, job); //If there are any reasons it failed, pass these back to the IDE. if (!initializeComplete || algorithm.ErrorMessages.Count > 0 || SetupHandler.Errors.Count > 0) { initializeComplete = false; //Get all the error messages: internal in algorithm and external in setup handler. var errorMessage = String.Join(",", algorithm.ErrorMessages); errorMessage += String.Join(",", SetupHandler.Errors); throw new Exception(errorMessage); } } catch (Exception err) { var runtimeMessage = "Algorithm.Initialize() Error: " + err.Message + " Stack Trace: " + err.StackTrace; ResultHandler.RuntimeError(runtimeMessage, err.StackTrace); Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, runtimeMessage); } //-> Using the job + initialization: load the designated handlers: if (initializeComplete) { //Set algorithm as locked; set it to live mode if we're trading live, and set it to locked for no further updates. algorithm.SetAlgorithmId(job.AlgorithmId); algorithm.SetLiveMode(LiveMode); algorithm.SetLocked(); //Load the associated handlers for data, transaction and realtime events: ResultHandler.SetAlgorithm(algorithm); DataFeed = GetDataFeedHandler(algorithm, job); TransactionHandler = GetTransactionHandler(algorithm, _brokerage, ResultHandler, job); RealTimeHandler = GetRealTimeHandler(algorithm, _brokerage, DataFeed, ResultHandler, job); //Set the error handlers for the brokerage asynchronous errors. SetupHandler.SetupErrorHandler(ResultHandler, _brokerage); //Send status to user the algorithm is now executing. ResultHandler.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Running); //Launch the data, transaction and realtime handlers into dedicated threads threadFeed = new Thread(DataFeed.Run, 0) { Name = "DataFeed Thread" }; threadTransactions = new Thread(TransactionHandler.Run, 0) { Name = "Transaction Thread" }; threadRealTime = new Thread(RealTimeHandler.Run, 0) { Name = "RealTime Thread" }; //Launch the data feed, result sending, and transaction models/handlers in separate threads. threadFeed.Start(); // Data feed pushing data packets into thread bridge; threadTransactions.Start(); // Transaction modeller scanning new order requests threadRealTime.Start(); // RealTime scan time for time based events: // Result manager scanning message queue: (started earlier) try { // Execute the Algorithm Code: var complete = Isolator.ExecuteWithTimeLimit(SetupHandler.MaximumRuntime, () => { try { //Run Algorithm Job: // -> Using this Data Feed, // -> Send Orders to this TransactionHandler, // -> Send Results to ResultHandler. AlgorithmManager.Run(job, algorithm, DataFeed, TransactionHandler, ResultHandler, SetupHandler, RealTimeHandler); } catch (Exception err) { //Debugging at this level is difficult, stack trace needed. Log.Error("Engine.Run(): Error in Algo Manager: " + err.Message + " ST >> " + err.StackTrace); } Log.Trace("Engine.Run(): Exiting Algorithm Manager"); }, MaximumRamAllocation); if (!complete) { Log.Error("Engine.Main(): Failed to complete in time: " + SetupHandler.MaximumRuntime.ToString("F")); throw new Exception("Failed to complete algorithm within " + SetupHandler.MaximumRuntime.ToString("F") + " seconds. Please make it run faster."); } // Algorithm runtime error: if (AlgorithmManager.RunTimeError != null) { throw AlgorithmManager.RunTimeError; } } catch (Exception err) { //Error running the user algorithm: purge datafeed, send error messages, set algorithm status to failed. Log.Error("Engine.Run(): Breaking out of parent try-catch: " + err.Message + " " + err.StackTrace); if (DataFeed != null) { DataFeed.Exit(); } if (ResultHandler != null) { var message = "Runtime Error: " + err.Message; Log.Trace("Engine.Run(): Sending runtime error to user..."); ResultHandler.LogMessage(message); ResultHandler.RuntimeError(message, err.StackTrace); Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, message + " Stack Trace: " + err.StackTrace); } } //Send result data back: this entire code block could be rewritten. // todo: - Split up statistics class, its enormous. // todo: - Make a dedicated Statistics.Benchmark class. // todo: - Move all creation and transmission of statistics out of primary engine loop. // todo: - Statistics.Generate(algorithm, resulthandler, transactionhandler); try { var charts = new Dictionary <string, Chart>(ResultHandler.Charts); var orders = new Dictionary <int, Order>(algorithm.Transactions.Orders); var holdings = new Dictionary <string, Holding>(); var statistics = new Dictionary <string, string>(); var banner = new Dictionary <string, string>(); try { //Generates error when things don't exist (no charting logged, runtime errors in main algo execution) const string strategyEquityKey = "Strategy Equity"; const string equityKey = "Equity"; const string dailyPerformanceKey = "Daily Performance"; // make sure we've taken samples for these series before just blindly requesting them if (charts.ContainsKey(strategyEquityKey) && charts[strategyEquityKey].Series.ContainsKey(equityKey) && charts[strategyEquityKey].Series.ContainsKey(dailyPerformanceKey)) { var equity = charts[strategyEquityKey].Series[equityKey].Values; var performance = charts[strategyEquityKey].Series[dailyPerformanceKey].Values; var profitLoss = new SortedDictionary <DateTime, decimal>(algorithm.Transactions.TransactionRecord); statistics = Statistics.Statistics.Generate(equity, profitLoss, performance, SetupHandler.StartingCapital, 252); } } catch (Exception err) { Log.Error("Algorithm.Node.Engine(): Error generating statistics packet: " + err.Message); } //Diagnostics Completed, Send Result Packet: ResultHandler.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") completed analysis in " + timer.Elapsed.TotalSeconds.ToString("F2") + " seconds"); ResultHandler.SendFinalResult(job, orders, algorithm.Transactions.TransactionRecord, holdings, statistics, banner); } catch (Exception err) { Log.Error("Engine.Main(): Error sending analysis result: " + err.Message + " ST >> " + err.StackTrace); } //Before we return, send terminate commands to close up the threads timer.Stop(); //Algorithm finished running. TransactionHandler.Exit(); DataFeed.Exit(); RealTimeHandler.Exit(); } //Close result handler: ResultHandler.Exit(); //Wait for the threads to complete: var ts = Stopwatch.StartNew(); while ((ResultHandler.IsActive || (TransactionHandler != null && TransactionHandler.IsActive) || (DataFeed != null && DataFeed.IsActive)) && ts.ElapsedMilliseconds < 30 * 1000) { Thread.Sleep(100); Log.Trace("Waiting for threads to exit..."); } if (threadFeed != null && threadFeed.IsAlive) { threadFeed.Abort(); } if (threadTransactions != null && threadTransactions.IsAlive) { threadTransactions.Abort(); } if (threadResults != null && threadResults.IsAlive) { threadResults.Abort(); } Log.Trace("Engine.Main(): Analysis Completed and Results Posted."); } catch (Exception err) { Log.Error("Engine.Main(): Error running algorithm: " + err.Message + " >> " + err.StackTrace); } finally { //Delete the message from the job queue: Queue.AcknowledgeJob(job); Log.Trace("Engine.Main(): Packet removed from queue: " + job.AlgorithmId); //No matter what for live mode; make sure we've set algorithm status in the API for "not running" conditions: if (LiveMode && AlgorithmManager.State != AlgorithmStatus.Running && AlgorithmManager.State != AlgorithmStatus.RuntimeError) { Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmManager.State); } //Attempt to clean up ram usage: GC.Collect(); } //If we're running locally will execute just once. } while (!IsLocal); // Send the exit signal and then kill the thread StateCheck.Ping.Exit(); // Make the console window pause so we can read log output before exiting and killing the application completely Console.ReadKey(); //Finally if ping thread still not complete, kill. if (statusPingThread != null && statusPingThread.IsAlive) { statusPingThread.Abort(); } }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler"></param> /// <param name="api"></param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { //Redirect the log messages here: _job = job; var desktopLogging = new FunctionalLogHandler(DebugMessage, DebugMessage, ErrorMessage); Log.LogHandler = new CompositeLogHandler(new[] { desktopLogging, Log.LogHandler }); }
/// <summary> /// Initialize the result handler with this result packet. /// </summary> /// <param name="job">Algorithm job packet for this result handler</param> /// <param name="messagingHandler"></param> /// <param name="api"></param> /// <param name="dataFeed"></param> /// <param name="setupHandler"></param> /// <param name="transactionHandler"></param> public void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, IDataFeed dataFeed, ISetupHandler setupHandler, ITransactionHandler transactionHandler) { _api = api; _dataFeed = dataFeed; _messagingHandler = messagingHandler; _setupHandler = setupHandler; _transactionHandler = transactionHandler; _job = (LiveNodePacket)job; if (_job == null) throw new Exception("LiveResultHandler.Constructor(): Submitted Job type invalid."); _deployId = _job.DeployId; _compileId = _job.CompileId; }