using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Xml; using TradeIdeas.XML; using System.Windows.Forms; using TradeIdeas.TIProGUI; using TradeIdeas.TIProData; using TradeIdeas.TIProData.Configuration; using TradeIdeas.MiscSupport; using TradeIdeas.TIProGUI.OddsMaker; using System.IO; using TradeIdeas.TIProData.Interfaces; namespace TIProAutoTradeExtension { public partial class StrategyGrid : UserControl, IRobotSaveable, IFont { public event RobotMessageSentHandler MessageSent; /// /// Fires when a trading strategy is changed by the user. Can be either a status change or a edit by the user. /// public event TradingStrategyUserChangedHandler TradingStrategyUserChanged; private BindingListWithRemoving _filteredStrategies = new BindingListWithRemoving(); private BindingListWithRemoving _strategies = new BindingListWithRemoving(); private BindingList _rowDatas = new BindingList(); private TradingStrategy _currentTradingStrategy = null; private TradingStrategy _mostRecentTradingStrategy = null; private int _mostRecentRowIndex = -1; private bool _hoveringOnHeader = false; // add parameter for form type - RVH20210602 //List _columns = RowDataHelper.GetColumnInfoFromClass(typeof(TradingStrategy)); List _columns = RowDataHelper.GetColumnInfoFromClass(typeof(TradingStrategy), "TRADING_STRATEGY_GRID"); private Dictionary _dataGridViewColumns = new Dictionary(); private Dictionary _dataGridViewColumnsNames = new Dictionary(); private ColumnListState _columnListState = new ColumnListState(); private Dictionary _strategyToRowData = new Dictionary(); private List _selectedRowList = new List(); private Dictionary> _selectedRowCellDictionary = new Dictionary>(); private bool _sorting = false; private SortType _sortType = SortType.Descending; private ColumnInfo _sortByColumn = null; private BindingList _accounts = new BindingList(); private bool _loadingFromCloud = false; private bool _usingPinnedMenuItem = false; private bool _pinned = false; private Form _parentForm = null; // new variable for symbol linking channel - RVH20210927 private string _linkChannel = "1"; /// /// Set the symbol link channel /// /// The link channel public void SetLinkChannel(string linkChannel) { _linkChannel = linkChannel; } public BindingList Positions { get; set; } public void SetParentForm(Form p) //for positioning purposes { _parentForm = p; } public Boolean UsingPinnedMenuItem { get { return _usingPinnedMenuItem; } set { _usingPinnedMenuItem = value; if (_usingPinnedMenuItem) { pinnedToolStripMenuItem.Visible = true; toolStripSeparator1.Visible = true; } else { pinnedToolStripMenuItem.Visible = false; toolStripSeparator1.Visible = false; } } } public BindingListWithRemoving Strategies { get { return _strategies; } set { _strategies = value; DoDataBinding(); } } private bool _attachedToRobot = false; public bool AttachedToRobot { get { return _attachedToRobot; } set { _attachedToRobot = value; } } /// /// Exposes the data grid view. /// /// public DataGridView getDataGridView() { return dataGridView1; } public BindingList Accounts { get { return _accounts; } set { _accounts = value; // Update Account column in grid. dataGridView1.Invalidate(); } } private void DoDataBinding() { this.InvokeIfRequired(delegate () { updateSelectedCellDictionary(); SuspendLayout(); dataGridView1.ClearSelection(); _rowDatas.Clear(); _strategyToRowData.Clear(); foreach (TradingStrategy strategy in _strategies.ToList()) { if (!_strategyToRowData.ContainsKey(strategy)) { RowData rowData = strategy.ToRowData(); _rowDatas.Add(rowData); _strategyToRowData.Add(strategy, rowData); } } dataGridView1.DataSource = _rowDatas; _strategies.ListChanged -= new ListChangedEventHandler(_strategies_ListChanged); _strategies.ListChanged += new ListChangedEventHandler(_strategies_ListChanged); _strategies.BeforeRemove -= new EventHandler(_strategies_BeforeRemove); _strategies.BeforeRemove += new EventHandler(_strategies_BeforeRemove); RowDataHelper.DoSorting(dataGridView1, _rowDatas, _sortByColumn, _sortType); setSelectedRows(); ResumeLayout(); }); } void _strategies_BeforeRemove(object sender, ListChangedEventArgs e) { if (_strategies.ToList().Count > 0 && _strategies.ToList().Count > e.NewIndex && e.NewIndex >= 0) { TradingStrategy strategy = _strategies[e.NewIndex]; if (_strategyToRowData.ContainsKey(strategy)) { RowData rowData = _strategyToRowData[strategy]; _strategyToRowData.Remove(strategy); if (_rowDatas.Contains(rowData)) _rowDatas.Remove(rowData); } } } void _strategies_ListChanged(object sender, ListChangedEventArgs e) { if (e.ListChangedType == ListChangedType.ItemAdded && _strategies.ToList().Count > 0 && _strategies.ToList().Count > e.NewIndex && e.NewIndex >= 0) { TradingStrategy strategy = _strategies[e.NewIndex]; if (StrategyMatchesFilter(strategy)) { RowData rowData = strategy.ToRowData(); if (_strategyToRowData.ContainsKey(strategy)) _strategyToRowData[strategy].Data = rowData.Data; else { _strategyToRowData.Add(strategy, rowData); RowDataHelper.AddRowData(_rowDatas, rowData, _sorting, _sortByColumn, _sortType); } } } else if (e.ListChangedType == ListChangedType.ItemChanged && _strategies.ToList().Count > 0 && _strategies.ToList().Count > e.NewIndex && e.NewIndex >= 0) { TradingStrategy strategy = _strategies[e.NewIndex]; var rowDatas = _rowDatas.ToList().Where(x => x.Data.ContainsKey("object") && x.Data["object"] == strategy); if (rowDatas.Count() > 0) { RowData rowData = rowDatas.First(); int index = _rowDatas.IndexOf(rowData); _rowDatas[index].Data = strategy.ToRowData().Data; } } } private void FilterOrders() { _filteredStrategies = new BindingListWithRemoving(); foreach (TradingStrategy strategy in _strategies.ToList()) { if (StrategyMatchesFilter(strategy)) _filteredStrategies.Add(strategy); } } private bool StrategyMatchesFilter(TradingStrategy strategy) { return true; } private IConnectionMaster _connectionMaster; private ISendManager _sendManager; private LayoutManager _layoutManager; private string _defaultFileName = "DEFAULT_BPLUS_STRATEGY.tistrat"; public StrategyGrid(IConnectionMaster connectionMaster) { InitializeComponent(); _columnListState.ControlsColumnVisibility = true; dataGridView1.AutoGenerateColumns = false; _connectionMaster = connectionMaster; _sendManager = _connectionMaster.SendManager; _layoutManager = LayoutManager.Instance(); // check to see if auto-size columns is set - RVH20210720 if (GuiEnvironment.autosizeColumns) dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; ExtensionMethods.DoubleBufferedDatagrid(dataGridView1, true); Text = "Strategies"; DoDataBinding(); Timer refreshTimer = new Timer(); refreshTimer.Interval = 1000; refreshTimer.Tick += new EventHandler(refreshTimer_Tick); refreshTimer.Start(); selectTheFont(); InstallColumns(); } private Dictionary _columnInfosMap = new Dictionary(); private void InstallColumns() { try { RowDataHelper.SetGridDefaults(dataGridView1); dataGridView1.MultiSelect = true; _columnInfosMap.Clear(); foreach (ColumnInfo columnInfo in _columns.ToList()) { columnInfo.UseEmptyColor = false; DataGridViewColumn column = DataCell.GetColumn(columnInfo, _connectionMaster, this, null, false, this.CreateGraphics(), Font); RowDataHelper.SetHeaderCellDefaults(column.HeaderCell); if (columnInfo.InternalCode == "Strategy") //"Strategy" is the internal code of the strategy Name column column.DefaultCellStyle.WrapMode = DataGridViewTriState.True; else column.DefaultCellStyle.WrapMode = DataGridViewTriState.False; _dataGridViewColumns.Add(columnInfo, column); _dataGridViewColumnsNames.Add(columnInfo, column); dataGridView1.Columns.Add(column); _columnInfosMap.Add(columnInfo, column); } } catch (Exception e) { string debugView = e.Message; } } void refreshTimer_Tick(object sender, EventArgs e) { if (!_loadingFromCloud) UpdateRealTimeProfit(); } private void RefreshGrid() { this.InvokeIfRequired(delegate () { foreach (TradingStrategy strategy in _strategies.ToList()) { strategy.UpdateProfit(); if (_strategyToRowData.ContainsKey(strategy)) { RowData rowData = _strategyToRowData[strategy]; rowData.Data = strategy.ToRowData().Data; } } RowDataHelper.DoSorting(dataGridView1, _rowDatas, _sortByColumn, _sortType); //dataGridView1.Refresh(); }); } private void UpdateRealTimeProfit() { this.InvokeIfRequired(delegate () { try { //Random random = new Random(); decimal openProfitFiltered = 0; decimal closedProfitFiltered = 0; Dictionary openProfitByStrategy = new Dictionary(); Dictionary closedProfitByStrategy = new Dictionary(); foreach (Position position in Positions.ToList()) { if (null != position.Strategy) { if (!openProfitByStrategy.ContainsKey(position.Strategy)) openProfitByStrategy.Add(position.Strategy, 0); if (!closedProfitByStrategy.ContainsKey(position.Strategy)) closedProfitByStrategy.Add(position.Strategy, 0); if (position.UnrealizedProfit.HasValue) openProfitByStrategy[position.Strategy] += position.UnrealizedProfit.Value; closedProfitByStrategy[position.Strategy] += position.RealizedProfit; } } foreach (TradingStrategy strategy in _strategies.ToList()) { strategy.OpenProfit = 0; strategy.ClosedProfit = 0; if (openProfitByStrategy.ContainsKey(strategy)) strategy.OpenProfit = openProfitByStrategy[strategy]; if (closedProfitByStrategy.ContainsKey(strategy)) strategy.ClosedProfit = closedProfitByStrategy[strategy]; openProfitFiltered += strategy.OpenProfit; closedProfitFiltered += strategy.ClosedProfit; if (_strategyToRowData.ContainsKey(strategy)) { RowData rowData = _strategyToRowData[strategy]; rowData.Data = strategy.ToRowData().Data; int index = _rowDatas.IndexOf(rowData); if (index != -1) dataGridView1.InvalidateRow(index); //dataGridView1.InvalidateCell(2, index); } } if (RowDataHelper.OutOfSortOrder(_rowDatas.ToList(), _sortByColumn, _sortType)) RowDataHelper.DoSorting(dataGridView1, _rowDatas, _sortByColumn, _sortType); this.Parent.Text = "Strategies - Total P&L: " + (Math.Round(openProfitFiltered + closedProfitFiltered, 0)) + ", Open: " + (Math.Round(openProfitFiltered, 0)) + ", Closed: " + Math.Round(closedProfitFiltered, 0); } catch (Exception e) { SendMessage("Got exception in UpdateRealTimeProfit() function: " + e.Source + ", message=" + e.Message + ", stacktrace=" + e.StackTrace); } }); } private void newTradingStrategyToolStripMenuItem_Click(object sender, EventArgs e) { GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.NewStrategy", _sendManager); TradingStrategy defaultStrategy = GetDefaultTradingStrategy(); TradingStrategyForm strategyForm = new TradingStrategyForm(_connectionMaster, _accounts.ToList(), defaultStrategy); strategyForm.StartPosition = FormStartPosition.CenterParent; strategyForm.ShowDialog(); if (strategyForm.DialogResult == DialogResult.OK) { // Create new ID for new strategy. strategyForm.TradingStrategy.Id = TradingStrategy.GenerateId(); _strategies.Add(strategyForm.TradingStrategy); if (null != TradingStrategyUserChanged) TradingStrategyUserChanged(strategyForm.TradingStrategy, "new strategy"); } } private TradingStrategy GetDefaultTradingStrategy() { TradingStrategy strategy = null; try { string programDirFileName = _layoutManager.Directory + "\\" + _defaultFileName; if (File.Exists(programDirFileName)) { XmlDocument document = new XmlDocument(); string xml = File.ReadAllText(programDirFileName); document.LoadXml(xml); strategy = new TradingStrategy(_connectionMaster, document.Node("STRATEGY_DEFINITION").Node("TRADING_STRATEGY")); } } catch (Exception e) { string debugView = e.ToString(); } return strategy; } private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e) { int hoveringRow = e.RowIndex; if (hoveringRow != -1) { if (!contextMenuStrip1.Visible) { _hoveringOnHeader = false; RowData rowData = dataGridView1.Rows[hoveringRow].DataBoundItem as RowData; _currentTradingStrategy = _strategyToRowData.FirstOrDefault(x => x.Value == rowData).Key; _mostRecentTradingStrategy = _currentTradingStrategy; _mostRecentRowIndex = hoveringRow; } } else _hoveringOnHeader = true; } private void dataGridView1_CellMouseLeave(object sender, DataGridViewCellEventArgs e) { _currentTradingStrategy = null; _hoveringOnHeader = false; } private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) { if (_hoveringOnHeader) { // hide "main" menu items newTradingStrategyToolStripMenuItem.Visible = false; editTradingStrategyToolStripMenuItem.Visible = false; deleteTradingStrategyToolStripMenuItem.Visible = false; saveStrategyAsDefaultToolStripMenuItem.Visible = false; toolStripMenuItemEnableDisableStrategy.Visible = false; goToAlertWindowToolStripMenuItem.Visible = false; loadFromCloudToolStripMenuItem.Visible = false; } else { newTradingStrategyToolStripMenuItem.Visible = true; loadFromCloudToolStripMenuItem.Visible = true; if (null != _currentTradingStrategy) { // Only have show the currently selected row when opening the context menu. if (_mostRecentRowIndex != -1 && dataGridView1.SelectedRows.Count > 1) { dataGridView1.ClearSelection(); dataGridView1.Rows[_mostRecentRowIndex].Selected = true; } ShowStrategySpecificMenuItems(); } else HideStrategySpecificMenuItems(); } } private void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e) { HideStrategySpecificMenuItems(); } private void ShowStrategySpecificMenuItems() { editTradingStrategyToolStripMenuItem.Visible = true; setStrategyAsChartDefaultToolStripMenuItem.Visible = true; setStrategyAsChartDefaultToolStripMenuItem.Checked = _currentTradingStrategy.ChartLongStrategy || _currentTradingStrategy.ChartShortStrategy; if (_currentTradingStrategy.Long && !_currentTradingStrategy.ChartLongStrategy) setStrategyAsChartDefaultToolStripMenuItem.Text = "Set as Default Chart Long Strategy"; if (_currentTradingStrategy.Long && _currentTradingStrategy.ChartLongStrategy) setStrategyAsChartDefaultToolStripMenuItem.Text = "Default Chart Long Strategy"; if (!_currentTradingStrategy.Long && !_currentTradingStrategy.ChartShortStrategy) setStrategyAsChartDefaultToolStripMenuItem.Text = "Set as Default Chart Short Strategy"; if (!_currentTradingStrategy.Long && _currentTradingStrategy.ChartShortStrategy) setStrategyAsChartDefaultToolStripMenuItem.Text = "Default Chart Short Strategy"; deleteTradingStrategyToolStripMenuItem.Visible = true; saveStrategyAsDefaultToolStripMenuItem.Visible = true; toolStripMenuItemEnableDisableStrategy.Visible = true; goToAlertWindowToolStripMenuItem.Visible = true; if (_currentTradingStrategy.TradingEnabled) { toolStripMenuItemEnableDisableStrategy.Text = "Strategy Enabled - Click to Disable"; toolStripMenuItemEnableDisableStrategy.Checked = true; } else { toolStripMenuItemEnableDisableStrategy.Text = "Strategy Disabled - Click to Enable"; toolStripMenuItemEnableDisableStrategy.Checked = false; } editTradingStrategyToolStripMenuItem.Enabled = _currentTradingStrategy.Id != "1" && _currentTradingStrategy.Id != "-1"; deleteTradingStrategyToolStripMenuItem.Enabled = _currentTradingStrategy.Id != "1" && _currentTradingStrategy.Id != "-1"; toolStripMenuItemEnableDisableStrategy.Enabled = _currentTradingStrategy.Id != "1" && _currentTradingStrategy.Id != "-1"; setStrategyAsChartDefaultToolStripMenuItem.Enabled = _currentTradingStrategy.Id != "1" && _currentTradingStrategy.Id != "-1"; saveStrategyAsDefaultToolStripMenuItem.Enabled = _currentTradingStrategy.Id != "1" && _currentTradingStrategy.Id != "-1"; goToAlertWindowToolStripMenuItem.Enabled = _currentTradingStrategy.MainAlerts != null; } private void HideStrategySpecificMenuItems() { setStrategyAsChartDefaultToolStripMenuItem.Visible = false; editTradingStrategyToolStripMenuItem.Visible = false; deleteTradingStrategyToolStripMenuItem.Visible = false; saveStrategyAsDefaultToolStripMenuItem.Visible = false; goToAlertWindowToolStripMenuItem.Visible = false; toolStripMenuItemEnableDisableStrategy.Visible = false; advancedExitsToolStripMenuItem.Visible = false; } private void editTradingStrategyToolStripMenuItem_Click(object sender, EventArgs e) { if (null != _mostRecentTradingStrategy) { int strategyIndex = _strategies.IndexOf(_mostRecentTradingStrategy); string config = ""; if (null != _mostRecentTradingStrategy.MainAlerts) { config = _mostRecentTradingStrategy.MainAlerts.Config; _mostRecentTradingStrategy.MainAlerts.Stop(); } SendMessage("Going to edit strategy: (" + strategyIndex + ") " + _mostRecentTradingStrategy.Name + ", config=" + config, "fileonly"); GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.EditStrategy", _sendManager); TradingStrategyForm strategyForm = new TradingStrategyForm(_connectionMaster, _accounts.ToList(), _mostRecentTradingStrategy); strategyForm.StartPosition = FormStartPosition.CenterParent; strategyForm.ShowDialog(); if (strategyForm.DialogResult == DialogResult.OK && strategyIndex != -1) { _strategies[strategyIndex] = strategyForm.TradingStrategy; string newConfig = ""; if (null != strategyForm.TradingStrategy.MainAlerts) newConfig = strategyForm.TradingStrategy.MainAlerts.Config; // We must apply any changes to the alert strategy if changed. if (null != _strategies[strategyIndex].MainAlerts && !config.Equals(newConfig)) { _strategies[strategyIndex].MainAlerts.Stop(); _strategies[strategyIndex].MainAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(newConfig); } if (null != TradingStrategyUserChanged) TradingStrategyUserChanged(_strategies[strategyIndex], "Saved Edits"); } else if (null != _mostRecentTradingStrategy && null != _mostRecentTradingStrategy.MainAlerts) { // To avoid an exception when the user modified the MainAlerts but then cancels the trade strategy edit. // We must stop the MainAlerts. _mostRecentTradingStrategy.MainAlerts.Stop(); _mostRecentTradingStrategy.MainAlerts.Start(); } dataGridView1.Refresh(); UpdateStrategiesStatus(); } else SendMessage("Edit strategy clicked but most recent strategy is null.", "fileonly"); } public void EditChartTradingStrategy(TradingStrategy tradingStrategy) { if (null == tradingStrategy) return; string config = ""; int strategyIndex = _strategies.IndexOf(tradingStrategy); if (null != tradingStrategy.MainAlerts) { config = tradingStrategy.MainAlerts.Config; tradingStrategy.MainAlerts.Stop(); } string isLong = tradingStrategy.Long ? "long" : "short"; SendMessage("Going to edit default chart " + isLong + " strategy: " + tradingStrategy.Name + ", config=" + config, "fileonly"); GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.EditChartStrategy", _sendManager); TradingStrategyForm strategyForm = new TradingStrategyForm(_connectionMaster, _accounts.ToList(), tradingStrategy); strategyForm.StartPosition = FormStartPosition.CenterParent; strategyForm.ShowDialog(); if (strategyForm.DialogResult == DialogResult.OK && strategyIndex != -1) { _strategies[strategyIndex] = strategyForm.TradingStrategy; // We must apply any changes to the alert strategy if changed. if (null != _strategies[strategyIndex].MainAlerts && !config.Equals(_strategies[strategyIndex].MainAlerts.Config)) _strategies[strategyIndex].MainAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(_strategies[strategyIndex].MainAlerts.Config); if (null != TradingStrategyUserChanged) TradingStrategyUserChanged(_strategies[strategyIndex], "Saved Edits"); } else if (null != tradingStrategy && null != tradingStrategy.MainAlerts) { tradingStrategy.MainAlerts.Start(); } dataGridView1.Refresh(); UpdateStrategiesStatus(); } private void deleteTradingStrategyToolStripMenuItem_Click(object sender, EventArgs e) { if (null != _mostRecentTradingStrategy) { if (_mostRecentTradingStrategy.Id != "1" && _mostRecentTradingStrategy.Id != "-1") { DialogResult result = MessageBox.Show("Really delete selected strategy: " + _mostRecentTradingStrategy.Name + "?", "Delete Strategy Confirmation", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { if (null != _mostRecentTradingStrategy.MainAlerts) { SendMessage("Deleting strategy: (" + _mostRecentRowIndex + ") " + _mostRecentTradingStrategy.Name + ", config=" + _mostRecentTradingStrategy.MainAlerts.Config); _mostRecentTradingStrategy.MainAlerts.Stop(); } else SendMessage("Deleting strategy: (" + _mostRecentRowIndex + ") " + _mostRecentTradingStrategy.Name + ", config=NONE"); _strategies.Remove(_mostRecentTradingStrategy); _currentTradingStrategy = null; _mostRecentTradingStrategy = null; _mostRecentRowIndex = -1; //DoDataBinding(); GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.StrategyDeleted", _sendManager); } } } else SendMessage("Delete strategy clicked but most recent strategy is null."); } private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) { if (e.RowIndex != -1) { if (e.Button == MouseButtons.Right) { dataGridView1.CurrentCell = dataGridView1[e.ColumnIndex, e.RowIndex]; dataGridView1.Rows[e.RowIndex].Selected = true; } RowData rowData = dataGridView1.Rows[e.RowIndex].DataBoundItem as RowData; _currentTradingStrategy = _strategyToRowData.FirstOrDefault(x => x.Value == rowData).Key; _mostRecentTradingStrategy = _currentTradingStrategy; _mostRecentRowIndex = e.RowIndex; } } public void Restore(XmlNode description) { if (null != description.Node("COLUMNS")) { _columnListState.LoadFrom(description.Node("COLUMNS")); _columnListState.isNewer = true; // add parameter for form type - RVH20210528 //_columnListState.SaveTo(dataGridView1); _columnListState.SaveTo(dataGridView1, "TRADING_STRATEGY_GRID"); } // Hide AdvancedExitsEnabled column if (!GuiEnvironment.DevelopmentMode) { foreach (Column col in dataGridView1.Columns.OfType().ToList()) { if (col.ColumnInfo.WireName.Equals("AdvancedExitsEnabled")) { col.Visible = false; } } } Pinned = description.Property("PINNED", false); _sorting = description.Property("SORTING", false); if (_sorting) { _sortType = description.PropertyEnum("SORTTYPE", SortType.Ascending); string sortColumnInternalCode = description.Property("SORTINGBY", ""); if (sortColumnInternalCode != "") { foreach (ColumnInfo columnInfo in _columns.ToList()) { if (columnInfo.InternalCode == sortColumnInternalCode) _sortByColumn = columnInfo; } if (sortColumnInternalCode != "") { RowDataHelper.DoSorting(dataGridView1, _rowDatas, _sortByColumn, _sortType); RowDataHelper.FixCellHeaders(dataGridView1, _columns, _sortByColumn); } else _sorting = false; } else _sorting = false; } } public void Save(XmlNode parent) { _columnListState.LoadFrom(dataGridView1); _columnListState.SaveTo(parent.NewNode("COLUMNS")); parent.SetProperty("SORTING", _sorting.ToString()); parent.SetProperty("PINNED", Pinned); if (null != _sortByColumn) parent.SetProperty("SORTINGBY", _sortByColumn.InternalCode); parent.SetProperty("SORTTYPE", _sortType.ToString()); } private void closeTabToolStripMenuItem_Click(object sender, EventArgs e) { TabPageWithSingleControl.RemoveTabFromParent(this.Parent); } private void toolStripMenuItemEnableDisableStrategy_Click(object sender, EventArgs e) { if (null != _mostRecentTradingStrategy) { _mostRecentTradingStrategy.TradingEnabled = !_mostRecentTradingStrategy.TradingEnabled; string changeType = "Enabled"; if (!_mostRecentTradingStrategy.TradingEnabled) changeType = "Disabled"; if (_mostRecentTradingStrategy.TradingEnabled) GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.StrategyEnabled", _sendManager); else GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.StrategyDisabled", _sendManager); if (null != TradingStrategyUserChanged) TradingStrategyUserChanged(_mostRecentTradingStrategy, changeType); RefreshGrid(); } } private void goToAlertWindowToolStripMenuItem_Click(object sender, EventArgs e) { GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.GoToAlertWindow", _sendManager); if (null != _mostRecentTradingStrategy && null != _mostRecentTradingStrategy.MainAlerts) { List alertForms = Application.OpenForms.OfType().ToList().Where(x => !x.IsDisposed && x.GetConfigString() == _mostRecentTradingStrategy.MainAlerts.Config).ToList(); if (alertForms.Count > 0) { AlertForm alertForm = alertForms.First(); alertForm.WindowState = FormWindowState.Normal; alertForm.BringToFront(); alertForm.SetOddsMakerSettings(GetOddsMakerSettings(_mostRecentTradingStrategy)); } else { AlertForm alertForm = new AlertForm(_connectionMaster, _mostRecentTradingStrategy.MainAlerts.Config); alertForm.SetOddsMakerSettings(GetOddsMakerSettings(_mostRecentTradingStrategy)); alertForm.Show(); if (_parentForm != null) { GuiEnvironment.SetWindowOpeningPosition(alertForm, _parentForm); } } } } private OddsMakerConfiguration.OddsMakerConfigMemento GetOddsMakerSettings(TradingStrategy strategy) { OddsMakerConfiguration.OddsMakerConfigMemento settings = new OddsMakerConfiguration.OddsMakerConfigMemento(); settings.Long = strategy.Long; settings.EntryMinutesStart = (int)(strategy.StartTime - GuiEnvironment.GetMarketOpenLocalTime()).TotalMinutes; settings.EntryMinutesEnd = (int)(GuiEnvironment.GetMarketCloseLocalTime() - strategy.EndTime).TotalMinutes; settings.cboLocation = 0; settings.UseProfitTarget = strategy.TargetType == TradeStopLossType.Percent || strategy.TargetType == TradeStopLossType.Dollars; settings.ProfitTarget = (double)strategy.TargetOffset; settings.UseStopLoss = strategy.StopLossType == TradeStopLossType.Dollars || strategy.StopLossType == TradeStopLossType.Percent; settings.StopLoss = (double)strategy.StopLossOffset; settings.UseDollars = strategy.StopLossType == TradeStopLossType.Dollars || strategy.TargetType == TradeStopLossType.Dollars; settings.UsePercent = !settings.UseDollars; if (strategy.TimeStopType == TradeTimeStopType.TimeAfterSignal) { settings.UseExitTimeMinutesAfter = true; settings.ExitTimeMinutesAfter = strategy.TimeStopDuration; } else if (strategy.TimeStopType == TradeTimeStopType.TimeOfDay) { if (strategy.TimeStopMinutesAfterOpen == 0 && strategy.TimeStopDays > 0) { settings.UseExitTimeFutureOpen = true; settings.ExitTimeOpenDays = strategy.TimeStopDays; settings.ExitTimeCloseDays = settings.ExitTimeOpenDays; } else if (strategy.TimeStopDays > 0 && strategy.TimeStopMinutesAfterOpen >= 385) { settings.UseExitTimeFutureClose = true; settings.ExitTimeCloseDays = strategy.TimeStopDays; settings.ExitTimeOpenDays = settings.ExitTimeCloseDays; } else { settings.UseExitAtTimeOfDay = true; settings.ExitTimeMinutesBefore = 390 - strategy.TimeStopMinutesAfterOpen; } } if (null != strategy.ExitAlerts) { settings.ExitCondition = strategy.ExitAlerts.Config; settings.UseExitCondAnotherAlert = true; } return settings; } private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { updateSelectedCellDictionary(); dataGridView1.ClearSelection(); if (e.RowIndex == -1) { Column column = (Column)dataGridView1.Columns[e.ColumnIndex]; if (null != column && null != column.ColumnInfo) { GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.Sort." + column.ColumnInfo.InternalCode, _sendManager); _sortByColumn = column.ColumnInfo; _sorting = true; if (!_sorting) _sortType = SortType.Descending; else { if (_sortType == SortType.Ascending) _sortType = SortType.Descending; else _sortType = SortType.Ascending; } RowDataHelper.DoSorting(dataGridView1, _rowDatas, _sortByColumn, _sortType); RowDataHelper.FixCellHeaders(dataGridView1, _columns, _sortByColumn); } } else { int index = e.RowIndex; RowData rowData = _rowDatas[index]; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy) { string symbol = strategy.LastSymbol; if (symbol != "") { string exchange = _connectionMaster.SymbolDetailsCacheManager.Request(symbol).Exchange ?? ""; GuiEnvironment.sendSymbolToExternalConnector(symbol, exchange, "", null, rowData, linkChannel: _linkChannel, dockWindowID: GuiEnvironment.GetDockWindowID(this.ParentForm)); } } } } // Set selected row/cell after sort setSelectedRows(); } private void ExchangeCallback(string symbol, string exchange, RowData rowData) { this.BeginInvokeIfRequired((MethodInvoker)delegate { GuiEnvironment.sendSymbolToExternalConnector(symbol, exchange, "", null, rowData, linkChannel: _linkChannel, dockWindowID: GuiEnvironment.GetDockWindowID(this.ParentForm)); }); } private void SendMessage(string message, string source = "StrategyGrid") { if (null != MessageSent) MessageSent(message, source); } private void loadFromCloudToolStripMenuItem_Click(object sender, EventArgs e) { _loadingFromCloud = true; LoadFromCloud cloudForm = new LoadFromCloud(_sendManager); cloudForm.CreateLayoutOnLoad = false; cloudForm.StartPosition = FormStartPosition.CenterParent; cloudForm.ShowDialog(); if (cloudForm.DialogResult == DialogResult.OK) { if (null != cloudForm.ItemDefinition) { int i = 1; foreach (TradingStrategy strategy in _strategies.ToList()) { SendMessage("[StrategyGrid Add] Before load to cloud strategy " + i + ". " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); i++; } List strategiesFound = new List(); foreach (XmlNode xml in cloudForm.ItemDefinition.Node("LAYOUT").ChildNodes) { if (xml.Property("FORM_TYPE", "") == "MULTI_STRATEGY_WINDOW") { XmlNode strategiesNode = xml.Node("STRATEGIES"); foreach (XmlNode strategyNode in strategiesNode.ChildNodes) { TradingStrategy strategy = ConvertAlertsToTradingStrategy(strategyNode); if (null != strategy) strategiesFound.Add(strategy); } } else if (xml.Property("FORM_TYPE", "") == "ALERT_WINDOW") { TradingStrategy strategy = ConvertAlertsToTradingStrategy(xml); if (null != strategy) strategiesFound.Add(strategy); } } i = 1; foreach (TradingStrategy strategy in strategiesFound) { // Create a unique strategy Id for all found strategies with an empty Id. if (strategy.Id == "") strategy.Id = TradingStrategy.GenerateId(); SendMessage("[StrategyGrid Add] Found strategy from load to cloud " + i + ". " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); i++; } if (strategiesFound.Count > 0) { if (_strategies.ToList().Count > 0) { int matchingStrategies = 0; foreach (TradingStrategy strategy in strategiesFound) { if (_strategies.ToList().Where(x => x.Name == strategy.Name).Count() > 0) matchingStrategies++; } LoadStrategiesFromCloudConfirm confirmForm = new LoadStrategiesFromCloudConfirm(strategiesFound.Count, _strategies.ToList().Count, matchingStrategies); confirmForm.StartPosition = FormStartPosition.CenterParent; DialogResult result = confirmForm.ShowDialog(); if (result == DialogResult.OK) { if (confirmForm.LoadStrategyType == LoadStrategyFromCloudType.Add) { foreach (TradingStrategy strategy in strategiesFound) { SendMessage("[StrategyGrid Add] Adding strategy " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); _strategies.Add(strategy); } //DoDataBinding(); } else if (confirmForm.LoadStrategyType == LoadStrategyFromCloudType.ReplaceAll) { foreach (TradingStrategy strategy in _strategies.ToList()) { if (strategy.Id != "1" && strategy.Id != "-1") { if (null != strategy.MainAlerts) strategy.MainAlerts.Stop(); SendMessage("[StrategyGrid Replace] Removing strategy " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); _strategies.Remove(strategy); } } foreach (TradingStrategy strategy in strategiesFound) { SendMessage("[StrategyGrid Replace] Adding strategy " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); _strategies.Add(strategy); } //DoDataBinding(); } else if (confirmForm.LoadStrategyType == LoadStrategyFromCloudType.ReplaceByName) { foreach (TradingStrategy strategy in strategiesFound) { if (_strategies.ToList().Where(x => x.Name == strategy.Name).Count() > 0) { TradingStrategy strategyToUpdate = _strategies.ToList().Where(x => x.Name == strategy.Name).First(); SendMessage("[StrategyGrid Merge] Merging strategy " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id + " with strategy " + strategyToUpdate.Name + ", long=" + strategyToUpdate.Long + ", id=" + strategyToUpdate.Id); MergeStrategy(strategyToUpdate, strategy); if (null != strategy.MainAlerts) strategy.MainAlerts.Stop(); } } //DoDataBinding(); } } } else { foreach (TradingStrategy strategy in strategiesFound) { SendMessage("[StrategyGrid Add] No strategies found so adding strategy " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); _strategies.Add(strategy); } } } i = 1; foreach (TradingStrategy strategy in _strategies.ToList()) { SendMessage("[StrategyGrid Add] After load to cloud strategy " + i + ". " + strategy.Name + ", long=" + strategy.Long + ", id=" + strategy.Id); i++; } } } _loadingFromCloud = false; } private void MergeStrategy(TradingStrategy originalStrategy, TradingStrategy newStrategy) { originalStrategy.Long = newStrategy.Long; if (null != originalStrategy.MainAlerts) originalStrategy.MainAlerts.Stop(); if (null != newStrategy.MainAlerts) originalStrategy.MainAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(newStrategy.MainAlerts.Config); originalStrategy.StartTime = newStrategy.StartTime; originalStrategy.EndTime = newStrategy.EndTime; originalStrategy.TimeStopMinutesAfterOpen = newStrategy.TimeStopMinutesAfterOpen; originalStrategy.TimeStopType = newStrategy.TimeStopType; originalStrategy.TimeStopDays = newStrategy.TimeStopDays; originalStrategy.TimeStopDuration = newStrategy.TimeStopDuration; originalStrategy.StopLossType = newStrategy.StopLossType; originalStrategy.StopLossOffset = newStrategy.StopLossOffset; originalStrategy.TargetType = newStrategy.TargetType; originalStrategy.TargetOffset = newStrategy.TargetOffset; originalStrategy.TrailingStopType = newStrategy.TrailingStopType; originalStrategy.TrailingStopOffset = newStrategy.TrailingStopOffset; if (null != originalStrategy.ExitAlerts) originalStrategy.ExitAlerts.Stop(); if (null != newStrategy.ExitAlerts) originalStrategy.ExitAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(newStrategy.ExitAlerts.Config); } /// /// Converts layout XML from an alert window to a B+ TradingStrategy object. /// /// The XML. /// private TradingStrategy ConvertAlertsToTradingStrategy(XmlNode xml) { TradingStrategy strategy = new TradingStrategy(_connectionMaster); if (xml.Property("CONFIG", "") != "") { string config = xml.Property("CONFIG", ""); config = TradingStrategy.MakeConfigStringEdits(config); strategy.MainAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(config); strategy.Name = GuiEnvironment.GetWindowName(config); } else return null; XmlNode oddsMakerNode = xml.Node("ODDSMAKER"); if (null == oddsMakerNode) return null; strategy.Long = oddsMakerNode.Property("LONG", true); strategy.StartTimeMinutesFromOpen = oddsMakerNode.Property("TXT_ENTRY_MINUTES_START", 0) + oddsMakerNode.Property("TXT_ENTRY_HOURS_START", 0); strategy.EndTimeMinutesFromClose = oddsMakerNode.Property("TXT_ENTRY_MINUTES_END", 0) + oddsMakerNode.Property("TXT_ENTRY_HOURS_END", 0); if (oddsMakerNode.Property("RDO_EXIT_TIME_FUTURE_CLOSE", false)) { strategy.TimeStopMinutesAfterOpen = 385; strategy.TimeStopType = TradeTimeStopType.AtCloseDays; strategy.TimeStopDays = oddsMakerNode.Property("EXIT_TIME_CLOSE_DAYS", 0) + 1; } else if (oddsMakerNode.Property("RDO_EXIT_TIME_AT_THE_OPEN", false)) { strategy.TimeStopMinutesAfterOpen = 0; strategy.TimeStopType = TradeTimeStopType.AtOpenDays; strategy.TimeStopDays = oddsMakerNode.Property("EXIT_TIME_OPEN_DAYS", 0) + 1; } else if (oddsMakerNode.Property("RDO_EXIT_AT_THE_CLOSE", false)) { strategy.TimeStopType = TradeTimeStopType.TimeOfDay; strategy.TimeStopMinutesAfterOpen = 390 - oddsMakerNode.Property("EXIT_TIME_MINUTES_BEFORE", 0); if (strategy.TimeStopMinutesAfterOpen >= 390 - TradingStrategy.MIN_MINUTES_FROM_CLOSE_FOR_TIME_STOP) strategy.TimeStopMinutesAfterOpen = 390 - TradingStrategy.MIN_MINUTES_FROM_CLOSE_FOR_TIME_STOP; } else { strategy.TimeStopType = TradeTimeStopType.TimeAfterSignal; strategy.TimeStopDuration = oddsMakerNode.Property("EXIT_TIME_MINUTES_AFTER", 0); } bool usingPercents = oddsMakerNode.Property("RDO_BY_AT_LEAST_PERCENT", false); if (oddsMakerNode.Property("CHK_STOP_LOSS", false)) { bool useStopLossFilter = oddsMakerNode.Property("USE_STOP_LOSS_FILTER", false); string stopLossFilter = oddsMakerNode.Property("STOP_LOSS_FILTER", "SmartStopD"); if (useStopLossFilter) { strategy.StopLossType = TradeStopLossType.Filter; strategy.StopLossFilter = stopLossFilter; } else if (usingPercents) strategy.StopLossType = TradeStopLossType.Percent; else strategy.StopLossType = TradeStopLossType.Dollars; strategy.StopLossOffset = (decimal)oddsMakerNode.Property("TXT_STOP_LOSS", 0.00); } else strategy.StopLossType = TradeStopLossType.None; if (oddsMakerNode.Property("CHK_PROFIT_TARGET", false)) { bool useProfitTargetFilter = oddsMakerNode.Property("USE_PROFIT_TARGET_FILTER", false); string targetFilter = oddsMakerNode.Property("PROFIT_TARGET_FILTER", "SmartStopD"); if (useProfitTargetFilter) { strategy.TargetType = TradeStopLossType.Filter; strategy.TargetFilter = targetFilter; } else if (usingPercents) strategy.TargetType = TradeStopLossType.Percent; else strategy.TargetType = TradeStopLossType.Dollars; strategy.TargetOffset = (decimal)oddsMakerNode.Property("TXT_PROFIT_TARGET", 0.00); } else strategy.TargetType = TradeStopLossType.None; if (oddsMakerNode.Property("RDO_EXIT_COND_ANOTHER_ALERT", false)) strategy.ExitAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(oddsMakerNode.Property("EXIT_CONDITION", "")); else if (oddsMakerNode.Property("RDO_EXIT_COND_PERCENT", false)) { strategy.TrailingStopType = TradeStopLossType.Percent; strategy.TrailingStopOffset = (decimal)oddsMakerNode.Property("TXT_EXIT_COND_PERCENT", 0.00); } return strategy; } private void buttonSelectAll_Click(object sender, EventArgs e) { dataGridView1.SelectAll(); } private void buttonSelectLong_Click(object sender, EventArgs e) { foreach (DataGridViewRow row in dataGridView1.Rows.OfType().ToList()) { RowData rowData = row.DataBoundItem as RowData; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy) row.Selected = strategy.Long; } } } private void buttonSelectShort_Click(object sender, EventArgs e) { foreach (DataGridViewRow row in dataGridView1.Rows.OfType().ToList()) { RowData rowData = row.DataBoundItem as RowData; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy) row.Selected = !strategy.Long; } } } private void buttonEnableSelected_Click(object sender, EventArgs e) { foreach (DataGridViewRow row in dataGridView1.SelectedRows) { RowData rowData = row.DataBoundItem as RowData; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy) strategy.TradingEnabled = true; } } } private void buttonDisableSelected_Click(object sender, EventArgs e) { foreach (DataGridViewRow row in dataGridView1.SelectedRows) { RowData rowData = row.DataBoundItem as RowData; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy) strategy.TradingEnabled = false; } } } private List GetSelectedStrategies() { List strategies = new List(); foreach (DataGridViewRow row in dataGridView1.SelectedRows) { RowData rowData = row.DataBoundItem as RowData; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy && strategy.Id != "1" && strategy.Id != "-1") strategies.Add(strategy); } } return strategies; } private void buttonDeleteSelected_Click(object sender, EventArgs e) { List strategies = GetSelectedStrategies(); int selectedCount = strategies.Count; if (selectedCount > 0) { DialogResult result = MessageBox.Show("Really delete " + selectedCount + " strategies?", "Delete Strategies", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { foreach (TradingStrategy strategy in strategies) { if (null != strategy.MainAlerts) strategy.MainAlerts.Stop(); _strategies.Remove(strategy); } } //DoDataBinding(); } } private void runOddsMakerToolStripMenuItem_Click(object sender, EventArgs e) { if (null != _mostRecentTradingStrategy && null != _mostRecentTradingStrategy.MainAlerts && _mostRecentTradingStrategy.Id != "1" && _mostRecentTradingStrategy.Id != "-1") PopulateOddsMaker(_mostRecentTradingStrategy); } private bool _oddsMakerRunning = false; private void PopulateOddsMaker() { List strategies = new List(); foreach (TradingStrategy strategy in _strategies.ToList()) { if (strategy.Id != "1" && strategy.Id != "-1" && strategy.OddsMakerIsQueued && !strategy.OddsMakerIsRunning && null != strategy.MainAlerts) strategies.Add(strategy); } if (strategies.Count > 0) { BackgroundWorker bgw = new BackgroundWorker(); bgw.DoWork += bgw_DoWork; bgw.RunWorkerCompleted += bgw_RunWorkerCompleted; object[] arguments = { strategies }; _oddsMakerRunning = true; bgw.RunWorkerAsync(arguments); } } void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { _oddsMakerRunning = false; // check again in case some have been queued PopulateOddsMaker(); } void bgw_DoWork(object sender, DoWorkEventArgs e) { object[] arguments = (object[])e.Argument; List strategies = arguments[0] as List; if (null != strategies) { foreach (TradingStrategy strategy in strategies) { strategy.OddsMakerIsQueued = false; strategy.RunOddsMaker(); while (strategy.OddsMakerIsRunning) System.Threading.Thread.Sleep(1000); } } } private void PopulateOddsMaker(TradingStrategy strategy) { QueueStrategyForOddsMaker(strategy); } private OddsMakerRequest GetOddsMakerRequest(TradingStrategy strategy) { if (null != strategy && null != strategy.MainAlerts) { OddsMakerRequest request = new OddsMakerRequest(); request.SuccessDirectionUp = strategy.Long; request.EntryCondition = strategy.MainAlerts.Config; request.EntryTimeStart = (int)(strategy.StartTime - GuiEnvironment.GetMarketOpenLocalTime()).TotalMinutes; request.EntryTimeEnd = (int)(GuiEnvironment.GetMarketCloseLocalTime() - strategy.EndTime).TotalMinutes; request.Location = SelectedLocation.US; if (strategy.TargetType == TradeStopLossType.Percent || strategy.TargetType == TradeStopLossType.Dollars) request.ProfitTarget = (double)strategy.TargetOffset; else if (strategy.TargetType == TradeStopLossType.Filter && strategy.TargetFilter != "") { request.UseTargetFilter = true; request.TargetFilter = strategy.TargetFilter; } if (strategy.StopLossType == TradeStopLossType.Dollars || strategy.StopLossType == TradeStopLossType.Percent) request.StopLoss = (double)strategy.StopLossOffset; else if (strategy.StopLossType == TradeStopLossType.Filter && strategy.StopLossFilter != "") { request.UseStopFilter = true; request.StopFilter = strategy.StopLossFilter; } request.SuccessTypePercent = strategy.StopLossType == TradeStopLossType.Percent || strategy.TargetType == TradeStopLossType.Percent; if (strategy.TimeStopType == TradeTimeStopType.TimeAfterSignal) request.TimeoutMinutes = strategy.TimeStopDuration; else if (strategy.TimeStopType == TradeTimeStopType.TimeOfDay) { if (strategy.TimeStopMinutesAfterOpen == 0 && strategy.TimeStopDays > 0) { request.AtOpenDays = strategy.TimeStopDays; } else if (strategy.TimeStopDays > 0 && strategy.TimeStopMinutesAfterOpen >= 385) { request.AtCloseDays = strategy.TimeStopDays; } else { request.BeforeCloseMinutes = 390 - strategy.TimeStopMinutesAfterOpen; } } if (null != strategy.ExitAlerts) { request.ExitConditionAlert = strategy.ExitAlerts.Config; request.ExitConditionType = ExitConditionType.Alert; } return request; } else return null; } private void showOddsMakerResultsToolStripMenuItem_Click(object sender, EventArgs e) { if (null != _mostRecentTradingStrategy && null != _mostRecentTradingStrategy.MainAlerts && _mostRecentTradingStrategy.OddsMakerCsv != "") { OddsMakerConfiguration.OddsMakerConfigMemento settings = GetOddsMakerSettings(_mostRecentTradingStrategy); OddsMakerRequest omRequest = GetOddsMakerRequest(_mostRecentTradingStrategy); OddsMakerConfigWindow configDialog = new OddsMakerConfigWindow(_mostRecentTradingStrategy.MainAlerts.Config, _connectionMaster, _mostRecentTradingStrategy.Name, new AlertForm(_connectionMaster, _mostRecentTradingStrategy.MainAlerts.Config), settings); configDialog.DialogResult = DialogResult.OK; OddsMakerResults omResults = new OddsMakerResults(omRequest, _connectionMaster, configDialog, _mostRecentTradingStrategy.Name, settings); omResults.Show(); omResults.SetCSV(_mostRecentTradingStrategy.OddsMakerCsv); } } private void buttonRunOddsMaker_Click(object sender, EventArgs e) { List strategies = GetSelectedStrategies(); int selectedCount = strategies.Count; if (selectedCount > 0) { foreach (TradingStrategy strategy in strategies) { QueueStrategyForOddsMaker(strategy); } } UpdateRunOddsMakerButtonStatus(); } private void QueueStrategyForOddsMaker(TradingStrategy strategy) { if (null != strategy && null != strategy.MainAlerts && !strategy.OddsMakerIsQueued && !strategy.OddsMakerIsRunning && strategy.Id != "-1" && strategy.Id != "-1") { strategy.OddsMakerIsQueued = true; strategy.WinRate = null; strategy.OmTrades = null; strategy.ProfitFactor = null; } if (!_oddsMakerRunning) PopulateOddsMaker(); } private void UpdateRunOddsMakerButtonStatus() { int selectedCount = dataGridView1.SelectedRows.Count; if (selectedCount > 0) { List strategiesNotRunningOddsMaker = new List(); foreach (DataGridViewRow row in dataGridView1.SelectedRows) { RowData rowData = row.DataBoundItem as RowData; if (null != rowData && rowData.Data.ContainsKey("object")) { TradingStrategy strategy = rowData.Data["object"] as TradingStrategy; if (null != strategy && !strategy.OddsMakerIsQueued && !strategy.OddsMakerIsRunning && strategy.Id != "-1" && strategy.Id != "1" && null != strategy.MainAlerts) strategiesNotRunningOddsMaker.Add(strategy); } } buttonRunOddsMaker.Enabled = strategiesNotRunningOddsMaker.Count > 0; } else buttonRunOddsMaker.Enabled = false; } private void dataGridView1_SelectionChanged(object sender, EventArgs e) { UpdateRunOddsMakerButtonStatus(); } private void dataGridView1_Click(object sender, EventArgs e) { if (_currentTradingStrategy == null && !_hoveringOnHeader) dataGridView1.ClearSelection(); } public bool Pinned { get { return _pinned; } set { _pinned = value; if (_pinned) { pinnedToolStripMenuItem.Checked = true; } } } private void pinnedToolStripMenuItem_Click(object sender, EventArgs e) { _pinned = pinnedToolStripMenuItem.Checked; if (Parent as FormWithSingleControl != null) { FormWithSingleControl frm = (FormWithSingleControl)Parent; if (_pinned) { frm.Pinned = true; } else { frm.Pinned = false; } } } public void selectTheFont() { Font = GuiEnvironment.FontSettings; contextMenuStrip1.Font = Font; dataGridView1.DefaultCellStyle.Font = Font; foreach (DataGridViewRow row in dataGridView1.Rows.OfType().ToList()) { row.DefaultCellStyle.Font = Font; } } private void saveStrategyAsDefaultToolStripMenuItem_Click(object sender, EventArgs e) { if (null != _mostRecentTradingStrategy) { if (_mostRecentTradingStrategy.Id != "1" && _mostRecentTradingStrategy.Id != "-1") { try { GuiEnvironment.RecordUseCase("Robot.Main.StrategyGrid.SaveDefault", _sendManager); string programDirFileName = _layoutManager.Directory + "\\" + _defaultFileName; XmlDocument document = new XmlDocument(); XmlNode strategyNode = document.CreateElement("STRATEGY_DEFINITION"); document.AppendChild(strategyNode); _mostRecentTradingStrategy.Save(strategyNode); File.WriteAllText(programDirFileName, document.OuterXml); } catch (Exception exc) { string debugView = exc.ToString(); } } } } private void saveAsDefaultToolStripMenuItem_Click(object sender, EventArgs e) { Robot.SaveToolLayoutToFile(this, Robot.DEFAULT_STRATEGIES_LAYOUT_FILE); } private void columnsToolStripMenuItem_Click(object sender, EventArgs e) { ConfigWindowWrapper configWindowWrapper = new TraditionalConfigWindowWrapper(ConfigurationType.CustomColumns, _connectionMaster); configWindowWrapper.VisibleCustomColumns = RowDataHelper.GetVisibleColumns(_dataGridViewColumns); configWindowWrapper.AllCustomColumns = RowDataHelper.GetAllColumns(_dataGridViewColumns); configWindowWrapper.ShowIt(); string[] defaultColumns = new string[] { "Strategy", "Profit", "L/S", "Last Symbol", "Last Signal Time", "Time Stop" }; if (!configWindowWrapper.CanceledAIColumnConfig) RowDataHelper.ApplyVisibleColumns(defaultColumns, _columns, configWindowWrapper.VisibleCustomColumns, _dataGridViewColumnsNames); } private void SetStrategyAsChartDefaultToolStripMenuItem_Click(object sender, EventArgs e) { if (_mostRecentTradingStrategy.Long) { foreach (TradingStrategy strategy in _strategies.ToList().Where(x => x.Long).ToList()) { if (_mostRecentTradingStrategy.Id == strategy.Id) _mostRecentTradingStrategy.ChartLongStrategy = !strategy.ChartLongStrategy; else strategy.ChartLongStrategy = false; } _mostRecentTradingStrategy.ChartShortStrategy = !_mostRecentTradingStrategy.Long; } else { foreach (TradingStrategy strategy in _strategies.ToList().Where(x => !x.Long).ToList()) { if (_mostRecentTradingStrategy.Id == strategy.Id) _mostRecentTradingStrategy.ChartShortStrategy = !strategy.ChartShortStrategy; else strategy.ChartShortStrategy = false; } _mostRecentTradingStrategy.ChartLongStrategy = _mostRecentTradingStrategy.Long; } UpdateStrategiesStatus(); } private void UpdateStrategiesStatus() { //Update the Strategy settings on the global variables var longStrategy = _strategies.ToList().Where(x => x.Long && x.ChartLongStrategy).FirstOrDefault(); var shortStrategy = _strategies.ToList().Where(x => !x.Long && x.ChartShortStrategy).FirstOrDefault(); GuiEnvironment.TradeRequirements.ChartLongStrategyConfigured = longStrategy != default; GuiEnvironment.TradeRequirements.ChartShortStrategyConfigured = shortStrategy != default; GuiEnvironment.TradeRequirements.IsAccountLongConfigured = !string.IsNullOrEmpty(longStrategy?.AccountName) && longStrategy?.AccountName != "None"; GuiEnvironment.TradeRequirements.IsAccountShortConfigured = !string.IsNullOrEmpty(shortStrategy?.AccountName) && shortStrategy?.AccountName != "None"; GuiEnvironment.TradeRequirements.LongAccountName = GuiEnvironment.TradeRequirements.IsAccountLongConfigured ? longStrategy.AccountName : string.Empty; GuiEnvironment.TradeRequirements.ShortAccountName = GuiEnvironment.TradeRequirements.IsAccountShortConfigured ? shortStrategy.AccountName : string.Empty; //Call subscribers to update settings if (GuiEnvironment.ChartTradeRequirementsUpdated != null) GuiEnvironment.ChartTradeRequirementsUpdated(); } /// /// This method ensures retention of user-selected rows/cells and setting the grid's current cell. /// It's called by "checkPositions". /// private void setSelectedRows() { int rowIndex = 0; if (GuiEnvironment.HighlightGridRow) { foreach (DataGridViewRow row in dataGridView1.Rows.OfType().ToList()) { RowData test = (RowData)row.DataBoundItem; if (isRowInRowDataList(test, _selectedRowList)) row.Selected = true; rowIndex++; } } else { foreach (DataGridViewRow row in dataGridView1.Rows.OfType().ToList()) { RowData test = (RowData)row.DataBoundItem; TradingStrategy testTradingStrategy = (TradingStrategy)test.GetAsObject("object"); String strategy = test.GetAsString("Name", ""); if (isRowInRowDataList(test, _rowDatas.ToList())) { foreach (KeyValuePair> pair in _selectedRowCellDictionary.ToList()) { TradingStrategy tradingStrategy = (TradingStrategy)pair.Key.GetAsObject("object"); if (pair.Key.GetAsString("Name") == strategy && tradingStrategy == testTradingStrategy) { List cellIndices = pair.Value; foreach (int index in cellIndices) row.Cells[index].Selected = true; } } } rowIndex++; } } } private Boolean isRowInRowDataList(RowData row, List listInQuestion) { //being that the some datas belonging to a row might change over time, using the .ContiansKey could inadvertently result in two different objects //being compared(even though we're looking at the same row) which may cause the valid row which needs to be selected, to be skipped instead. So //we'll compare the name of the rowdata in question to that in binding list as this item does *not* change. This logic is not fool proof since //the user can have multiple strategies with the same name. String strategy = row.GetAsString("Name", ""); TradingStrategy testTradingStrategy = (TradingStrategy)row.GetAsObject("object"); foreach (RowData r in listInQuestion) { TradingStrategy tradingStrategy = (TradingStrategy)r.GetAsObject("object"); if (r.GetAsString("Name") == strategy && tradingStrategy == testTradingStrategy) return true; } return false; } private void updateSelectedRowList(DataGridViewCellEventArgs e) { _selectedRowList.Clear(); RowData rowData = _rowDatas[e.RowIndex]; DataGridViewSelectedRowCollection selectedRows = dataGridView1.SelectedRows; foreach (DataGridViewRow selectedRow in selectedRows) { RowData test = (RowData)selectedRow.DataBoundItem; _selectedRowList.Add(test); } } private void updateSelectedCellDictionary() { _selectedRowCellDictionary.Clear(); DataGridViewSelectedCellCollection selectedCells = dataGridView1.SelectedCells; //System.Diagnostics.Debug.WriteLine("[UpdateSelected] Found " + selectedCells.Count + " selected cells."); foreach (DataGridViewCell selectedCell in selectedCells) { DataGridViewRow row = selectedCell.OwningRow; RowData data = (RowData)row.DataBoundItem; if (_selectedRowCellDictionary.ContainsKey(data)) _selectedRowCellDictionary[data].Add(selectedCell.ColumnIndex); else { List temp = new List(); temp.Add(selectedCell.ColumnIndex); _selectedRowCellDictionary.Add(data, temp); } } //System.Diagnostics.Debug.WriteLine("[UpdateSelected] End " + _selectedRowCellDictionary.Count + " selected rowdata objects."); } private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { // We clear the selection of the after data binding to clear the automatic selection of a row // not selected by the user. // See https://stackoverflow.com/questions/12494719/how-can-one-disable-the-first-autoselect-in-a-vs-datagridview dataGridView1.ClearSelection(); } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { int index = e.RowIndex; if (index != -1) { //update the list, dictionary. Every time a user clicks on cell/row, the respective list/dictionary are reloaded with the current number of selected items. updateSelectedRowList(e); updateSelectedCellDictionary(); } } } }