Прочие классы в библиотеке DoEasy (Часть 67): Класс объекта-чарта
Содержание
Концепция
Сегодня начинаем разрабатывать функционал библиотеки по работе с графиками символов. Это основной рабочий инструмент и мы постараемся за несколько статей сделать его весьма удобным и комфортным. В первую очередь мы создадим объект чарта, который будет хранить все свойства графика, и посредством изменения этих свойств мы сможем легко управлять им. Набор свойств объекта-чарта будет представлять собой набор целочисленных, вещественных и строковых параметров графика. При постепенной и последовательной доработке объекта-чарта, его набор параметров будет изменяться — какие-то параметры будут добавлены, какие-то перенесены в другие объекты, и т. д. Но начнём с малого.
Помимо создания объекта-чарта мы сегодня немного доработаем класс объекта mql5-сигнала и класс-коллекцию Сигналов MQL5.com. На данный момент работа с коллекцией сигналов у нас организована так, что при первом создании полного списка всех доступных сигналов, их свойства больше не меняются. Даже если заново попробовать обновить список-коллекцию, то в неё, максимум, будет добавлен вновь появившийся в базе Сигналов MQL5.com сигнал, а те сигналы, которые ранее были добавлены в список-коллекцию, так и останутся без изменения их свойств. Это не правильное поведение — у сигналов же изменяются их свойства в результате торговли на счёте провайдера сигнала. Поэтому мы сегодня изменим это поведение — при любом обновлении списка-коллекции сигналов, новые сигналы будут добавляться в список, а для уже присутствующих будут обновляться их свойства.
Доработка классов библиотеки
Сейчас у нас в библиотеке в классе-коллекции сигналов сделано так, что все значения параметров Сигнала MQL5.com сразу вписываются в соответствующие свойства объекта mql5-сигнала в его конструкторе при создании нового объекта-сигнала. Нам нужно добавить метод, в котором будут вписываться все значения параметров выбранного сигнала в свойства объекта. Таким образом, мы сможем для обновления свойств уже существующего объекта-сигнала, выбрать нужный сигнал и вызвать этот новый метод. Также нам потребуется метод, выбирающий нужный нам сигнал в Базе Сигналов MQL5.com по идентификатору сигнала (в MQL5 сигнал выбирается только по его индексу, но хранение индекса сигнала в свойствах объекта — ненадёжный способ, так как индексы сигналов в Базе могут меняться наверняка).
В файле \MQL5\Include\DoEasy\Objects\MQLSignalBase\MQLSignal.mqh впишем три новых публичных метода:
метод для записи значений параметров выбранного Сигнала MQL5.com в соответствующие свойства объекта-сигнала,
метод, возвращающий индекс сигнала в Базе Сигналов MQL5.com по его идентификатору, и
метод, выбирающий указанный по идентификатору сигнал в Базе Сигналов MQL5.com, для дальнейшей с ним работы:
//--- Сравнивает объекты CMQLSignal между собой по указанному свойству (для сортировки списка по свойству объекта-mql5-сигнала) virtual int Compare(const CObject *node,const int mode=0) const; //--- Сравнивает объекты CMQLSignal между собой по всем свойствам (для поиска равных объектов-mql5-сигналов) bool IsEqual(CMQLSignal* compared_obj) const; //--- Устанавливает свойства объекта-сигнала void SetProperties(void); //--- Ищет в базе сигналов сигнал с указанным идентификатором, возвращает индекс сигнала int IndexBase(const long signal_id); //--- Выбирает сигнал в базе сигналов по его идентификатору bool SelectBase(const long signal_id); //--- Конструкторы CMQLSignal(){;} CMQLSignal(const long signal_id);
Из параметрического конструктора класса перенесём запись параметров сигнала в соответствующие свойства объекта в новый метод SetProperties():
//+------------------------------------------------------------------+ //| Устанавливает свойства объекта | //+------------------------------------------------------------------+ void CMQLSignal::SetProperties(void) { this.m_long_prop[SIGNAL_MQL5_PROP_SUBSCRIPTION_STATUS] = (::SignalInfoGetInteger(SIGNAL_INFO_ID)==this.ID()); this.m_long_prop[SIGNAL_MQL5_PROP_TRADE_MODE] = ::SignalBaseGetInteger(SIGNAL_BASE_TRADE_MODE); this.m_long_prop[SIGNAL_MQL5_PROP_DATE_PUBLISHED] = ::SignalBaseGetInteger(SIGNAL_BASE_DATE_PUBLISHED); this.m_long_prop[SIGNAL_MQL5_PROP_DATE_STARTED] = ::SignalBaseGetInteger(SIGNAL_BASE_DATE_STARTED); this.m_long_prop[SIGNAL_MQL5_PROP_DATE_UPDATED] = ::SignalBaseGetInteger(SIGNAL_BASE_DATE_UPDATED); this.m_long_prop[SIGNAL_MQL5_PROP_LEVERAGE] = ::SignalBaseGetInteger(SIGNAL_BASE_LEVERAGE); this.m_long_prop[SIGNAL_MQL5_PROP_PIPS] = ::SignalBaseGetInteger(SIGNAL_BASE_PIPS); this.m_long_prop[SIGNAL_MQL5_PROP_RATING] = ::SignalBaseGetInteger(SIGNAL_BASE_RATING); this.m_long_prop[SIGNAL_MQL5_PROP_SUBSCRIBERS] = ::SignalBaseGetInteger(SIGNAL_BASE_SUBSCRIBERS); this.m_long_prop[SIGNAL_MQL5_PROP_TRADES] = ::SignalBaseGetInteger(SIGNAL_BASE_TRADES); this.m_double_prop[this.IndexProp(SIGNAL_MQL5_PROP_BALANCE)] = ::SignalBaseGetDouble(SIGNAL_BASE_BALANCE); this.m_double_prop[this.IndexProp(SIGNAL_MQL5_PROP_EQUITY)] = ::SignalBaseGetDouble(SIGNAL_BASE_EQUITY); this.m_double_prop[this.IndexProp(SIGNAL_MQL5_PROP_GAIN)] = ::SignalBaseGetDouble(SIGNAL_BASE_GAIN); this.m_double_prop[this.IndexProp(SIGNAL_MQL5_PROP_MAX_DRAWDOWN)] = ::SignalBaseGetDouble(SIGNAL_BASE_MAX_DRAWDOWN); this.m_double_prop[this.IndexProp(SIGNAL_MQL5_PROP_PRICE)] = ::SignalBaseGetDouble(SIGNAL_BASE_PRICE); this.m_double_prop[this.IndexProp(SIGNAL_MQL5_PROP_ROI)] = ::SignalBaseGetDouble(SIGNAL_BASE_ROI); this.m_string_prop[this.IndexProp(SIGNAL_MQL5_PROP_AUTHOR_LOGIN)] = ::SignalBaseGetString(SIGNAL_BASE_AUTHOR_LOGIN); this.m_string_prop[this.IndexProp(SIGNAL_MQL5_PROP_BROKER)] = ::SignalBaseGetString(SIGNAL_BASE_BROKER); this.m_string_prop[this.IndexProp(SIGNAL_MQL5_PROP_BROKER_SERVER)]= ::SignalBaseGetString(SIGNAL_BASE_BROKER_SERVER); this.m_string_prop[this.IndexProp(SIGNAL_MQL5_PROP_NAME)] = ::SignalBaseGetString(SIGNAL_BASE_NAME); this.m_string_prop[this.IndexProp(SIGNAL_MQL5_PROP_CURRENCY)] = ::SignalBaseGetString(SIGNAL_BASE_CURRENCY); } //+------------------------------------------------------------------+
Так как сигнал должен быть предварительно выбран в Базе Сигналов MQL5.com, то получение значений параметров сигнала и запись их в свойства объекта подразумевает, что сигнал выбран априори.
В конструкторе класса вместо перенесённых в новый метод строк впишем вызов этого метода:
//+------------------------------------------------------------------+ //| Параметрический конструктор | //+------------------------------------------------------------------+ CMQLSignal::CMQLSignal(const long signal_id) { this.m_long_prop[SIGNAL_MQL5_PROP_ID] = signal_id; this.SetProperties(); } //+------------------------------------------------------------------+
Метод, возвращающий индекс указанного по идентификатору сигнала в Базе Сигналов MQL5.com:
//+------------------------------------------------------------------+ //| Ищет в базе сигналов сигнал с указанным идентификатором, | //| возвращает индекс найденного сигнала | //+------------------------------------------------------------------+ int CMQLSignal::IndexBase(const long signal_id) { int total=::SignalBaseTotal(); for(int i=0;i<total;i++) { if(::SignalBaseSelect(i) && ::SignalBaseGetInteger(SIGNAL_BASE_ID)==signal_id) return i; } return WRONG_VALUE; } //+------------------------------------------------------------------+
Здесь: в цикле по общему количеству сигналов выбираем очередной сигнал и сравниваем его идентификатор с переданным в метод. Если идентификаторы совпадают, то возвращаем индекс цикла (он и является индексом сигнала в Базе). Если сигнал с таким идентификатором не найден — возвращаем -1.
После работы этого метода при условии, что сигнал был найден, он остаётся выбранным в Базе Сигналов для дальнейшей с ним работы.
На этом построен метод, выбирающий указанный по идентификатору сигнал:
//+------------------------------------------------------------------+ //| Выбирает сигнал в базе сигналов по его идентификатору | //+------------------------------------------------------------------+ bool CMQLSignal::SelectBase(const long signal_id) { return(this.IndexBase(signal_id)!=WRONG_VALUE); } //+------------------------------------------------------------------+
Метод возвращает флаг того, что поиск сигнала по указанному идентификатору не вернул -1. Т. е. если индекс сигнала найден (он не равен -1), то и сигнал является выбранным, и возвращается true. Если поиск сигнала вернул -1, то возвращается false — сигнала с таким идентификатором нет и он не выбран, соответственно.
В файле класса-коллекции mql5-сигналов \MQL5\Include\DoEasy\Collections\MQLSignalsCollection.mqh внесём небольшие доработки в метод обновления списка-коллекции:
//+------------------------------------------------------------------+ //| Обновляет список-коллекцию объектов-mql5-сигналов | //+------------------------------------------------------------------+ void CMQLSignalsCollection::Refresh(const bool messages=true) { this.m_signals_base_total=::SignalBaseTotal(); //--- цикл по всем сигналам в базе сигналов for(int i=0;i<this.m_signals_base_total;i++) { //--- Выбираем сигнал из базы сигналов по индексу цикла if(!::SignalBaseSelect(i)) continue; //--- Получаем идентификатор текущего сигнала и //--- на его основании создаём новый объект-mql5-сигнал long id=::SignalBaseGetInteger(SIGNAL_BASE_ID); CMQLSignal *signal=new CMQLSignal(id); if(signal==NULL) continue; //--- Устанавливаем списку флаг сортировки по идентификатору сигналов this.m_list.Sort(SORT_BY_SIGNAL_MQL5_ID); //--- Получаем индекс объекта-mql5-сигнала в списке int index=this.m_list.Search(signal); //--- Если такой объект существует (индекс больше -1) if(index!=WRONG_VALUE) { //--- Удаляем вновь созданный объект, delete signal; //--- получаем указатель на такой объект в списке signal=this.m_list.At(index); //--- если указатель получен - обновляем все свойства сигнала if(signal!=NULL) signal.SetProperties(); //--- идём на следующую итерацию цикла continue; } //--- Такого объекта ещё нет в списке-коллекции //--- Если новый объект-сигнал не удалось добавить в список-коллекцию - //--- удаляем созданный объект и идём на следующую итерацию цикла if(!this.m_list.InsertSort(signal)) { delete signal; continue; } //--- Если объект-mql5-сигнал успешно добавлен в коллекцию //--- и установлен флаг сообщения о новом объекте в переданных в метод параметрах - //--- выводим сообщение о новом найденном сигнале else if(messages) { ::Print(DFUN,CMessage::Text(MSG_MQLSIG_COLLECTION_TEXT_SIGNALS_NEW),":"); signal.PrintShort(true); } } } //+------------------------------------------------------------------+
Здесь в новом блоке кода вся логика прописана в комментариях. Если вкратце, то теперь существующие в коллекции объекты не пропускаются, а для них вызывается новый метод SetProperties(), рассмотренный нами выше, который и вписывает во все свойства объекта значения соответствующих параметров выбранного в базе сигнала.
На этом доработка классов для работы с Сигналами MQL5.com завершена.
Приступим к разработке класса объекта-чарта.
Параметров у графика и, соответственно, у объекта-чарта достаточно много. И нам в первую очередь необходимо создать новые текстовые сообщения, так или иначе связанные с объектом-чартом.
В файле \MQL5\Include\DoEasy\Data.mqh впишем индексы новых сообщений:
//--- CChartObj MSG_CHART_OBJ_ID, // Идентификатор графика MSG_CHART_OBJ_SHOW, // Отрисовка атрибутов ценового графика MSG_CHART_OBJ_IS_OBJECT, // Объект "График" MSG_CHART_OBJ_BRING_TO_TOP, // График поверх всех других MSG_CHART_OBJ_CONTEXT_MENU, // Доступ к контекстному меню по нажатию правой клавиши мыши MSG_CHART_OBJ_CROSSHAIR_TOOL, // Доступ к инструменту "Перекрестие" по нажатию средней клавиши мыши MSG_CHART_OBJ_MOUSE_SCROLL, // Прокрутка графика левой кнопкой мышки по горизонтали MSG_CHART_OBJ_EVENT_MOUSE_WHEEL, // Отправка всем mql5-программам на графике сообщений о событиях колёсика мыши MSG_CHART_OBJ_EVENT_MOUSE_MOVE, // Отправка всем mql5-программам на графике сообщений о событиях перемещения и нажатия кнопок мыши MSG_CHART_OBJ_EVENT_OBJECT_CREATE, // Отправка всем mql5-программам на графике сообщений о событии создания графического объекта MSG_CHART_OBJ_EVENT_OBJECT_DELETE, // Отправка всем mql5-программам на графике сообщений о событии уничтожения графического объекта MSG_CHART_OBJ_MODE, // Тип графика MSG_CHART_OBJ_FOREGROUND, // Ценовой график на переднем плане MSG_CHART_OBJ_SHIFT, // Отступ ценового графика от правого края MSG_CHART_OBJ_AUTOSCROLL, // Автоматический переход к правому краю графика MSG_CHART_OBJ_KEYBOARD_CONTROL, // Управление графиком с помощью клавиатуры MSG_CHART_OBJ_QUICK_NAVIGATION, // Перехват графиком нажатий клавиш Space и Enter для активации строки быстрой навигации MSG_CHART_OBJ_SCALE, // Масштаб MSG_CHART_OBJ_SCALEFIX, // Фиксированный масштаб MSG_CHART_OBJ_SCALEFIX_11, // Масштаб 1:1 MSG_CHART_OBJ_SCALE_PT_PER_BAR, // Масштаб в пунктах на бар MSG_CHART_OBJ_SHOW_TICKER, // Отображение в левом верхнем углу тикера символа MSG_CHART_OBJ_SHOW_OHLC, // Отображение в левом верхнем углу значений OHLC MSG_CHART_OBJ_SHOW_BID_LINE, // Отображение значения Bid горизонтальной линией на графике MSG_CHART_OBJ_SHOW_ASK_LINE, // Отображение значения Ask горизонтальной линией на графике MSG_CHART_OBJ_SHOW_LAST_LINE, // Отображение значения Last горизонтальной линией на графике MSG_CHART_OBJ_SHOW_PERIOD_SEP, // Отображение вертикальных разделителей между соседними периодами MSG_CHART_OBJ_SHOW_GRID, // Отображение сетки на графике MSG_CHART_OBJ_SHOW_VOLUMES, // Отображение объемов на графике MSG_CHART_OBJ_SHOW_OBJECT_DESCR, // Отображение текстовых описаний объектов MSG_CHART_OBJ_VISIBLE_BARS, // Количество баров на графике, доступных для отображения MSG_CHART_OBJ_WINDOWS_TOTAL, // Общее количество окон графика с подокнами индикаторов MSG_CHART_OBJ_WINDOW_IS_VISIBLE, // Видимость подокон MSG_CHART_OBJ_WINDOW_HANDLE, // Хэндл окна графика MSG_CHART_OBJ_WINDOW_YDISTANCE, // Дистанция в пикселях по оси Y между верхней рамкой подокна индикатора и верхней рамкой главного окна графика MSG_CHART_OBJ_FIRST_VISIBLE_BAR, // Номер первого видимого бара на графике MSG_CHART_OBJ_WIDTH_IN_BARS, // Ширина графика в барах MSG_CHART_OBJ_WIDTH_IN_PIXELS, // Ширина графика в пикселях MSG_CHART_OBJ_HEIGHT_IN_PIXELS, // Высота графика в пикселях MSG_CHART_OBJ_COLOR_BACKGROUND, // Цвет фона графика MSG_CHART_OBJ_COLOR_FOREGROUND, // Цвет осей, шкалы и строки OHLC MSG_CHART_OBJ_COLOR_GRID, // Цвет сетки MSG_CHART_OBJ_COLOR_VOLUME, // Цвет объемов и уровней открытия позиций MSG_CHART_OBJ_COLOR_CHART_UP, // Цвет бара вверх, тени и окантовки тела бычьей свечи MSG_CHART_OBJ_COLOR_CHART_DOWN, // Цвет бара вниз, тени и окантовки тела медвежьей свечи MSG_CHART_OBJ_COLOR_CHART_LINE, // Цвет линии графика и японских свечей "Доджи" MSG_CHART_OBJ_COLOR_CANDLE_BULL, // Цвет тела бычьей свечи MSG_CHART_OBJ_COLOR_CANDLE_BEAR, // Цвет тела медвежьей свечи MSG_CHART_OBJ_COLOR_BID, // Цвет линии Bid-цены MSG_CHART_OBJ_COLOR_ASK, // Цвет линии Ask-цены MSG_CHART_OBJ_COLOR_LAST, // Цвет линии цены последней совершенной сделки (Last) MSG_CHART_OBJ_COLOR_STOP_LEVEL, // Цвет уровней стоп-ордеров (Stop Loss и Take Profit) MSG_CHART_OBJ_SHOW_TRADE_LEVELS, // Отображение на графике торговых уровней (уровни открытых позиций, Stop Loss, Take Profit и отложенных ордеров) MSG_CHART_OBJ_DRAG_TRADE_LEVELS, // Перетаскивание торговых уровней на графике с помощью мышки MSG_CHART_OBJ_SHOW_DATE_SCALE, // Отображение на графике шкалы времени MSG_CHART_OBJ_SHOW_PRICE_SCALE, // Отображение на графике ценовой шкалы MSG_CHART_OBJ_SHOW_ONE_CLICK, // Отображение на графике панели быстрой торговли MSG_CHART_OBJ_IS_MAXIMIZED, // Окно графика развернуто MSG_CHART_OBJ_IS_MINIMIZED, // Окно графика свернуто MSG_CHART_OBJ_IS_DOCKED, // Окно графика закреплено MSG_CHART_OBJ_FLOAT_LEFT, // Левая координата открепленного графика относительно виртуального экрана MSG_CHART_OBJ_FLOAT_TOP, // Верхняя координата открепленного графика относительно виртуального экрана MSG_CHART_OBJ_FLOAT_RIGHT, // Правая координата открепленного графика относительно виртуального экрана MSG_CHART_OBJ_FLOAT_BOTTOM, // Нижняя координата открепленного графика относительно виртуального экрана MSG_CHART_OBJ_SHIFT_SIZE, // Размер отступа нулевого бара от правого края в процентах MSG_CHART_OBJ_FIXED_POSITION, // Положение фиксированной позиции графика от левого края в процентах MSG_CHART_OBJ_FIXED_MAX, // Фиксированный максимум графика MSG_CHART_OBJ_FIXED_MIN, // Фиксированный минимум графика MSG_CHART_OBJ_POINTS_PER_BAR, // Масштаб в пунктах на бар MSG_CHART_OBJ_PRICE_MIN, // Минимум графика MSG_CHART_OBJ_PRICE_MAX, // Максимум графика MSG_CHART_OBJ_COMMENT, // Текст комментария на графике MSG_CHART_OBJ_EXPERT_NAME, // Имя эксперта, запущенного на графике MSG_CHART_OBJ_SCRIPT_NAME, // Имя скрипта, запущенного на графике MSG_CHART_OBJ_CHART_BARS, // Отображение в виде баров MSG_CHART_OBJ_CHART_CANDLES, // Отображение в виде японских свечей MSG_CHART_OBJ_CHART_LINE, // Отображение в виде линии, проведенной по ценам Close MSG_CHART_OBJ_CHART_VOLUME_HIDE, // Объемы не показаны MSG_CHART_OBJ_CHART_VOLUME_TICK, // Тиковые объемы MSG_CHART_OBJ_CHART_VOLUME_REAL, // Торговые объемы MSG_CHART_OBJ_CHART_WINDOW, // Окно графика }; //+------------------------------------------------------------------+
и текстовые сообщения, соответствующие вновь добавленным индексам:
//--- CChartObj {"Идентификатор графика","Chart ID"}, {"Отрисовка атрибутов ценового графика","Drawing attributes of a price chart"}, {"Объект \"График\"","Object \"Chart\""}, {"График поверх всех других","Chart on top of other charts"}, {"Доступ к контекстному меню по нажатию правой клавиши мыши","Accessing the context menu by pressing the right mouse button"}, {"Доступ к инструменту \"Перекрестие\" по нажатию средней клавиши мыши","Accessing the \"Crosshair tool\" by pressing the middle mouse button"}, {"Прокрутка графика левой кнопкой мышки по горизонтали","Scrolling the chart horizontally using the left mouse button"}, {"Отправка всем mql5-программам на графике сообщений о событиях колёсика мыши","Sending messages about mouse wheel events to all mql5 programs on a chart"}, {"Отправка всем mql5-программам на графике сообщений о событиях перемещения и нажатия кнопок мыши","Send notifications of mouse move and mouse click events to all mql5 programs on a chart"}, {"Отправка всем mql5-программам на графике сообщений о событии создания графического объекта","Send a notification of an event of new object creation to all mql5-programs on a chart"}, {"Отправка всем mql5-программам на графике сообщений о событии уничтожения графического объекта","Send a notification of an event of object deletion to all mql5-programs on a chart"}, {"Тип графика","Chart type"}, {"Ценовой график на переднем плане","Price chart in the foreground"}, {"Отступ ценового графика от правого края","Price chart indent from the right border"}, {"Автоматический переход к правому краю графика","Automatic moving to the right border of the chart"}, {"Управление графиком с помощью клавиатуры","Managing the chart using a keyboard"}, {"Перехват графиком нажатий клавиш Space и Enter для активации строки быстрой навигации","Allowed to intercept Space and Enter key presses on the chart to activate the quick navigation bar"}, {"Масштаб","Scale"}, {"Фиксированный масштаб","Fixed scale mode"}, {"Масштаб 1:1","Scale 1:1 mode"}, {"Масштаб в пунктах на бар","Scale to be specified in points per bar"}, {"Отображение в левом верхнем углу тикера символа","Display a symbol ticker in the upper left corner"}, {"Отображение в левом верхнем углу значений OHLC","Display OHLC values in the upper left corner"}, {"Отображение значения Bid горизонтальной линией на графике","Display Bid values as a horizontal line in a chart"}, {"Отображение значения Ask горизонтальной линией на графике","Display Ask values as a horizontal line in a chart"}, {"Отображение значения Last горизонтальной линией на графике","Display Last values as a horizontal line in a chart"}, {"Отображение вертикальных разделителей между соседними периодами","Display vertical separators between adjacent periods"}, {"Отображение сетки на графике","Display grid in the chart"}, {"Отображение объемов на графике","Display volume in the chart"}, {"Отображение текстовых описаний объектов","Display textual descriptions of objects"}, {"Количество баров на графике, доступных для отображения","The number of bars on the chart that can be displayed"}, {"Общее количество окон графика с подокнами индикаторов","The total number of chart windows, including indicator subwindows"}, {"Видимость подокон","Visibility of subwindows"}, {"Хэндл окна графика","Chart window handle"}, {"Дистанция в пикселях по оси Y между верхней рамкой подокна индикатора и верхней рамкой главного окна графика","The distance between the upper frame of the indicator subwindow and the upper frame of the main chart window"}, {"Номер первого видимого бара на графике","Number of the first visible bar in the chart"}, {"Ширина графика в барах","Chart width in bars"}, {"Ширина графика в пикселях","Chart width in pixels"}, {"Высота графика в пикселях","Chart height in pixels"}, {"Цвет фона графика","Chart background color"}, {"Цвет осей, шкалы и строки OHLC","Color of axes, scales and OHLC line"}, {"Цвет сетки","Grid color"}, {"Цвет объемов и уровней открытия позиций","Color of volumes and position opening levels"}, {"Цвет бара вверх, тени и окантовки тела бычьей свечи","Color for the up bar, shadows and body borders of bull candlesticks"}, {"Цвет бара вниз, тени и окантовки тела медвежьей свечи","Color for the down bar, shadows and body borders of bear candlesticks"}, {"Цвет линии графика и японских свечей \"Доджи\"","Line chart color and color of \"Doji\" Japanese candlesticks"}, {"Цвет тела бычьей свечи","Body color of a bull candlestick"}, {"Цвет тела медвежьей свечи","Body color of a bear candlestick"}, {"Цвет линии Bid-цены","Bid price level color"}, {"Цвет линии Ask-цены","Ask price level color"}, {"Цвет линии цены последней совершенной сделки (Last)","Line color of the last executed deal price (Last)"}, {"Цвет уровней стоп-ордеров (Stop Loss и Take Profit)","Color of stop order levels (Stop Loss and Take Profit)"}, {"Отображение на графике торговых уровней (уровни открытых позиций, Stop Loss, Take Profit и отложенных ордеров)","Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders)"}, {"Перетаскивание торговых уровней на графике с помощью мышки","Permission to drag trading levels on a chart with a mouse"}, {"Отображение на графике шкалы времени","Showing the time scale on a chart"}, {"Отображение на графике ценовой шкалы","Showing the price scale on a chart"}, {"Отображение на графике панели быстрой торговли","Showing the \"One click trading\" panel on a chart"}, {"Окно графика развернуто","Chart window is maximized"}, {"Окно графика свернуто","Chart window is minimized"}, {"Окно графика закреплено","The chart window is docked"}, {"Левая координата открепленного графика относительно виртуального экрана","The left coordinate of the undocked chart window relative to the virtual screen"}, {"Верхняя координата открепленного графика относительно виртуального экрана","The top coordinate of the undocked chart window relative to the virtual screen"}, {"Правая координата открепленного графика относительно виртуального экрана","The right coordinate of the undocked chart window relative to the virtual screen"}, {"Нижняя координата открепленного графика относительно виртуального экрана","The bottom coordinate of the undocked chart window relative to the virtual screen"}, {"Размер отступа нулевого бара от правого края в процентах","The size of the zero bar indent from the right border in percents"}, {"Положение фиксированной позиции графика от левого края в процентах","Chart fixed position from the left border in percent value"}, {"Фиксированный максимум графика","Fixed chart maximum"}, {"Фиксированный минимум графика","Fixed chart minimum "}, {"Масштаб в пунктах на бар","Scale in points per bar"}, {"Минимум графика","Chart minimum"}, {"Максимум графика","Chart maximum"}, {"Текст комментария на графике","Text of a comment in a chart"}, {"Имя эксперта, запущенного на графике","The name of the Expert Advisor running on the chart"}, {"Имя скрипта, запущенного на графике","The name of the script running on the chart"}, {"Отображение в виде баров","Display as a sequence of bars"}, {"Отображение в виде японских свечей","Display as Japanese candlesticks"}, {"Отображение в виде линии, проведенной по ценам Close","Display as a line drawn by Close prices"}, {"Объемы не показаны","Volumes are not shown"}, {"Тиковые объемы","Tick volumes"}, {"Торговые объемы","Trade volumes"}, {"Окно графика","Chart window"}, }; //+---------------------------------------------------------------------+
Чтобы понимать для чего нам необходимо вписывать именованные константы-индексы сообщений, сами сообщения, да и вообще, чтобы понимать как работают эти списки, рекомендую обратиться к статье 19, в которой подробно описан процесс разработки класса сообщений библиотеки.
Для вывода описания некоторых свойств создаваемого объекта-чарта нам потребуются две функции — для возврата описания режима отображения графика (бары, свечи, линия) и для возврата описания режима отображения объёмов на графике (не показываются, тиковые, реальные). Чтобы такие функции всегда были "под рукой", впишем их в файл сервисных функций \MQL5\Include\DoEasy\Services\DELib.mqh:
//+------------------------------------------------------------------+ //| Возвращает описание способа отображения ценового графика | //+------------------------------------------------------------------+ string ChartModeDescription(ENUM_CHART_MODE mode) { return ( mode==CHART_BARS ? CMessage::Text(MSG_CHART_OBJ_CHART_BARS) : mode==CHART_CANDLES ? CMessage::Text(MSG_CHART_OBJ_CHART_CANDLES) : CMessage::Text(MSG_CHART_OBJ_CHART_LINE) ); } //+------------------------------------------------------------------+ //|Возвращает описание режима отображения объемов на ценовом графике | //+------------------------------------------------------------------+ string ChartModeVolumeDescription(ENUM_CHART_VOLUME_MODE mode) { return ( mode==CHART_VOLUME_TICK ? CMessage::Text(MSG_CHART_OBJ_CHART_VOLUME_TICK) : mode==CHART_VOLUME_REAL ? CMessage::Text(MSG_CHART_OBJ_CHART_VOLUME_REAL) : CMessage::Text(MSG_CHART_OBJ_CHART_VOLUME_HIDE) ); } //+------------------------------------------------------------------+
В обе функции передаётся соответствующее свойство графика, в функции проверяется его соответствие одной из констант перечисления и возвращается строковое описание этого режима графика/объёмов.
У каждого из объектов библиотеки есть список свойств, прописанных в файле \MQL5\Include\DoEasy\Defines.mqh. Объект-чарт не является исключением, и для него также пропишем все необходимые свойства в трёх перечислениях целочисленных, вещественных и строковых свойств:
//+------------------------------------------------------------------+ //| Данные для работы с чартами | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Список возможных событий чарта | //+------------------------------------------------------------------+ #define CHART_EVENTS_NEXT_CODE (SIGNAL_MQL5_EVENTS_NEXT_CODE+1) // Код следующего события после последнего кода события чарта //+------------------------------------------------------------------+ //| Целочисленные свойства чарта | //+------------------------------------------------------------------+ enum ENUM_CHART_PROP_INTEGER { CHART_PROP_ID = 0, // Идентификатор графика CHART_PROP_TIMEFRAME, // Таймфрейм графика CHART_PROP_SHOW, // Признак отрисовки ценового графика CHART_PROP_IS_OBJECT, // Признак идентификации объекта "График" (OBJ_CHART) CHART_PROP_BRING_TO_TOP, // Показ графика поверх всех других CHART_PROP_CONTEXT_MENU, // Включение/отключение доступа к контекстному меню по нажатию правой клавиши мышки. CHART_PROP_CROSSHAIR_TOOL, // Включение/отключение доступа к инструменту "Перекрестие" по нажатию средней клавиши мышки CHART_PROP_MOUSE_SCROLL, // Прокрутка графика левой кнопкой мышки по горизонтали CHART_PROP_EVENT_MOUSE_WHEEL, // Отправка всем mql5-программам на графике сообщений о событиях колёсика мышки (CHARTEVENT_MOUSE_WHEEL) CHART_PROP_EVENT_MOUSE_MOVE, // Отправка всем mql5-программам на графике сообщений о событиях перемещения и нажатия кнопок мышки (CHARTEVENT_MOUSE_MOVE) CHART_PROP_EVENT_OBJECT_CREATE, // Отправка всем mql5-программам на графике сообщений о событии создания графического объекта (CHARTEVENT_OBJECT_CREATE) CHART_PROP_EVENT_OBJECT_DELETE, // Отправка всем mql5-программам на графике сообщений о событии уничтожения графического объекта (CHARTEVENT_OBJECT_DELETE) CHART_PROP_MODE, // Тип графика (свечи, бары или линия (ENUM_CHART_MODE)) CHART_PROP_FOREGROUND, // Ценовой график на переднем плане CHART_PROP_SHIFT, // Режим отступа ценового графика от правого края CHART_PROP_AUTOSCROLL, // Режим автоматического перехода к правому краю графика CHART_PROP_KEYBOARD_CONTROL, // Разрешение на управление графиком с помощью клавиатуры CHART_PROP_QUICK_NAVIGATION, // Разрешение на перехват графиком нажатий клавиш Space и Enter для активации строки быстрой навигации CHART_PROP_SCALE, // Масштаб CHART_PROP_SCALEFIX, // Режим фиксированного масштаба CHART_PROP_SCALEFIX_11, // Режим масштаба 1:1 CHART_PROP_SCALE_PT_PER_BAR, // Режим указания масштаба в пунктах на бар CHART_PROP_SHOW_TICKER, // Отображение в левом верхнем углу тикера символа CHART_PROP_SHOW_OHLC, // Отображение в левом верхнем углу значений OHLC CHART_PROP_SHOW_BID_LINE, // Отображение значения Bid горизонтальной линией на графике CHART_PROP_SHOW_ASK_LINE, // Отображение значения Ask горизонтальной линией на графике CHART_PROP_SHOW_LAST_LINE, // Отображение значения Last горизонтальной линией на графике CHART_PROP_SHOW_PERIOD_SEP, // Отображение вертикальных разделителей между соседними периодами CHART_PROP_SHOW_GRID, // Отображение сетки на графике CHART_PROP_SHOW_VOLUMES, // Отображение объемов на графике CHART_PROP_SHOW_OBJECT_DESCR, // Отображение текстовых описаний объектов CHART_PROP_VISIBLE_BARS, // Количество баров на графике, доступных для отображения CHART_PROP_WINDOWS_TOTAL, // Общее количество окон графика, включая подокна индикаторов //CHART_PROP_WINDOW_IS_VISIBLE, // Видимость подокна CHART_PROP_WINDOW_HANDLE, // Хэндл окна графика //CHART_PROP_WINDOW_YDISTANCE, // Дистанция в пикселях по вертикальной оси Y между верхней рамкой подокна индикатора и верхней рамкой главного окна графика CHART_PROP_FIRST_VISIBLE_BAR, // Номер первого видимого бара на графике CHART_PROP_WIDTH_IN_BARS, // Ширина графика в барах CHART_PROP_WIDTH_IN_PIXELS, // Ширина графика в пикселях //CHART_PROP_HEIGHT_IN_PIXELS, // Высота графика в пикселях CHART_PROP_COLOR_BACKGROUND, // Цвет фона графика CHART_PROP_COLOR_FOREGROUND, // Цвет осей, шкалы и строки OHLC CHART_PROP_COLOR_GRID, // Цвет сетки CHART_PROP_COLOR_VOLUME, // Цвет объемов и уровней открытия позиций CHART_PROP_COLOR_CHART_UP, // Цвет бара вверх, тени и окантовки тела бычьей свечи CHART_PROP_COLOR_CHART_DOWN, // Цвет бара вниз, тени и окантовки тела медвежьей свечи CHART_PROP_COLOR_CHART_LINE, // Цвет линии графика и японских свечей "Доджи" CHART_PROP_COLOR_CANDLE_BULL, // Цвет тела бычьей свечи CHART_PROP_COLOR_CANDLE_BEAR, // Цвет тела медвежьей свечи CHART_PROP_COLOR_BID, // Цвет линии Bid-цены CHART_PROP_COLOR_ASK, // Цвет линии Ask-цены CHART_PROP_COLOR_LAST, // Цвет линии цены последней совершенной сделки (Last) CHART_PROP_COLOR_STOP_LEVEL, // Цвет уровней стоп-ордеров (Stop Loss и Take Profit) CHART_PROP_SHOW_TRADE_LEVELS, // Отображение на графике торговых уровней (уровни открытых позиций, Stop Loss, Take Profit и отложенных ордеров) CHART_PROP_DRAG_TRADE_LEVELS, // Разрешение на перетаскивание торговых уровней на графике с помощью мышки CHART_PROP_SHOW_DATE_SCALE, // Отображение на графике шкалы времени CHART_PROP_SHOW_PRICE_SCALE, // Отображение на графике ценовой шкалы CHART_PROP_SHOW_ONE_CLICK, // Отображение на графике панели быстрой торговли CHART_PROP_IS_MAXIMIZED, // Окно графика развернуто CHART_PROP_IS_MINIMIZED, // Окно графика свернуто CHART_PROP_IS_DOCKED, // Окно графика закреплено CHART_PROP_FLOAT_LEFT, // Левая координата открепленного графика относительно виртуального экрана CHART_PROP_FLOAT_TOP, // Верхняя координата открепленного графика относительно виртуального экрана CHART_PROP_FLOAT_RIGHT, // Правая координата открепленного графика относительно виртуального экрана CHART_PROP_FLOAT_BOTTOM, // Нижняя координата открепленного графика относительно виртуального экрана }; #define CHART_PROP_INTEGER_TOTAL (62) // Общее количество целочисленных свойств #define CHART_PROP_INTEGER_SKIP (0) // Количество неиспользуемых в сортировке целочисленных свойств стакана //+------------------------------------------------------------------+ //| Вещественные свойства чарта | //+------------------------------------------------------------------+ enum ENUM_CHART_PROP_DOUBLE { CHART_PROP_SHIFT_SIZE = CHART_PROP_INTEGER_TOTAL, // Размер отступа нулевого бара от правого края в процентах CHART_PROP_FIXED_POSITION, // Положение фиксированной позиции графика от левого края в процентах CHART_PROP_FIXED_MAX, // Фиксированный максимум графика CHART_PROP_FIXED_MIN, // Фиксированный минимум графика CHART_PROP_POINTS_PER_BAR, // Значение масштаба в пунктах на бар CHART_PROP_PRICE_MIN, // Минимум графика CHART_PROP_PRICE_MAX, // Максимум графика }; #define CHART_PROP_DOUBLE_TOTAL (7) // Общее количество вещественных свойств #define CHART_PROP_DOUBLE_SKIP (0) // Количество неиспользуемых в сортировке вещественных свойств //+------------------------------------------------------------------+ //| Строковые свойства чарта | //+------------------------------------------------------------------+ enum ENUM_CHART_PROP_STRING { CHART_PROP_COMMENT = (CHART_PROP_INTEGER_TOTAL+CHART_PROP_DOUBLE_TOTAL), // Текст комментария на графике CHART_PROP_EXPERT_NAME, // Имя эксперта, запущенного на графике CHART_PROP_SCRIPT_NAME, // Имя скрипта, запущенного на графике CHART_PROP_SYMBOL, // Символ графика }; #define CHART_PROP_STRING_TOTAL (4) // Общее количество строковых свойств //+------------------------------------------------------------------+
Три закомментированных свойства в перечислении целочисленных свойств объекта пока нам не нужны — они вписаны сюда по причине наличия этих свойств у графика, но они относятся не только к объекту чарта (главного окна графика), но также и к подокнам главного окна, и не могут быть однозначно свойствами только одного объекта-чарта. Их использование мы введём чуть позже.
И, как обычно, после добавления новых перечислений свойств объекта нам необходимо добавить перечисление возможных критериев сортировки этих объектов:
//+------------------------------------------------------------------+ //| Возможные критерии сортировки чартов | //+------------------------------------------------------------------+ #define FIRST_CHART_DBL_PROP (CHART_PROP_INTEGER_TOTAL-CHART_PROP_INTEGER_SKIP) #define FIRST_CHART_STR_PROP (CHART_PROP_INTEGER_TOTAL-CHART_PROP_INTEGER_SKIP+CHART_PROP_DOUBLE_TOTAL-CHART_PROP_DOUBLE_SKIP) enum ENUM_SORT_CHART_MODE { //--- Сортировка по целочисленным свойствам SORT_BY_CHART_SHOW = 0, // Сортировать по признаку отрисовки ценового графика SORT_BY_CHART_IS_OBJECT, // Сортировать по признаку идентификации объекта "График" (OBJ_CHART) SORT_BY_CHART_BRING_TO_TOP, // Сортировать по флагу показа графика поверх всех других SORT_BY_CHART_CONTEXT_MENU, // Сортировать по флагу включения/отключения доступа к контекстному меню по нажатию правой клавиши мышки SORT_BY_CHART_CROSSHAIR_TOO, // Сортировать по флагу включения/отключения доступа к инструменту "Перекрестие" по нажатию средней клавиши мышки SORT_BY_CHART_MOUSE_SCROLL, // Сортировать по флагу прокрутки графика левой кнопкой мышки по горизонтали SORT_BY_CHART_EVENT_MOUSE_WHEEL, // Сортировать по флагу отправки всем mql5-программам на графике сообщений о событиях колёсика мышки SORT_BY_CHART_EVENT_MOUSE_MOVE, // Сортировать по флагу отправки всем mql5-программам на графике сообщений о событиях перемещения и нажатия кнопок мышки SORT_BY_CHART_EVENT_OBJECT_CREATE, // Сортировать по флагу отправки всем mql5-программам на графике сообщений о событии создания графического объекта SORT_BY_CHART_EVENT_OBJECT_DELETE, // Сортировать по флагу отправки всем mql5-программам на графике сообщений о событии уничтожения графического объекта SORT_BY_CHART_MODE, // Сортировать по типу графика SORT_BY_CHART_FOREGROUND, // Сортировать по флагу "Ценовой график на переднем плане" SORT_BY_CHART_SHIFT, // Сортировать по флагу "Режим отступа ценового графика от правого края" SORT_BY_CHART_AUTOSCROLL, // Сортировать по флагу "Режим автоматического перехода к правому краю графика" SORT_BY_CHART_KEYBOARD_CONTROL, // Сортировать по флагу разрешения на управление графиком с помощью клавиатуры SORT_BY_CHART_QUICK_NAVIGATION, // Сортировать по флагу разрешения на перехват графиком нажатий клавиш Space и Enter для активации строки быстрой навигации SORT_BY_CHART_SCALE, // Сортировать по масштабу SORT_BY_CHART_SCALEFIX, // Сортировать по флагу фиксированного масштаба SORT_BY_CHART_SCALEFIX_11, // Сортировать по флагу масштаба 1:1 SORT_BY_CHART_SCALE_PT_PER_BAR, // Сортировать по флагу указания масштаба в пунктах на бар SORT_BY_CHART_SHOW_TICKER, // Сортировать по флагу отображения в левом верхнем углу тикера символа SORT_BY_CHART_SHOW_OHLC, // Сортировать по флагу отображения в левом верхнем углу значений OHLC SORT_BY_CHART_SHOW_BID_LINE, // Сортировать по флагу отображения значения Bid горизонтальной линией на графике SORT_BY_CHART_SHOW_ASK_LINE, // Сортировать по флагу отображения значения Ask горизонтальной линией на графике SORT_BY_CHART_SHOW_LAST_LINE, // Сортировать по флагу отображения значения Last горизонтальной линией на графике SORT_BY_CHART_SHOW_PERIOD_SEP, // Сортировать по флагу отображения вертикальных разделителей между соседними периодами SORT_BY_CHART_SHOW_GRID, // Сортировать по флагу отображения сетки на графике SORT_BY_CHART_SHOW_VOLUMES, // Сортировать по режиму отображения объемов на графике SORT_BY_CHART_SHOW_OBJECT_DESCR, // Сортировать по флагу отображения текстовых описаний объектов SORT_BY_CHART_VISIBLE_BARS, // Сортировать по количеству баров на графике, доступных для отображения SORT_BY_CHART_WINDOWS_TOTAL, // Сортировать по общему количеству окон графика, включая подокна индикаторов SORT_BY_CHART_WINDOW_IS_VISIBLE, // Сортировать по флагу видимости подокон SORT_BY_CHART_WINDOW_HANDLE, // Сортировать по хэндлу графика SORT_BY_CHART_WINDOW_YDISTANCE, // Сортировать по дистанции в пикселях по вертикальной оси Y между верхней рамкой подокна индикатора и верхней рамкой главного окна графика SORT_BY_CHART_FIRST_VISIBLE_BAR, // Сортировать по номеру первого видимого бара на графике SORT_BY_CHART_WIDTH_IN_BARS, // Сортировать по ширине графика в барах SORT_BY_CHART_WIDTH_IN_PIXELS, // Сортировать по ширине графика в пикселях SORT_BY_CHART_HEIGHT_IN_PIXELS, // Сортировать по высоте графика в пикселях SORT_BY_CHART_COLOR_BACKGROUND, // Сортировать по цвету фона графика SORT_BY_CHART_COLOR_FOREGROUND, // Сортировать по цвету осей, шкалы и строки OHLC SORT_BY_CHART_COLOR_GRID, // Сортировать по цвету сетки SORT_BY_CHART_COLOR_VOLUME, // Сортировать по цвету объемов и уровней открытия позиций SORT_BY_CHART_COLOR_CHART_UP, // Сортировать по цвету бара вверх, тени и окантовки тела бычьей свечи SORT_BY_CHART_COLOR_CHART_DOWN, // Сортировать по цвету бара вниз, тени и окантовки тела медвежьей свечи SORT_BY_CHART_COLOR_CHART_LINE, // Сортировать по цвету линии графика и японских свечей "Доджи" SORT_BY_CHART_COLOR_CANDLE_BULL, // Сортировать по цвету тела бычьей свечи SORT_BY_CHART_COLOR_CANDLE_BEAR, // Сортировать по цвету тела медвежьей свечи SORT_BY_CHART_COLOR_BID, // Сортировать по цвету линии Bid-цены SORT_BY_CHART_COLOR_ASK, // Сортировать по цвету линии Ask-цены SORT_BY_CHART_COLOR_LAST, // Сортировать по цвету линии цены последней совершенной сделки (Last) SORT_BY_CHART_COLOR_STOP_LEVEL, // Сортировать по цвету уровней стоп-ордеров (Stop Loss и Take Profit) SORT_BY_CHART_SHOW_TRADE_LEVELS, // Сортировать по флагу отображения на графике торговых уровней SORT_BY_CHART_DRAG_TRADE_LEVELS, // Сортировать по флагу разрешения на перетаскивание торговых уровней на графике с помощью мышки SORT_BY_CHART_SHOW_DATE_SCALE, // Сортировать по флагу отображения на графике шкалы времени SORT_BY_CHART_SHOW_PRICE_SCALE, // Сортировать по флагу отображения на графике ценовой шкалы SORT_BY_CHART_SHOW_ONE_CLICK, // Сортировать по флагу отображения на графике панели быстрой торговли SORT_BY_CHART_IS_MAXIMIZED, // Сортировать по флагу "Окно графика развернуто" SORT_BY_CHART_IS_MINIMIZED, // Сортировать по флагу "Окно графика свернуто" SORT_BY_CHART_IS_DOCKED, // Сортировать по флагу "Окно графика закреплено" SORT_BY_CHART_FLOAT_LEFT, // Сортировать по левой координате открепленного графика относительно виртуального экрана SORT_BY_CHART_FLOAT_TOP, // Сортировать по верхней координате открепленного графика относительно виртуального экрана SORT_BY_CHART_FLOAT_RIGHT, // Сортировать по правой координате открепленного графика относительно виртуального экрана SORT_BY_CHART_FLOAT_BOTTOM, // Сортировать по нижней координате открепленного графика относительно виртуального экрана //--- Сортировка по вещественным свойствам SORT_BY_CHART_SHIFT_SIZE = FIRST_CHART_DBL_PROP, // Сортировать по размеру отступа нулевого бара от правого края в процентах SORT_BY_CHART_FIXED_POSITION, // Сортировать по положению фиксированной позиции графика от левого края в процентах SORT_BY_CHART_FIXED_MAX, // Сортировать по фиксированному максимуму графика SORT_BY_CHART_FIXED_MIN, // Сортировать по фиксированному минимуму графика SORT_BY_CHART_POINTS_PER_BAR, // Сортировать по значению масштаба в пунктах на бар SORT_BY_CHART_PRICE_MIN, // Сортировать по минимуму графика SORT_BY_CHART_PRICE_MAX, // Сортировать по максимуму графика //--- Сортировка по строковым свойствам SORT_BY_CHART_COMMENT = FIRST_CHART_STR_PROP, // Сортировать по тексту комментария на графике SORT_BY_CHART_EXPERT_NAME, // Сортировать по имени эксперта, запущенного на графике SORT_BY_CHART_SCRIPT_NAME, // Сортировать по имени скрипта, запущенного на графике }; //+------------------------------------------------------------------+
Подробнее ознакомиться с устройством объектов библиотеки можно в первой и нескольких последующих статьях.
Теперь у нас всё готово для создания непосредствнно класса объекта-чарта.
Класс объекта-чарта
В каталоге библиотеки в новой папке \MQL5\Include\DoEasy\Objects\Chart\ создадим новый файл ChartObj.mqh класса CChartObj.
Базовым объектом должен быть базовый объект всех объектов библиотеки, и его файл должен быть подключен к файлу класса:
//+------------------------------------------------------------------+ //| ChartObj.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" #property strict // Нужно для mql4 //+------------------------------------------------------------------+ //| Включаемые файлы | //+------------------------------------------------------------------+ #include "..\..\Objects\BaseObj.mqh" //+------------------------------------------------------------------+ //| Класс объекта-чарта | //+------------------------------------------------------------------+ class CChartObj : public CBaseObj { }
В приватной секции класса впишем стандартные для объектов библиотеки массивы для хранения его свойств, методы, возвращающие фактический индекс свойства в массиве, и переменную-член класса для хранения значения Digits() символа.
//+------------------------------------------------------------------+ //| Класс объекта-чарта | //+------------------------------------------------------------------+ class CChartObj : public CBaseObj { private: long m_long_prop[CHART_PROP_INTEGER_TOTAL]; // Целочисленные свойства double m_double_prop[CHART_PROP_DOUBLE_TOTAL]; // Вещественные свойства string m_string_prop[CHART_PROP_STRING_TOTAL]; // Строковые свойства int m_digits; // Digits() символа //--- Возвращает индекс массива, по которому фактически расположено (1) double-свойство и (2) string-свойство int IndexProp(ENUM_CHART_PROP_DOUBLE property) const { return(int)property-CHART_PROP_INTEGER_TOTAL; } int IndexProp(ENUM_CHART_PROP_STRING property) const { return(int)property-CHART_PROP_INTEGER_TOTAL-CHART_PROP_DOUBLE_TOTAL; }
В публичной секции класса тоже пропишем все стандартные для объектов библиотеки методы: методы установки и возврата свойств объекта, виртуальные методы, возвращающие флаги поддержания объектом того, или иного свойства (хоть мы и не будем делать объекты-наследники, но методы должны быть виртуальными для возможного их изменения в классах-наследниках в случае, если они потребуются), методы, возвращающие описания свойств, методы вывода в журнал и описания свойств и наименований объекта, методы сравнения и конструкторы.
public: //--- Устанавливает (1) целочисленное, (2) вещественное и (3) строковое свойство объекта void SetProperty(ENUM_CHART_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_CHART_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_CHART_PROP_STRING property,string value) { this.m_string_prop[this.IndexProp(property)]=value; } //--- Возвращает из массива свойств (1) целочисленное, (2) вещественное и (3) строковое свойство объекта long GetProperty(ENUM_CHART_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_CHART_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_CHART_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Возвращает себя CChartObj *GetObject(void) { return &this;} //--- Возвращает флаг поддержания объектом данного свойства virtual bool SupportProperty(ENUM_CHART_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_CHART_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_CHART_PROP_STRING property) { return true; } //--- Возвращает описание (1) целочисленного, (2) вещественного и (3) строкового свойства string GetPropertyDescription(ENUM_CHART_PROP_INTEGER property); string GetPropertyDescription(ENUM_CHART_PROP_DOUBLE property); string GetPropertyDescription(ENUM_CHART_PROP_STRING property); //--- Выводит в журнал описание свойств объекта (full_prop=true - все свойства, false - только поддерживаемые) void Print(const bool full_prop=false); //--- Выводит в журнал краткое описание объекта virtual void PrintShort(const bool dash=false); //--- Возвращает краткое наименование объекта virtual string Header(void); //--- Сравнивает объекты CChartObj между собой по указанному свойству (для сортировки списка по свойству объекта-чарта) virtual int Compare(const CObject *node,const int mode=0) const; //--- Сравнивает объекты CChartObj между собой по всем свойствам (для поиска равных объектов-чартов) bool IsEqual(CChartObj* compared_obj) const; //--- Конструкторы CChartObj(){;} CChartObj(const long chart_id);
Это стандартный набор методов объектов библиотеки, назначение которых неоднократно обсуждалось и описывалось. Не будем на них останавливаться.
Так как при создании объекта-чарта подразумевается, что соответствующий ему график выбран, и можно получать его свойства посредством функций ChartGetInteger(), ChartGetDouble() и ChartGetString(), то в конструкторе класса просто заполняются все свойства объекта-чарта значениями, возвращаемыми соответствующими свойствам функциями и, напоследок, вписывается значение Digits() символа в переменную, предназначенную для его хранения:
//+------------------------------------------------------------------+ //| Параметрический конструктор | //+------------------------------------------------------------------+ CChartObj::CChartObj(const long chart_id) { //--- Установка целочисленных свойств this.SetProperty(CHART_PROP_ID,chart_id); // Идентификатор графика this.SetProperty(CHART_PROP_TIMEFRAME,::ChartPeriod(this.ID())); // Таймфрейм графика this.SetProperty(CHART_PROP_SHOW,::ChartGetInteger(this.ID(),CHART_SHOW)); // Признак отрисовки ценового графика this.SetProperty(CHART_PROP_IS_OBJECT,::ChartGetInteger(this.ID(),CHART_IS_OBJECT)); // Признак идентификации объекта "График" this.SetProperty(CHART_PROP_BRING_TO_TOP,false); // Показ графика поверх всех других this.SetProperty(CHART_PROP_CONTEXT_MENU,::ChartGetInteger(this.ID(),CHART_CONTEXT_MENU)); // Доступ к контекстному меню по нажатию правой клавиши мышки this.SetProperty(CHART_PROP_CROSSHAIR_TOOL,::ChartGetInteger(this.ID(),CHART_CROSSHAIR_TOOL)); // Доступ к инструменту "Перекрестие" по нажатию средней клавиши мышки this.SetProperty(CHART_PROP_MOUSE_SCROLL,::ChartGetInteger(this.ID(),CHART_MOUSE_SCROLL)); // Прокрутка графика левой кнопкой мышки по горизонтали this.SetProperty(CHART_PROP_EVENT_MOUSE_WHEEL,::ChartGetInteger(this.ID(),CHART_EVENT_MOUSE_WHEEL)); // Отправка всем mql5-программам на графике сообщений о событиях колёсика мышки this.SetProperty(CHART_PROP_EVENT_MOUSE_MOVE,::ChartGetInteger(this.ID(),CHART_EVENT_MOUSE_MOVE)); // Отправка всем mql5-программам на графике сообщений о событиях перемещения и нажатия кнопок мышки this.SetProperty(CHART_PROP_EVENT_OBJECT_CREATE,::ChartGetInteger(this.ID(),CHART_EVENT_OBJECT_CREATE)); // Отправка всем mql5-программам на графике сообщений о событии создания графического объекта this.SetProperty(CHART_PROP_EVENT_OBJECT_DELETE,::ChartGetInteger(this.ID(),CHART_EVENT_OBJECT_DELETE)); // Отправка всем mql5-программам на графике сообщений о событии уничтожения графического объекта this.SetProperty(CHART_PROP_MODE,::ChartGetInteger(this.ID(),CHART_MODE)); // Тип графика (свечи, бары или линия this.SetProperty(CHART_PROP_FOREGROUND,::ChartGetInteger(this.ID(),CHART_FOREGROUND)); // Ценовой график на переднем плане this.SetProperty(CHART_PROP_SHIFT,::ChartGetInteger(this.ID(),CHART_SHIFT)); // Режим отступа ценового графика от правого края this.SetProperty(CHART_PROP_AUTOSCROLL,::ChartGetInteger(this.ID(),CHART_AUTOSCROLL)); // Режим автоматического перехода к правому краю графика this.SetProperty(CHART_PROP_KEYBOARD_CONTROL,::ChartGetInteger(this.ID(),CHART_KEYBOARD_CONTROL)); // Разрешение на управление графиком с помощью клавиатуры this.SetProperty(CHART_PROP_QUICK_NAVIGATION,::ChartGetInteger(this.ID(),CHART_QUICK_NAVIGATION)); // Разрешение на перехват графиком нажатий клавиш Space и Enter для активации строки быстрой навигации this.SetProperty(CHART_PROP_SCALE,::ChartGetInteger(this.ID(),CHART_SCALE)); // Масштаб this.SetProperty(CHART_PROP_SCALEFIX,::ChartGetInteger(this.ID(),CHART_SCALEFIX)); // Режим фиксированного масштаба this.SetProperty(CHART_PROP_SCALEFIX_11,::ChartGetInteger(this.ID(),CHART_SCALEFIX_11)); // Режим масштаба 1:1 this.SetProperty(CHART_PROP_SCALE_PT_PER_BAR,::ChartGetInteger(this.ID(),CHART_SCALE_PT_PER_BAR)); // Режим указания масштаба в пунктах на бар this.SetProperty(CHART_PROP_SHOW_TICKER,::ChartGetInteger(this.ID(),CHART_SHOW_TICKER)); // Отображение в левом верхнем углу тикера символа this.SetProperty(CHART_PROP_SHOW_OHLC,::ChartGetInteger(this.ID(),CHART_SHOW_OHLC)); // Отображение в левом верхнем углу значений OHLC this.SetProperty(CHART_PROP_SHOW_BID_LINE,::ChartGetInteger(this.ID(),CHART_SHOW_BID_LINE)); // Отображение значения Bid горизонтальной линией на графике this.SetProperty(CHART_PROP_SHOW_ASK_LINE,::ChartGetInteger(this.ID(),CHART_SHOW_ASK_LINE)); // Отображение значения Ask горизонтальной линией на графике this.SetProperty(CHART_PROP_SHOW_LAST_LINE,::ChartGetInteger(this.ID(),CHART_SHOW_LAST_LINE)); // Отображение значения Last горизонтальной линией на графике this.SetProperty(CHART_PROP_SHOW_PERIOD_SEP,::ChartGetInteger(this.ID(),CHART_SHOW_PERIOD_SEP)); // Отображение вертикальных разделителей между соседними периодами this.SetProperty(CHART_PROP_SHOW_GRID,::ChartGetInteger(this.ID(),CHART_SHOW_GRID)); // Отображение сетки на графике this.SetProperty(CHART_PROP_SHOW_VOLUMES,::ChartGetInteger(this.ID(),CHART_SHOW_VOLUMES)); // Отображение объемов на графике this.SetProperty(CHART_PROP_SHOW_OBJECT_DESCR,::ChartGetInteger(this.ID(),CHART_SHOW_OBJECT_DESCR)); // Отображение текстовых описаний объектов this.SetProperty(CHART_PROP_VISIBLE_BARS,::ChartGetInteger(this.ID(),CHART_VISIBLE_BARS)); // Количество баров на графике, доступных для отображения this.SetProperty(CHART_PROP_WINDOWS_TOTAL,::ChartGetInteger(this.ID(),CHART_WINDOWS_TOTAL)); // Общее количество окон графика, включая подокна индикаторов this.SetProperty(CHART_PROP_WINDOW_HANDLE,::ChartGetInteger(this.ID(),CHART_WINDOW_HANDLE)); // Хэндл окна графика this.SetProperty(CHART_PROP_FIRST_VISIBLE_BAR,::ChartGetInteger(this.ID(),CHART_FIRST_VISIBLE_BAR)); // Номер первого видимого бара на графике this.SetProperty(CHART_PROP_WIDTH_IN_BARS,::ChartGetInteger(this.ID(),CHART_WIDTH_IN_BARS)); // Ширина графика в барах this.SetProperty(CHART_PROP_WIDTH_IN_PIXELS,::ChartGetInteger(this.ID(),CHART_WIDTH_IN_PIXELS)); // Ширина графика в пикселях this.SetProperty(CHART_PROP_COLOR_BACKGROUND,::ChartGetInteger(this.ID(),CHART_COLOR_BACKGROUND)); // Цвет фона графика this.SetProperty(CHART_PROP_COLOR_FOREGROUND,::ChartGetInteger(this.ID(),CHART_COLOR_FOREGROUND)); // Цвет осей, шкалы и строки OHLC this.SetProperty(CHART_PROP_COLOR_GRID,::ChartGetInteger(this.ID(),CHART_COLOR_GRID)); // Цвет сетки this.SetProperty(CHART_PROP_COLOR_VOLUME,::ChartGetInteger(this.ID(),CHART_COLOR_VOLUME)); // Цвет объемов и уровней открытия позиций this.SetProperty(CHART_PROP_COLOR_CHART_UP,::ChartGetInteger(this.ID(),CHART_COLOR_CHART_UP)); // Цвет бара вверх, тени и окантовки тела бычьей свечи this.SetProperty(CHART_PROP_COLOR_CHART_DOWN,::ChartGetInteger(this.ID(),CHART_COLOR_CHART_DOWN)); // Цвет бара вниз, тени и окантовки тела медвежьей свечи this.SetProperty(CHART_PROP_COLOR_CHART_LINE,::ChartGetInteger(this.ID(),CHART_COLOR_CHART_LINE)); // Цвет линии графика и японских свечей "Доджи" this.SetProperty(CHART_PROP_COLOR_CANDLE_BULL,::ChartGetInteger(this.ID(),CHART_COLOR_CANDLE_BULL)); // Цвет тела бычьей свечи this.SetProperty(CHART_PROP_COLOR_CANDLE_BEAR,::ChartGetInteger(this.ID(),CHART_COLOR_CANDLE_BEAR)); // Цвет тела медвежьей свечи this.SetProperty(CHART_PROP_COLOR_BID,::ChartGetInteger(this.ID(),CHART_COLOR_BID)); // Цвет линии Bid-цены this.SetProperty(CHART_PROP_COLOR_ASK,::ChartGetInteger(this.ID(),CHART_COLOR_ASK)); // Цвет линии Ask-цены this.SetProperty(CHART_PROP_COLOR_LAST,::ChartGetInteger(this.ID(),CHART_COLOR_LAST)); // Цвет линии цены последней совершенной сделки (Last) this.SetProperty(CHART_PROP_COLOR_STOP_LEVEL,::ChartGetInteger(this.ID(),CHART_COLOR_STOP_LEVEL)); // Цвет уровней стоп-ордеров (Stop Loss и Take Profit) this.SetProperty(CHART_PROP_SHOW_TRADE_LEVELS,::ChartGetInteger(this.ID(),CHART_SHOW_TRADE_LEVELS)); // Отображение на графике торговых уровней (уровни открытых позиций, Stop Loss, Take Profit и отложенных ордеров) this.SetProperty(CHART_PROP_DRAG_TRADE_LEVELS,::ChartGetInteger(this.ID(),CHART_DRAG_TRADE_LEVELS)); // Разрешение на перетаскивание торговых уровней на графике с помощью мышки this.SetProperty(CHART_PROP_SHOW_DATE_SCALE,::ChartGetInteger(this.ID(),CHART_SHOW_DATE_SCALE)); // Отображение на графике шкалы времени this.SetProperty(CHART_PROP_SHOW_PRICE_SCALE,::ChartGetInteger(this.ID(),CHART_SHOW_PRICE_SCALE)); // Отображение на графике ценовой шкалы this.SetProperty(CHART_PROP_SHOW_ONE_CLICK,::ChartGetInteger(this.ID(),CHART_SHOW_ONE_CLICK)); // Отображение на графике панели быстрой торговли this.SetProperty(CHART_PROP_IS_MAXIMIZED,::ChartGetInteger(this.ID(),CHART_IS_MAXIMIZED)); // Окно графика развернуто this.SetProperty(CHART_PROP_IS_MINIMIZED,::ChartGetInteger(this.ID(),CHART_IS_MINIMIZED)); // Окно графика свернуто this.SetProperty(CHART_PROP_IS_DOCKED,::ChartGetInteger(this.ID(),CHART_IS_DOCKED)); // Окно графика закреплено this.SetProperty(CHART_PROP_FLOAT_LEFT,::ChartGetInteger(this.ID(),CHART_FLOAT_LEFT)); // Левая координата открепленного графика относительно виртуального экрана this.SetProperty(CHART_PROP_FLOAT_TOP,::ChartGetInteger(this.ID(),CHART_FLOAT_TOP)); // Верхняя координата открепленного графика относительно виртуального экрана this.SetProperty(CHART_PROP_FLOAT_RIGHT,::ChartGetInteger(this.ID(),CHART_FLOAT_RIGHT)); // Правая координата открепленного графика относительно виртуального экрана this.SetProperty(CHART_PROP_FLOAT_BOTTOM,::ChartGetInteger(this.ID(),CHART_FLOAT_BOTTOM)); // Нижняя координата открепленного графика относительно виртуального экрана //--- Установка вещественных свойств this.SetProperty(CHART_PROP_SHIFT_SIZE,::ChartGetDouble(this.ID(),CHART_SHIFT_SIZE)); // Размер отступа нулевого бара от правого края в процентах this.SetProperty(CHART_PROP_FIXED_POSITION,::ChartGetDouble(this.ID(),CHART_FIXED_POSITION)); // Положение фиксированной позиции графика от левого края в процентах this.SetProperty(CHART_PROP_FIXED_MAX,::ChartGetDouble(this.ID(),CHART_FIXED_MAX)); // Фиксированный максимум графика this.SetProperty(CHART_PROP_FIXED_MIN,::ChartGetDouble(this.ID(),CHART_FIXED_MIN)); // Фиксированный минимум графика this.SetProperty(CHART_PROP_POINTS_PER_BAR,::ChartGetDouble(this.ID(),CHART_POINTS_PER_BAR)); // Значение масштаба в пунктах на бар this.SetProperty(CHART_PROP_PRICE_MIN,::ChartGetDouble(this.ID(),CHART_PRICE_MIN)); // Минимум графика this.SetProperty(CHART_PROP_PRICE_MAX,::ChartGetDouble(this.ID(),CHART_PRICE_MAX)); // Максимум графика //--- Установка строковых свойств this.SetProperty(CHART_PROP_COMMENT,::ChartGetString(this.ID(),CHART_COMMENT)); // Текст комментария на графике this.SetProperty(CHART_PROP_EXPERT_NAME,::ChartGetString(this.ID(),CHART_EXPERT_NAME)); // Имя эксперта, запущенного на графике this.SetProperty(CHART_PROP_SCRIPT_NAME,::ChartGetString(this.ID(),CHART_SCRIPT_NAME)); // Имя скрипта, запущенного на графике this.SetProperty(CHART_PROP_SYMBOL,::ChartSymbol(this.ID())); // Символ графика this.m_digits=(int)::SymbolInfoInteger(this.Symbol(),SYMBOL_DIGITS); } //+------------------------------------------------------------------+
Digits() символа потребуется для корректного вывода некоторых значений свойств графика.
Метод, сравнивающий объекты CChartObj между собой по указанному свойству:
//+------------------------------------------------------------------+ //| Сравнивает объекты CChartObj между собой по указанному свойству | //+------------------------------------------------------------------+ int CChartObj::Compare(const CObject *node,const int mode=0) const { const CChartObj *obj_compared=node; //--- сравнение целочисленных свойств двух объектов if(mode<CHART_PROP_INTEGER_TOTAL) { long value_compared=obj_compared.GetProperty((ENUM_CHART_PROP_INTEGER)mode); long value_current=this.GetProperty((ENUM_CHART_PROP_INTEGER)mode); return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0); } //--- сравнение вещественных свойств двух объектов else if(mode<CHART_PROP_DOUBLE_TOTAL+CHART_PROP_INTEGER_TOTAL) { double value_compared=obj_compared.GetProperty((ENUM_CHART_PROP_DOUBLE)mode); double value_current=this.GetProperty((ENUM_CHART_PROP_DOUBLE)mode); return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0); } //--- сравнение строковых свойств двух объектов else if(mode<CHART_PROP_DOUBLE_TOTAL+CHART_PROP_INTEGER_TOTAL+CHART_PROP_STRING_TOTAL) { string value_compared=obj_compared.GetProperty((ENUM_CHART_PROP_STRING)mode); string value_current=this.GetProperty((ENUM_CHART_PROP_STRING)mode); return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0); } return 0; } //+------------------------------------------------------------------+
Проверяется переданное свойство на предмет его принадлежности к целочисленным, вещественным или строковым свойствам, и в соответствующем блоке кода сравнивается свойство текущего объекта со свойством переданного в метод для сравнения. Возвращается результат сравнения на больше (1), меньше (-1) или равно (0).
Метод, сравнивающий объекты CChartObj между собой по всем свойствам:
//+------------------------------------------------------------------+ //| Сравнивает объекты CChartObj между собой по всем свойствам | //+------------------------------------------------------------------+ bool CChartObj::IsEqual(CChartObj *compared_obj) const { int beg=0, end=CHART_PROP_INTEGER_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_INTEGER prop=(ENUM_CHART_PROP_INTEGER)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } beg=end; end+=CHART_PROP_DOUBLE_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_DOUBLE prop=(ENUM_CHART_PROP_DOUBLE)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } beg=end; end+=CHART_PROP_STRING_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_STRING prop=(ENUM_CHART_PROP_STRING)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } return true; } //+------------------------------------------------------------------+
В трёх циклах по всем свойствам объекта сравниваются все последующие очередные свойства двух объектов — текущего и переданного в метод. Если хоть одно из свойств у двух сравниваемых объектов не равны друг другу, то сразу же возвращается false — объекты не идентичны. По завершении всех циклов по всем свойствам возвращается true — нет разных свойств, а значит — объекты идентичны друг другу.
Методы, возвращающие описания целочисленных, вещественных и строковых свойств объекта:
//+------------------------------------------------------------------+ //| Возвращает описание целочисленного свойства объекта | //+------------------------------------------------------------------+ string CChartObj::GetPropertyDescription(ENUM_CHART_PROP_INTEGER property) { return ( property==CHART_PROP_ID ? CMessage::Text(MSG_CHART_OBJ_ID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_TIMEFRAME ? CMessage::Text(MSG_LIB_TEXT_BAR_PERIOD)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+TimeframeDescription((ENUM_TIMEFRAMES)this.GetProperty(property)) ) : property==CHART_PROP_SHOW ? CMessage::Text(MSG_CHART_OBJ_SHOW)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_OBJECT ? CMessage::Text(MSG_CHART_OBJ_IS_OBJECT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_BRING_TO_TOP ? CMessage::Text(MSG_CHART_OBJ_BRING_TO_TOP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_CONTEXT_MENU ? CMessage::Text(MSG_CHART_OBJ_CONTEXT_MENU)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_CROSSHAIR_TOOL ? CMessage::Text(MSG_CHART_OBJ_CROSSHAIR_TOOL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_MOUSE_SCROLL ? CMessage::Text(MSG_CHART_OBJ_MOUSE_SCROLL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_MOUSE_WHEEL ? CMessage::Text(MSG_CHART_OBJ_EVENT_MOUSE_WHEEL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_MOUSE_MOVE ? CMessage::Text(MSG_CHART_OBJ_EVENT_MOUSE_MOVE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_OBJECT_CREATE ? CMessage::Text(MSG_CHART_OBJ_EVENT_OBJECT_CREATE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_OBJECT_DELETE ? CMessage::Text(MSG_CHART_OBJ_EVENT_OBJECT_DELETE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_MODE ? CMessage::Text(MSG_CHART_OBJ_MODE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ChartModeDescription((ENUM_CHART_MODE)this.GetProperty(property)) ) : property==CHART_PROP_FOREGROUND ? CMessage::Text(MSG_CHART_OBJ_FOREGROUND)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHIFT ? CMessage::Text(MSG_CHART_OBJ_SHIFT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_AUTOSCROLL ? CMessage::Text(MSG_CHART_OBJ_AUTOSCROLL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_KEYBOARD_CONTROL ? CMessage::Text(MSG_CHART_OBJ_KEYBOARD_CONTROL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_QUICK_NAVIGATION ? CMessage::Text(MSG_CHART_OBJ_QUICK_NAVIGATION)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SCALE ? CMessage::Text(MSG_CHART_OBJ_SCALE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_SCALEFIX ? CMessage::Text(MSG_CHART_OBJ_SCALEFIX)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SCALEFIX_11 ? CMessage::Text(MSG_CHART_OBJ_SCALEFIX_11)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SCALE_PT_PER_BAR ? CMessage::Text(MSG_CHART_OBJ_SCALE_PT_PER_BAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_TICKER ? CMessage::Text(MSG_CHART_OBJ_SHOW_TICKER)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_OHLC ? CMessage::Text(MSG_CHART_OBJ_SHOW_OHLC)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_BID_LINE ? CMessage::Text(MSG_CHART_OBJ_SHOW_BID_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_ASK_LINE ? CMessage::Text(MSG_CHART_OBJ_SHOW_ASK_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_LAST_LINE ? CMessage::Text(MSG_CHART_OBJ_SHOW_LAST_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_PERIOD_SEP ? CMessage::Text(MSG_CHART_OBJ_SHOW_PERIOD_SEP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_GRID ? CMessage::Text(MSG_CHART_OBJ_SHOW_GRID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_VOLUMES ? CMessage::Text(MSG_CHART_OBJ_SHOW_VOLUMES)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ChartModeVolumeDescription((ENUM_CHART_VOLUME_MODE)this.GetProperty(property)) ) : property==CHART_PROP_SHOW_OBJECT_DESCR ? CMessage::Text(MSG_CHART_OBJ_SHOW_OBJECT_DESCR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_VISIBLE_BARS ? CMessage::Text(MSG_CHART_OBJ_VISIBLE_BARS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WINDOWS_TOTAL ? CMessage::Text(MSG_CHART_OBJ_WINDOWS_TOTAL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WINDOW_HANDLE ? CMessage::Text(MSG_CHART_OBJ_WINDOW_HANDLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FIRST_VISIBLE_BAR ? CMessage::Text(MSG_CHART_OBJ_FIRST_VISIBLE_BAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WIDTH_IN_BARS ? CMessage::Text(MSG_CHART_OBJ_WIDTH_IN_BARS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WIDTH_IN_PIXELS ? CMessage::Text(MSG_CHART_OBJ_WIDTH_IN_PIXELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_COLOR_BACKGROUND ? CMessage::Text(MSG_CHART_OBJ_COLOR_BACKGROUND)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_FOREGROUND ? CMessage::Text(MSG_CHART_OBJ_COLOR_FOREGROUND)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_GRID ? CMessage::Text(MSG_CHART_OBJ_COLOR_GRID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_VOLUME ? CMessage::Text(MSG_CHART_OBJ_COLOR_VOLUME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CHART_UP ? CMessage::Text(MSG_CHART_OBJ_COLOR_CHART_UP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CHART_DOWN ? CMessage::Text(MSG_CHART_OBJ_COLOR_CHART_DOWN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CHART_LINE ? CMessage::Text(MSG_CHART_OBJ_COLOR_CHART_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CANDLE_BULL ? CMessage::Text(MSG_CHART_OBJ_COLOR_CANDLE_BULL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CANDLE_BEAR ? CMessage::Text(MSG_CHART_OBJ_COLOR_CANDLE_BEAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_BID ? CMessage::Text(MSG_CHART_OBJ_COLOR_BID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_ASK ? CMessage::Text(MSG_CHART_OBJ_COLOR_ASK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_LAST ? CMessage::Text(MSG_CHART_OBJ_COLOR_LAST)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_STOP_LEVEL ? CMessage::Text(MSG_CHART_OBJ_COLOR_STOP_LEVEL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_SHOW_TRADE_LEVELS ? CMessage::Text(MSG_CHART_OBJ_SHOW_TRADE_LEVELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_DRAG_TRADE_LEVELS ? CMessage::Text(MSG_CHART_OBJ_DRAG_TRADE_LEVELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_DATE_SCALE ? CMessage::Text(MSG_CHART_OBJ_SHOW_DATE_SCALE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_PRICE_SCALE ? CMessage::Text(MSG_CHART_OBJ_SHOW_PRICE_SCALE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_ONE_CLICK ? CMessage::Text(MSG_CHART_OBJ_SHOW_ONE_CLICK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_MAXIMIZED ? CMessage::Text(MSG_CHART_OBJ_IS_MAXIMIZED)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_MINIMIZED ? CMessage::Text(MSG_CHART_OBJ_IS_MINIMIZED)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_DOCKED ? CMessage::Text(MSG_CHART_OBJ_IS_DOCKED)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_FLOAT_LEFT ? CMessage::Text(MSG_CHART_OBJ_FLOAT_LEFT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FLOAT_TOP ? CMessage::Text(MSG_CHART_OBJ_FLOAT_TOP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FLOAT_RIGHT ? CMessage::Text(MSG_CHART_OBJ_FLOAT_RIGHT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FLOAT_BOTTOM ? CMessage::Text(MSG_CHART_OBJ_FLOAT_BOTTOM)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : "" ); } //+------------------------------------------------------------------+ //| Возвращает описание вещественного свойства объекта | //+------------------------------------------------------------------+ string CChartObj::GetPropertyDescription(ENUM_CHART_PROP_DOUBLE property) { return ( property==CHART_PROP_SHIFT_SIZE ? CMessage::Text(MSG_CHART_OBJ_SHIFT_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==CHART_PROP_FIXED_POSITION ? CMessage::Text(MSG_CHART_OBJ_FIXED_POSITION)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==CHART_PROP_FIXED_MAX ? CMessage::Text(MSG_CHART_OBJ_FIXED_MAX)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),this.m_digits) ) : property==CHART_PROP_FIXED_MIN ? CMessage::Text(MSG_CHART_OBJ_FIXED_MIN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),this.m_digits) ) : property==CHART_PROP_POINTS_PER_BAR ? CMessage::Text(MSG_CHART_OBJ_POINTS_PER_BAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==CHART_PROP_PRICE_MIN ? CMessage::Text(MSG_CHART_OBJ_PRICE_MIN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),this.m_digits) ) : property==CHART_PROP_PRICE_MAX ? CMessage::Text(MSG_CHART_OBJ_PRICE_MAX)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),this.m_digits) ) : "" ); } //+------------------------------------------------------------------+ //| Возвращает описание строкового свойства объекта | //+------------------------------------------------------------------+ string CChartObj::GetPropertyDescription(ENUM_CHART_PROP_STRING property) { return ( property==CHART_PROP_COMMENT ? CMessage::Text(MSG_CHART_OBJ_COMMENT)+": \""+this.GetProperty(property)+"\"" : property==CHART_PROP_EXPERT_NAME ? CMessage::Text(MSG_CHART_OBJ_EXPERT_NAME)+": \""+this.GetProperty(property)+"\"" : property==CHART_PROP_SCRIPT_NAME ? CMessage::Text(MSG_CHART_OBJ_SCRIPT_NAME)+": \""+this.GetProperty(property)+"\"" : property==CHART_PROP_SYMBOL ? CMessage::Text(MSG_LIB_PROP_SYMBOL)+": \""+this.GetProperty(property)+"\"" : "" ); } //+------------------------------------------------------------------+
В методах проверяется свойство, переданное в него, и в соответствии со значением свойства создаётся и возвращается строка с его описанием.
Метод, выводящий в журнал полное описание свойств объекта:
//+------------------------------------------------------------------+ //| Выводит в журнал свойства объекта | //+------------------------------------------------------------------+ void CChartObj::Print(const bool full_prop=false) { ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") ============="); int beg=0, end=CHART_PROP_INTEGER_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_INTEGER prop=(ENUM_CHART_PROP_INTEGER)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); beg=end; end+=CHART_PROP_DOUBLE_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_DOUBLE prop=(ENUM_CHART_PROP_DOUBLE)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); beg=end; end+=CHART_PROP_STRING_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_STRING prop=(ENUM_CHART_PROP_STRING)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n"); } //+------------------------------------------------------------------+
В трёх циклах по всем свойствам объекта получаем описание каждого очередного свойства и распечатываем его в журнал.
Метод, выводящий в журнал краткое описание объекта:
//+------------------------------------------------------------------+ //| Выводит в журнал краткое описание объекта | //+------------------------------------------------------------------+ void CChartObj::PrintShort(const bool dash=false) { ::Print((dash ? "- " : ""),this.Header()," ID: ",(string)this.ID(),", HWND: ",(string)this.Handle()); } //+------------------------------------------------------------------+
В метод передаётся флаг необходимости вывести дефис перед описанием объекта. Дефис нужен будет в классе-коллекции объектов-чартов для вывода краткого описания всей коллекции. По умолчанию дефис не ставится. Метод создаёт строку с описанием объекта и некоторыми дополнительными его свойствами — идентификаторм графика и хэндлом окна.
Метод, возвращающий краткое наименование объекта:
//+------------------------------------------------------------------+ //| Возвращает краткое наименование объекта | //+------------------------------------------------------------------+ string CChartObj::Header(void) { return(CMessage::Text(MSG_CHART_OBJ_CHART_WINDOW)+" "+this.Symbol()+" "+TimeframeDescription(this.Timeframe())); } //+------------------------------------------------------------------+
В методе создаётся и возвращается строка, состоящая из заголовка и наименований символа и таймфрейма графика.
Все эти методы стандартны для объектов библиотеки и составляют основу каждого объекта. Но для удобного использования этих методов, мы обычно добавляем методы для быстрого доступа к свойствам объекта. И таких методов у нас будет много, так как много и разных свойств у объекта-чарта.
В основном все его свойства — это флаги, указывающие на состояние того или иного параметра графика. Их можно включить и можно выключить — т. е. всего два состояния. Значит, нам нужны методы для установки флагов таких свойств объекта. И это будут приватные методы. Публичными же методами мы сделаем методы, для включения свойства и его же выключения. Это будет удобнее в использовании.
В приватной секции класса объявим методы для установки флагов некоторых свойств объекта, и там же объявим методы для установки свойств, имеющих граничное число значений (3 и 6), а также методы для установки только свойств объекта-чарта — для параметров графика read only — чтобы можно было вписать в свойство объекта-чарта значение соответствующего параметра графика:
//+------------------------------------------------------------------+ //| ChartObj.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" #property strict // Нужно для mql4 //+------------------------------------------------------------------+ //| Включаемые файлы | //+------------------------------------------------------------------+ #include "..\..\Objects\BaseObj.mqh" //+------------------------------------------------------------------+ //| Класс объекта-чарта | //+------------------------------------------------------------------+ class CChartObj : public CBaseObj { private: long m_long_prop[CHART_PROP_INTEGER_TOTAL]; // Целочисленные свойства double m_double_prop[CHART_PROP_DOUBLE_TOTAL]; // Вещественные свойства string m_string_prop[CHART_PROP_STRING_TOTAL]; // Строковые свойства int m_digits; // Digits() символа //--- Возвращает индекс массива, по которому фактически расположено (1) double-свойство и (2) string-свойство int IndexProp(ENUM_CHART_PROP_DOUBLE property) const { return(int)property-CHART_PROP_INTEGER_TOTAL; } int IndexProp(ENUM_CHART_PROP_STRING property) const { return(int)property-CHART_PROP_INTEGER_TOTAL-CHART_PROP_DOUBLE_TOTAL; } //--- Методы установки флагов параметров bool SetShowFlag(const string source,const bool flag,const bool redraw=false); bool SetBringToTopFlag(const string source,const bool flag,const bool redraw=false); bool SetContextMenuFlag(const string source,const bool flag,const bool redraw=false); bool SetCrosshairToolFlag(const string source,const bool flag,const bool redraw=false); bool SetMouseScrollFlag(const string source,const bool flag,const bool redraw=false); bool SetEventMouseWhellFlag(const string source,const bool flag,const bool redraw=false); bool SetEventMouseMoveFlag(const string source,const bool flag,const bool redraw=false); bool SetEventObjectCreateFlag(const string source,const bool flag,const bool redraw=false); bool SetEventObjectDeleteFlag(const string source,const bool flag,const bool redraw=false); bool SetForegroundFlag(const string source,const bool flag,const bool redraw=false); bool SetShiftFlag(const string source,const bool flag,const bool redraw=false); bool SetAutoscrollFlag(const string source,const bool flag,const bool redraw=false); bool SetKeyboardControlFlag(const string source,const bool flag,const bool redraw=false); bool SetQuickNavigationFlag(const string source,const bool flag,const bool redraw=false); bool SetScaleFixFlag(const string source,const bool flag,const bool redraw=false); bool SetScaleFix11Flag(const string source,const bool flag,const bool redraw=false); bool SetScalePTPerBarFlag(const string source,const bool flag,const bool redraw=false); bool SetShowTickerFlag(const string source,const bool flag,const bool redraw=false); bool SetShowOHLCFlag(const string source,const bool flag,const bool redraw=false); bool SetShowBidLineFlag(const string source,const bool flag,const bool redraw=false); bool SetShowAskLineFlag(const string source,const bool flag,const bool redraw=false); bool SetShowLastLineFlag(const string source,const bool flag,const bool redraw=false); bool SetShowPeriodSeparatorsFlag(const string source,const bool flag,const bool redraw=false); bool SetShowGridFlag(const string source,const bool flag,const bool redraw=false); bool SetShowObjectDescriptionsFlag(const string source,const bool flag,const bool redraw=false); bool SetShowTradeLevelsFlag(const string source,const bool flag,const bool redraw=false); bool SetDragTradeLevelsFlag(const string source,const bool flag,const bool redraw=false); bool SetShowDateScaleFlag(const string source,const bool flag,const bool redraw=false); bool SetShowPriceScaleFlag(const string source,const bool flag,const bool redraw=false); bool SetShowOneClickPanelFlag(const string source,const bool flag,const bool redraw=false); bool SetDockedFlag(const string source,const bool flag,const bool redraw=false); //--- Методы установки значений свойств bool SetMode(const string source,const ENUM_CHART_MODE mode,const bool redraw=false); bool SetScale(const string source,const int scale,const bool redraw=false); bool SetModeVolume(const string source,const ENUM_CHART_VOLUME_MODE mode,const bool redraw=false); void SetVisibleBars(void); void SetWindowsTotal(void); void SetFirstVisibleBars(void); void SetWidthInBars(void); void SetWidthInPixels(void); void SetMaximizedFlag(void); void SetMinimizedFlag(void); void SetExpertName(void); void SetScriptName(void); public:
За пределами тела класса напишем реализацию объявленных приватных методов.
Методы установки флагов идентичны друг другу.
Поэтому рассмотрим логику на примере метода, устанавливающего флаг отрисовки ценового графика:
//+------------------------------------------------------------------+ //| Устанавливает флаг отрисовки ценового графика | //+------------------------------------------------------------------+ bool CChartObj::SetShowFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+
В метод передаётся источник (source) — наименование метода, из которого был вызван этот приватный метод, значение флага (flag), которое необходимо установить в параметры графика и в свойство объекта-чарта, и флаг необходимости перерисовки графика (redraw).
Функции работы с графиками ChartSet* — асинхронные, т. е. возвращают лишь результат постановки команды в очередь событий графика, но не результат изменения самого параметра. Обычно, результат работы функции проявляется после некоего события графика — изменение его размеров, приход нового тика, обновление графика, и т. д. Для немедленного отображения изменения параметра нужно принудительно обновить график, что и делает функция ChartRedraw().
Здесь есть одно "НО" — обычно меняются несколько значений параметров графика, т. е. пакетное их изменение. В этом случае нужно сначала отправить все события изменения всех нужных параметров графика, и лишь после вызвать принудительную перерисовку графика — чтобы после каждой команды изменения параметров не перерисовывать график. Для этого и служит флаг redraw, выставленный по умолчанию в false.
Здесь: первым делом отсылаем команду на изменение параметра графика и, если событие не было поставлено в очередь — сообщаем об ошибке и возвращаем false.
Если же событие успешно было поставлено в очередь, то изменяем свойство объекта-чарта и, если установлен флаг перерисовки — принудительно перерисовываем график. Возвращаем true — метод отработал успешно.
Реализация остальных приватных методов на установку флагов идентична рассмотренному; приведём их полный листинг:
//+------------------------------------------------------------------+ //| Устанавливает флаг графика поверх всех других | //+------------------------------------------------------------------+ bool CChartObj::SetBringToTopFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_BRING_TO_TOP,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_BRING_TO_TOP,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг доступа к контекстному меню | //| по нажатию правой клавиши мышки | //+------------------------------------------------------------------+ bool CChartObj::SetContextMenuFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_CONTEXT_MENU,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_CONTEXT_MENU,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг доступа к инструменту "Перекрестие" | //| по нажатию средней клавиши мышки | //+------------------------------------------------------------------+ bool CChartObj::SetCrosshairToolFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_CROSSHAIR_TOOL,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_CROSSHAIR_TOOL,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг прокрутки графика | //| левой кнопкой мышки по горизонтали | //+------------------------------------------------------------------+ bool CChartObj::SetMouseScrollFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_MOUSE_SCROLL,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_MOUSE_SCROLL,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отправки всем mql5-программам на графике | //| сообщений о событиях колёсика мышки | //+------------------------------------------------------------------+ bool CChartObj::SetEventMouseWhellFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_EVENT_MOUSE_WHEEL,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_EVENT_MOUSE_WHEEL,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отправки всем mql5-программам на графике | //| сообщений о событиях перемещения и нажатия кнопок мышки | //+------------------------------------------------------------------+ bool CChartObj::SetEventMouseMoveFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_EVENT_MOUSE_MOVE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_EVENT_MOUSE_MOVE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отправки всем mql5-программам на графике | //| сообщений о событии создания графического объекта | //+------------------------------------------------------------------+ bool CChartObj::SetEventObjectCreateFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_EVENT_OBJECT_CREATE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_EVENT_OBJECT_CREATE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отправки всем mql5-программам на графике | //| сообщений о событии уничтожения графического объекта | //+------------------------------------------------------------------+ bool CChartObj::SetEventObjectDeleteFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_EVENT_OBJECT_DELETE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_EVENT_OBJECT_DELETE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг ценового графика на переднем плане | //+------------------------------------------------------------------+ bool CChartObj::SetForegroundFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_FOREGROUND,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FOREGROUND,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отступа ценового графика от правого края | //+------------------------------------------------------------------+ bool CChartObj::SetShiftFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHIFT,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHIFT,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает флаг автоматического перехода к правому краю графика| //+------------------------------------------------------------------+ bool CChartObj::SetAutoscrollFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_AUTOSCROLL,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_AUTOSCROLL,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг управления графиком с помощью клавиатуры | //+------------------------------------------------------------------+ bool CChartObj::SetKeyboardControlFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_KEYBOARD_CONTROL,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_KEYBOARD_CONTROL,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг перехвата графиком нажатий клавиш | //| Space и Enter для активации строки быстрой навигации | //+------------------------------------------------------------------+ bool CChartObj::SetQuickNavigationFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_QUICK_NAVIGATION,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_QUICK_NAVIGATION,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг фиксированного масштаба | //+------------------------------------------------------------------+ bool CChartObj::SetScaleFixFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SCALEFIX,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SCALEFIX,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг масштаба 1:1 | //+------------------------------------------------------------------+ bool CChartObj::SetScaleFix11Flag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SCALEFIX_11,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SCALEFIX_11,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг указания масштаба в пунктах на бар | //+------------------------------------------------------------------+ bool CChartObj::SetScalePTPerBarFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SCALE_PT_PER_BAR,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SCALE_PT_PER_BAR,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает флаг отображения в левом верхнем углу тикера символа| //+------------------------------------------------------------------+ bool CChartObj::SetShowTickerFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_TICKER,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_TICKER,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает флаг отображения в левом верхнем углу значений OHLC | //+------------------------------------------------------------------+ bool CChartObj::SetShowOHLCFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_OHLC,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_OHLC,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения значения Bid | //| горизонтальной линией на графике | //+------------------------------------------------------------------+ bool CChartObj::SetShowBidLineFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_BID_LINE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_BID_LINE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения значения Ask | //| горизонтальной линией на графике | //+------------------------------------------------------------------+ bool CChartObj::SetShowAskLineFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_ASK_LINE,flag)) { CMessage::ToLog(source,::GetLastError(),flag); return false; } this.SetProperty(CHART_PROP_SHOW_ASK_LINE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения значения Last | //| горизонтальной линией на графике | //+------------------------------------------------------------------+ bool CChartObj::SetShowLastLineFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_LAST_LINE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_LAST_LINE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения вертикальных разделителей | //| между соседними периодами | //+------------------------------------------------------------------+ bool CChartObj::SetShowPeriodSeparatorsFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_PERIOD_SEP,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_PERIOD_SEP,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения сетки на графике | //+------------------------------------------------------------------+ bool CChartObj::SetShowGridFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_GRID,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_GRID,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения текстовых описаний объектов | //+------------------------------------------------------------------+ bool CChartObj::SetShowObjectDescriptionsFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_OBJECT_DESCR,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_OBJECT_DESCR,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения на графике торговых уровней | //+------------------------------------------------------------------+ bool CChartObj::SetShowTradeLevelsFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_TRADE_LEVELS,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_TRADE_LEVELS,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг разрешения на перетаскивание | //| торговых уровней на графике с помощью мышки | //+------------------------------------------------------------------+ bool CChartObj::SetDragTradeLevelsFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_DRAG_TRADE_LEVELS,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_DRAG_TRADE_LEVELS,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения на графике шкалы времени | //+------------------------------------------------------------------+ bool CChartObj::SetShowDateScaleFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_DATE_SCALE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_DATE_SCALE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг отображения на графике ценовой шкалы | //+------------------------------------------------------------------+ bool CChartObj::SetShowPriceScaleFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_PRICE_SCALE,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_PRICE_SCALE,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает флаг отображения на графике панели быстрой торговли | //+------------------------------------------------------------------+ bool CChartObj::SetShowOneClickPanelFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_ONE_CLICK,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_ONE_CLICK,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает флаг закрепления окна графика | //+------------------------------------------------------------------+ bool CChartObj::SetDockedFlag(const string source,const bool flag,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_IS_DOCKED,flag)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_IS_DOCKED,flag); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+
Как видим, все эти методы идентичны вышерассмотренному, за исключением изменяемого свойства (помечен цветом в последнем методе).
Три приватных метода для установки режимов отображения графика, масштаба и объёмов на графике:
//+------------------------------------------------------------------+ //| Устанавливает тип графика | //+------------------------------------------------------------------+ bool CChartObj::SetMode(const string source,const ENUM_CHART_MODE mode,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_MODE,mode)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_MODE,mode); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает масштаб графика | //+------------------------------------------------------------------+ bool CChartObj::SetScale(const string source,const int scale,const bool redraw=false) { int value=(scale<0 ? 0 : scale>5 ? 5 : scale); ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SCALE,value)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SCALE,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает режим отображения объемов на графике | //+------------------------------------------------------------------+ bool CChartObj::SetModeVolume(const string source,ENUM_CHART_VOLUME_MODE mode,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_SHOW_VOLUMES,mode)) { CMessage::ToLog(source,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHOW_VOLUMES,mode); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+
Методы так же идентичны вышерассмотренным, за исключением входных параметров, в которых вместо флагов передаются требуемые режимы, и в методе установки масштаба графика дополнительно проверяются пределы переданного значения масштаба — от 0 до 5.
У графиков есть свойства, которые невозможно установить — их можно только получить. Но для того, чтобы объект-чарт имел такие же значения, как и у графика, нам нужны методы, позволяющие вписать в соответствующие свойства объекта значения параметров графика. Они устанавливаются в момент создания объекта-чарта, но если они будут изменены терминалом, то нам необходимо будет вовремя отреагировать на это изменение, и внести соответствующие правки и в свойства объекта-чарта.
Для этого и предназначены следующие приватные методы:
//+------------------------------------------------------------------+ //| Устанавливает свойство | //| "Количество баров на графике, доступных для отображения" | //+------------------------------------------------------------------+ void CChartObj::SetVisibleBars(void) { this.SetProperty(CHART_PROP_VISIBLE_BARS,::ChartGetInteger(this.ID(),CHART_VISIBLE_BARS)); } //+------------------------------------------------------------------+ //| Устанавливает свойство | //| "Общее количество окон графика, включая подокна индикаторов" | //+------------------------------------------------------------------+ void CChartObj::SetWindowsTotal(void) { this.SetProperty(CHART_PROP_WINDOWS_TOTAL,::ChartGetInteger(this.ID(),CHART_WINDOWS_TOTAL)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Номер первого видимого бара на графике" | //+------------------------------------------------------------------+ void CChartObj::SetFirstVisibleBars(void) { this.SetProperty(CHART_PROP_FIRST_VISIBLE_BAR,::ChartGetInteger(this.ID(),CHART_FIRST_VISIBLE_BAR)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Ширина графика в барах" | //+------------------------------------------------------------------+ void CChartObj::SetWidthInBars(void) { this.SetProperty(CHART_PROP_WIDTH_IN_BARS,::ChartGetInteger(this.ID(),CHART_WIDTH_IN_BARS)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Ширина графика в пикселях" | //+------------------------------------------------------------------+ void CChartObj::SetWidthInPixels(void) { this.SetProperty(CHART_PROP_WIDTH_IN_PIXELS,::ChartGetInteger(this.ID(),CHART_WIDTH_IN_PIXELS)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Окно графика развернуто" | //+------------------------------------------------------------------+ void CChartObj::SetMaximizedFlag(void) { this.SetProperty(CHART_PROP_IS_MAXIMIZED,::ChartGetInteger(this.ID(),CHART_IS_MAXIMIZED)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Окно графика свернуто" | //+------------------------------------------------------------------+ void CChartObj::SetMinimizedFlag(void) { this.SetProperty(CHART_PROP_IS_MINIMIZED,::ChartGetInteger(this.ID(),CHART_IS_MINIMIZED)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Имя эксперта, запущенного на графике" | //+------------------------------------------------------------------+ void CChartObj::SetExpertName(void) { this.SetProperty(CHART_PROP_EXPERT_NAME,::ChartGetString(this.ID(),CHART_EXPERT_NAME)); } //+------------------------------------------------------------------+ //| Устанавливает свойство "Имя скрипта, запущенного на графике" | //+------------------------------------------------------------------+ void CChartObj::SetScriptName(void) { this.SetProperty(CHART_PROP_SCRIPT_NAME,::ChartGetString(this.ID(),CHART_SCRIPT_NAME)); } //+------------------------------------------------------------------+
Здесь лишь записывается параметр графика в соответствующее ему свойство объекта. Реализацию работы с этими методами будем делать в последующих статьях.
Теперь нам необходимо добавить в публичную секцию класса методы для упрощённого доступа к свойствам объекта-чарта. Это будут методы для установки параметров графика в состояние Вкл/Выкл, установку цвета, размеров и другой необходимый для работы с графиком функционал.
Методов достаточно много, рассмотрим их по группам.
Методы возврата/установки свойствам значений Вкл/Выкл:
//--- Конструкторы CChartObj(){;} CChartObj(const long chart_id); //+------------------------------------------------------------------+ //| Методы упрощённого доступа к свойствам объекта-чарта | //+------------------------------------------------------------------+ //--- (1) Возвращает, (2) Включает, (3) отключает отрисовку ценового графика bool IsShow(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW); } bool SetShowON(const bool redraw=false) { return this.SetShowFlag(DFUN,true,redraw); } bool SetShowOFF(const bool redraw=false) { return this.SetShowFlag(DFUN,true,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает доступ к контекстному меню по нажатию правой клавиши мышки bool IsAllowedContextMenu(void) const { return (bool)this.GetProperty(CHART_PROP_CONTEXT_MENU); } bool SetContextMenuON(const bool redraw=false) { return this.SetContextMenuFlag(DFUN,true,redraw); } bool SetContextMenuOFF(const bool redraw=false) { return this.SetContextMenuFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает доступ к инструменту "Перекрестие" по нажатию средней клавиши мышки bool IsCrosshairTool(void) const { return (bool)this.GetProperty(CHART_PROP_CROSSHAIR_TOOL); } bool SetCrosshairToolON(const bool redraw=false); bool SetCrosshairToolOFF(const bool redraw=false); //--- (1) Возвращает, (2) Включает, (3) отключает прокрутку графика левой кнопкой мышки по горизонтали bool IsMouseScroll(void) const { return (bool)this.GetProperty(CHART_PROP_MOUSE_SCROLL); } bool SetMouseScrollON(const bool redraw=false) { return this.SetMouseScrollFlag(DFUN,true,redraw); } bool SetMouseScrollOFF(const bool redraw=false) { return this.SetMouseScrollFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отправку всем mql5-программам на графике сообщений о событиях колёсика мышки bool IsEventMouseWhell(void) const { return (bool)this.GetProperty(CHART_PROP_EVENT_MOUSE_WHEEL); } bool SetEventMouseWhellON(const bool redraw=false) { return this.SetEventMouseWhellFlag(DFUN,true,redraw); } bool SetEventMouseWhellOFF(const bool redraw=false) { return this.SetEventMouseWhellFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отправку всем mql5-программам на графике сообщений о событиях перемещения и нажатия кнопок мышки bool IsEventMouseMove(void) const { return (bool)this.GetProperty(CHART_PROP_EVENT_MOUSE_MOVE); } bool SetEventMouseMoveON(const bool redraw=false) { return this.SetEventMouseMoveFlag(DFUN,true,redraw); } bool SetEventMouseMoveOFF(const bool redraw=false) { return this.SetEventMouseMoveFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отправку всем mql5-программам на графике сообщений о событии создания графического объекта bool IsEventObjectCreate(void) const { return (bool)this.GetProperty(CHART_PROP_EVENT_OBJECT_CREATE);} bool SetEventObjectCreateON(const bool redraw=false) { return this.SetEventObjectCreateFlag(DFUN,true,redraw); } bool SetEventObjectCreateOFF(const bool redraw=false) { return this.SetEventObjectCreateFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отправку всем mql5-программам на графике сообщений о событии уничтожения графического объекта bool IsEventObjectDelete(void) const { return (bool)this.GetProperty(CHART_PROP_EVENT_OBJECT_DELETE);} bool SetEventObjectDeleteON(const bool redraw=false) { return this.SetEventObjectDeleteFlag(DFUN,true,redraw); } bool SetEventObjectDeleteOFF(const bool redraw=false) { return this.SetEventObjectDeleteFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает ценовой график на переднем плане bool IsForeground(void) const { return (bool)this.GetProperty(CHART_PROP_FOREGROUND); } bool SetForegroundON(const bool redraw=false) { return this.SetForegroundFlag(DFUN,true,redraw); } bool SetForegroundOFF(const bool redraw=false) { return this.SetForegroundFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отступ ценового графика от правого края bool IsShift(void) const { return (bool)this.GetProperty(CHART_PROP_SHIFT); } bool SetShiftON(const bool redraw=false) { return this.SetShiftFlag(DFUN,true,redraw); } bool SetShiftOFF(const bool redraw=false) { return this.SetShiftFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает автоматический переход к правому краю графика bool IsAutoscroll(void) const { return (bool)this.GetProperty(CHART_PROP_AUTOSCROLL); } bool SetAutoscrollON(const bool redraw=false) { return this.SetAutoscrollFlag(DFUN,true,redraw); } bool SetAutoscrollOFF(const bool redraw=false) { return this.SetAutoscrollFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает разрешение на управление графиком с помощью клавиатуры bool IsKeyboardControl(void) const { return (bool)this.GetProperty(CHART_PROP_KEYBOARD_CONTROL); } bool SetKeyboardControlON(const bool redraw=false) { return this.SetKeyboardControlFlag(DFUN,true,redraw); } bool SetKeyboardControlOFF(const bool redraw=false) { return this.SetKeyboardControlFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает разрешение на перехват графиком нажатий клавиш Space и Enter для активации строки быстрой навигации bool IsQuickNavigation(void) const { return (bool)this.GetProperty(CHART_PROP_QUICK_NAVIGATION); } bool SetQuickNavigationON(const bool redraw=false) { return this.SetQuickNavigationFlag(DFUN,true,redraw); } bool SetQuickNavigationOFF(const bool redraw=false) { return this.SetQuickNavigationFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает фиксированный масштаб bool IsScaleFix(void) const { return (bool)this.GetProperty(CHART_PROP_SCALEFIX); } bool SetScaleFixON(const bool redraw=false) { return this.SetScaleFixFlag(DFUN,true,redraw); } bool SetScaleFixOFF(const bool redraw=false) { return this.SetScaleFixFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает масштаб 1:1 bool IsScaleFix11(void) const { return (bool)this.GetProperty(CHART_PROP_SCALEFIX_11); } bool SetScaleFix11ON(const bool redraw=false) { return this.SetScaleFix11Flag(DFUN,true,redraw); } bool SetScaleFix11OFF(const bool redraw=false) { return this.SetScaleFix11Flag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает режим указания масштаба в пунктах на бар bool IsScalePTPerBar(void) const { return (bool)this.GetProperty(CHART_PROP_SCALE_PT_PER_BAR); } bool SetScalePTPerBarON(const bool redraw=false) { return this.SetScalePTPerBarFlag(DFUN,true,redraw); } bool SetScalePTPerBarOFF(const bool redraw=false) { return this.SetScalePTPerBarFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение в левом верхнем углу тикера символа bool IsShowTicker(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_TICKER); } bool SetShowTickerON(const bool redraw=false) { return this.SetShowTickerFlag(DFUN,true,redraw); } bool SetShowTickerOFF(const bool redraw=false) { return this.SetShowTickerFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение в левом верхнем углу значений OHLC bool IsShowOHLC(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_OHLC); } bool SetShowOHLCON(const bool redraw=false) { return this.SetShowOHLCFlag(DFUN,true,redraw); } bool SetShowOHLCOFF(const bool redraw=false) { return this.SetShowOHLCFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение значения Bid горизонтальной линией на графике bool IsShowBidLine(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_BID_LINE); } bool SetShowBidLineON(const bool redraw=false) { return this.SetShowBidLineFlag(DFUN,true,redraw); } bool SetShowBidLineOFF(const bool redraw=false) { return this.SetShowBidLineFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение значения Ask горизонтальной линией на графике bool IsShowAskLine(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_ASK_LINE); } bool SetShowAskLineON(const bool redraw=false) { return this.SetShowAskLineFlag(DFUN,true,redraw); } bool SetShowAskLineOFF(const bool redraw=false) { return this.SetShowAskLineFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение значения Last горизонтальной линией на графике bool IsShowLastLine(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_LAST_LINE); } bool SetShowLastLineON(const bool redraw=false) { return this.SetShowLastLineFlag(DFUN,true,redraw); } bool SetShowLastLineOFF(const bool redraw=false) { return this.SetShowLastLineFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение вертикальных разделителей между соседними периодами bool IsShowPeriodSeparators(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_PERIOD_SEP); } bool SetShowPeriodSeparatorsON(const bool redraw=false) { return this.SetShowPeriodSeparatorsFlag(DFUN,true,redraw); } bool SetShowPeriodSeparatorsOFF(const bool redraw=false) { return this.SetShowPeriodSeparatorsFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение сетки на графике bool IsShowGrid(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_GRID); } bool SetShowGridON(const bool redraw=false) { return this.SetShowGridFlag(DFUN,true,redraw); } bool SetShowGridOFF(const bool redraw=false) { return this.SetShowGridFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение текстовых описаний объектов bool IsShowObjectDescriptions(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_OBJECT_DESCR); } bool SetShowObjectDescriptionsON(const bool redraw=false); bool SetShowObjectDescriptionsOFF(const bool redraw=false); //--- (1) Возвращает, (2) Включает, (3) отключает отображение на графике торговых уровней (уровни открытых позиций, Stop Loss, Take Profit и отложенных ордеров) bool IsShowTradeLevels(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_TRADE_LEVELS); } bool SetShowTradeLevelsON(const bool redraw=false) { return this.SetShowTradeLevelsFlag(DFUN,true,redraw); } bool SetShowTradeLevelsOFF(const bool redraw=false) { return this.SetShowTradeLevelsFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает разрешение на перетаскивание торговых уровней на графике с помощью мышки bool IsDragTradeLevels(void) const { return (bool)this.GetProperty(CHART_PROP_DRAG_TRADE_LEVELS); } bool SetDragTradeLevelsON(const bool redraw=false) { return this.SetDragTradeLevelsFlag(DFUN,true,redraw); } bool SetDragTradeLevelsOFF(const bool redraw=false) { return this.SetDragTradeLevelsFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение на графике шкалы времени bool IsShowDateScale(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_DATE_SCALE); } bool SetShowDateScaleON(const bool redraw=false) { return this.SetShowDateScaleFlag(DFUN,true,redraw); } bool SetShowDateScaleOFF(const bool redraw=false) { return this.SetShowDateScaleFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение на графике ценовой шкалы bool IsShowPriceScale(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_PRICE_SCALE); } bool SetShowPriceScaleON(const bool redraw=false) { return this.SetShowPriceScaleFlag(DFUN,true,redraw); } bool SetShowPriceScaleOFF(const bool redraw=false) { return this.SetShowPriceScaleFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает отображение на графике панели быстрой торговли bool IsShowOneClickPanel(void) const { return (bool)this.GetProperty(CHART_PROP_SHOW_ONE_CLICK); } bool SetShowOneClickPanelON(const bool redraw=false) { return this.SetShowOneClickPanelFlag(DFUN,true,redraw); } bool SetShowOneClickPanelOFF(const bool redraw=false) { return this.SetShowOneClickPanelFlag(DFUN,false,redraw); } //--- (1) Возвращает, (2) Включает, (3) отключает закрепление окна графика bool IsDocked(void) const { return (bool)this.GetProperty(CHART_PROP_IS_DOCKED); } bool SetDockedON(const bool redraw=false) { return this.SetDockedFlag(DFUN,true,redraw); } bool SetDockedOFF(const bool redraw=false) { return this.SetDockedFlag(DFUN,false,redraw); } //--- (1) Включает, (2) отключает показ графика поверх всех других bool SetBringToTopON(const bool redraw=false) { return this.SetBringToTopFlag(DFUN,true,redraw); } bool SetBringToTopOFF(const bool redraw=false) { return this.SetBringToTopFlag(DFUN,false,redraw); }
Все методы установки флагов идентичны и возвращают результат работы соответствующих приватных методов установки флагов, рассмотренных нами выше. Методы возврата значений свойств возвращают значение, записанное в соответствующем свойстве объекта. Два последних метода только устанавливают флаги, так как нет возможности вернуть свойство графика "Поверх всех других" при помощи функции ChartGetInteger() с идентификатором CHART_BRING_TO_TOP — это свойство графика только для записи значений.
Методы возврата/установки режимов отображения графика, масштаба графика и объёмов на графике:
//--- (1) Возвращает, устанавливает тип графика (2) бары, (3) свечи, (4) линия ENUM_CHART_MODE Mode(void) const { return (ENUM_CHART_MODE)this.GetProperty(CHART_PROP_MODE); } bool SetModeBars(const bool redraw=false) { return this.SetMode(DFUN,CHART_BARS,redraw); } bool SetModeCandles(const bool redraw=false) { return this.SetMode(DFUN,CHART_CANDLES,redraw); } bool SetModeLine(const bool redraw=false) { return this.SetMode(DFUN,CHART_LINE,redraw); } //--- (1) Возвращает, (2 - 7) устанавливает масштаб графика int Scale(void) const { return (int)this.GetProperty(CHART_PROP_SCALE); } bool SetScale0(const bool redraw=false) { return this.SetScale(DFUN,0,redraw); } bool SetScale1(const bool redraw=false) { return this.SetScale(DFUN,1,redraw); } bool SetScale2(const bool redraw=false) { return this.SetScale(DFUN,2,redraw); } bool SetScale3(const bool redraw=false) { return this.SetScale(DFUN,3,redraw); } bool SetScale4(const bool redraw=false) { return this.SetScale(DFUN,4,redraw); } bool SetScale5(const bool redraw=false) { return this.SetScale(DFUN,5,redraw); } //--- (1) Возвращает, устанавливает режимы отображения объемов на графике (2) отключено, (3) тиковые, (4 реальные объёмы ENUM_CHART_VOLUME_MODE ModeVolume(void) const { return (ENUM_CHART_VOLUME_MODE)this.GetProperty(CHART_PROP_SHOW_VOLUMES);} bool SetModeVolumeHide(const bool redraw=false) { return this.SetModeVolume(DFUN,CHART_VOLUME_HIDE,redraw); } bool SetModeVolumeTick(const bool redraw=false) { return this.SetModeVolume(DFUN,CHART_VOLUME_TICK,redraw); } bool SetModeVolumeReal(const bool redraw=false) { return this.SetModeVolume(DFUN,CHART_VOLUME_REAL,redraw); }
Здесь методы возврата значения свойств идентичны методам возврата флагов — возвращается значение, установленное в соответствующем свойстве объекта. А методы установки значений возвращают результат работы приватных методов с указанным значением, которое необходимо установить свойству объекта и графику.
Методы возврата и установки цветов отображения различных элементов графика и других изменяемых параметров графика:
//--- Возвращает, (2) устанавливает цвет фона графика color ColorBackground(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_BACKGROUND); } bool SetColorBackground(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет осей, шкалы и строки OHLC color ColorForeground(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_FOREGROUND); } bool SetColorForeground(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет сетки color ColorGrid(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_GRID); } bool SetColorGrid(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет объемов и уровней открытия позиций color ColorVolume(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_VOLUME); } bool SetColorVolume(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет бара вверх, тени и окантовки тела бычьей свечи color ColorUp(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_CHART_UP); } bool SetColorUp(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет бара вниз, тени и окантовки тела медвежьей свечи color ColorDown(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_CHART_DOWN); } bool SetColorDown(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет линии графика и японских свечей "Доджи" color ColorLine(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_CHART_LINE); } bool SetColorLine(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет тела бычьей свечи color ColorCandleBull(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_CANDLE_BULL);} bool SetColorCandleBull(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет тела медвежьей свечи color ColorCandleBear(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_CANDLE_BEAR);} bool SetColorCandleBear(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет линии Bid-цены color ColorBid(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_BID); } bool SetColorBid(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет линии Ask-цены color ColorAsk(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_ASK); } bool SetColorAsk(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет линии цены последней совершенной сделки (Last) color ColorLast(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_LAST); } bool SetColorLast(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает цвет уровней стоп-ордеров (Stop Loss и Take Profit) color ColorStops(void) const { return (color)this.GetProperty(CHART_PROP_COLOR_STOP_LEVEL); } bool SetColorStops(const color colour,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает левую координату открепленного графика относительно виртуального экрана int FloatLeft(void) const { return (int)this.GetProperty(CHART_PROP_FLOAT_LEFT); } bool SetFloatLeft(const int value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает верхнюю координату открепленного графика относительно виртуального экрана int FloatTop(void) const { return (int)this.GetProperty(CHART_PROP_FLOAT_TOP); } bool SetFloatTop(const int value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает правую координату открепленного графика относительно виртуального экрана int FloatRight(void) const { return (int)this.GetProperty(CHART_PROP_FLOAT_RIGHT); } bool SetFloatRight(const int value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает нижнюю координату открепленного графика относительно виртуального экрана int FloatBottom(void) const { return (int)this.GetProperty(CHART_PROP_FLOAT_BOTTOM); } bool SetFloatBottom(const int value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает размер отступа нулевого бара от правого края в процентах double ShiftSize(void) const { return this.GetProperty(CHART_PROP_SHIFT_SIZE); } bool SetShiftSize(const double value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает положение фиксированной позиции графика от левого края в процентах double FixedPosition(void) const { return this.GetProperty(CHART_PROP_FIXED_POSITION); } bool SetFixedPosition(const double value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает фиксированный максимум графика double FixedMaximum(void) const { return this.GetProperty(CHART_PROP_FIXED_MAX); } bool SetFixedMaximum(const double value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает фиксированный минимум графика double FixedMinimum(void) const { return this.GetProperty(CHART_PROP_FIXED_MIN); } bool SetFixedMinimum(const double value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает значение масштаба в пунктах на бар double PointsPerBar(void) const { return this.GetProperty(CHART_PROP_POINTS_PER_BAR); } bool SetPointsPerBar(const double value,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает текст комментария на графике string Comment(void) const { return this.GetProperty(CHART_PROP_COMMENT); } bool SetComment(const string comment,const bool redraw=false); //--- (1) Возвращает, (2) устанавливает символ графика string Symbol(void) const { return this.GetProperty(CHART_PROP_SYMBOL); } bool SetSymbol(const string symbol); //--- (1) Возвращает, (2) устанавливает период графика ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(CHART_PROP_TIMEFRAME); } bool SetTimeframe(const ENUM_TIMEFRAMES timeframe);
Методы возврата значений свойств возвращают значения, записанные в соответствующем свойстве объекта, а методы установки здесь только объявлены и их реализацию рассмотрим далее.
Методы, возвращающие свойства объекта-чарта, соответствующие параметрам графика только для чтения:
//--- (1) Возвращает признак идентификации объекта "График" bool IsObject(void) const { return (bool)this.GetProperty(CHART_PROP_IS_OBJECT); } //--- Возвращает идентификатор графика long ID(void) const { return this.GetProperty(CHART_PROP_ID); } //--- Возвращает количество баров на графике, доступных для отображения int VisibleBars(void) const { return (int)this.GetProperty(CHART_PROP_VISIBLE_BARS); } //--- Возвращает общее количество окон графика, включая подокна индикаторов int WindowsTotal(void) const { return (int)this.GetProperty(CHART_PROP_WINDOWS_TOTAL); } //--- Возвращает хэндл окна графика int Handle(void) const { return (int)this.GetProperty(CHART_PROP_WINDOW_HANDLE); } //--- Возвращает номер первого видимого бара на графике int FirstVisibleBars(void) const { return (int)this.GetProperty(CHART_PROP_FIRST_VISIBLE_BAR); } //--- Возвращает ширину графика в барах int WidthInBars(void) const { return (int)this.GetProperty(CHART_PROP_WIDTH_IN_BARS); } //--- Возвращает ширину графика в пикселях int WidthInPixels(void) const { return (int)this.GetProperty(CHART_PROP_WIDTH_IN_PIXELS); } //--- Возвращает свойство "Окно графика развернуто" bool IsMaximized(void) const { return (bool)this.GetProperty(CHART_PROP_IS_MAXIMIZED); } //--- Возвращает свойство "Окно графика свернуто" bool IsMinimized(void) const { return (bool)this.GetProperty(CHART_PROP_IS_MINIMIZED); } //--- Возвращает имя эксперта, запущенного на графике string ExpertName(void) const { return this.GetProperty(CHART_PROP_EXPERT_NAME); } //--- Возвращает имя скрипта, запущенного на графике string ScriptName(void) const { return this.GetProperty(CHART_PROP_SCRIPT_NAME); }
Методы возвращают значение, записанное в соответствующее свойство объекта-чарта.
Методы, возвращающие/устанавливающие значения параметров графика, для которых необходимо указывать номер подокна:
//--- (1) Возвращает, (2) устанавливает высоту указанного графика в пикселях int WindowHeightInPixels(const int sub_window) const { return (int)::ChartGetInteger(this.ID(),CHART_HEIGHT_IN_PIXELS,sub_window); } bool SetWindowHeightInPixels(const int height,const int sub_window,const bool redraw=false); //--- Возвращает дистанцию в пикселях по вертикальной оси Y между верхней рамкой подокна индикатора и верхней рамкой главного окна графика int WindowYDistance(const int sub_window) const { return (int)::ChartGetInteger(this.ID(),CHART_WINDOW_YDISTANCE,sub_window); } //--- Возвращает видимость указанного подокна bool IsVisibleWindow(const int sub_window) const { return (bool)::ChartGetInteger(this.Handle(),CHART_WINDOW_IS_VISIBLE,sub_window); } //--- Возвращает минимум указанного графика double PriceMinimum(const int sub_window) const { return ::ChartGetDouble(this.ID(),CHART_PRICE_MIN,sub_window); } //--- Возвращает максимум указанного графика double PriceMaximum(const int sub_window) const { return ::ChartGetDouble(this.ID(),CHART_PRICE_MAX,sub_window); }
Эти методы пока тут временно, так как в последующем в объекте-чарте будет присутствовать список принадлежащих графику подокон индикаторов, номера которых необходимо указывать в функциях установки/возврата значений, и эти методы будут переработаны. Поэтому и значения возвращаются не из свойств объекта, а напрямую от графика, который описывается этим объектом-чартом.
Метод для эмуляции тика:
//--- Эмулирует тик (обновления графика - аналогично команде Refresh в терминале) void EmulateTick(void) { ::ChartSetSymbolPeriod(this.ID(),this.Symbol(),this.Timeframe());} }; //+------------------------------------------------------------------+ //| Параметрический конструктор | //+------------------------------------------------------------------+
Вызов функции ChartSetSymbolPeriod() с указанием того же символа и таймфрейма, что и у текущего графика, можно использовать для обновления графика (аналогично команде Refresh в терминале). Обновление графика в свою очередь запускает перерасчет индикаторов, прикрепленных к нему. Таким образом, можно рассчитать индикатор на графике даже при отсутствии тиков (например, в выходные дни).
За пределами тела класса напишем реализацию объявленных методов в блоке методов упрощённого доступа к свойствам объекта.
Методы для установки цвета элементов графика и других настраиваемых параметров графика:
//+------------------------------------------------------------------+ //| Устанавливает цвет фона графика | //+------------------------------------------------------------------+ bool CChartObj::SetColorBackground(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_BACKGROUND,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_BACKGROUND,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет осей, шкалы и строки OHLC | //+------------------------------------------------------------------+ bool CChartObj::SetColorForeground(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_FOREGROUND,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_FOREGROUND,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет сетки | //+------------------------------------------------------------------+ bool CChartObj::SetColorGrid(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_GRID,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_GRID,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет объемов и уровней открытия позиций | //+------------------------------------------------------------------+ bool CChartObj::SetColorVolume(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_VOLUME,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_VOLUME,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает цвет бара вверх, тени и окантовки тела бычьей свечи | //+------------------------------------------------------------------+ bool CChartObj::SetColorUp(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_CHART_UP,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_CHART_UP,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+-------------------------------------------------------------------+ //|Устанавливает цвет бара вниз, тени и окантовки тела медвежьей свечи| //+-------------------------------------------------------------------+ bool CChartObj::SetColorDown(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_CHART_DOWN,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_CHART_DOWN,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет линии графика и японских свечей "Доджи" | //+------------------------------------------------------------------+ bool CChartObj::SetColorLine(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_CHART_LINE,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_CHART_LINE,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет тела бычьей свечи | //+------------------------------------------------------------------+ bool CChartObj::SetColorCandleBull(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_CANDLE_BULL,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_CANDLE_BULL,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет тела медвежьей свечи | //+------------------------------------------------------------------+ bool CChartObj::SetColorCandleBear(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_CANDLE_BEAR,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_CANDLE_BEAR,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет линии Bid-цены | //+------------------------------------------------------------------+ bool CChartObj::SetColorBid(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_BID,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_BID,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает цвет линии Ask-цены | //+------------------------------------------------------------------+ bool CChartObj::SetColorAsk(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_ASK,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_ASK,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает цвет линии цены последней совершенной сделки (Last) | //+------------------------------------------------------------------+ bool CChartObj::SetColorLast(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_LAST,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_LAST,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //|Устанавливает цвет уровней стоп-ордеров (Stop Loss и Take Profit) | //+------------------------------------------------------------------+ bool CChartObj::SetColorStops(const color colour,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_COLOR_STOP_LEVEL,colour)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COLOR_STOP_LEVEL,colour); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает левую координату открепленного графика | //| относительно виртуального экрана | //+------------------------------------------------------------------+ bool CChartObj::SetFloatLeft(const int value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_FLOAT_LEFT,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FLOAT_LEFT,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает верхнюю координату открепленного графика | //| относительно виртуального экрана | //+------------------------------------------------------------------+ bool CChartObj::SetFloatTop(const int value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_FLOAT_TOP,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FLOAT_TOP,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает правую координату открепленного графика | //| относительно виртуального экрана | //+------------------------------------------------------------------+ bool CChartObj::SetFloatRight(const int value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_FLOAT_RIGHT,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FLOAT_RIGHT,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает нижнюю координату открепленного графика | //| относительно виртуального экрана | //+------------------------------------------------------------------+ bool CChartObj::SetFloatBottom(const int value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_FLOAT_BOTTOM,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FLOAT_BOTTOM,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает размер отступа нулевого бара | //| от правого края в процентах | //+------------------------------------------------------------------+ bool CChartObj::SetShiftSize(const double value,const bool redraw=false) { double size=(value<10.0 ? 10.0 : value>50.0 ? 50.0 : value); ::ResetLastError(); if(!::ChartSetDouble(this.ID(),CHART_SHIFT_SIZE,size)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SHIFT_SIZE,size); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает положение фиксированной позиции графика | //| от левого края в процентах | //+------------------------------------------------------------------+ bool CChartObj::SetFixedPosition(const double value,const bool redraw=false) { double pos=(value<0 ? 0 : value>100.0 ? 100.0 : value); ::ResetLastError(); if(!::ChartSetDouble(this.ID(),CHART_FIXED_POSITION,pos)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FIXED_POSITION,pos); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает фиксированный максимум графика | //+------------------------------------------------------------------+ bool CChartObj::SetFixedMaximum(const double value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetDouble(this.ID(),CHART_FIXED_MAX,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FIXED_MAX,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает фиксированный минимум графика | //+------------------------------------------------------------------+ bool CChartObj::SetFixedMinimum(const double value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetDouble(this.ID(),CHART_FIXED_MIN,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_FIXED_MIN,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает значение масштаба в пунктах на бар | //+------------------------------------------------------------------+ bool CChartObj::SetPointsPerBar(const double value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetDouble(this.ID(),CHART_POINTS_PER_BAR,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_POINTS_PER_BAR,value); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает текст комментария на графике | //+------------------------------------------------------------------+ bool CChartObj::SetComment(const string comment,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetString(this.ID(),CHART_COMMENT,comment)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_COMMENT,comment); if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает высоту указанного графика в пикселях | //+------------------------------------------------------------------+ bool CChartObj::SetWindowHeightInPixels(const int height,const int sub_window,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.ID(),CHART_HEIGHT_IN_PIXELS,sub_window,height)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } if(redraw) ::ChartRedraw(this.ID()); return true; } //+------------------------------------------------------------------+ //| Устанавливает символ графика | //+------------------------------------------------------------------+ bool CChartObj::SetSymbol(const string symbol) { ::ResetLastError(); if(!::ChartSetSymbolPeriod(this.ID(),symbol,this.Timeframe())) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_SYMBOL,symbol); this.m_digits=(int)::SymbolInfoInteger(this.Symbol(),SYMBOL_DIGITS); return true; } //+------------------------------------------------------------------+ //| Устанавливает период графика | //+------------------------------------------------------------------+ bool CChartObj::SetTimeframe(const ENUM_TIMEFRAMES timeframe) { ::ResetLastError(); if(!::ChartSetSymbolPeriod(this.ID(),this.Symbol(),timeframe)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } this.SetProperty(CHART_PROP_TIMEFRAME,timeframe); return true; } //+------------------------------------------------------------------+
Методы идентичны вышерассмотренным приватным методам и имеют ту же логику, поэтому оставим их для самостоятельного изучения. Любые вопросы всегда можно задать в обсуждении к статье.
На этом создание объекта-чарта завершено. Полный его листинг можно посмотреть в прикреплённых к статье файлах библиотеки.
Тестирование
Для тестирования возьмём советник из прошлой статьи
и сохраним его в новой папке \MQL5\Experts\TestDoEasy\Part67\ под новым именем TestDoEasyPart67.mq5.
Что мы сделаем... Откроем три графика разных инструментов, т. е. на первом будет работать советник, а два других будут просто открыты. При первом запуске советник прочитает все графики, создаст соответствующие им объекты-чарты, добавит их во временно созданный для тестирования список и затем прочитает созданный список и выведет краткие описания находящихся в нём объектов-чартов. Для самого первого графика — на котором работает советник — выведем полное описание объекта-чарта.
Так как классы сигналов у нас теперь подключены посредством главного объекта библиотеки CEngine, то
вместо строки подключения класса объекта-mql5-сигнала
//| TestDoEasyPart66.mq5 | //| Copyright 2021, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" //--- includes #include <DoEasy\Engine.mqh> #include <DoEasy\Objects\MQLSignalBase\MQLSignal.mqh> //--- enums
подключим файл класса объекта-чарта:
//| TestDoEasyPart67.mq5 | //| Copyright 2021, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" //--- includes #include <DoEasy\Engine.mqh> #include <DoEasy\Objects\Chart\ChartObj.mqh> //--- enums
В обработчике OnTick() вместо блока кода для работы с сигналами
//--- Поиск доступных сигналов в базе и проверка возможности подписаться на сигнал по его имени static bool done=false; //--- Если первый запуск и работа с сигналами разрешена в пользовательских настройках советника if(InpUseMqlSignals && !done) { //--- Выводим в журнал список всех бесплатных сигналов Print(""); engine.GetSignalsMQL5Collection().PrintShort(true,false,true); //--- Получаем список только бесплатных сигналов CArrayObj *list=engine.GetListSignalsMQL5Free(); //--- Если список получен if(list!=NULL) { //--- Находим в списке сигнал с максимальным приростом в процентах int index_max_gain=CSelect::FindMQLSignalMax(list,SIGNAL_MQL5_PROP_GAIN); CMQLSignal *signal_max_gain=list.At(index_max_gain); //--- Если сигнал найден if(signal_max_gain!=NULL) { //--- Выведем в журнал полное описание сигнала signal_max_gain.Print(); //--- Если удалось подписаться на сигнал if(engine.SignalsMQL5Subscribe(signal_max_gain.ID())) { //--- Устанавливаем параметры подписки //--- Разрешаем копирование сделок по подписке engine.SignalsMQL5CurrentSetSubscriptionEnableON(); //--- Устанавливаем запрет синхронизации без показа диалога подтверждения engine.SignalsMQL5CurrentSetConfirmationsDisableOFF(); //--- Устанавливаем разрешение копирования Stop Loss и Take Profit engine.SignalsMQL5CurrentSetSLTPCopyON(); //--- Устанавливаем величину проскальзывания, с которой выставляются рыночные ордера при синхронизации позиций и копировании сделок engine.SignalsMQL5CurrentSetSlippage(2); //--- Устанавливаем процент для конвертации объема сделки engine.SignalsMQL5CurrentSetEquityLimit(50); //--- Устанавливаем ограничения по депозиту (в %) engine.SignalsMQL5CurrentSetDepositPercent(70); //--- Выводим в журнал параметры подписки engine.SignalsMQL5CurrentSubscriptionParameters(); } } } done=true; return; } //--- Если есть подписка на сигнал - отписываемся от него if(engine.SignalsMQL5CurrentID()>0) { engine.SignalsMQL5Unsubscribe(); } //---
впишем блок кода для работы с объектами-чартами:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Обработка события NewTick в библиотеке engine.OnTick(rates_data); //--- Если работа в тестере if(MQLInfoInteger(MQL_TESTER)) { engine.OnTimer(rates_data); // Работа в таймере PressButtonsControl(); // Контроль нажатия кнопок engine.EventsHandling(); // Работа с событиями } //--- Если установлен флаг трейлинга if(trailing_on) { TrailingPositions(); // Трейлинг позиций TrailingOrders(); // Трейлинг отложенных ордеров } //--- Если первый запуск static bool done=false; if(!done) { //--- Создадим объект-список для хранения объектов-чартов CArrayObj *list=new CArrayObj(); if(list==NULL) return; //--- Объявим переменные и получим идентификатор первого графика long currChart,prevChart=ChartFirst(); int i=0; //--- Создадим объект-чарт и добавим его в список CChartObj *chart_first=new CChartObj(prevChart); list.Add(chart_first); //--- В цикле по общему количеству графиков терминала (не более 100) while(i<CHARTS_MAX) { //--- на основании предыдущего получим новый график currChart=ChartNext(prevChart); //--- Если достигли конца списка графиков - завершаем цикл if(currChart<0) break; //--- Создаём объект-чарт на основании идентификатора текущего графика в цикле и добавим его в список CChartObj *chart=new CChartObj(currChart); list.Add(chart); //--- запомним идентификатор текущего графика для ChartNext() и увеличим счётчик цикла prevChart=currChart; i++; } Print(""); //--- Из заполненного списка в цикле получим очередной объект-чарт и выведем его краткое описание int total=list.Total(); for(int j=0;j<total;j++) { CChartObj *chart_obj=list.At(j); chart_obj.PrintShort(); } Print(""); //--- Выведем полное описание самого первого графика chart_first=list.At(0); chart_first.Print(); //--- Уничтожим список объектов-чартов delete list; done=true; } //--- } //+------------------------------------------------------------------+
Вся логика подробно расписана в коде и в дополнительных пояснениях не нуждается. В любом случае все вопросы можно задать в обсуждении статьи.
Это всё, что мы хотели сделать сегодня.
Скомпилируем советник, откроем в терминале три графика и на первом из них запустим советник, предварительно указав в параметрах "работать только с текущим символом и таймфреймом":
При наступлении первого тика советник создаст три объекта-чарта и выведет в журнал помимо сообщений об инициализации различных классов библиотеки, а также краткие описания созданных трёх объектов-чартов:
Chart window EURUSD H4 ID: 131733844391938630, HWND: 918600 Chart window AUDUSD H1 ID: 131733844391938632, HWND: 1182638 Chart window GBPUSD H4 ID: 131733844391938633, HWND: 1705036
Затем выведет полное описание всех свойств объекта-чарта, описывающего первый график терминала:
============= The beginning of the parameter list (Chart window EURUSD H4) ============= Chart ID: 131733844391938630 Timeframe: H4 Drawing attributes of a price chart: Yes Object "Chart": No Chart on top of other charts: No Accessing the context menu by pressing the right mouse button: Yes Accessing the "Crosshair tool" by pressing the middle mouse button: Yes Scrolling the chart horizontally using the left mouse button: Yes Sending messages about mouse wheel events to all mql5 programs on a chart: No Send notifications of mouse move and mouse click events to all mql5 programs on a chart: No Send a notification of an event of new object creation to all mql5-programs on a chart: No Send a notification of an event of object deletion to all mql5-programs on a chart: No Chart type: Display as Japanese candlesticks Price chart in the foreground: No Price chart indent from the right border: Yes Automatic moving to the right border of the chart: Yes Managing the chart using a keyboard: Yes Allowed to intercept Space and Enter key presses on the chart to activate the quick navigation bar: Yes Scale: 2 Fixed scale mode: No Scale 1:1 mode: No Scale to be specified in points per bar: No Display a symbol ticker in the upper left corner: Yes Display OHLC values in the upper left corner: Yes Display Bid values as a horizontal line in a chart: Yes Display Ask values as a horizontal line in a chart: Yes Display Last values as a horizontal line in a chart: No Display vertical separators between adjacent periods: No Display grid in the chart: No Display volume in the chart: Tick volumes Display textual descriptions of objects: Yes The number of bars on the chart that can be displayed: 96 The total number of chart windows, including indicator subwindows: 1 Chart window handle: 918600 Number of the first visible bar in the chart: 95 Chart width in bars: 117 Chart width in pixels: 466 Chart background color: clrWhite Color of axes, scales and OHLC line: clrBlack Grid color: clrSilver Color of volumes and position opening levels: clrGreen Color for the up bar, shadows and body borders of bull candlesticks: clrBlack Color for the down bar, shadows and body borders of bear candlesticks: clrBlack Line chart color and color of "Doji" Japanese candlesticks: clrBlack Body color of a bull candlestick: clrWhite Body color of a bear candlestick: clrBlack Bid price level color: clrLightSkyBlue Ask price level color: clrCoral Line color of the last executed deal price (Last): clrSilver Color of stop order levels (Stop Loss and Take Profit): clrOrangeRed Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders): Yes Permission to drag trading levels on a chart with a mouse: Yes Showing the time scale on a chart: Yes Showing the price scale on a chart: Yes Showing the "One click trading" panel on a chart: No Chart window is maximized: No Chart window is minimized: No The chart window is docked: Yes The left coordinate of the undocked chart window relative to the virtual screen: 0 The top coordinate of the undocked chart window relative to the virtual screen: 0 The right coordinate of the undocked chart window relative to the virtual screen: 0 The bottom coordinate of the undocked chart window relative to the virtual screen: 0 ------ The size of the zero bar indent from the right border in percents: 18.63 Chart fixed position from the left border in percent value: 0.00 Fixed chart maximum: 1.22650 Fixed chart minimum : 1.17770 Scale in points per bar: 1.00 Chart minimum: 1.17770 Chart maximum: 1.22650 ------ Text of a comment in a chart: "" The name of the Expert Advisor running on the chart: "TestDoEasyPart67" The name of the script running on the chart: "" Symbol: "EURUSD" ============= End of the parameter list (Chart window EURUSD H4) =============
Что дальше
В следующей статье расширим возможности объекта-чарта, создав для него объекты подокон, и создадим коллекцию объектов-чартов
Ниже прикреплены все файлы текущей версии библиотеки и файл тестового советника для MQL5. Их можно скачать и протестировать всё самостоятельно.
Хочу отметить, что использовать объекты-чарты в своих разработках в текущем их состоянии не рекомендуется ввиду дальнейших их изменений.
При возникновении вопросов, замечаний и пожеланий, вы можете озвучить их в комментариях к статье.
*Статьи этой серии:
Работа с ценами в библиотеке DoEasy (Часть 62): Реалтайм-обновление тиковых серий, подготовка к работе со стаканом цен
Работа с ценами в библиотеке DoEasy (Часть 63): Стакан цен, класс абстрактной заявки стакана цен
Работа с ценами в библиотеке DoEasy (Часть 64): Стакан цен, классы объекта-снимка и объекта-серии снимков стакана цен
Работа с ценами и Сигналами в библиотеке DoEasy (Часть 65): Коллекция стаканов и класс для работы с Сигналами MQL5.com
Прочие классы в библиотеке DoEasy (Часть 66): Класс-коллекция Сигналов MQL5.com
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования