示例#1
0
        private int?CreateQuantConnectProject(string projectName, Language projectLanguage)
        {
            var api             = AuthorizationManager.GetInstance().GetApi();
            var projectResponse = api.CreateProject(projectName, projectLanguage);

            if (!projectResponse.Success)
            {
                return(null);
            }
            return(projectResponse.Projects[0].ProjectId);
        }
示例#2
0
        private void RegisterLogoutCommand(OleMenuCommandService commandService)
        {
            var menuCommandId  = new CommandID(_commandSet, _logoutCommandId);
            var logoutMenuItem = new OleMenuCommand(LogoutCallback, menuCommandId);

            logoutMenuItem.BeforeQueryStatus += (sender, evt) =>
            {
                logoutMenuItem.Enabled = AuthorizationManager.GetInstance().IsLoggedIn();
            };
            commandService.AddCommand(logoutMenuItem);
        }
示例#3
0
        private bool LoggedInWithLastStorredPassword(Credentials?previousCredentials)
        {
            if (!previousCredentials.HasValue)
            {
                return(false);
            }

            var credentials = previousCredentials.Value;

            return(AuthorizationManager.GetInstance().Login(credentials));
        }
        private void UploadFilesToServer(int selectedProjectId, List <SelectedItem> files)
        {
            var api = AuthorizationManager.GetInstance().GetApi();

            foreach (var file in files)
            {
                api.DeleteProjectFile(selectedProjectId, file.FileName);
                var fileContent = File.ReadAllText(file.FilePath);
                api.AddProjectFile(selectedProjectId, file.FileName, fileContent);
            }
        }
示例#5
0
        /// <summary>
        /// Callback for the delete button in the backtest data grid, shared by all rows. Deletes backtest.
        /// </summary>
        private async void Delete_OnClick(object sender, RoutedEventArgs e)
        {
            var obj = ((FrameworkElement)sender).DataContext as DataGridItem;

            if (obj != null)
            {
                var projectId  = obj.ProjectId;
                var backtestId = obj.BacktestId;
                VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Deleting backtest...");
                var deleteResult = false;
                if (await _authenticationCommand.Login(ServiceProvider.GlobalProvider, false))
                {
                    try
                    {
                        deleteResult = await System.Threading.Tasks.Task.Run(() =>
                        {
                            var api = AuthorizationManager.GetInstance().GetApi();
                            return(api.DeleteBacktest(projectId, backtestId).Success);
                        });
                    }
                    catch (Exception exception)
                    {
                        VsUtils.ShowErrorMessageBox(ServiceProvider.GlobalProvider,
                                                    "QuantConnect Exception", exception.ToString());
                    }
                }
                if (deleteResult)
                {
                    var selectedItem = projectNameBox.SelectedItem as ComboboxProjectItem;
                    // Verify the backtest is from the selected project
                    if (selectedItem?.Id == projectId)
                    {
                        lock (_dataGridCollection)
                        {
                            foreach (DataGridItem item in _dataGridCollection)
                            {
                                if (item.BacktestId == backtestId)
                                {
                                    _dataGridCollection.Remove(item);
                                    break;
                                }
                            }
                        }
                    }
                    VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Successfully deleted backtest");
                }
                else
                {
                    VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Error when deleting backtest");
                }
            }
        }
        private Api.Compile CompileProjectOnServer(int projectId)
        {
            var api           = AuthorizationManager.GetInstance().GetApi();
            var compileStatus = api.CreateCompile(projectId);
            var compileId     = compileStatus.CompileId;

            while (compileStatus.State == Api.CompileState.InQueue)
            {
                Thread.Sleep(5000);
                compileStatus = api.ReadCompile(projectId, compileId);
            }
            return(compileStatus);
        }
        private Api.Backtest BacktestProjectOnServer(int projectId, string compileId)
        {
            var api            = AuthorizationManager.GetInstance().GetApi();
            var backtestStatus = api.CreateBacktest(projectId, compileId, "My New Backtest");
            var backtestId     = backtestStatus.BacktestId;

            while (!backtestStatus.Completed)
            {
                Thread.Sleep(5000);
                backtestStatus = api.ReadBacktest(projectId, backtestId);
            }
            return(backtestStatus);
        }
示例#8
0
        private async void ExecuteOnProjectAsync(object sender, Action <int, string, List <SelectedItem> > onProject)
        {
            if (await _authenticationCommand.Login(_serviceProvider, false))
            {
                var projects = await System.Threading.Tasks.Task.Run(() =>
                {
                    var api = AuthorizationManager.GetInstance().GetApi();
                    return(api.ListProjects().Projects);
                });

                var projectNames = projects.Select(p => Tuple.Create(p.ProjectId, p.Name)).ToList();

                var files                = GetSelectedFiles(sender);
                var fileNames            = files.Select(tuple => tuple.FileName).ToList();
                var suggestedProjectName = _lazyProjectFinder.ProjectNameForFiles(fileNames);
                var projectNameDialog    = new ProjectNameDialog(projectNames, suggestedProjectName);
                VsUtils.DisplayDialogWindow(projectNameDialog);

                if (projectNameDialog.ProjectNameProvided)
                {
                    var selectedProjectName = projectNameDialog.SelectedProjectName;
                    var selectedProjectId   = projectNameDialog.SelectedProjectId;
                    _lazyProjectFinder.AssociateProjectWith(selectedProjectName, fileNames);

                    if (!selectedProjectId.HasValue)
                    {
                        var newProjectLanguage = PathUtils.DetermineProjectLanguage(files.Select(f => f.FilePath).ToList());
                        if (!newProjectLanguage.HasValue)
                        {
                            VsUtils.ShowMessageBox(_serviceProvider, "Failed to determine project language",
                                                   $"Failed to determine programming laguage for a project");
                            return;
                        }

                        selectedProjectId = CreateQuantConnectProject(selectedProjectName, newProjectLanguage.Value);
                        if (!selectedProjectId.HasValue)
                        {
                            VsUtils.ShowMessageBox(_serviceProvider, "Failed to create a project", $"Failed to create a project {selectedProjectName}");
                        }
                        onProject.Invoke(selectedProjectId.Value, selectedProjectName, files);
                    }
                    else
                    {
                        onProject.Invoke(selectedProjectId.Value, selectedProjectName, files);
                    }
                }
            }
        }
示例#9
0
        /// <summary>
        /// Updates available backtests in the backtest data grid for a specific project
        /// </summary>
        /// <param name="projectId">Target project id</param>
        private async void UpdateAvailableBacktests(int projectId)
        {
            VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Loading project backtests...");
            if (await _authenticationCommand.Login(ServiceProvider.GlobalProvider, false))
            {
                try
                {
                    var backtestsList = await System.Threading.Tasks.Task.Run(() =>
                    {
                        var api    = AuthorizationManager.GetInstance().GetApi();
                        var result = api.ListBacktests(projectId);
                        return(result.Backtests);
                    });

                    var selectedItem = projectNameBox.SelectedItem as ComboboxProjectItem;
                    // Verify the backtest are from the selected project
                    if (selectedItem?.Id == projectId)
                    {
                        lock (_dataGridCollection)
                        {
                            _dataGridCollection.Clear();
                            // Setting a limit of _maximumBacktestToShow backtests in the table...
                            for (var i = 0; i < backtestsList.Count && i < _maximumBacktestToShow; i++)
                            {
                                _dataGridCollection.Add(new DataGridItem
                                {
                                    Name       = backtestsList[i].Name,
                                    Progress   = backtestsList[i].Progress,
                                    ProjectId  = projectId,
                                    Date       = backtestsList[i].Created,
                                    BacktestId = backtestsList[i].BacktestId,
                                    Status     = string.IsNullOrEmpty(backtestsList[i].Error) ?
                                                 DataGridItem.BacktestSucceeded : DataGridItem.BacktestFailed,
                                    Note = backtestsList[i].Note
                                });
                            }
                        }
                        VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Successfully loaded backtests");
                    }
                }
                catch (Exception exception)
                {
                    VsUtils.ShowErrorMessageBox(ServiceProvider.GlobalProvider,
                                                "QuantConnect Exception", exception.ToString());
                }
            }
        }
