Перейти к содержанию
Форекс Форум трейдеров Академии «MasterForex-V»

Создание индикаторов


Рекомендуемые сообщения

В этой ветке мы будем создавать индикаторы... разные... нужные!

 

Для начала я предлагаю создать индикаторы для ТС Сидуса. Имеется приличная ветка форума ("Система Сидуса"), посвящённая этой системе, вот ей в помощь мы и начнём работать.

 

Для создания индикатора нужно сначала немного продумать нашу стратегию.

В ТС Сидуса используются четыре мувинга - значит будет 4 линии, затем для каждой линии нужно определить период и цвет.

Итак, у нас будут четыре внешних (extern) переменных и четыре цвета линий.

 

Открыть редактор вы сможете теми же способами, которые были описаны в "Создание библиотек". Таким же способом, как там указано, вы создадите новый индикатор, только в приглашающем окне нужно будет:

  1. выбрать опцию "Пользовательский индикатор"
  2. указать наименование индикатора, например, "Индикатор Сидуса"
  3. определить все переменные
    Для этого на следующей странице окна нужно определить их:
    http://forex.orotukan.ru/images/new03.jpg
    Как вы видите, я определил четыре внешних переменных (или 4 входных параметра индикатора) со значениями по умолчанию 5, 12, 18, 28. В готовом индикаторе эти параметры каждый пользователь сможет менять соглано его собственной стратегии.
  4. определить количество и цвет линий
    Переходим "Далее" и определяем количество и цвет линий индикатора:
    http://forex.orotukan.ru/images/new04.jpg
    Обратите внимание, что бы не стояла галочка у "Индикатор в отдельном окне" (обведено красным), т.к. сам индикатор должен накладываться на график цен.

После нажатия кнопки "Готово" редактор создаст файл индикатора и откроет его для редактирования.

Вы можете видеть, что основа модуля уже создана: имеются определения линий препроцессора (т.е. то, что будет обработано ещё перед компилляцией), имеются объявления и назначения внешних параметров и объявление массивов-линий, имеется функции init() и start(). Нам остаётся только сделать расчёт значений линий и назначений этих данных в массивы-линии.

Расчёты делаются для каждого бара, присутствуюшего на графике. Для чего в цикле мы будем проходить все бары. В виду того, что в MQL отсутствуют условные циклы, мы будем пользоваться безусловным циклом for():

MQL
for(int i=Bars-1; i>=0; i--) {

 // вычисления

}

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

 

А теперь маленькое отступление. Если с приходом каждого тика будут проходиться в цикле все бары графика, то это может создать "неплохие" тормоза в работе терминала. Для одного графика это ещё не очень заметно, но для нескольких графиках на разных валютных парах терминал начинает серьёзно тормозить!

К счастью, разработчики MQL об этом подумали. Имеется встроенная функция IndicatorCounted(), которая будет выдавать только то количество баров, которые неизменились после последнего тика. Получается, что при каждом тике надо будет пересчитать и перерисовать только 1 бар - последний. Кстати, мастер создания модуля сразу подготовил именно эту функцию и вы можете её увидеть в функции start().

Теперь наш цикл будет выглядеть так:

MQL
int start() {

 int counted_bars=IndicatorCounted();

 for(int i=counted_bars;i>=0;i--){

  /* вычисления */

 }

 return(0);

}

Изменено пользователем Liv
Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 159
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Privet..

Tak kak okonchatelnaya versiya TS Sidiusa poterpela dovolno bolshix izmeneniy(muvingi 5,8,18,28 bolshe ne ispolzuyutsa) porabotat nad indikatorom kotoriy budet vsebe soderjat samie poslednie dorobotki TS Sidiusa..

Rad budu v etom vam pomaqat i samomu uchitsa... :blush:

Ссылка на комментарий
Поделиться на другие сайты

Теперь, когда всё готово мы займёмся кодингом - собственно написанием исходного кода программы.

 

Сразу же некоторые правила написания программ на языке MQL.

  1. в программе нет переносов строк и операционная строка должна заканчиваться точкой с запятой (;)
    Вот два фрагмента программы,
    вот:
    MQL
    if (a==ДвижениеВверх) Событие=МожноПокупать;

    и вот:
    MQL
    if (
    a ==
    ДвижениеВверх
    )
    Событие=МожноПокупать;

    Казалось бы имеется огромная видимая разница! Но, на самом деле никакой разницы в этих двух фрагментах нет, они совершенно идентичны и будут одинаково работать. В первом варианте всё написано одной строкой и заканчивается кроме точки с запятой ещё и переносом строки. Во втором варианте имеется куча переносов строк... но, как я говорил ранее, перенос строк в программе MQL не имеет значения (за некотороми исключениями) и здесь операционную строку закрывает точка с запятой, что мы и видим во втором варианте.
  2. исходя из первого, желательно делать отступы так, чтобы было удобно читать программу. Вот два вида расстановки операционных скобок:
    MQL
    /* так я привык расставлять скобки */
    if (Событие==МожноПокупать) {
     OpenOrder();
    }
    /* так предлагает редактор */
    if (Событие==МожноПокупать)
     {
    OpenOrder();
     }

    Оба вида совершенно идентичны в работе, но я давно пишу и привык именно к такой расстановке скобок, а вы может будете использовать другой... или сами свой придумаете! Главное, не лепить всё в кучу, а писать так, чтобы и через года можно было без труда прочитать вашу программу.
  3. обязательно коментируйте свои программы, чтобы и через года вы легко в них разобрались.
    Есть два вида коментариев:

    1. строчный начинается с двух наклонных // и до конца строки - здесь действует перенос строки
    2. многострочный начинается с комбинации наклонная+звёздочка /* и до следующей комбинации звёздочка+наклонная */

[*]операционные скобки не требуют точки с запятой

Как я ранее говорил, фигурные скобки являются операционными скобками и всё, что находится внутри них - есть единый блок выполнения.

Примеры:

MQL
/*

здесь открывается операционная скобка ЕСЛИ

и до тех пор, пока она не будет закрыта

будут выполняться инструкции, заключённые

внутри скобок */

if (a==ДвижениеВверх) {

 Событие=МожноПокупать;

 for (int i=0; i<=10; i++) {

Проба();

 } // здесь не обязательно ставить точку с запятой

} // здесь тоже не обязательно, хотя ошибки не будет

/* и только после закрытия сработает слудующая операция */

Событие=МожноПродавать;

/* здесь операционными скобками ограничена функция */

void Проба() {

 Событие=0;

} // здесь тоже нет....

/* всё, что будет далее никак не войдёт в саму функцию */

[*]для нормального чтения программы желательно делать отступы. Редактор сам автоматически делает отступ по предыдущему, чем упрощается написание кода. Можно пользоваться пробелами или символами табуляции, нажимая клавишу TAB. В настройках редакторая есть установка как делать эти отступы при нажатии клавиши TAB (символы табуляции или пробела, количество символов отступа).

Остальное вы быстро освоите в процессе написания программ.

 

  aura сказал:

Privet..

Tak kak okonchatelnaya versiya TS Sidiusa poterpela dovolno bolshix izmeneniy(muvingi 5,8,18,28 bolshe ne ispolzuyutsa) porabotat nad indikatorom kotoriy budet vsebe soderjat samie poslednie dorobotki TS Sidiusa..

Rad budu v etom vam pomaqat i samomu uchitsa... :blush:

Для учёбы и создана эта ветка.... присоединяйтесь к работе. :smile:

 

Ну, а мы сначала сделаем инидикатор под стандартный "Сидус".... тем более что переделать под новую модификацию после этого нам не составит труда. Верно? :blush:

Ссылка на комментарий
Поделиться на другие сайты

После того, как мы определили цикл, начинаем делать расчёты внутри цикла. Расчёт мувинга (скользящего среднего) будет делаться с помощью встроенной функции iMA.

Не обязательно запоминать полностью написание всех параметров функций, - достаточно запомнить только написание имени функции. Уже при написании имени функции редактор предложит вам список, из которого вы сможете выбрать нужное слово. Пишем её, выделяем и нажимаем F1. Откроется окно подсказки, где вы увидите полностью расписанную функцию со всеми параметрами.

http://forex.orotukan.ru/images/new05.jpg

У редактора очень хороший хелп (помощь, справка) и вы всегда сможете быстро найти нужный раздел, стоит только выделить ключевое слово и нажать клавишу F1. И даже если вы не помните написание той или иной функции, то и тут есть удобный выход: нужно запомнить как пишется всего одна функция из каждой группы, после чего достаточно будет написать её, выделить и нажать клавишу F1. Откроется описание самой функции, а слева (выделено красным) будет список всех функций в группе. Чтобы мне больше не возвращаться к теме хелпа по языку MQL, предлагаю вам самостоятельно покопаться в этом замечательном справочнике.

 

