Структура советника в MQL5: OnInit(), OnTick(), OnDeinit() — простыми словами для новичков

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

Представьте, что советник — это автономный робот-трейдер, который поселился в терминале MetaTrader 5. Его «жизненный цикл» состоит из трех ключевых этапов, за которые отвечают три специальные функции:

  1. Робот включается и готовится к работеOnInit() (Инициализация)
  2. Робот постоянно анализирует рынок и торгуетOnTick() (Основной цикл)
  3. Робот завершает работу и убирает за собойOnDeinit() (Деинициализация)

Вот как это выглядит в коде и на практике:

//+------------------------------------------------------------------+
//|                                                  SimpleExpert.mq5 |
//|                                        Автор: Ваше Имя           |
//|                        https://your-site.ru                      |
//+------------------------------------------------------------------+
#property copyright "Ваше Имя"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Глобальные переменные (память робота)                            |
//+------------------------------------------------------------------+
int    MagicNumber = 123456; // Уникальный ID для ордеров советника
double LotSize     = 0.1;    // Фиксированный объем для торговли

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Этап 1: ПОДГОТОВКА К РАБОТЕ
   Print("Советник запущен на символе ", Symbol(), " на таймфрейме ", Period());

   // -- Здесь обычно происходит:
   // 1. Проверка настроек (корректность лота, наличие индикаторов).
   // 2. Инициализация индикаторов.
   // 3. Восстановление состояния после перезапуска (если нужно).

   return(INIT_SUCCEEDED); // Сигнал терминалу: "Я готов к работе!"
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // Этап 2: ОСНОВНАЯ РАБОТА (вызывается КАЖДЫЙ раз при новом тике)

   // 1. Получаем необходимые данные
   double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK); // Цена покупки
   double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID); // Цена продажи

   // 2. Проверяем условия для открытия позиции
   // Например: "Если нет открытых позиций, открываем Buy"
   if(PositionsTotal() == 0) // У нас нет открытых позиций
     {
      // Сигнальная логика (упрощенно - всегда true)
      bool buySignal = true; // Здесь должна быть ваша реальная торговая логика!

      if(buySignal)
        {
         // 3. Выполняем торговую операцию
         MqlTradeRequest request = {};
         request.action    = TRADE_ACTION_DEAL;
         request.symbol    = Symbol();
         request.volume    = LotSize;
         request.type      = ORDER_TYPE_BUY;
         request.price     = ask;
         request.magic     = MagicNumber;

         MqlTradeResult result;
         OrderSend(request, result);
        }
     }

   // Здесь также может быть логика для модификации ордеров, трейлинг-стопа и т.д.
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   // Этап 3: ЗАВЕРШЕНИЕ РАБОТЫ
   // reason - код причины остановки (закрыли терминал, сменили символ, отключили советника)

   Print("Советник остановлен. Причина: ", GetUninitReasonText(reason));

   // -- Здесь обычно происходит:
   // 1. Удаление графических объектов (стрелок, линий), созданных советником.
   // 2. Корректное закрытие соединений с сервером (если были).
   // 3. Сохранение логов или финальной статистики в файл.
  }
//+------------------------------------------------------------------+
//| Функция для получения текстового описания причины деинициализации|
//+------------------------------------------------------------------+
string GetUninitReasonText(int reasonCode)
  {
   switch(reasonCode)
     {
      case REASON_PROGRAM:        return "Советник был удален с графика";
      case REASON_REMOVE:         return "Советник был удален с графика";
      case REASON_RECOMPILE:      return "Советник был перекомпилирован";
      case REASON_CHARTCHANGE:    return "Пользователь сменил символ или таймфрейм";
      case REASON_CHARTCLOSE:     return "Вкладка с графиком была закрыта";
      case REASON_PARAMETERS:     return "Были изменены входные параметры";
      case REASON_ACCOUNT:        return "Был осуществлен переход на другой торговый счет";
      case REASON_TEMPLATE:       return "Была загружен новый шаблон графика";
      case REASON_INITFAILED:     return "Ошибка инициализации (OnInit завершился с ошибкой)";
      case REASON_CLOSE:          return "Терминал был закрыт";
      default:                    return "Неизвестная причина";
     }
  }

Теперь подробнее о каждой функции

