Учебник по MQL4 Стандартные функции Графические объекты
Как известно, индикатор MACD часто используется трейдерами для формирования торговых критериев. Индикатор представлен двумя линиями - главной и сигнальной. Считается, что торговый критерий срабатывает в момент пересечения указанных линий. Если главная линия индикатора (обычно серая гистограмма) пересекает сверху вниз сигнальную линию (обычно красную пунктирную), то нужно продавать, а если снизу вверх, - то покупать. В промежутках между пересечениями линий индикатора необходимо удерживать рыночные ордера, а в момент срабатывания противоположного критерия зарывать их и одновременно открывать новые в противоположном направлении. Таким образом, необходимо подготовить 4 вида сообщения: открытие Buy, открытие Sell, удержание Buy и удержание Sell. В данной задаче все сообщения являются взаимоисключающими, т.е. невозможна ситуация, при которой возникает необходимость вывести на экран одновременно два или более сообщений. Поэтому в данном случае можно использовать всего один графический объект, постоянно присутствующий на экране, и по мере необходимости изменять выводимый текст. Отобразим объект в правом верхнем углу окна финансового инструмента, в котором будет работать эксперт. Поскольку положение объекта по ходу торгов менять не предполагается, то удобно использовать объект типа OBJ_LABEL, т.к. он позиционируется относительно окна финансового инструмента. В качестве решения Задачи 32 рассмотрим эксперт grafobjects.mq4, использующий графический объект OBJ_LABEL: //-------------------------------------------------------------------- В блоке 1-2 эксперта определены переменные, в частности, заданы значения элементов массивов Text[] и Color[], которые в дальнейшем используются для изменения свойств объекта. В блоке 2-3 создаётся объект, и устанавливаются значения некоторых его свойств. Разберём это блок подробно. Согласно этой строки кода эксперта в окне финансового инструмента, в котором исполняется эксперт, создаётся графический объект: ObjectCreate("Label_Obj_MACD", OBJ_LABEL, 0, 0, 0);// Создание объ. Значение "Label_Obj_MACD" указывает, что объекту назначено такое имя (имя создаваемому объекту присваивает программист по своему усмотрению). OBJ_LABEL - идентификатор типа объекта, указывает, что создаваемый объект будет иметь такой тип (выбирается из списка возможных типов). Первый из трёх последующих нолей указывает, что объект создаётся в основном окне (основное окно, где отображается ценовой график, всегда имеет индекс 0). Следующие два ноля устанавливают для создаваемого объекта координаты, в соответствии с которыми объект должен быть отображён в указанном окне. В данном конкретном случае создаётся объект OBJ_LABEL, который не использует координаты цены и времени. Обратите внимание, в описании функции ObjectCreate() указываются только координаты цены и времени. Причём, для второй и третьей пары координат имеются умолчательные значения, в то время как для первой пары координат умолчательных значений нет. Это значит, что несмотря на то что для объекта OBJ_LABEL вообще не требуются координаты цены и времени, в вызове функции ObjectCreate() должны быть указаны какие-то значения. В данном случае указаны нули, можно было бы указать другие значения, но и в том и в другом случае они всё равно игнорируются при установлении свойств объекта OBJ_LABEL. В последующих трёх строках программы (ранее созданному) объекту с именем Label_Obj_MACD устанавливаются значения для некоторых его свойств: ObjectSet("Label_Obj_MACD", OBJPROP_CORNER, 1); // Привязка угол Для угла привязки (OBJPROP_CORNER) устанавливается значение 1, что означает привязку к правому верхнему углу (ранее определённого основного) окна финансового инструмента. В следующих двух строках устанавливаются значения дистанции в пикселях от объекта до угла привязки: по горизонтали (OBJPROP_XDISTANCE) 10 пикселей и по вертикали (OBJPROP_YDISTANCE) 15 пикселей. На этой стадии исполнения программы объект создан, имеет уникальное имя и определены его основные свойства. Для того чтобы объект отобразил нужный текст, сначала необходимо вычислить каким этот текст должен быть. Для этого сначала в блоке 3-4 определяется взаимное положение индикаторных линий индикатора MACD на текущем и предыдущем барах, а затем в блоке 4-5 вычисляется значение Sit, соответствующее текущей ситуации (см. также Рис. 107 и callstohastic.mq4) В следующей строке определяются свойства объекта в зависимости от сложившейся ситуации: // Изменение свойств объекта В результате исполнения функции ObjectSetText() объекту с именем Label_Obj_MACD назначается текстовое описание, а именно значение строковой переменной Text[Sit]. Это значение для разных ситуаций будет различным в зависимости от значения переменной Sit. Например, если главная линия пересекла сигнальную сверху вниз, то в блоке 4-5 переменная Sit получит значение 1, в результате чего графическому объекту будет назначено текстовое описание, содержащееся в элементе массива Text[1], а именно "Открытие Sell". Следующие параметры: 10, "Arial" и Color[Sit] указывают размер, название и цвет шрифта для текстового описания. В результате исполнения эксперта в окне финансового инструмента EURUSD можно наблюдать следующее:
На Рис. 137 видно, что в окне финансового инструмента имеется также подокно индикатора MACD. Нужно заметить, что для полноценной работы эксперта наличие этого индикатора в окне финансового инструмента не требуется, т.к. вычисление торговых критериев в эксперте происходит в результате исполнения функции технического индикатора, не связанной с выводом индикатора на экран. Здесь индикатор показан только для того, чтобы можно было визуально определить момент срабатывания торгового критерия и вывод необходимого для этого случая текстового описания графического объекта. Эксперт будет работать аналогично и при всех других сочетаниях взаимного положения индикаторных линий, всякий раз отображая описание, соответствующее ситуации. Удаление графических объектовРассмотренный выше эксперт grafobjects.mq4 имеет небольшой недостаток. По окончании работы эксперта в окне финансового инструмента останется графический объект (при этом его свойства будут такими, какими они были на момент последнего изменения). Графические объекты самопроизвольно не удаляются. По мере развития торгов, начиная с некоторого момента, надпись Открытие Sell уже не будет соответствовать действительности. Чтобы не вводить пользователя в заблуждение, графический объект нужно удалить. Для удаления любого графического объекта (независимо от способа его создания - вручную или программно) достаточно выделить его и нажать клавишу Delete. Однако, говоря о программировании, следует подчеркнуть, что правильно составленная программа обязательно должна "почистить" после себя окно финансового инструмента. Иными словами, в программе должен быть предусмотрен блок, в котором удаляются все созданные программой графические объекты. Функция ObjectDelete()bool ObjectDelete(string name) Удаление объекта с указанным именем. При успешном удалении функция возвращает TRUE, иначе FALSE. Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError(). Параметры:
Использование функции ObjectDelete() крайне просто: достаточно указать имя удаляемого объекта. Для того чтобы устранить недоработку, допущенную в предыдущем примере, достаточно дополнить эксперт grafobjects.mq4 специальной функцией deinit(), в которой и указать функцию удаления объекта: //--------------------------------------------------------------- 7 -- При исполнении эксперта, дополненного функцией deinit() с таким кодом, объект с именем Label_Obj_MACD будет удалён. В общем случае программа может создавать множество объектов. Каждый из них может быть удалён программно в соответствии с алгоритмом. Модификация графических объектовВ ряде случаев требуется программно изменить положение объекта в окне финансового инструмента. Чаще всего такая необходимость возникает по причине появления новых баров. Например, торговые критерии в эксперте могут формироваться на основе канала линейной регрессии, построенного на баровой истории определённой длительности (например, по последним 50 барам). Если графический объект "канал линейной регрессии" просто отобразить в окне финансового инструмента и в дальнейшем не предпринимать никаких мер, то он всё время будет оставаться в том месте ценового графика, где был установлен, и с появлением новых баров будет смещаться влево вместе с историческими барами. Для того, чтобы этот графический объект не "съезжал", его необходимо перерисовывать на каждом новом баре. Для этой цели необходимо вычислить и сообщить объекту новые координаты, в соответствии с которыми объект должен быть отображён в окне финансового инструмента. Для того, чтобы узнать какие свойства имеются у графического объекта на текущий момент, необходимо использовать функцию: Функция ObjectGet()double ObjectGet(string name, int prop_id) Функция возвращает значение указанного свойства объекта. Для получения информации об ошибке необходимо вызвать функцию GetLastError(). Параметры:
Сообщение новых координат объекту осуществляется с помощью функции ObjectMove(). Функция ObjectMove()bool ObjectMove(string name, int point, datetime time1, double price1) Изменение одной из координат объекта на графике. Функция возвращает TRUE в случае успеха, иначе FALSE. Для получения дополнительной информации об ошибке необходимо вызвать функцию GetLastError(). Нумерация координат объекта начинается с 0. Параметры:
Графический объект "канал линейной регрессии" использует две координаты времени. Координаты цены (если они были назначены в программе) при построении этого объекта клиентским терминалом игнорируются. Канал линейной регрессии вычисляется клиентским терминалом на основе исторических цен и по своей сути не может быть отображён в стороне от ценового графика. Поэтому отсутствие привязки этого объекта по цене (игнорирование координат цены терминалом) является собственным неизменным свойством этого объекта. Эксперт (moveobjects.mq4), управляющий положением графического объекта может быть составлен так: //-------------------------------------------------------------------- Алгоритм эксперта moveobjects.mq4 предполагает, что однажды выставленный графический объект будет оставаться на экране в течение всего времени исполнения программы. В подобных случаях имеет смысл использовать в программе пользовательскую функцию (здесь это функция Create(), блок 6-7) для создания объекта и обращаться к ней из программы по мере необходимости. Для отображения объекта необходимы две координаты времени (Т1 - координата левой границы объекта и Т2 - координата правой границы): datetime T1 = Time[Len_Cn-1]; // Определение 1 коорд времени В данном примере правая граница графического объекта должна всегда находиться на нулевом баре, поэтому значение второй координаты совпадает со временем открытия нулевого бара. Левая координата вычисляется в зависимости от заданного пользователем количества баров (внешняя переменная Len_Cn) и определяется как время открытия бара с соответствующим индексом. Например, если длина канала составляет 50 баров, то левая координата объекта будет равна времени открытия бара с индексом 49. В следующих строках пользовательской функции Create() с помощью ObjectCreate() создаётся объект OBJ_REGRESSION, и с помощью ObjectSet() созданный объект наделяется необходимыми свойствами (заданный пользователем во внешней переменной цвет, запрещено рисовать объект как луч, стиль линии - пунктирная). В строке: ObjectSetText("Obj_Reg_Ch","Создан экспертом moveobjects",10); объекту сообщается текстовое описание. В отличие от ранее рассмотренного объекта OBJ_LABEL, текстовое описание объекта OBJ_REGRESSION не выводится на экран. Текстовое описание графических объектов можно увидеть на панели свойств объектов. Это очень удобно использовать во время практической работы для того, чтобы отличить объекты, созданные программой, от объектов, выставленных пользователем вручную:
В программе используется ещё одна функция, с помощью которой перерисовывается текущий график: WindowRedraw(); // Перерисовка изображения Функция WindowRedraw()void WindowRedraw() Функция принудительно перерисовывает текущий график. Обычно применяется после изменения свойств объектов. Обычный порядок отображения графических объектов клиентским терминалом предусматривает фактическое изменение изображения в момент поступления нового тика. Поэтому, если не использовать WindowRedraw(), то изменения свойств объекта становятся видимы пользователю на следующем тике, т.е. процесс отображения постоянно запаздывает на один тик. Использование WindowRedraw() позволяет принудительно перерисовать все объекты в нужный момент, например, сразу после изменения свойств объектов. В общем случае, если в программе изменяются свойства нескольких объектов, то функцию WindowRedraw() достаточно использовать один раз, после изменения свойств последнего из объектов. Первое обращение к пользовательской функции осуществляется из специальной функции init(). В момент прикрепления эксперта к окну финансового инструмента начнётся исполнение init(), в результате чего графический объект "канал линейной регрессии" отобразится в окне финансового инструмента. В функции start() рассматривается две возможных ситуации: когда объект случайно удалён пользователем (блок 3-4) и когда объект необходимо переместить вправо при образовании нового нулевого бара (блок 4-5). Для того чтобы определить, существует ли вообще графический объект на текущий момент, достаточно запросить значение одной из его координат. Если объект существует, то функция ObjectGet() вернёт некоторое значение, соответствующее запрошенной координате, а функция GetLastError() вернёт нулевое значение (т.е. при запросе координаты ошибка не возникла). Если же объекта с заданным именем в окне финансового инструмента нет, то функция GetLastError() вернёт код ошибки 4202, т.е. объект не существует: T2=ObjectGet("Obj_Reg_Ch",OBJPROP_TIME2); // Запрос коорд. t2 Если анализ ошибки показал, что объекта нет, значит его надо вновь создать, уведомив пользователя о недопустимых действиях (программа не удаляет объект в процессе работы, значит объект удалён пользователем). Поэтому после вывода сообщения в программе выполняется обращение к ранее рассмотренной пользовательской функции Create(), в результате чего объект снова создаётся в окне финансового инструмента. К моменту, когда исполняется следующий блок (4-5), графический объект обязательно присутствует. Чтобы решить, надо ли его двигать, следует знать, каково положение объекта на текущий момент. Для этого достаточно проанализировать (ранее полученное) значение первой координаты объекта, и если это значение не совпадает со временем открытия нулевого бара, то сообщить объекту новые координаты. Изменение координат объекта осуществляется с помощью функции ObjectMove(): ObjectMove("Obj_Reg_Ch", 0, Time[Len_Cn-1],0); //Новая коорд. t1 Здесь объекту с именем Obj_Reg_Ch для первой координаты (координата 0) устанавливается значение Time[Len_Cn-1], а для второй координаты (координата 1) -Time[0]. Последним среди передаваемых в функцию ObjectMove() параметров указан 0. Это - координата цены, которую в соответствии с описанием функции передавать необходимо, но которое в данном случае будет проигнорировано клиентским терминалом. В результате исполнения этих строк свойства указанного графического объекта будут изменены, а в результате последующего исполнения функции WindowRedraw() графический объект будет принудительно перерисован клиентским терминалом - теперь уже соответственно новым значениям координат. Таким образом, при исполнении функции start() графический объект "канал линейной регрессии" будет перерисовываться клиентским терминалом всякий раз при образовании нового бара, на первом же его тике (см. рис. 139). По окончании выполнения эксперта в окне финансового инструмента, в момент исполнения специальной функции deinit(), указанный объект будет удалён (т.е. программа "подметёт" после работы своё рабочее место).
В общем случае можно создавать и удалять графические объекты в зависимости от некоторых вычисленных в программе условий. Можно отображать линии поддержки и сопротивления (OBJ_TREND), вертикальными линиями (OBJ_VLINE) отмечать время приближающихся значительных событий, текстовыми объектами (OBJ_LABEL и OBJ_TEXT) указывать пересечения различных линий, прогнозируемое направление движения цены и т.д. Отдельно нужно заметить, что в ряде случаев использование графических объектов не требуется. Например, если есть необходимость вывести на экран множество простых однотипных изображений (например, стрелки), то для этого можно воспользоваться индикаторными линиями, соответствующим образом настроив стиль линий. Такой подход избавит от необходимости отслеживать в программе множество координат объектов и предотвратит возможность случайного удаления изображения (значки, отображающие индикаторные линии, невозможно ни выделить, ни удалить). Функции для работы с графическими объектами
Для получения подробного описания этих и других функций необходимо обратиться к справочной документации на MQL4.community, сайте MetaQuotes Ltd. или к разделу "Справка" в редакторе MetaEditor. |