Ну, а мы вернёмся к нашим расчётам:

MQL
ExtMapBuffer1=iMA(NULL,0,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,i);

где параметры:

  • NULL - обозначает, что мы не будем конкретизировать инструмент, по которому считается эта средняя, а будет использован тот, который установлен на графике. Первое время я прописывал здесь используемый инструмент. А однажды никак не мог понять почему линия показвает полную билиберду! Только после я понял, что на график с фунто-йеной воткнул расчёт евро-бакса! :biggrin: После чего, на подобных расчётах у меня всегда свободный выбор.
  • 0 - мы не конкретизируем таймфрэйм.
  • ПервыйПериод - внешний параметр, определённый у нас в начале модуля
  • 0 - обойдёмся без сдвига.
  • MODE_SMA - встроенная константа выбора метода усреднения, хорошо описаная в хелпе. В данном случае мы применяем "простое скользящее среднее".
  • PRICE_CLOSE - встроенная константа выбора используемой цены. Здесь мы указываем, что будет цена закрытия.
  • i - наша переменная цикла, указывающая текущий бар.

Точно так же делаем расчёт остальных линий.

MQL
ExtMapBuffer1=iMA(NULL,0,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,i);

ExtMapBuffer2=iMA(NULL,0,ВторойПериод,0,MODE_SMA,PRICE_CLOSE,i);

ExtMapBuffer3=iMA(NULL,0,ТретийПериод,0,MODE_SMA,PRICE_CLOSE,i);

ExtMapBuffer4=iMA(NULL,0,ЧетвертыйПериод,0,MODE_SMA,PRICE_CLOSE,i);

Как вы уже наверное поняли, массивы ExtMapBuffer1-4 - это и есть собственно линии. Сами массивы были связаны с вычерчиванием линий в функции начальной загрузки init() с помощью функции SetIndexBuffer. Предоставляю вам самим разобраться с назначением и использованием этой функции.

 

Вот и всё! Наш индикатор готов. Остаётся только сохраниться (меню "Файл" -> "Сохранить Ctrl+S") и нажать кнопку "Компилировать". Если в синтаксисе вашего модуля всё впорядке, то ошибок компиляции не будет и должны появиться две строчки:

 

Компиляция "Индикатор Сидуса.mq4"...

0 ошибок, 0 предупреждений

 

После этого можно кидать ваш индикатор на график и наслаждаться сразу четырьмя линиями "одним движением" :biggrin:

Ссылка на комментарий
Поделиться на другие сайты

Я удивлён, что никто не задал вопроса! Никто не учится здесь и сейчас? Если есть те, кто хочет научиться, то пусть скажут мне одну не очень приятную особенность написанного нами индикатора....

Жду ещё 1 день.

Ссылка на комментарий
Поделиться на другие сайты

мы учимся. нужно время все осознать и переварить. а такой ценный материал всегда пригодиться и в любое время можно перечитать сдесь в ветке. я считаю это очень нужная тема .
Ссылка на комментарий
Поделиться на другие сайты

с трудом ,но получилось. скомпилировались. 0 ошибок, 0 предупреждений .

 

о какой неприятной вещи идет упоминание ?

Изменено пользователем XCh
Ссылка на комментарий
Поделиться на другие сайты

Нда... учиться лучше на собственной работе - быстрее запоминается, легче осваивается...

Ну, да ладно!

 

Если есть те, кто сделал себе этот индикатор (поверьте - он пригодится, я им часто пользуюсь), то могли заметить одну неприятную особенность: при запуске, индикатор не сразу появляется на графике, а только после прихода тика или после принудительного обновление графика через контекстное меню. Это связано с тем, что при запуске модуля значение функции IndicatorCounted() ещё не определено и появится только после тика или обновления. А для того, чтобы наш индикатор (да и все остальные, какие мы будем ваять :blush: ) сразу появлялся на графике, мы будем сравнивать значение функции IndicatorCounted() с переменной Bars. Таким самым образом, даже при начальной загрузке, у нас будут определённые значения и индикатор появится на графике.

MQL
int limit;

int counted_bars=IndicatorCounted();