示例#10
0
        /// <summary>
        /// Uploads a list of files to a specific project at QuantConnect
        /// </summary>
        /// <param name="selectedProjectId">Target project Id</param>
        /// <param name="files">List of files to upload</param>
        /// <returns>Returns false if any file failed to be uploaded</returns>
        private bool UploadFilesToServer(int selectedProjectId, IEnumerable <SelectedItem> files)
        {
            VsUtils.DisplayInStatusBar(_serviceProvider, "Uploading files to server...");
            var api = AuthorizationManager.GetInstance().GetApi();
            // Counters to keep track of files uploaded or not
            var filesUploaded    = 0;
            var filesNotUploaded = 0;

            foreach (var file in files)
            {
                api.DeleteProjectFile(selectedProjectId, file.FileName);
                try
                {
                    var fileContent = File.ReadAllText(file.FilePath);
                    var response    = api.AddProjectFile(selectedProjectId, file.FileName, fileContent);
                    if (response.Success)
                    {
                        filesUploaded++;
                    }
                    else
                    {
                        VSActivityLog.Error("Failed to add project file " + file.FileName);
                        filesNotUploaded++;
                    }
                }
                catch (Exception exception)
                {
                    VSActivityLog.Error("Exception adding project file " + file.FileName + ". Exception " + exception);
                    filesNotUploaded++;
                }
            }
            // Update Status bar accordingly based on counters
            var message = "Files upload complete";

            message += (filesUploaded != 0) ? ". Uploaded " + filesUploaded : "";
            message += (filesNotUploaded != 0) ? ". Failed to upload " + filesNotUploaded : "";
            VsUtils.DisplayInStatusBar(_serviceProvider, message);

            // Return false if any file failed to be uploaded
            var result = filesNotUploaded == 0;

            if (!result)
            {
                VsUtils.ShowErrorMessageBox(_serviceProvider, "Upload Files Failed", message);
            }
            return(result);
        }
        private void ExecuteOnProject(object sender, Action <int, string, List <SelectedItem> > onProject)
        {
            if (_logInCommand.DoLogIn(this.ServiceProvider, _package.DataPath, explicitLogin: false))
            {
                var api          = AuthorizationManager.GetInstance().GetApi();
                var projects     = api.ListProjects().Projects;
                var projectNames = projects.Select(p => Tuple.Create(p.ProjectId, p.Name)).ToList();

                var files                = GetSelectedFiles(sender);
                var fileNames            = files.Select(tuple => tuple.FileName).ToList();
                var suggestedProjectName = ProjectFinder.ProjectNameForFiles(fileNames);
                var projectNameDialog    = new ProjectNameDialog(projectNames, suggestedProjectName);
                VsUtils.DisplayDialogWindow(projectNameDialog);

                if (projectNameDialog.ProjectNameProvided())
                {
                    var selectedProjectName = projectNameDialog.GetSelectedProjectName();
                    var selectedProjectId   = projectNameDialog.GetSelectedProjectId();
                    ProjectFinder.AssociateProjectWith(selectedProjectName, fileNames);

                    if (!selectedProjectId.HasValue)
                    {
                        var newProjectLanguage = PathUtils.DetermineProjectLanguage(files.Select(f => f.FilePath).ToList());
                        if (!newProjectLanguage.HasValue)
                        {
                            VsUtils.ShowMessageBox(this.ServiceProvider, "Failed to determine project language",
                                                   $"Failed to determine programming laguage for a project");
                            return;
                        }

                        selectedProjectId = CreateQuantConnectProject(selectedProjectName, newProjectLanguage.Value);
                        if (!selectedProjectId.HasValue)
                        {
                            VsUtils.ShowMessageBox(this.ServiceProvider, "Failed to create a project", $"Failed to create a project {selectedProjectName}");
                        }
                        onProject.Invoke(selectedProjectId.Value, selectedProjectName, files);
                    }
                    else
                    {
                        onProject.Invoke(selectedProjectId.Value, selectedProjectName, files);
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Callback for the new project button. Will show a new popup so the user can select name and language
        /// Will create project calling the server through API.
        /// </summary>
        private async void NewProjectButton_OnClick(object sender, RoutedEventArgs e)
        {
            var window = new NewProjectDialog();

            VsUtils.DisplayDialogWindow(window);
            if (window.CreateNewProject &&
                await _authenticationCommand.Login(ServiceProvider.GlobalProvider, false))
            {
                var result    = false;
                var projectId = 0;
                try
                {
                    var apiResponse = await System.Threading.Tasks.Task.Run(() =>
                    {
                        var api = AuthorizationManager.GetInstance().GetApi();
                        return(api.CreateProject(window.NewProjectName, window.NewProjectLanguage));
                    });

                    if (apiResponse.Success && apiResponse.Projects.Count > 0)
                    {
                        result    = true;
                        projectId = apiResponse.Projects.First().ProjectId;
                    }
                }
                catch (Exception exception)
                {
                    VsUtils.ShowErrorMessageBox(ServiceProvider.GlobalProvider,
                                                "QuantConnect Exception", exception.ToString());
                }
                if (result)
                {
                    // lets update the combo box without having to go to the server again
                    var newProject = new ComboboxProjectItem(projectId, window.NewProjectName, window.NewProjectLanguage);
                    projectNameBox.Items.Add(newProject);
                    projectNameBox.SelectedItem = newProject;
                    VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Successfully created a new project");
                }
                else
                {
                    VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Failed to create a new project");
                }
            }
        }
示例#13
0
        /// <summary>
        /// Callback for the edit button. Will show a new popup so the user can edit backtest name and note.
        /// Will update the server through API.
        /// </summary>
        private async void Edit_OnClick(object sender, RoutedEventArgs e)
        {
            var obj = ((FrameworkElement)sender).DataContext as DataGridItem;

            if (obj != null)
            {
                var projectId    = obj.ProjectId;
                var backtestId   = obj.BacktestId;
                var backtestNote = obj.Note;
                var window       = new EditBacktestDialog(obj.Name, backtestNote);
                VsUtils.DisplayDialogWindow(window);
                if (window.BacktestNameProvided &&
                    !string.IsNullOrEmpty(window.BacktestName) &&
                    await _authenticationCommand.Login(ServiceProvider.GlobalProvider, false))
                {
                    var result = false;
                    try
                    {
                        result = await System.Threading.Tasks.Task.Run(() =>
                        {
                            var api = AuthorizationManager.GetInstance().GetApi();
                            return(api.UpdateBacktest(projectId, backtestId, window.BacktestName, window.BacktestNote).Success);
                        });
                    }
                    catch (Exception exception)
                    {
                        VsUtils.ShowErrorMessageBox(ServiceProvider.GlobalProvider,
                                                    "QuantConnect Exception", exception.ToString());
                    }
                    if (result)
                    {
                        // lets update the data grid without having to go to the server again
                        obj.Name = window.BacktestName;
                        obj.Note = window.BacktestNote;
                        VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Successfully edited backtest");
                    }
                    else
                    {
                        VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Failed to edit backtest");
                    }
                }
            }
        }
示例#14
0
        private bool LoginWithDialog(IServiceProvider serviceProvider, Credentials?previousCredentials)
        {
            var logInDialog = new LoginDialog(AuthorizationManager.GetInstance(), previousCredentials, serviceProvider);

            VsUtils.DisplayDialogWindow(logInDialog);

            var credentials = logInDialog.GetCredentials();

            if (credentials.HasValue)
            {
                VSActivityLog.Info("Storing credentials");
                CredentialsManager.StoreCredentials(credentials.Value);
                return(true);
            }
            else
            {
                VSActivityLog.Info("Login cancelled");
                return(false);
            }
        }
示例#15
0
        /// <summary>
        /// Updates available projects in the combo box
        /// </summary>
        public async void UpdateAvailableProjects(bool showLoginDialog = true)
        {
            VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Loading available projects...");
            if (await _authenticationCommand.Login(ServiceProvider.GlobalProvider, false, showLoginDialog))
            {
                try
                {
                    var projectNames = await System.Threading.Tasks.Task.Run(() =>
                    {
                        var api      = AuthorizationManager.GetInstance().GetApi();
                        var projects = api.ListProjects().Projects;
                        return(projects.Select(p => Tuple.Create(p.ProjectId, p.Name, p.Language)).ToList());
                    });

                    // Clear available projects
                    projectNameBox.Items.Clear();
                    lock (_dataGridCollection)
                    {
                        // Clear rows in the backtest data grid
                        _dataGridCollection.Clear();
                    }
                    if (projectNames.Count > 0)
                    {
                        projectNames.ForEach(p => projectNameBox.Items.Add(new ComboboxProjectItem(p.Item1, p.Item2, p.Item3)));
                        VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "Successfully loaded projects");
                        // Select first project and load available backtest
                        var project = projectNameBox.Items[0] as ComboboxProjectItem;
                        projectNameBox.SelectedItem = project;
                    }
                    else
                    {
                        VsUtils.DisplayInStatusBar(ServiceProvider.GlobalProvider, "No projects available");
                    }
                }
                catch (Exception exception)
                {
                    VsUtils.ShowErrorMessageBox(ServiceProvider.GlobalProvider,
                                                "QuantConnect Exception", exception.ToString());
                }
            }
        }
        private bool LogInWithDialog(IServiceProvider serviceProvider, Credentials?previousCredentials, string dataFolderPath)
        {
            var logInDialog = new LogInDialog(AuthorizationManager.GetInstance(), previousCredentials, dataFolderPath);

            VsUtils.DisplayDialogWindow(logInDialog);

            var credentials = logInDialog.GetCredentials();

            if (credentials.HasValue)
            {
                _log.Info("Logged in successfully");
                _log.Info("Storring credentials");
                _credentialsManager.StoreCredentials(credentials.Value);
                VsUtils.DisplayInStatusBar(serviceProvider, "Logged into QuantConnect");
                return(true);
            }
            else
            {
                _log.Info("Log in cancelled");
                return(false);
            }
        }
示例#17
0
        /// <summary>
        /// Perform QuantConnect authentication
        /// </summary>
        /// <param name="serviceProvider">Visual Studio services provider</param>
        /// <param name="explicitLogin">User explicitly clicked Log In button</param>
        /// <returns>true if user logged into QuantConnect, false otherwise</returns>
        public bool Login(IServiceProvider serviceProvider, bool explicitLogin)
        {
            VSActivityLog.Info("Logging in");

            var authorizationManager = AuthorizationManager.GetInstance();

            if (authorizationManager.IsLoggedIn())
            {
                VSActivityLog.Info("Already logged in");
                return(true);
            }

            var previousCredentials = CredentialsManager.GetLastCredential();

            if (!explicitLogin && LoggedInWithLastStorredPassword(previousCredentials))
            {
                VSActivityLog.Info("Logged in with previously storred credentials");
                return(true);
            }

            return(LoginWithDialog(serviceProvider, previousCredentials));
        }
示例#18
0
        /// <summary>
        /// Backtests specific projectId and compileId at QuantConnect
        /// </summary>
        /// <param name="projectId">Target project Id</param>
        /// <param name="compileId">Target compile Id</param>
        /// <returns>Tuple&lt;bool, string&gt;. Item1 is true if backtest succeeded.
        /// Item2 is error message if backtest failed.</returns>
        private Tuple <bool, string> BacktestProjectOnServer(int projectId, string compileId)
        {
            VsUtils.DisplayInStatusBar(_serviceProvider, "Backtesting project...");
            var api            = AuthorizationManager.GetInstance().GetApi();
            var backtestStatus = api.CreateBacktest(projectId, compileId, "My New Backtest");
            var backtestId     = backtestStatus.BacktestId;

            while (!backtestStatus.Completed)
            {
                Thread.Sleep(5000);
                backtestStatus = api.ReadBacktest(projectId, backtestId);
            }

            if (!string.IsNullOrEmpty(backtestStatus.Error))
            {
                VsUtils.DisplayInStatusBar(_serviceProvider, "Error when backtesting project");
                return(new Tuple <bool, string>(false, backtestStatus.Error));
            }
            var successMessage = "Backtest completed successfully";

            VsUtils.DisplayInStatusBar(_serviceProvider, successMessage);
            return(new Tuple <bool, string>(true, successMessage));
        }
示例#19
0
        /// <summary>
        /// Backtests specific projectId and compileId at QuantConnect
        /// </summary>
        /// <param name="projectId">Target project Id</param>
        /// <param name="compileId">Target compile Id</param>
        /// <returns>Tuple&lt;bool, string&gt;. Item1 is true if backtest succeeded.
        /// Item2 is error message if backtest failed.</returns>
        private async Task <Tuple <bool, string> > BacktestProjectOnServer(int projectId, string compileId)
        {
            VsUtils.DisplayInStatusBar(_serviceProvider, "Backtesting project...");
            var api            = AuthorizationManager.GetInstance().GetApi();
            var backtestName   = BacktestNameProvider.GetNewName();
            var backtestStatus = await System.Threading.Tasks.Task.Run(() => api.CreateBacktest(projectId, compileId, backtestName));

            var backtestId = backtestStatus.BacktestId;

            // Notify observer new backtest
            _backtestObserver.BacktestCreated(projectId, backtestStatus);

            var errorPresent = false;

            while (backtestStatus.Progress < 1 && !errorPresent)
            {
                backtestStatus = await System.Threading.Tasks.Task.Delay(4000).
                                 ContinueWith(_ => api.ReadBacktest(projectId, backtestId));

                errorPresent = !string.IsNullOrEmpty(backtestStatus.Error) ||
                               !string.IsNullOrEmpty(backtestStatus.StackTrace);
                // Notify observer backtest status
                _backtestObserver.BacktestStatusUpdated(projectId, backtestStatus);
            }

            // Notify observer backtest finished
            _backtestObserver.BacktestFinished(projectId, backtestStatus);
            if (errorPresent)
            {
                VsUtils.DisplayInStatusBar(_serviceProvider, "Error when backtesting project");
                return(new Tuple <bool, string>(false, backtestStatus.Error));
            }
            var successMessage = "Backtest completed successfully";

            VsUtils.DisplayInStatusBar(_serviceProvider, successMessage);
            return(new Tuple <bool, string>(true, successMessage));
        }
示例#20
0
        /// <summary>
        /// Compiles specific projectId at QuantConnect
        /// </summary>
        /// <param name="projectId">Target project Id</param>
        /// <returns>Tuple&lt;bool, string&gt;. Item1 is true if compilation succeeded.
        /// Item2 is compile Id if compilation succeeded else error message.</returns>
        private Tuple <bool, string> CompileProjectOnServer(int projectId)
        {
            VsUtils.DisplayInStatusBar(_serviceProvider, "Compiling project...");
            var api           = AuthorizationManager.GetInstance().GetApi();
            var compileStatus = api.CreateCompile(projectId);
            var compileId     = compileStatus.CompileId;

            while (compileStatus.State == Api.CompileState.InQueue)
            {
                Thread.Sleep(2000);
                compileStatus = api.ReadCompile(projectId, compileId);
            }

            if (compileStatus.State == Api.CompileState.BuildError)
            {
                // Default to show Errors, now it is coming empty so use Logs. Will only show First Error || Log
                var error = compileStatus.Errors.Count == 0 ?
                            compileStatus.Logs.FirstOrDefault() : compileStatus.Errors.FirstOrDefault();
                VsUtils.DisplayInStatusBar(_serviceProvider, "Error when compiling project");
                return(new Tuple <bool, string>(false, error));
            }
            VsUtils.DisplayInStatusBar(_serviceProvider, "Compilation completed successfully");
            return(new Tuple <bool, string>(true, compileStatus.CompileId));
        }
示例#21
0
 /// <summary>
 /// Log out QuantConnect API
 /// </summary>
 /// <param name="serviceProvider">Visual Studio service provider</param>
 public void Logout(IServiceProvider serviceProvider)
 {
     AuthorizationManager.GetInstance().Logout();
     VsUtils.DisplayInStatusBar(serviceProvider, "Logged out of QuantConnect");
 }
 /// <summary>
 /// Log out QuantConnect API
 /// </summary>
 /// <param name="serviceProvider">Visual Studio service provider</param>
 public void DoLogOut(IServiceProvider serviceProvider)
 {
     _credentialsManager.ForgetCredentials();
     AuthorizationManager.GetInstance().LogOut();
     VsUtils.DisplayInStatusBar(serviceProvider, "Logged out of QuantConnect");
 }