/* *Ваши права на использование кода регулируются данной лицензией http://o-s-a.net/doc/license_simple_engine.pdf */ using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms; using System.Windows.Forms.Integration; using OsEngine.Entity; using OsEngine.Logging; using OsEngine.Market.Servers; namespace OsEngine.OsTrader { /// <summary> /// класс отвечающий за прорисовку глобальной позиции всех роботов в главном окне /// </summary> public class GlobalPosition { // сервис /// <summary> /// конструктор /// </summary> /// <param name="allPositionHost">хост на который будем рисовать дата грид</param> public GlobalPosition(WindowsFormsHost allPositionHost) { _host = allPositionHost; _grid = CreateNewTable(); _host.Child = _grid; _host.Child.Show(); if (Watcher == null) { Watcher = new Thread(WatcherHome); Watcher.IsBackground = true; Watcher.Name = "GlobalPositionThread"; Watcher.Start(); } } /// <summary> /// добавить ещё один журнал в коллекцию для прорисовки его сделок /// </summary> /// <param name="journal">новый журнал</param> public void SetJournal(Journal.Journal journal) { try { if (_journals == null) { _journals = new List<Journal.Journal>(); } if (_journals.Find(journal1 => journal1.Name == journal.Name) == null) { _journals.Add(journal); journal.PositionChangeEvent += journal_PositionChangeEvent; List<Position> openPositions = journal.OpenPositions; for (int i = 0; openPositions != null && i < openPositions.Count; i++) { journal_PositionChangeEvent(openPositions[i]); } } } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } } /// <summary> /// очистить от ранее загруженых журналов /// </summary> public void ClearJournals() { try { if (_grid.InvokeRequired) { _grid.Invoke(new Action(ClearJournals)); return; } for (int i = 0; _journals != null && i < _journals.Count; i++) { // отписываемся от обновления позиции _journals[i].PositionChangeEvent -= journal_PositionChangeEvent; } _journals = null; _grid.Rows.Clear(); } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } } /// <summary> /// журналы за которыми мы следим /// </summary> private List<Journal.Journal> _journals; /// <summary> /// хост на котором отображаем таблицу /// </summary> private WindowsFormsHost _host; /// <summary> /// таблица для прорисовки позиций /// </summary> private DataGridView _grid; //прорисовка /// <summary> /// остановить прорисовку элементов /// </summary> public void StopPaint() { try { if (!_host.CheckAccess()) { _host.Dispatcher.Invoke(StopPaint); return; } _host.Child = null; } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } } /// <summary> /// запустить прорисовку элементов /// </summary> public void StartPaint() { try { if (!_host.CheckAccess()) { _host.Dispatcher.Invoke(StartPaint); return; } _host.Child = _grid; } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } } /// <summary> /// создать таблицу /// </summary> /// <returns>таблица для прорисовки на ней позиций</returns> private DataGridView CreateNewTable() { try { DataGridView newGrid = new DataGridView(); newGrid.AllowUserToOrderColumns = false; newGrid.AllowUserToResizeRows = false; newGrid.AllowUserToDeleteRows = false; newGrid.AllowUserToAddRows = false; newGrid.RowHeadersVisible = false; newGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect; newGrid.MultiSelect = false; DataGridViewCellStyle style = new DataGridViewCellStyle(); style.Alignment = DataGridViewContentAlignment.BottomRight; DataGridViewTextBoxCell cell0 = new DataGridViewTextBoxCell(); cell0.Style = style; DataGridViewColumn colum0 = new DataGridViewColumn(); colum0.CellTemplate = cell0; colum0.HeaderText = @"Номер"; colum0.ReadOnly = true; colum0.Width = 50; newGrid.Columns.Add(colum0); DataGridViewColumn colum01 = new DataGridViewColumn(); colum01.CellTemplate = cell0; colum01.HeaderText = @"Время"; colum01.ReadOnly = true; colum01.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum01); DataGridViewColumn colu = new DataGridViewColumn(); colu.CellTemplate = cell0; colu.HeaderText = @"Бот"; colu.ReadOnly = true; colu.Width = 70; newGrid.Columns.Add(colu); DataGridViewColumn colum1 = new DataGridViewColumn(); colum1.CellTemplate = cell0; colum1.HeaderText = @"Инструмент"; colum1.ReadOnly = true; colum1.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum1); DataGridViewColumn colum2 = new DataGridViewColumn(); colum2.CellTemplate = cell0; colum2.HeaderText = @"Напр."; colum2.ReadOnly = true; colum2.Width = 40; newGrid.Columns.Add(colum2); DataGridViewColumn colum3 = new DataGridViewColumn(); colum3.CellTemplate = cell0; colum3.HeaderText = @"Cостояние"; colum3.ReadOnly = true; colum3.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum3); DataGridViewColumn colum4 = new DataGridViewColumn(); colum4.CellTemplate = cell0; colum4.HeaderText = @"Объём"; colum4.ReadOnly = true; colum4.Width = 60; newGrid.Columns.Add(colum4); DataGridViewColumn colum45 = new DataGridViewColumn(); colum45.CellTemplate = cell0; colum45.HeaderText = @"Текущий"; colum45.ReadOnly = true; colum45.Width = 60; newGrid.Columns.Add(colum45); DataGridViewColumn colum5 = new DataGridViewColumn(); colum5.CellTemplate = cell0; colum5.HeaderText = @"Ожидает"; colum5.ReadOnly = true; colum5.Width = 60; newGrid.Columns.Add(colum5); DataGridViewColumn colum6 = new DataGridViewColumn(); colum6.CellTemplate = cell0; colum6.HeaderText = @"Цена входа"; colum6.ReadOnly = true; colum6.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum6); DataGridViewColumn colum61 = new DataGridViewColumn(); colum61.CellTemplate = cell0; colum61.HeaderText = @"Цена выхода"; colum61.ReadOnly = true; colum61.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum61); DataGridViewColumn colum8 = new DataGridViewColumn(); colum8.CellTemplate = cell0; colum8.HeaderText = @"Прибыль"; colum8.ReadOnly = true; colum8.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum8); DataGridViewColumn colum9 = new DataGridViewColumn(); colum9.CellTemplate = cell0; colum9.HeaderText = @"СтопАктивация"; colum9.ReadOnly = true; colum9.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum9); DataGridViewColumn colum10 = new DataGridViewColumn(); colum10.CellTemplate = cell0; colum10.HeaderText = @"СтопЦена"; colum10.ReadOnly = true; colum10.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum10); DataGridViewColumn colum11 = new DataGridViewColumn(); colum11.CellTemplate = cell0; colum11.HeaderText = @"ПрофитАктивация"; colum11.ReadOnly = true; colum11.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum11); DataGridViewColumn colum12 = new DataGridViewColumn(); colum12.CellTemplate = cell0; colum12.HeaderText = @"ПрофитЦена"; colum12.ReadOnly = true; colum12.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; newGrid.Columns.Add(colum12); return newGrid; } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } return null; } /// <summary> /// в журнале изменилась позиция /// </summary> /// <param name="position">позиция</param> [System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute] public void journal_PositionChangeEvent(Position position) { // В ТЕСТЕРЕ позиции прорисоываются по очереди, В реале, в методе ThreadWatcher() if (ServerMaster.StartProgram != ServerStartProgramm.IsTester) { return; } try { if (_grid.InvokeRequired) { _grid.Invoke(new Action<Position>(journal_PositionChangeEvent), position); return; } if (position.State != PositionStateType.Open && position.State != PositionStateType.Opening && position.State != PositionStateType.Closing && position.State != PositionStateType.ClosingFail) {// сделка была удалена. Надо её удалить отовсюду for (int i = 0; i < _grid.Rows.Count; i++) { if ((int)_grid.Rows[i].Cells[0].Value == position.Number) { _grid.Rows.Remove(_grid.Rows[i]); return; } } } else { // сделкка должна быть прорисована в таблице for (int i = 0; i < _grid.Rows.Count; i++) { if ((int)_grid.Rows[i].Cells[0].Value == position.Number) { _grid.Rows.Remove(_grid.Rows[i]); DataGridViewRow row1 = GetRow(position); if (row1 != null) { _grid.Rows.Insert(i, row1); } return; } } DataGridViewRow row = GetRow(position); if (row != null) { _grid.Rows.Add(row); } } } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } } /// <summary> /// взять строку для таблицы представляющую позицию /// </summary> /// <param name="position">позиция</param> /// <returns>строка для таблицы</returns> private DataGridViewRow GetRow(Position position) { if (position == null) { return null; } try { DataGridViewRow nRow = new DataGridViewRow(); nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[0].Value = position.Number; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[1].Value = position.TimeCreate; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[2].Value = position.NameBot; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[3].Value = position.SecurityName; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[4].Value = position.Direction; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[5].Value = position.State; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[6].Value = position.MaxVolume; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[7].Value = position.OpenVolume; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[8].Value = position.WaitVolume; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[9].Value = position.EntryPrice; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[10].Value = position.ClosePrice; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[11].Value = position.ProfitPortfolioPunkt; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[12].Value = position.StopOrderRedLine; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[13].Value = position.StopOrderPrice; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[14].Value = position.ProfitOrderRedLine; nRow.Cells.Add(new DataGridViewTextBoxCell()); nRow.Cells[15].Value = position.ProfitOrderPrice; return nRow; } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } return null; } /// <summary> /// поток /// </summary> private Thread Watcher; /// <summary> /// место работы потока который сохраняет логи /// </summary> private void WatcherHome() { if (ServerMaster.StartProgram != ServerStartProgramm.IsOsTrader) { return; } while (true) { Thread.Sleep(2000); CheckPosition(); if (!MainWindow.ProccesIsWorked) { return; } } } /// <summary> /// проверить позиции на правильность прорисовки /// </summary> [System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions] private void CheckPosition() { if (_grid.InvokeRequired) { _grid.Invoke(new Action(CheckPosition)); return; } try { List<Position> openPositions = new List<Position>(); for (int i = 0; _journals != null && i < _journals.Count; i++) { if (_journals[i].OpenPositions != null && _journals[i].OpenPositions.Count != 0) { openPositions.AddRange(_journals[i].OpenPositions); } } for (int i1 = 0; i1 < openPositions.Count; i1++) { Position position = openPositions[i1]; DataGridViewRow row = GetRow(position); bool isIn = false; for (int i = 0; i < _grid.Rows.Count; i++) { if (_grid.Rows[i].Cells[0].Value != null && (int) _grid.Rows[i].Cells[0].Value == position.Number) { _grid.Rows.Remove(_grid.Rows[i]); DataGridViewRow row1 = GetRow(position); if (row1 != null) { _grid.Rows.Add(row1); } isIn = true; break; } } if (isIn == false && row != null) { _grid.Rows.Add(row); } } for (int i = 0; i < _grid.Rows.Count; i++) { if (openPositions.Find(pos => pos.Number == (int) _grid.Rows[i].Cells[0].Value) == null) { _grid.Rows.Remove(_grid.Rows[i]); } } } catch (Exception error) { SendNewLogMessage(error.ToString(), LogMessageType.Error); } } // сообщения в лог /// <summary> /// выслать новое сообщение на верх /// </summary> private void SendNewLogMessage(string message, LogMessageType type) { if (LogMessageEvent != null) { LogMessageEvent(message, type); } else if (type == LogMessageType.Error) { System.Windows.MessageBox.Show(message); } } /// <summary> /// исходящее сообщение для лога /// </summary> public event Action<string, LogMessageType> LogMessageEvent; } }