Как написать советник mt4? [ Пишем форекс советник ]

Тема в разделе "Форекс для начинающих - учимся (торгуем на Forex)", создана пользователем assurkov, 4 май 2016.

  1. Приглашаем принять участие в акции "Ты пишешь - мы платим" от нашего спонсора AMEGA
    Пиши сообщения и получай бонусы на торговый счёт каждый месяц.
    Выводи прибыль в любое время и без ограничений.
    Торгуй на лучших условиях рынка Forex!

Рекламные объявления MyForex
  1. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    Можно сколь угодно долго спорить о том, насколько жизнеспособна та или иная торговая идея, но ХОРОШАЯ идея - это АЛГОРИТМИЗИРОВАННАЯ идея. И здесь на основе простых кодов мы будем рассматривать написания своих собственных кодов индикаторов и советников для МТ4.
     
  2. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    Итак, что необходимо для того чтобы написать советник ( по индикатору ). В теме про системный подход к трейдингу (http://forum.myforex.ru/threads/sistemnyj-podxod-k-trejdingu.4136/) Mila_ya затронула тему сопоставления того, как торгуются валюты, входящие в пару на других графиках, с другими валютами, как индикаторный показатель потенциальной сделки по нашему текущему графику. Я же использую это несколько шире и анализирую уже поведение валюты в целом на 6 графиках, выявляя, как она торгуется со всеми остальными основными валютами. И сейчас попробуем разобраться, как написать такой осциллятор, который покажет там именно состояние перекупленности/перепроданности какой-либо национальной валюты. Пусть это будет британский фунт. Сам код данного индикатора в прикрепленном архиве. Здесь же мы подробно разбираем его структуру.
    Все что идет в строке после «//» - это комментарий, то, что не исполняется программой и служит для удобства пояснений, получается таким серым шрифтом.
    В разделе #property, т.н. препроцессоре мы описываем некоторые параметры, который позволяют правильно и быстро обслуживать наш код. Например, в нашем случае мы указываем, что индикатор должен рисоваться в отдельном окне (indicator_separate_window), закрепленные максимумы и минимумы этого окна (indicator_minimum, maximum), уровни (indicator_level), количество используемых буферов и цвет линии.
    Далее идет блок входных переменных:
    extern int Period=10;
    Задается переменная Period, по умолчанию ее значение 14, она целочисленного типа (int). Вместо extern можно использовать input, но во втором случае уже не получится изменять значение этой переменной по ходу кода.
    В блоке инициализации int init() мы связываем наш буфер и рисуемую линию, задаем короткое имя индикатора GBP_RSI.
    А далее мы запускаем некоторый цикл while со счетчиком i. В нашем случае I – это будет номер свечи на графике. Текущая (строящаяся) свеча имеет номер 0, предыдущая -1, следующая 2 и т.д. То есть цикл будет начинаться с большого какого то значения, равного чуть меньше количества баров на графике и уменьшаться на единицу (i--) До тех пор, пока не станет меньше нуля.
    А вот далее мы вводим переменные, названия которых идентичны названию валютных пар с типом данных – все действительные числа (double). И каждая эта переменная равна у нас будет значению индикатора RSI на соответствующем графике. Например:
    GBPCHF=iRSI("GBPCHF",0, Period,PRICE_CLOSE,i);
    Переменная GBPCHF получит значение индикатора RSI на этой паре, текущем таймфрейме, с заданным периодом, применяя к ценам закрытия на свече i). Таким же образом вы вполне можете использовать значения абсолютно любого осциллятора, используя соответствующую функцию (iMFI, iStochastic, iATR и др.)
    А вот для EURGBP нас будет интересовать «обратное» значение: 100- iRSI("EURGBP"….). Тут наш фунт стоит на втором месте, а это значит, что перекупленность фунта будет при значениях индикатора менее 30, скажем:
    2.jpg

    Использование уже этого осциллятора в совокупности со стандартным RSI позволяет отслеживать нам состояние перекупленности/перепроданности как данного графика, так и фунта на других графиках, а значит сделать сигналы на вход более точными. Еще же скажу, что отрабатывать такие моменты стараюсь на малых таймфреймах М1, реже М5. после их появления на Н1.
     
  3. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    Приношу извинения. Сам то код к предыдущему посту о том как написать советник для mt4 забыл прикрепить. Он в архиве. Аналогично можете переписать для любой валютной пары.
     

    Вложения:

    • GBP-RSI.rar
      Размер файла:
      745 байт
      Просмотров:
      195
  4. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    А сейчас рассмотрим написание стрелочного индикатора для советника mt4. Дабы не перегружать окно терминала разными осцилляторами и не отслеживать их гораздо удобнее при наступлении заданных условий, чтобы эта торговая идея отображала нам на графике соответствующую точку на вход. И такой торговой идеей у нас будет следующее:

    Одновременное нахождение осциллятора (MFIв нашем случае) на текущем таймфрейме и заданном (как правило следующем старшем) в заданных зонах перекупленности/перепроданности. На графике это выглядит так:
    1.jpg

    В принципе, точки на вход в виде стрелок могут быть весьма точными. И теперь переходим к самому коду. Т.к. рисуем мы все в окне основного графика, то теперь уже вначале указываем indicator_chart_window. В блоке входных параметров видим следующие переменные:

    TimeFrame – период графика в минутах, где отслеживается индикатор дополнительно к текущему графику, как правило следующий (для текущего графика М1 укажем 5, М5 – 15 или может что то даже большее)

    Period_Fast – период расчета индикатора на текущем графике;

    Period_Slow – период расчета индикатора на заданном старшем таймфрейме;

    Zone_Fast – размер зоны перекупленности/перепроданности для текущего графика;

    Zone_Slow – размер этой зоны для заданного таймфрейма.

    Индикатор использует два буфера double BuyBuffer[],SellBuffer[]; на покупку и на продажу. В каждом из них рисуются стрелки. Но в буфере на покупку они красные (indicator_color1 Red), на продажу – синие (indicator_color2 Blue). И стрелки эти являются символами шрифта Wingdings. На покупку, стрелка вверх – символ 241 (SetIndexArrow(0,241)), а продажу – стрелка вниз, символ 242 (SetIndexArrow(1,242)). Кто желает, чтобы отображались не стрелки, а иные какие то символы, просто напишите вместо этих цифр другие.

    В счетчике, который перебирает номера свечей мы рассчитываем значение индикатора MFI на текущем ТФ с заданным периодом:

    double MFI1=iMFI(NULL,0,Period_Fast,i);


    А далее, чтобы на узнать номер свечи, на какую выпадает текущая свеча на старшем ТФ, например, 7 свеча на М1 должна выпадать на вторую на М5, мы рассчитываем номер свечи на стершем, заданном ТФ, используя функцию времени:

    iNext1=iBarShift(NULL,TimeFrame,iTime(NULL,0,i)); а теперь номер этой свечи подставляем в расчет значения индикатора:

    MFI2=iMFI(NULL,TimeFrame,Period_Slow,iNext1);


    Теперь у нас есть значения индикатора MFI на текущем и на заданном ТФ на каждой свече. Условиями для рисования стрелок являются нахождения индикаторов одновременно (оператор И) в заданных зонах перекупленности или перепроданности. На языке MQL это выглядит так:

    if(MFI1<Zone_Fast && MFI2<Zone_Slow )

    { BuyBuffer=Low-iATR(NULL,0,14,i); }


    Если значения меньше этих зон, то заполняем буфер на покупку, рисуем значит стрелку вверх. Аналогично на продажу. Только там размер зоны вычисляем как (100-Zone_Slow). Если больше этого значения, то продаем. С базовыми настройками для ТФ менее 15 сигналы получаются весьма точными (Исходный код индикатора в прикрепленном архиве MFI Arrows):
    2.jpg
    3.jpg
    5.jpg

    Подробности о том, как написать советник по индикатору планирую привести ниже.
     

    Вложения:

    • 4.jpg
      4.jpg
      Размер файла:
      175,1 КБ
      Просмотров:
      265
    • MFI Arrows.rar
      Размер файла:
      870 байт
      Просмотров:
      168
  5. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    Итак, возвращаясь к теме о написании советника форекс самому...
    Продолжу...

    Задача любого кода – это автоматизация. В нашем случае оптимизация трейдинга. То ли советник сам по нашим правилам начнет сам торговать, отслеживая те моменты, которые мы может сами по графику и не увидим и ведя одновременно значительное количество графиков, то ли это будут индикаторы, которые отслеживают ситуацию на любом количестве графиков, а при наступлении соответствующего события уведомляют трейдера о возможной сделке на каких то из них, а он уже сам принимает решение о торговле. Сейчас мы остановимся на втором моменте. А именно, функциях оповещения, как я их называю, хотя они входят в раздел общих функций в мануале нашего любимого языка программирования mql4.

    Терминал нас может автоматически оповещать следующим образом:
    • В виде алерта (текстового сообщения, сопровождаемого звуковым сигналом в терминал);
    • По E-mail;
    • В виде Push-сообщения (на мобильную версию платформы в смартфон).
    Функции отправки алерта и Push-сообщения имеют схожую структуру:
    • Alert("символьная строка")
    • SendNotification("символьная строка")
    Эта символьная строка может просто иметь значение "покупай" или "продавай". Но это будет неудобно. Как правило, сюда добавляют валютный инструмент, таймфрейм, сделка. В нашем случае это выглядит так:
    Alert( "RSI " +Symbol()+" _ "+"SELL ""_ "+TimeFrame);
    SendNotification("RSI "+Symbol()+" _ "+"SELL ""_ "+TimeFrame);


    Текущая структура нам выдаст сообщение, например, такое:
    RSI EURUSD_SELL_ M5, вполне удобно увидеть, что на неотслеживаемом графике формируется сигнал на сделку.
    66.jpg
    Функция SendMail (для отправки сообщений на электронку имеет несколько иную структуру и включает уже два элемента, разделенных запятой:
    SendMail ("тема", "тест письма").
    Образуется аналогично исходя из операций с символьными переменными. Наш пример:
    SendMail( "RSI ", +Symbol()+" _ "+"SELL ""_ "+TimeFrame);
    То есть на почту придет письмо с темой RSI и текстом, например, «EURUSD_SELL_ M5». Кстати, чтобы сделать отправку писем с терминала, необходимо ее настроить в разделе Инструменты, Настройки, Email.
    А теперь все же немного о самом прикрепленном индикаторе. Он рисует стрелки при нахождении индикатора RSI в зонах перекупленности/перепроданности.
    5.jpg
    Размер этих зон задается пользователем:
    input int RSI_Zone1 =25;
    Дальше есть выбор уведомлять или нет:
    extern bool Alert=False;
    extern bool E_mail=False;
    extern bool Push=False;

    Тип данных bool принимает одно из двух значений. False (по умолчанию у нас), либо True.
    И вот если выбрано True, то будет формироваться уведомление:
    if(Alert==TRUE) {Alert("RSI "+Symbol()+" _ "+"BUY ""_ "+TimeFrame);}
    А если оставить False, то условие выполнено не будет и сигнал не будет сформирован.
    Сама структура стрелочного индикатора рассматривалась выше. И чтобы индикатор не «пищал» на каждой свече или даже тике, мы перед блоком уведомлений добавляем условия:
    if(SellBuffer[0]!=EMPTY_VALUE){
    if(SellBuffer[1]==EMPTY_VALUE)

    Согласно которым, уведомление будет формироваться, если на текущей нулевой свече сигнал есть (стрелка рисуется, буфер заполняется), а на первой предыдущей – нет, значение буфера EMPTY_VALUE.
     

    Вложения:

    • RSI_ST.rar
      Размер файла:
      1,2 КБ
      Просмотров:
      155
  6. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    Сейчас рассмотрим торговлю на так называемых выбросах, когда цена без особого фундамента начинает торговаться в несколько отдаленных от нормализованных диапазонах. Несколько с этим схожа описанная ранее стратегия Льюиса Борселино, но она имеет следующие недостатки (хотя может для чьей то торговли это наоборот достоинства):
    • Ориентирована преимущественно на дневной таймфрейм, что фактически сводит на нет торговлю по ней внутри дня;
    • Используются скользящие средние, не всегда оперативно реагирующие на рыночную ситуацию.
    Все же определенные моменты в ней заслуживают особого внимания. А именно этот самый нонсенсный выброс цены. Для внутридневной торговли я использую М1 и определяю этот выброс на основе индикатора Ишимоку по отходу цены от линий Тенкан и Киджун. Суть стратегии предельно проста. Сигнал на точный почти скальперский вход следующий на М1 для золота:
    1) отход текущей цены минимум на 2 спреда от линии Киджун;
    2) отход текущей цены минимум на 2 спреда от линии Тенкан;
    3) нахождение индикатора RSIв зонах перекупленности, перепроданности (более 70, менее 30).

    Применяем этот метод в высоковолатильные периода европейской и американской сессий при отсутствии фундамента. Для определения значений отхода цены от рассматриваемых линий я написал приложенный индикатор Difference, структуру которого далее рассмотрим. Это осциллятор, который показывает в пунктах значение отхода цены от указанных линий, а во входных параметрах мы и можем только выбрать одну из двух линий. Сигналы сегодня мы видим следующие при двух спредах в сумме 500 пунктов:
    1.jpg

    Написать советник для мт4
    Достаточно неплохая торговая система может получиться. Более того, скоро будет советник с этой идеей, и совсем более того он даже поторгует открыто на реале. Но это будет потом. А пока разберем код данного осциллятора.

    Из еще неразобранного в теме тут у нас добавляется работа с раскрывающимся списком в инпуте:
    enum Indicator
    { h0=0,// Tenkan
    h1=1,// Kijun };
    input Indicator StartIndicator=h1; // Line

    сначала в блоке enum мы перечисляем значения возможные из списка, а чтобы удобно отображались через коммент (//) мы пишем их отображаемые значения Tenkan или Kijun, по какой линии строим индикатор.
    Далее при формировании короткого имени индикатора (слева вверху окна) нам надо, чтобы отображалась эта линия, иначе можно запутаться при торговле. Тут мы переменной Sitприсваиваем соответствующее символьное значение в зависимости от входных пользовательских данных:

    if(StartIndicator==h0) Sit="Tenkan";
    if(StartIndicator==h1) Sit="Kijun";


    А короткое имя будет состоять из названия индикатора и как раз таки той линии, которую пользователь выбрал:

    sShortName="Difference "+Sit;

    А далее уже в цикле мы должны выбрать ту линию, значение разницы от которой мы считаем и это значение присваиваем переменной Basa:

    Basa=iIchimoku(NULL,0,9,26,52,MODE_KIJUNSEN,i);}
    else Basa=iIchimoku(NULL,0,9,26,52,MODE_TENKANSEN,i);


    И расчет самого индикатора в пунктах будет выглядеть как разница между ценой закрытия и заданной линией индикатор Ишимоку:

    dif=(iClose(NULL,0,i)-Basa)/Point;

    Эта идей будет получать продолжение и дальше.
     

    Вложения:

    • Difference.rar
      Размер файла:
      754 байт
      Просмотров:
      124
  7. assurkov

    assurkov Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    4 май 2016
    Сообщения:
    46
    Симпатии:
    27
    -- В отступлении продолжу писать о том как как написать советник по индикатору --
    Ну а теперь переходим к советникам. Вообще есть 3 класса программ. Это рассмотренные индикаторы, скрипты и советники. Индикаторы от остальных отличаются тем, что в их кодах запрещено использовать функции открытия, закрытия, модификации ордером. В скриптах и советниках – можно и нужно. Скрипты же я как то обхожу стороной. Они должны разово запускаться на выполнение определенной задачи. Например, одновременную установку двух стоповых ордеров при заданном в пунктах уровне установке ордеров от текущей цены, стопах, тейках.

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

    Советник наш во входных параметрах имеет целочисленные данные, это Magic (магический номер ордера, меджик намбер), TakeProfit(в пунктах), STOP (в пунктах), RSI_Zone (размер зоны перекупленности/перепроданности), RSI_Period(Период RSI) и дробное значение Lots.

    Функция void OnTick(void) запускает наш код в работу с каждым новым тиком.
    Изначально мы в цикле считаем, сколько ордеров открыто нашим советником. Для этого в цикле ордере перебираются по порядковому номеру от количества ордеров, уменьшенного на единицу до нулевого. Дело в том, что первый открытый ордер будет иметь порядковый номер ноль, а не один:

    for (int r=OrdersTotal()-1; r>=0; r--)

    А уже теперь происходит идентификация «свой-чужой». Если у открытого ордера меджик номер совпал с нащим меджиком, то данный ордер считается открытым данным советником:

    if (OrderMagicNumber()==Magic)
    И счетчик ордеров, открытых советником увеличивается на единицу:
    OpenOrd++;
    В нашем случае советником может быть открыт только один ордер, а значит значения этого счетчика либо 0, либо 1.

    Для определения сигнала на вход мы рассчитываем значение индикатора RSI:

    RSI=iRSI(NULL,0,RSI_Period,PRICE_CLOSE,0);


    И теперь, если у нас на счете нет открытых советником ордеров, т.е. if(OpenOrd<1), то тогда при выполнении условий наличия свободных денег и нахождении RSI в соответствующей зоне мы можем открывать ордер (if(RSI<RSI_Zone)). А именно вводим переменную, которой присвоим тикет нашего ордера:

    ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Bid-STOP*Point,Ask+TakeProfit*Point,"Sovetnik RSI",Magic,0,Green);


    Открываются ордера функцией OrderSend, аргументы которой легко понять.
    Для М15 с начала текущего года с настройками:
    TakeProfit=950
    STOP =100
    RSI_Zone =19
    RSI_Period=14

    Работа этого советника выглядит так:

    еее.jpg
    Это один из самых простых кодов, на основе которого вполне можно начинать собирать что то свое.
     

    Вложения:

    • Sovetnik RSI.rar
      Размер файла:
      991 байт
      Просмотров:
      168
  8. Профит

    Профит Знаток

    Баланс: 0.15 y.e.
    Регистрация:
    17 дек 2015
    Сообщения:
    4.540
    Симпатии:
    906
    А нужны ли многим трейдерам вообще советники? Вот начал встречать сегодня профессиональных трейдеров и они говорят, что оказывается то что я не пробовал и не нужно как бы вообще для трейдинга. И советники в списке на первом месте стоят
     
  9. Denver

    Denver Знаток

    Баланс: 0.40 y.e.
    Регистрация:
    16 фев 2016
    Сообщения:
    3.305
    Симпатии:
    669
    Всё прочитать не осилил). Сильно много букв. Только начал читать и понял, что описанное тут - как-то всё сложно. Давно в сети в бесплатном доступе есть всевозможные конструкторы советников не требующие никаких знания языков программирования.
     
  10. vsergej

    vsergej Новичок

    Баланс: 0.00 y.e.
    Регистрация:
    9 май 2017
    Сообщения:
    5
    Симпатии:
    0
    Аможно написать стрелочник на основе сигналов многих индикаторов без отображения их на графике?
     
  11. Neo-30

    Neo-30 MyForex Team
    Команда форума

    Баланс: 1.80 y.e.
    Регистрация:
    11 авг 2015
    Сообщения:
    4.511
    Симпатии:
    4.712
    Язык программирования MQL4 позволяет это сделать.
     
  12. vsergej

    vsergej Новичок

    Баланс: 0.00 y.e.
    Регистрация:
    9 май 2017
    Сообщения:
    5
    Симпатии:
    0
    можете пример кода скинуть ?
     
  13. Neo-30

    Neo-30 MyForex Team
    Команда форума

    Баланс: 1.80 y.e.
    Регистрация:
    11 авг 2015
    Сообщения:
    4.511
    Симпатии:
    4.712
    неа, потому что не пользуюсь индикаторами и нет примеров..

    Но это же просто - в любом коде можно получить доступ к значению любого индикатора через iCustom или iAO - хоть 10, хоть 100 индикаторов просмотреть, и если есть совпадение сигналов, то разместить стрелку на графике, а стоят ли сами индикаторы на графике - неважно :Hi: (потому что доступ к индикатору идет напрямую, а не потому что он стоит или не стоит на графике)
     
  14. vsergej

    vsergej Новичок

    Баланс: 0.00 y.e.
    Регистрация:
    9 май 2017
    Сообщения:
    5
    Симпатии:
    0
    просто то это просто не для всех, я новичок один индюк на стрелки я могу заменить а как тут же к следующим обращаться? подскажите на примере! Please!
     
  15. Neo-30

    Neo-30 MyForex Team
    Команда форума

    Баланс: 1.80 y.e.
    Регистрация:
    11 авг 2015
    Сообщения:
    4.511
    Симпатии:
    4.712
    Да выкладывайте лучше свой пример, возьмите какой-то простой стрелочный индикатор, а нам нужно его переделать, чтобы эти же самые стрелки показывали сочетание сигналов от нескольких индикаторов.. ну и разберем..

    P.S. только не декомпил :Stop:
     
  16. vsergej

    vsergej Новичок

    Баланс: 0.00 y.e.
    Регистрация:
    9 май 2017
    Сообщения:
    5
    Симпатии:
    0
    ок
     
  17. vsergej

    vsergej Новичок

    Баланс: 0.00 y.e.
    Регистрация:
    9 май 2017
    Сообщения:
    5
    Симпатии:
    0
    а сможет ктонибудь декрмпилировать индикатор?
     
  18. artyr_forex

    artyr_forex Интересующийся

    Баланс: 0.00 y.e.
    Регистрация:
    19 фев 2018
    Сообщения:
    95
    Симпатии:
    6
    Я не хочу флудить, но по-моему сейчас проще найти советника на MQl5, чем писать самому код.
     
  19. expgalaxy

    expgalaxy Новичок

    Баланс: 0.00 y.e.
    Регистрация:
    21 мар 2018
    Сообщения:
    16
    Симпатии:
    1
    Если вам нужен советник для мт4, а стратегия не сложная(стандартные индикаторы мт4 и свечи), тогда пишите. Но то, что напишу буду сюда выкладывать и в формате exe4.
     
  20. Santio

    Santio Новичок

    Баланс: 1.05 y.e.
    Регистрация:
    15 ноя 2017
    Сообщения:
    29
    Симпатии:
    3
    Данная тема явно не для этого раздела. Если человек уже пришел к тому, что он пишет советники, то он явно не новичок.