1. OnInit() — Функция инициализации (вызывается ОДИН раз)

  • Когда срабатывает: В момент запуска советника — когда вы перетаскиваете его на график или меняете его параметры.
  • Аналогия: Робот только что прибыл на торговый пост. Он проверяет оборудование (индикаторы), настраивает рабочее место (проверяет введенные параметры), заводит журнал (открывает файл для логов) и докладывает: «Система готова!» (return(INIT_SUCCEEDED)).
  • Что тут писать:
    • Проверку входных параметров (например, что лот не меньше минимального).
    • Создание хэндлов для индикаторов (iMA, iRSI и т.д.).
    • Восстановление состояния после аварийного отключения.
    • Инициализацию глобальных переменных.
  • Важно: Если в этой функции что-то пошло не так (например, не загрузился индикатор), нужно вернуть INIT_FAILED. Советник тогда сразу остановится, не начав работу.

2. OnTick() — Функция обработки тиков (вызывается ПОСТОЯННО)

  • Когда срабатывает: При каждом изменении цены (тике) по символу, на котором работает советник. Это основная и самая важная функция.
  • Аналогия: Робот замер у монитора. Каждое мельчайшее движение цены — это для него новый сигнал к анализу. Он непрерывно смотрит на график, проверяет свои торговые условия («А не пора ли купить?») и отдает приказы на открытие/закрытие сделок.
  • Что тут писать:
    • Логику торговой стратегии. Весь ваш алгоритм («если RSI < 30 и цена коснулась скользящей средней, то покупать») находится здесь.
    • Получение данных с индикаторов.
    • Проверку наличия открытых позиций (PositionsTotal()).
    • Управление ордерами: открытие, модификация, закрытие.
    • Расчет и установку Stop Loss / Take Profit.
  • Ключевой принцип: Код в OnTick() должен выполняться быстро. Нельзя делать здесь долгих циклов или сложных математических расчетов, занимающих секунды. Иначе вы пропустите тики.

3. OnDeinit() — Функция деинициализации (вызывается ОДИН раз)

  • Когда срабатывает: В момент остановки советника — вы удалили его с графика, закрыли терминал, сменили таймфрейм или символ.
  • Аналогия: Рабочая смена робота закончена. Прежде чем уйти, он обязан привести пост в порядок: выбросить мусор (удалить графические объекты), закрыть журналы (закрыть файлы) и отчитаться о завершении работы.
  • Что тут писать:
    • Удаление всех созданных советником графических объектов (ObjectDelete, ObjectsDeleteAll).
    • Корректное освобождение хэндлов индикаторов (хотя в MQL5 это часто происходит автоматически).
    • Запись итоговой информации в файл или журнал.
  • Параметр reason: Очень полезный параметр, который говорит, почему советник остановился. Это помогает, например, не удалять графические объекты, если советник просто перекомпилировался (REASON_RECOMPILE).

Визуальная схема работы советника

          Запуск советника на графике
                    |
                    v
            Вызов функции OnInit()
        (Проверка настроек, загрузка данных)
                    |
                    |-- В случае успеха -> return(INIT_SUCCEEDED)
                    |
                    v
          Терминал начинает получать тики
        (каждое изменение цены по символу)
                    |
                    v
        На КАЖДЫЙ тик вызывается функция OnTick()
      (Здесь происходит весь анализ и торговля)
                    |
                    v
    Пользователь останавливает советника
   (Удаляет с графика, меняет параметры и т.д.)
                    |
                    v
          Вызов функции OnDeinit(reason)
        (Очистка, сохранение, финальный отчет)

Что дальше?

Теперь, понимая этот каркас, вы можете бесконечно усложнять и улучшать логику внутри OnTick(). Все, что вам нужно — это:

  1. Сформулировать четкие торговые правила своей стратегии («Что? Где? Когда? покупать/продавать»).
  2. Перевести эти правила на язык MQL5 с помощью условий (if, else) и торговых функций (OrderSend).
  3. Добавлять вспомогательный код в OnInit() и OnDeinit() для надежной работы.

Начните с малого: модифицируйте советника из первой статьи, чтобы он открывал не один ордер, а, например, выставлял отложенные ордера по границам канала. Удачи в создании своих торговых алгоритмов

Комментарии

Добавить комментарий

Причина возврата

Хотите получать персональные предложения и новости?

Разрешите уведомления от сайта и получайте новости и предложения нашего сайта.

Maybe later