Механические Торговые Системы на рынке FOREX. Все для трейдера о Метатрейдер, MQL4 и автоматизации торговли на форексе.
 
тень





  Основной раздел / Статьи /

Статья: Рождение эксперта. Простейший индикатор на MQL4.
Дата опубликования: 2007-12-10
Автор: Смирнов П.В. (www.autoforex.ru)
Источник: www.autoforex.ru

Рождение эксперта. Простейший индикатор на MQL4.

Для того, чтобы научиться самому писать индикаторы на MQL4, необходимо разобраться в том, как происходит построение линий индикатора. Зачем нужны те или иные функции и параметры. Сложного в этом ничего нет, просто надо сесть и попробовать написать свой первый индикатор.

Главное - начать.
Предлагаю начать с самого простого – нарисовать индикатор, который рисует линию, соединяющую цены High баров на графике. Этот, достаточно простой пример, позволит понять принцип построения индикаторов на графике.

Для начала определим специфические параметры индикатора с помощью указателя #property:

#property  copyright "autoforex"
#property  link "http://www.autoforex.ru"

С этими значениями все понятно, они обычно вставляются во все программы MQL4 и не являются обязательными, но лучше их все же вписать в программу (естественно подставляя свои значения). Эти данные нужны лишь для того, чтобы определить автора скомпилированного файла. Сам файл зашифрован и единственное, что можно разобрать в начале этого файла, открыв его в текстовом редакторе, это информацию, описанную в этих двух строчках.

Внешние настройки индикатора.
Далее определяем основные настройки, влияющие на рисование индикатора:

#property  indicator_chart_window

Указываем терминалу, что индикатор необходимо рисовать в том же окне, где и сам график. Для того, чтобы индикатор строился в отдельном окне необходимо заменить эту строку на - #property indicator_separate_window.

Затем, определяем количество буферов для расчета индикатора:

#property  indicator_buffers 1

Или, другими словами - определяем, сколько линий мы будем рисовать на графике. В нашем простейшем случае, это будет одна линия, поэтому нам нужен всего один буфер. В случае, например, с индикатором "Alligator" на графике изображаются три линии – поэтому требуется три буфера и в коде alligator.mq4, который поставляется вместе с MetaTrader 4, вы обнаружите следующую строчку кода: #property indicator_buffers 3.

Далее задаем цвет - Red (красный), которым будет отображаться линия:

#property  indicator_color1  Red

Для каждой линии можно задать свой цвет. В нашем случае будет использована только одна линия для индикатора, поэтому и цвет задаем только для одной - первой линии. В том же alligator.mq4 цвет линий задан следующим образом:

#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Lime

Три линии – три цвета.

Далее определяем толщину линии:

#property  indicator_width1 2

Здесь мы задаем толщину линии индикатора равную 2. Теперь линия под номером один будет изображаться на графике толщиной равной 2.

Затем определяем стиль рисования линии:

#property  indicator_style1 0

Стиль рисования линии 0 – простая линия. Можно выбрать из пяти различных стилей – пунктирная линия, штрихпунктирная и др. Заметьте, что различные стили рисования линии можно применять только в том случае, если ширина данной линии равна единице. Если ширина линии больше единицы, то терминал позволяет рисовать только сплошной линией. Поэтому в нашем случае, т.к. выбрана толщина линии 2 пикселя, мы ставим нулевой стиль. Поставь мы другой стиль, наш индикатор все равно будет нарисован простой линией.

Это были основные настройки индикатора, которые чаще всего используются. Если эти параметры не прописать в коде программы, то при наложении индикатора на график появится окно, в котором будет предложено выбрать цвет и толщину линии, а так же другие внешние настройки индикатора, в том числе и стиль линии.

Если внешние значения индикатора прописать в коде программы, как это сделали мы для цвета, толщины линии и стиля рисования, то при наложении индикатора на график так же появится окно с настройками. Но в окне уже будут выбраны соответствующие цвет толщина линии и стиль ее рисования, поэтому останется лишь подтвердить выбор, нажав "ОК". Это существенно экономит время даже в нашем, простейшем случае, я уже не говорю об индикаторах, в которых отображаются все восемь линий.

Затем, в программе идет объявление массива Buffer1[]:

double     Buffer1[];

Именно этот массив мы свяжем с нашей линией индикатора. Поскольку наша линия в коде фигурирует под номером один, то и название для массива, мы выбрали соответствующее.

Для чего нужен этот массив. Этот массив мы, с помощью функции SetIndexBuffer(), свяжем с предопределенным буфером индикатора. И затем, чтобы нарисовать линию на графике, мы просто запишем в массив Buffer1[] соответствующие значения для данной линии. А терминал, воспринимая наш массив Buffer1[], как массив со значениями, которые следует отобразить на графике, нарисует линию. И любые изменения в массиве Buffer1[] будут отображаться на графике.

