public async static Task <PacketBase> LoadLocalBacktest(string FileName) { if (string.IsNullOrEmpty(FileName)) { return(null); } if (!File.Exists(FileName)) { QCPluginUtilities.OutputCommandString("Backtest file doesn't exist " + FileName, QCPluginUtilities.Severity.Error); return(null); } string json = null; using (var reader = File.OpenText(FileName)) json = await reader.ReadToEndAsync(); var _results = JsonConvert.DeserializeObject <PacketBase>(json); _results.rawData = json; if (_results.Errors == null) { _results.Errors = new List <string>(); } return(_results); }
public static void UpdateLeanAndComposer(string pluginsPath) { if (string.IsNullOrEmpty(pluginsPath)) { QCPluginUtilities.OutputCommandString("Lean engine path is empty.", QCPluginUtilities.Severity.Error); composer = null; lean = null; return; } if (lean != null && composer != null && pluginsPath == _oldPluginsPath) { return; } _oldPluginsPath = pluginsPath; QCPluginUtilities.OutputCommandString("Started updating Lean engine and composer...", QCPluginUtilities.Severity.Info); AppDomain.CurrentDomain.SetData("APPBASE", pluginsPath); Environment.CurrentDirectory = pluginsPath; QCPluginUtilities.OutputCommandString("Using ApplicationDomain: " + AppDomain.CurrentDomain.BaseDirectory, QCPluginUtilities.Severity.Info); lean = new LeanProxy(); if (!string.IsNullOrEmpty(pluginsPath)) { lean.LoadLibraries(pluginsPath); var objVal = QCPluginUtilities.dte.Properties["QuantConnect Client", "General"].Item("PluginDirectory").Value; lean.SetConfiguration("plugin-directory", (string)objVal); } composer = lean.CreateComposer(); QCPluginUtilities.OutputCommandString("Finished updating Lean engine and composer...", QCPluginUtilities.Severity.Info); }
private async void ButtonSave_Click(object sender, EventArgs e) { buttonLogin.Enabled = false; UseWaitCursor = true; progressBar1.Visible = true; if (SuccessCallback != null) { try { await SuccessCallback(textBoxEmail.Text, textBoxPassword.Text, txtUID.Text, txtAuthToken.Text, checkBoxRememberCredentials.Checked); Close(); } catch (Exception ex) { progressBar1.Visible = false; buttonLogin.Enabled = true; QCPluginUtilities.OutputCommandString("Authentication Error: " + ex.ToString(), QCPluginUtilities.Severity.Error); } } else { Close(); } }
public static void Logout() { QCPluginUtilities.OutputCommandString("Removed user credentials.", QCPluginUtilities.Severity.Info); api.RemoveAuthentication(); var credentialFile = Path.Combine(QCPluginUtilities.InstallPath, "credentials.config"); if (File.Exists(credentialFile)) { File.Delete(credentialFile); } }
public async static void Login() { try { await Authenticate(); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Authentication error: " + ex.ToString(), QCPluginUtilities.Severity.Error); } }
private async void BacktestMenu_Click(object sender, ToolStripItemClickedEventArgs e) { if (dgrProjects.SelectedRows.Count == 0) { return; } var selproj = dgrProjects.SelectedRows[0].DataBoundItem as CombinedProject; if (selproj.Id == 0) { return; } var sourceControl = e.ClickedItem; if (sourceControl.Name == "RefreshBacktestsMenu") { dgrBacktests.DataSource = null; dgrBacktests.DataSource = await QCStudioPluginActions.GetBacktestList(selproj.Id); } else { if (dgrBacktests.SelectedRows.Count == 0) { return; } var selbacktest = dgrBacktests.SelectedRows[0].DataBoundItem as BacktestSummary; if (string.IsNullOrEmpty(selbacktest.BacktestId) || selbacktest.BacktestId == "0") { return; } switch (sourceControl.Name) { case "LoadBacktestMenu": QCPluginUtilities.ShowBacktestRemote(selbacktest.BacktestId); break; case "DeleteBacktestMenu": await QCStudioPluginActions.DeleteBacktest(selbacktest.BacktestId); RefreshBacktestsMenu.PerformClick(); break; case "SaveLocallyMenu": await QCStudioPluginActions.SaveRemoteBacktest(selbacktest.BacktestId); break; } } }
public async static Task DeleteProject(int ProjectID) { try { await Authenticate(); QCPluginUtilities.OutputCommandString("Deleting project...", QCPluginUtilities.Severity.Info); await api.ProjectDelete(ProjectID); QCPluginUtilities.OutputCommandString("Project deleted successfuly...", QCPluginUtilities.Severity.Info); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error deleting project: " + ex.ToString(), QCPluginUtilities.Severity.Error); } }
public async static Task DeleteBacktest(string BacktestID) { try { await Authenticate(); QCPluginUtilities.OutputCommandString("Deleting backtest...", QCPluginUtilities.Severity.Info); await api.BacktestDelete(BacktestID); QCPluginUtilities.OutputCommandString("Backtest deleted successfuly...", QCPluginUtilities.Severity.Info); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error deleting backtest: " + ex.ToString(), QCPluginUtilities.Severity.Error); } }
public async static Task <PacketBase> GetBacktestResults(string backtestId) { try { QCPluginUtilities.OutputCommandString("getting backtest results...", QCPluginUtilities.Severity.Info); var results = await api.BacktestResults(backtestId); return(results); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error getting backtest results: " + ex.ToString(), QCPluginUtilities.Severity.Error); } return(null); }
public async static Task CreateProject(string projectName) { try { await Authenticate(); QCPluginUtilities.OutputCommandString("Creating project...", QCPluginUtilities.Severity.Info); await api.ProjectCreate(projectName); QCPluginUtilities.OutputCommandString("Project created successfuly...", QCPluginUtilities.Severity.Info); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error creating project: " + ex.ToString(), QCPluginUtilities.Severity.Error); } }
public async static Task <List <BacktestSummary> > GetBacktestList(int ProjectID) { try { await Authenticate(); QCPluginUtilities.OutputCommandString("Receiving backtests...", QCPluginUtilities.Severity.Info); var backtests = await api.BacktestList(ProjectID); QCPluginUtilities.OutputCommandString("Backtests received successfuly...", QCPluginUtilities.Severity.Info); return(backtests.Summary); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error receiving backtests: " + ex.ToString(), QCPluginUtilities.Severity.Error); } return(null); }
public async static Task <bool> CreateBacktest(int ProjectID, string backtestName) { try { await Authenticate(); QCPluginUtilities.OutputCommandString("Building project...", QCPluginUtilities.Severity.Info); var res = await api.Compile(ProjectID); QCPluginUtilities.OutputCommandString("Running backtest...", QCPluginUtilities.Severity.Info); var backtestResult = await api.Backtest(ProjectID, res.CompileId, backtestName); if (string.IsNullOrEmpty(backtestResult.BacktestId) || backtestResult.BacktestId == "0") { throw new Exception("Failed to run backtest."); } QCPluginUtilities.OutputCommandString("Project Backtest created.", QCPluginUtilities.Severity.Info); return(true); } catch (Exception ex) { var msg = ex.Message; if (msg.Contains("Time out on build request")) { QCPluginUtilities.OutputCommandString("Build timed out, retrying...", QCPluginUtilities.Severity.Warning); return(false); } else if (msg.Contains("Please upgrade your account")) { QCPluginUtilities.OutputCommandString("You have reached the limit of 5 backtests per day via API on a free account. Please upgrade your account to unlock unlimited backtests.", QCPluginUtilities.Severity.Info); return(true); } else { QCPluginUtilities.OutputCommandString("Run backtest error: " + ex.ToString(), QCPluginUtilities.Severity.Error); return(true); } } }
public async static Task SaveRemoteBacktest(string backtestId) { await QCStudioPluginActions.Authenticate(); var _results = await QCStudioPluginActions.GetBacktestResults(backtestId); QCPluginUtilities.OutputCommandString("GetBacktestResults succeded: " + _results.Success, QCPluginUtilities.Severity.Info); foreach (var err in _results.Errors) { QCPluginUtilities.OutputCommandString(err, QCPluginUtilities.Severity.Error); } if (_results != null) { var dlg = new SaveFileDialog { AddExtension = true, Filter = "JSON file|*.json|All files|*.*", Title = "Save Backtest results to file" }; if (DialogResult.OK == dlg.ShowDialog()) { if (string.IsNullOrEmpty(dlg.FileName)) { return; } var json = JsonConvert.SerializeObject(_results); File.Delete(dlg.FileName); File.WriteAllText(dlg.FileName, json); } } else { QCPluginUtilities.OutputCommandString("No backtest results for: " + backtestId, QCPluginUtilities.Severity.Error); } }
public async static Task <List <CombinedProject> > GetProjectList() { try { await Authenticate(); QCPluginUtilities.OutputCommandString("Receiving projects...", QCPluginUtilities.Severity.Info); var projects = await api.ProjectList(); QCPluginUtilities.OutputCommandString("Projects received successfuly...", QCPluginUtilities.Severity.Info); //FULL OUTER JOIN !!! var alookup = QCPluginUtilities.GetAllProjects().Select(x => new KeyValuePair <int, dynamic>(x.Id, x)); var blookup = projects.Projects.Select(x => new KeyValuePair <int, dynamic>(x.Id, x)); var combproj = QCPluginUtilities.FullOuterJoin <int>(alookup, blookup); return(combproj .Select(x => new CombinedProject { Id = x.Item1, Name = x.Item3 != null ? x.Item3.Name : "", CloudProjectName = x.Item3 != null ? x.Item3.Name : "", Modified = x.Item3 != null ? x.Item3.Modified : DateTime.MinValue, LocalProjectName = x.Item2 != null ? x.Item2.name : "", LocalProjectPath = x.Item2 != null ? x.Item2.path : "", uniqueName = x.Item2 != null ? x.Item2.uniqueName : "" }) .ToList()); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error receiving projects: " + ex.ToString(), QCPluginUtilities.Severity.Error); } return(null); }
public async static Task SaveLocalBacktest(string pluginsPath, string dataPath) { string algorithmPath, className; QCPluginUtilities.GetSelectedItem(out algorithmPath, out className); if (algorithmPath == null || className == null) { return; } var json = await LeanActions.RunLocalBacktest(algorithmPath, className, pluginsPath, dataPath); if (json != null) { var dlg = new SaveFileDialog { AddExtension = true, Filter = "JSON file|*.json|All files|*.*", Title = "Save Backtest results to file" }; if (DialogResult.OK == dlg.ShowDialog()) { if (string.IsNullOrEmpty(dlg.FileName)) { return; } File.Delete(dlg.FileName); File.WriteAllText(dlg.FileName, json); } } else { QCPluginUtilities.OutputCommandString("No backtest results for: " + className, QCPluginUtilities.Severity.Error); } }
public static Task <string> RunLocalBacktest(string algorithmPath, string fileName, string pluginsPath, string dataPath) { var statistics = new Dictionary <string, string>(); var task = new TaskCompletionSource <string>(); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var timer = DateTime.Now; //lean.LoadLibraries(pluginsPath); UpdateLeanAndComposer(pluginsPath); if (lean == null || composer == null) { QCPluginUtilities.OutputCommandString("Failed to generate Lean proxy", QCPluginUtilities.Severity.Warning); task.SetException(new Exception("Failed to generate proxy")); return(task.Task); } try { //Config.Set("environment", ""); lean.SetConfiguration("environment", ""); //"backtesting-desktop" lean.SetConfiguration("data-folder", dataPath); lean.SetConfiguration("data-directory", dataPath); lean.SetConfiguration("algorithm-location", algorithmPath); lean.SetConfiguration("algorithm-type-name", fileName); //lean.SetConfiguration("api-access-token", ""); //lean.SetConfiguration("job-user-id", "0"); var props = TypeDescriptor.GetProperties(typeof(OptionPageGrid)).Cast <PropertyDescriptor>().Where(x => x.Category == "Configuration"); foreach (var prop in props) { var objVal = QCPluginUtilities.dte.Properties["QuantConnect Client", "General"].Item(prop.Name).Value; var strVal = objVal is bool?((bool)objVal).ToString().ToLower() : objVal.ToString(); lean.SetConfiguration(prop.DisplayName, strVal); } //Log.LogHandler = Composer.Instance.GetExportedValueByTypeName<ILogHandler>("QuantConnect.Logging.QueueLogHandler"); lean.SetLogHandler(composer, (packet) => { var json = JObject.FromObject(packet); var message = (json["sMessage"] ?? json["Message"] ?? JToken.FromObject("")).Value <string>(); var hstack = (json["sStackTrace"] ?? json["StackTrace"] ?? JToken.FromObject("")).Value <string>(); var msgtype = string.IsNullOrEmpty(hstack) ? QCPluginUtilities.Severity.Info : QCPluginUtilities.Severity.Error; QCPluginUtilities.OutputCommandString(message + ", " + hstack, msgtype); }); //var systemHandlers = LeanEngineSystemHandlers.FromConfiguration(Composer.Instance); var systemHandlers = lean.CreateLeanEngineSystemHandlers(composer); //var algorithmHandlers = LeanEngineAlgorithmHandlers.FromConfiguration(Composer.Instance); var algorithmHandlers = lean.CreateLeanEngineAlgorithmHandlers(composer); QCPluginUtilities.OutputCommandString("Running " + fileName + "...", QCPluginUtilities.Severity.Info); //var _messaging = systemHandlers.Notify; lean.AddMessagingEvents(systemHandlers, algorithmHandlers, (packet) => { var json = JObject.FromObject(packet); var message = (json["sMessage"] ?? json["Message"] ?? JToken.FromObject("")).Value <string>(); var hstack = (json["sStackTrace"] ?? json["StackTrace"] ?? JToken.FromObject("")).Value <string>(); var msgtype = string.IsNullOrEmpty(hstack) ? QCPluginUtilities.Severity.Info : QCPluginUtilities.Severity.Error; QCPluginUtilities.OutputCommandString(message + ", " + hstack, msgtype); }, (packet) => { var json = JObject.FromObject(packet); if (json["oResults"] == null && json["Results"] == null) { task.SetException(new Exception("No Backend Result!")); return; } var progress = (json["dProgress"] ?? json["Progress"] ?? JToken.FromObject("0")).Value <string>(); QCPluginUtilities.OutputCommandString("Backtest progress: " + progress, QCPluginUtilities.Severity.Info); if (progress == "1") { //result.Progress = "100%"; var strjson = json.ToString(Formatting.None); if (task.TrySetResult(strjson)) { tokenSource.Cancel(); (systemHandlers as IDisposable).Dispose(); (algorithmHandlers as IDisposable).Dispose(); } } }); string _algorithmPath; var job = lean.GetNextJob(systemHandlers, out _algorithmPath); //var engine = new Lean.Engine.Engine(systemHandlers, algorithmHandlers, false); var engine = lean.CreateEngine(systemHandlers, algorithmHandlers, false); Task.Run(() => { try { //engine.Run(job, _algorithmPath); lean.RunEngine(engine, job, _algorithmPath); QCPluginUtilities.OutputCommandString("Finished runnig backtest.", QCPluginUtilities.Severity.Info); } catch (Exception ex) { QCPluginUtilities.OutputCommandString(string.Format("{0} {1}", ex.ToString(), ex.StackTrace), QCPluginUtilities.Severity.Error); task.SetException(ex); } }, token); } catch (Exception ex) { QCPluginUtilities.OutputCommandString(string.Format("{0} {1}", ex.ToString(), ex.StackTrace), QCPluginUtilities.Severity.Error); task.SetException(ex); } return(task.Task); }
public async static Task Authenticate() { if (!api.IsAuthenticated) { var user = new User { Email = "", Password = "", AuthToken = "", UserID = "" }; var credentialFile = Path.Combine(QCPluginUtilities.InstallPath, "credentials.config"); QCPluginUtilities.OutputCommandString("Authenticating QC user...", QCPluginUtilities.Severity.Info); if (File.Exists(credentialFile)) { var userData = File.ReadAllText(credentialFile); var jsonUser = JsonConvert.DeserializeAnonymousType <User>(userData, user); user.Email = Encrypter.DecryptString(jsonUser.Email); user.Password = Encrypter.DecryptString(jsonUser.Password); user.UserID = Encrypter.DecryptString(jsonUser.UserID); user.AuthToken = Encrypter.DecryptString(jsonUser.AuthToken); } try { await api.Authenticate(user.Email, user.Password, user.UserID, user.AuthToken); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Authentication error: " + ex.ToString(), QCPluginUtilities.Severity.Error); QCPluginUtilities.OutputCommandString("Failed to authenticate. Enter credentials manually.", QCPluginUtilities.Severity.Info); bool remember = false; var win = new FormLogin(user.Email, user.Password, user.UserID, user.AuthToken); win.SuccessCallback = (email2, pass2, uid2, authtoken2, remember2) => { user.Email = Encrypter.EncryptString(email2); user.Password = Encrypter.EncryptString(pass2); user.UserID = Encrypter.EncryptString(uid2); user.AuthToken = Encrypter.EncryptString(authtoken2); remember = remember2; return(api.Authenticate(email2, pass2, uid2, authtoken2)); }; win.ShowDialog(); if (!api.IsAuthenticated) { throw new Exception("User authentication failed"); } else if (remember) { var jsonUser = JsonConvert.SerializeObject(user); if (File.Exists(credentialFile)) { File.Delete(credentialFile); } File.WriteAllText(credentialFile, jsonUser); } } QCPluginUtilities.OutputCommandString("User authenticated successfuly.", QCPluginUtilities.Severity.Info); } }
private async void ProjectsMenu_Click(object sender, ToolStripItemClickedEventArgs e) { var sourceControl = e.ClickedItem; switch (sourceControl.Name) { case "CreateProjectMenu": string projectName = QCPluginUtilities.GetStartupProjectName(); projectName = Microsoft.VisualBasic.Interaction.InputBox("Enter new project name", QCPluginUtilities.AppTitle, projectName); projectName = CleanInput(projectName); if (string.IsNullOrEmpty(projectName)) { QCPluginUtilities.OutputCommandString("Project name cannot be empty.", QCPluginUtilities.Severity.Error); return; } await QCStudioPluginActions.CreateProject(projectName); RefreshProjectsMenu.PerformClick(); break; case "LoginMenu": QCStudioPluginActions.Login(); break; case "LogoutMenu": QCStudioPluginActions.Logout(); break; case "RefreshProjectsMenu": dgrProjects.DataSource = await QCStudioPluginActions.GetProjectList(); var firstrow = dgrProjects.Rows.Cast <DataGridViewRow>().FirstOrDefault(x => (x.DataBoundItem as CombinedProject).Id > 0); if (firstrow != null) { firstrow.Selected = true; } RefreshBacktestsMenu.PerformClick(); break; case "ConnectProjectIDMenu": var projects = dgrProjects.DataSource as List <CombinedProject>; var cloudproj = projects.Where(x => string.IsNullOrEmpty(x.LocalProjectName)).ToArray(); var localproj = projects.Where(x => x.Id == 0).ToArray(); if (localproj.Length == 0 || cloudproj.Length == 0) { QCPluginUtilities.OutputCommandString("No orphaned projects found on both cloud and local side.", QCPluginUtilities.Severity.Error); return; } var win = new ConnectQCID(); win.cmbCloud.Items.AddRange(cloudproj); win.cmbLocal.Items.AddRange(localproj); if (dgrProjects.SelectedRows.Count > 0) { var selproj2 = dgrProjects.SelectedRows[0].DataBoundItem as CombinedProject; win.cmbCloud.SelectedItem = selproj2; win.cmbLocal.SelectedItem = selproj2; } var dlgres = win.ShowDialog(); if (dlgres == DialogResult.OK) { var selID = win.cmbCloud.SelectedItem as CombinedProject; var selName = win.cmbLocal.SelectedItem as CombinedProject; QCPluginUtilities.SetProjectID(selID.Id, selName.uniqueName); RefreshProjectsMenu.PerformClick(); } break; default: if (dgrProjects.SelectedRows.Count == 0) { return; } var selproj = dgrProjects.SelectedRows[0].DataBoundItem as CombinedProject; if (selproj.Id == 0) { return; } switch (sourceControl.Name) { case "DeleteProjectMenu": await QCStudioPluginActions.DeleteProject(selproj.Id); QCPluginUtilities.SetProjectID(0, selproj.uniqueName); RefreshProjectsMenu.PerformClick(); break; case "UploadProjectMenu": if (string.IsNullOrEmpty(selproj.LocalProjectPath)) { return; } await QCStudioPluginActions.UploadProject(selproj.Id, selproj.CloudProjectName, selproj.LocalProjectPath); break; case "DownloadProjectMenu": await QCStudioPluginActions.DownloadProject(selproj.Id, selproj.CloudProjectName, selproj.LocalProjectName, selproj.LocalProjectPath); break; case "DisconnectProjectIDMenu": QCPluginUtilities.SetProjectID(0, selproj.uniqueName); RefreshProjectsMenu.PerformClick(); break; case "CompileProjectMenu": string backtestName = QCPluginUtilities.GetStartupProjectName(); backtestName = Microsoft.VisualBasic.Interaction.InputBox("Enter new backtest name", QCPluginUtilities.AppTitle, backtestName); backtestName = CleanInput(backtestName); if (string.IsNullOrWhiteSpace(backtestName)) { QCPluginUtilities.OutputCommandString("Backtest name cannot be empty.", QCPluginUtilities.Severity.Error); return; } var isfinished = false; var cnt = 0; while (!isfinished && cnt++ < 5) { isfinished = await QCStudioPluginActions.CreateBacktest(selproj.Id, backtestName); } break; } break; } }
public async static Task DownloadProject(int ProjectID, string cloudProjectName, string ProjectName, string ProjectDir) { try { await Authenticate(); var fileList = new Dictionary <string, string>(); SavetoCloud_AddSubdirectoryToFileList(ProjectDir, ProjectDir, fileList); var cloudfiles = await api.ProjectFiles(ProjectID); //FULL OUTER JOIN !!! var alookup = fileList.Select(x => new KeyValuePair <string, dynamic>(x.Key, new QCFile(x.Key, x.Value))); var blookup = cloudfiles.Files.Select(x => new KeyValuePair <string, dynamic>(x.Name, x)); var combolist = QCPluginUtilities.FullOuterJoin <string>(alookup, blookup); var rows = combolist.Select(x => { var row = new DataGridViewRow(); var chkaction = new DataGridViewCheckBoxCell() { Value = false, Tag = x.Item3 }; row.Cells.Add(new DataGridViewTextBoxCell() { Value = x.Item3 != null ? x.Item3.Name : "" }); row.Cells.Add(chkaction); row.Cells.Add(new DataGridViewTextBoxCell() { Value = x.Item2 != null ? x.Item2.Name : "" }); if (x.Item3 == null) { chkaction.Style.BackColor = Color.LightGray; chkaction.ReadOnly = true; } return(row); }).ToArray(); var form = new ChooseFiles(); form.Text = "Download files from " + cloudProjectName; form.chkAction.HeaderText = "Download"; form.dgrFiles.Rows.AddRange(rows); var res = form.ShowDialog(); if (res != System.Windows.Forms.DialogResult.OK) { return; } var parsed_filesList = form.dgrFiles.Rows.Cast <DataGridViewRow>() .Where(x => (x.Cells[1] as DataGridViewCheckBoxCell).Selected) .Select(x => x.Cells[1].Tag as QCFile) .ToList(); QCPluginUtilities.UpdateLocalProject(parsed_filesList, ProjectName); QCPluginUtilities.OutputCommandString("Project created successfuly...", QCPluginUtilities.Severity.Info); } catch (Exception ex) { QCPluginUtilities.OutputCommandString("Error creating project: " + ex.ToString(), QCPluginUtilities.Severity.Error); } }