Уважаемые коллеги, на этом уроке мы напишем наш первый советник, познакомимся с некоторыми основными функциями языка MQL4, а также напишем несколько своих.
Приступим, и для начала запустим MetaEditor…

и создадим шаблон эксперта, ничего не меняя, просто нажимаем кнопку «Далее»…

Обязательно заполняем, как минимум, поле «Имя» — это название нашего будущего советника, поля «Автор» и «Ссылка» не обязательны к заполнению. Добавляем параметры «Lots», «TakeProfit», «StopLoss», обращая внимание тип данных каждого параметра. После заполнения нажимаем кнопку «Далее»:

На следующей форме мастера мы также ничего не отмечаем, просто нажимаем кнопку «Далее»:

И очередное окно мы оставляем без заполнения, нажимаем кнопку «Готово»:

Итак, мы получили шаблон будущего эксперта, с которым будем работать.

Итак, мы предусмотрим наш будущий советник для работы с 4-х и 5-значным брокером и тут два варианта как это реализовать. Можно заменить вид параметра «input» на «extern» для того, чтобы можно было из кода советника модифицировать эти значения (значения с видом параметра «input» изменять в коде эксперта нельзя!)
//--- input parameters extern double Lots=0.1; extern int TakeProfit=70; extern int StopLoss=40;
или добавить глобальные переменные «TP» и «SL», в которые скопируем значения «TakeProfit» и «StopLoss» и работать уже с ними.
Я выбираю первый вариант, т.е. меняю «input» на «extern«.
Далее в функции «OnInit» добавляю следующий код:
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if (Digits == 3 || Digits == 5)
{
TakeProfit *= 10;
StopLoss *= 10;
}
return(INIT_SUCCEEDED);
} Поясняю:
Функция Digits возвращает количество десятичных знаков после запятой, определяющее точность измерения цены символа текущего графика, таким образом:
- Я проверяю количество знаков после запятой у текущей валютной пары и если количество знаков равно 3 или равно 5, то делаю вывод, что мой брокер работает с пятизначными котировками.
- Следующим шагом я умножаю TakeProfit и StopLoss на 10. Запись «TakeProfit *= 10;» эквивалентна записи «TakeProfit = TakeProfit * 10;«
Продолжим.
Теперь нужно определиться как мы будем открывать позиции, в какую сторону и в какой момент? Покупать или продавать?
Осмелюсь предложить воспользоваться для этих целей индикатором «MovingAverage» и у нас будет следующий алгоритм:
- Если текущая цена будет выше, чем значение индикатора, то будем покупать.
- Если текущая цена будет ниже, чем значение индикатора, то будем продавать.
- Закрытие позиций будет происходить либо по TakeProfit, либо по StopLoss.
Язык программирования MQL4 предоставляет нам ряд функций для работы с индикаторами, и как раз одна из них позволяет получить нам текущее значения индикатора:

Итак, у нас есть функция iMA, из справочника(вызывается по клавише «F1») нам известны её параметры, часть из которых я сразу же переношу во внешние параметры советника для последующей оптимизации параметров самого индикатора:
//+-----------------------------------------------------------------------------+ extern double Lots = 0.1; extern int TakeProfit = 70; extern int StopLoss = 40; // Магический номер открытого ордера extern int Magic = 12345; //+-----------------------------------------------------------------------------+ extern string MA = "Настройки индикатора Moving average"; extern int ma_period = 20; extern int ma_shift = 8; extern ENUM_MA_METHOD ma_method = MODE_SMA; extern ENUM_APPLIED_PRICE applied_price = PRICE_CLOSE; extern int shift = 1; //+-----------------------------------------------------------------------------+
Обратите внимание на то, что я заменил тип «int» у двух параметров на перечисления «ENUM_MA_METHOD» и «ENUM_APPLIED_PRICE». Сделал я это для удобства восприятия самих параметров, согласитесь, что прочитать, к примеру, у параметра ma_method значение «MODE_SMA» гораздо понятней, чем наблюдать простое число. Кроме того я заранее добавил ещё один параметр «Magic». Он нам понадобится для открытия ордера.
Теперь переходим к функции «OnTick»(она выполняется каждый раз при поступлении новой котировки по валютной паре) и получим значение индикатора MovingAverage:
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double ma = iMA(NULL, 0, ma_period, ma_shift, ma_method, applied_price, shift);
}
//+------------------------------------------------------------------+ Мы объявляем переменную «ma» и записываем в неё значение функции «iMA» с заданными параметрами, значения которых определены в параметрах самого эксперта.
Также нам понадобится несколько функций:
- Функция подсчёта количества количества ордеров на покупку.
- Функция подсчёта количества количества ордеров на продажу.
Добавим их в код советника:
//+------------------------------------------------------------------+
//| Возвращает количество позиций на покупку | //+------------------------------------------------------------------+
int CountBuy()
{
int order_total=0;
for(int cnt=0; cnt Отлично, теперь разберём каждую строчку функции «CountBuy()«:
int CountBuy() // Объявление функции без параметров, тип возвращаемого значения - int(целое число)
{
// Объявление переменной order_total с типом int
// В этой переменной будет храниться счётчик количества открытых позиций, находящихся в рынке
int order_total=0;
// Объявляем цикл, для того чтобы пересчитать все ордера, которые мы открыли.
// Функция OrdersTotal() возвращает общее количество открытых и отложенных ордеров.
for(int cnt=0; cnt Точно аналогичное описание применимо и для функции «CountSell()«. Тут всё тоже самое, кроме одного условия:
if (OrderType()==OP_SELL ...
т.е. проверяется тип ордера «на продажу».
Далее вносим следующие дополнения в тело функции «OnTick()»:
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Объявляем переменную для работы с тикетом ордера
int ticket;
// Объявляем перменные для расчёта цен TakeProfit и StopLoss
double tp, sl;
// Получаем значение индикатора "MovingAverage"
double ma = iMA(NULL, 0, ma_period, ma_shift, ma_method, applied_price, shift);
// Если текущая цена выше значения индикатора И количество открытых позиций равно нулю,
if (Ask > ma && CountBuy() == 0)
{
// то открываем ордер на покупку с записью его тикета в переменную "ticket"
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 5, 0, 0, "", Magic, 0, Blue);
// Если по какой-то причине ордер открыть не удалось,
if (ticket
т.е. мы объявили переменные ticket, sl, tp для дальнейшей работы с ними, а также добавили код для открытия ордера на покупку.
Теперь дополним блоком для открытия ордера на продажу, я обычно копирую уже написанный код для покупок и меняю условия и параметры функций зеркально для продаж:
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Объявляем переменную для работы с тикетом ордера
int ticket;
// Объявляем перменные для расчёта цен TakeProfit и StopLoss
double tp, sl;
// Получаем значение индикатора "MovingAverage"
double ma = iMA(NULL, 0, ma_period, ma_shift, ma_method, applied_price, shift);
// Если текущая цена выше значения индикатора И количество открытых позиций на покупку равно нулю,
if (Ask > ma && CountBuy() == 0)
{
// то открываем ордер на покупку с записью его тикета в переменную "ticket"
// Ask - это текущая цена для ордера на покупку
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 5, 0, 0, "", Magic, 0, Blue);
// Если по какой-то причине ордер открыть не удалось,
if (ticket
На этом, пожалуй, всё. Простейший советник написан, остаётся его скомпилировать и обратить внимание на журнал ошибок:

Ну и конечно же его стоит протестировать, поэтому запускаем терминал и открываем форму тестера стратегий:

После компиляции наш первый советник в окне «Навигатор» и доступен для тестирования на форме тестера стратегий.
Выбираем параметры запуска, т.е. указываем, что тестировать будем советник «First_Expert.ex4», а также валютную пару и период:

Нажимаем кнопку «Старт» и смотрим результат:

На вкладке «График» тестера стратегий можно посмотреть график баланса.

Ну что-ж, для первого раза вполне неплохо, на этом наш урок закончен.
По ссылке доступен для скачивания полный код нашего с вами советника First_Expert.
Один комментарий к “Урок №10: Наш первый советник”