Инициализация.
Далее в коде следует функция инициализации индикатора:

int init()
  {
   SetIndexBuffer(0,Buffer1);
   SetIndexStyle(0,DRAW_LINE);
   return(0);
  }

Функция init() – функция инициализации, в данном случае индикатора, вызывается один раз при наложении индикатора на график. Внутри этой функции производят настройку индикатора – выполняют операции, которые необходимо выполнить один раз до запуска индикатора.

SetIndexBuffer(0,Buffer1); - как упоминалось ранее, эта функция связывает массив Buffer1[] с нулевым буфером индикатора. Всего буферов – 8 (считая с 0 до 7), т.е. с помощью одного индикатора можно нарисовать на графике восемь линий. Но т.к. в нашем случае отображается всего лишь одна линия, то нам требуется только один буфер – буфер номер 0. Теперь, чтобы записать информацию в нулевой буфер, тем самым, отобразив ее на графике, необходимо записать ее в массив Buffer1[].

SetIndexStyle(0,DRAW_LINE); - устанавливаем новый тип, стиль, ширину и цвет для линии индикатора (нулевой буфер индикатора). Первый параметр, равный 0 - номер буфера линии. Второй параметр, равный DRAW_LINE задает тип рисования линии. В нашем случае – простая линия. Третий, четвертый и пятый параметры этой функции – необязательные параметры. С их помощью можно изменить стиль, толщину и цвет отображения линии соответственно. В нашем случае в этом нет необходимости, т.к. нужные нам значения уже определены в начале программы с помощью инструкций #property и поэтому эти параметры отсутствуют в вызове функции SetIndexStyle().

return(0); – завершаем выполнение функции init();

Индикатор.
Теперь переходим к самому главному – рисованию линии индикатора на графике. Давайте, для начала соединим значения High первых семи баров на графике, при этом полный код индикатора примет вид:

#property  copyright "autoforex"
#property  link      "http://www.autoforex.ru"

#property  indicator_chart_window
#property  indicator_buffers 1
#property  indicator_color1  Red
#property  indicator_width1 2
#property  indicator_style1 0

double     Buffer1[];

int init()
  {
   SetIndexBuffer(0,Buffer1);
   SetIndexStyle(0,DRAW_LINE);
   return(0);
  }

int start()
  {
         Buffer1[0]=High[0];
         Buffer1[1]=High[1];
         Buffer1[2]=High[2];
         Buffer1[3]=High[3];
         Buffer1[4]=High[4];
         Buffer1[5]=High[5];
         Buffer1[6]=High[6];
         Buffer1[7]=High[7];
         Buffer1[8]=High[8];

         return(0);
  }

Вот что мы получим в результате, когда прикрепим индикатор к графику:

Построение индикатора на графике
Рис.1 Результат построения индикатора на графике EUR/USD D1

На рисунке представлен наш индикатор, который нарисован по следующим значениям:

Buffer1[0]=1.4767
Buffer1[1]=1.4707
Buffer1[2]=1.4784
Buffer1[3]=1.4842
Buffer1[4]=1.4857
Buffer1[5]=1.4906
Buffer1[6]=1.4886
Buffer1[7]=1.4966
Buffer1[8]=1.4872
Buffer1[9]=Empty_Value
Buffer1[10]=Empty_Value
и т.д.

Как видите, первые девять баров в точках High, начиная с нулевого, соединены линией индикатора.

Массив Buffer1[].
Несколько слов по поводу размера массива Buffer1[]. Размер массива Buffer1[] равняется количеству баров на текущем графике (т.е. на том, на котором находится индикатор). И, соответственно, совпадает со значением предопределенной переменной Bars. Если, например, у вас на текущем графике 56300 минутных баров, и вы запускаете индикатор на этом графике, то размер массива Buffer1[] будет равен 56300 ячеек. Это также означает, что на этом графике мы сможем построить линию состоящую из 56300 точек.

В нашем простейшем случае мы определили значения первых девяти точек нашего индикатора, поэтому они были построены на графике. Все остальные ячейки массива Buffer1[], по умолчанию, принимают значение равное EMPTY_VALUE (значение пустой величины). Пустые значения не рисуются на графике, вот почему мы видим линию индикатора только до восьмого бара. Все остальные значения индикатора равны пустому значению EMPTY_VALUE и не отображаются на графике.

Построение индикатора.
Теперь давайте разберемся, как происходит построение индикатора на графике.
Мы скомпилировали наш индикатор и наложили его на график, например, EUR/USD H1 для которого уже загружено, например, 674 бара (цифра взята из головы, просто для демонстрации примера).

При этом произойдет следующее:

Будет создан массив Buffer1[] размером 674 ячейки, во все ячейки по умолчанию запишется значение EMPTY_VALUE. Затем выполнится функция start() и в ней первым девяти ячейкам массива Buffer1[] будут присвоены определенные значения цен, которые и отобразятся в виде индикатора на графике.