// проверим возможные ошибки - зачем время терять, если нет ничего

if(counted_bars<0) return(-1);

// пересчитаем последний

if(counted_bars>0) counted_bars--;

limit=Bars-counted_bars;

for(int i=0; i<limit; i++) {

/// --- здесь идут вычисления

}

Вот теперь наш индикатор будет появляться сразу же при загрузке.

 

Жду ваши вопросы....

Ссылка на комментарий
Поделиться на другие сайты

  XCh сказал:

с трудом ,но получилось. скомпилировались. 0 ошибок, 0 предупреждений .

 

о какой неприятной вещи идет упоминание ?

С трудом, НО ПОЛУЧИЛОСЬ... :biggrin: этот труд воздастся сторицей... и я очень рад :rolleyes:

 

А что именно не получается с библиотекой? Там же не надо ничего придумывать, только я начале модуля сделать одну строку:

MQL
#property library

 

Но, всё-таки лучше эту тему будем обсуждать в топике, посвященном именно библиотекам: "Создание библиотек".

Ссылка на комментарий
Поделиться на другие сайты

Liv, спасибо за ветку, полезная, нужная.

У меня вопрос по параметрам, которые используются с iMa и других функциях:

 

double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift )

 

Это ma_shift и shift, правильно я понимяю что

iMA(NULL,1,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,0);

iMA(NULL,0,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,1);

 

дают одинаковый результат?

 

Еще вопрос, можете поделиться своими наработками по отладке? Редактор хороший, а отладчика нет, одно мучение с этими Print-ами да Alert-ми, двадцать первый век на дворе, а отладка - как в бейсике под дос.

Ссылка на комментарий
Поделиться на другие сайты

  sergan сказал:

Liv, спасибо за ветку, полезная, нужная.

У меня вопрос по параметрам, которые используются с iMa и других функциях:

 

double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift )

 

Это ma_shift и shift, правильно я понимяю что

iMA(NULL,1,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,0);

iMA(NULL,0,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,1);

 

дают одинаковый результат?

Не всегда одинаковый! Здесь указаны запросы средней по текущему бару и по предыдущему бару. Разумеется, не всегда эти бары одинаковые и чем больше таймфрэйм, тем больше, обычно, они отличаются.

 

  sergan сказал:

Еще вопрос, можете поделиться своими наработками по отладке? Редактор хороший, а отладчика нет, одно мучение с этими Print-ами да Alert-ми, двадцать первый век на дворе, а отладка - как в бейсике под дос.

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

Ссылка на комментарий
Поделиться на другие сайты

  Liv сказал:

Не всегда одинаковый! Здесь указаны запросы средней по текущему бару и по предыдущему бару. Разумеется, не всегда эти бары одинаковые и чем больше таймфрэйм, тем больше, обычно, они отличаются.

 

 

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

 

Ошибся, должно было быть так:

 

double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift )

 

iMA(NULL,0,ПервыйПериод,1,MODE_SMA,PRICE_CLOSE,0);

iMA(NULL,0,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,1);

Ссылка на комментарий
Поделиться на другие сайты

  sergan сказал:

Ошибся, должно было быть так:

 

double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift )

 

iMA(NULL,0,ПервыйПериод,1,MODE_SMA,PRICE_CLOSE,0);

iMA(NULL,0,ПервыйПериод,0,MODE_SMA,PRICE_CLOSE,1);

Ага, понял.... речь идёт о сдвиге.. то, что в хелпе проименовано как ma_shift. Конечно, значения функций на одном и том же баре никак отличаться не будут, за тем исключением, что одна линия будет сдвинута по отношению к другой на некоторое значение. Вот я сделал два индикатора с одинаковыми скольжениями, но со сдвигом 1.

http://forex.orotukan.ru/images/vid01.jpg

 

Тут совершенно не важно сама величина сдвига. Это применяется в основном для более ясного отображения линии.... Я не совсем хорошо знаю индикатор Ишимоку (надо будет его освоить - сам себе :wink: ), но очень похоже, что линия Chinkou - это средняя c нулевым скольжением по средней цене, но со сдвигом от 20 до 30 (26 - по-умолчанию). Поправьте меня, если не так....

Ссылка на комментарий
Поделиться на другие сайты

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

Жду с нетерпением

Ссылка на комментарий
Поделиться на другие сайты


×
×
  • Создать...