С приходом нового тика, продолжающего формировать нулевой бар, будет выполнена функция start(). И снова в ней первым девяти ячейкам массива Buffer1[] будут присвоены те же самые значения цен, которые уже записаны в этом массиве (т.к. бары на графике не изменились и значения High этих баров так же не изменились). Исключение составляет лишь нулевая ячейка массива – Buffer[0]. В нее будет записано новое значение величины High нулевого бара (если, конечно, оно изменилось с приходом нового тика).

Получается, что большинство точек индикатора не нуждаются в пересчете и перерисовке. Для того, чтобы оптимизировать построение индикатора, пользуются функцией IndicatorCounted(), … но об этом в другой статье.

Появление нового бара на графике.
Теперь, давайте разберем ситуацию, когда с приходом нового тика начинает формироваться новый бар. В этом случае новый бар, который выглядит как черточка, автоматически становится нулевым баром, а тот, что был нулевым – становится теперь первым, и таким образом смещается вся нумерация баров. При этом значение переменной Bars увеличивается на 1 и становится равной 675, и размер массива Buffer1[] также увеличивается на 1 и тоже становится равным 675.

Кроме того, что размер массива Buffer1[] увеличивается на единицу, все значения хранимые в нем смещаются на одну ячейку – то, что раньше хранилось в ячейке Buffer1[0], копируется в ячейку Buffer1[1], то, что раньше хранилось в Buffer1[1] копируется в Buffer1[2] и т.д. Из ячейки Buffer1[8] значение копируется в Buffer1[9]. Более наглядно этот процесс показан на рисунках:

Построение индикатора на графике
Рис.2 Так выглядит график до прихода нового тика формирующего новый бар.

Построение индикатора на графике
Рис.3 Так выглядит график после прихода тика, который начинает формировать новый бар.

Все эти смещения нумераций и перемещения данных в массиве Buffer1[] происходят в автоматическом режиме. После этого начинает выполняться функция start() индикатора. В ней происходит присвоение значений первым девяти ячейкам массива Buffer1[]. Таким образом, первые девять точек индикатора (Buffer1[0] – Buffer1[8]) будут заново определены. Но, т.к. в результате смещения нумерации баров в ячейку Buffer1[9] уже скопировано значение из ячейки Buffer1[8], то наш индикатор будет уже состоять из десяти точек соединенных линией.

Таким образом, при появлении новых баров, линия нашего индикатора будет удлиняться, включая в наш индикатор новые бары.

Функцию start() можно значительно сократить и записать так:

int start()
  {
    Buffer1[0]=High[0];
    return(0);
  }

Такой индикатор будет соединять линией цены High всех вновь появляющихся баров, в реальном времени.

Индикатор на весь график.
Для того чтобы построить линию на протяжении всего графика, а не только на первых или появляющихся в реальном времени барах, нужно воспользоваться циклом и присвоить все необходимые значения соответствующим ячейкам массива Buffer1[]. Для этого перепишем функцию start() следующим образом:

int start()
  {
   for(int i=0;i<Bars;i++)
   {
      Buffer1[i]=High[i];
   }
   return(0);
  }

В данном случае мы перебираем все бары от 0 до Bars-1 и присваиваем ячейкам массива Buffer1[] значения High соответствующего бара. При этом линия индикатора будет нарисована на протяжении всего ценового графика.

Наш индикатор выглядит теперь так:

#property  copyright "autoforex"
#property  link      "http://www.autoforex.ru"

#property  indicator_chart_window
#property  indicator_buffers 1
#property  indicator_color1  Red
#property  indicator_width1 2
#property  indicator_style1 0

double     Buffer1[];

int init()
  {
   SetIndexBuffer(0,Buffer1);
   SetIndexStyle(0,DRAW_LINE);
   return(0);
  }
int start()
  {
   for(int i=0;i<Bars;i++)
   {
      Buffer1[i]=High[i];
   }
   return(0);
  }

Вот, в принципе, и все. Простейший индикатор построен и теперь, вы можете поэкспериментировать с настройками и параметрами, влияющими на рисование индикатора.

Продолжение следует …

С Уважением.
Смирнов П.В.




Данная статья написана специально для сайта www.autoforex.ru и является интеллектуальной собственностью ее автора. Копирование данной статьи и размещение ее в Интернете разрешается только с сохранением всех ссылок, находящихся в тексте, и указанием первоисточника. Спасибо за понимание.
Хотите быть в курсе всех обновлений на сайте, подпишитесь на рассылку новостей сайта:
Рассылки Subscribe.Ru

FxMail.ru
Новости сайта autoforex
Свежий номер журнала Forex Magazine:
бесплатно !!!





  Copyright © 2007-2012 Павел Смирнов
При использовании материалов сайта ссылка на www.autoforex.ru обязательна.
 
   

Яндекс цитирования Рейтинг@Mail.ru Rambler's Top100