Типы данных в MQL: int, double, bool, string — полный разбор для начинающего разработчика
Когда начинающий программист впервые открывает MetaEditor и видит чужой код торгового советника, его встречают строки вроде int count = 0;, double price = 1.12345;, bool ready = false; и string symbol = "EURUSD";. Для опытного разработчика эти объявления очевидны, а новичка они часто пугают: зачем столько разных типов, почему нельзя хранить всё в одной переменной и что будет, если ошибиться? В этой статье подробно разберём четыре базовых типа данных MQL5 — int, double, bool и string, — покажем, как они работают на практике, и объясним, почему правильный выбор типа — основа надёжного торгового робота.
Что такое тип данных
Тип данных — это характеристика переменной, которая определяет три вещи: какие значения переменная может принимать, сколько памяти она занимает и какие операции с ней допустимы. Например, над целыми числами можно выполнять обычную арифметику, а над текстовыми строками — склеивание и сравнение. Компилятор строго следит за типами: если вы попытаетесь выполнить недопустимую операцию, код просто не соберётся.
В языке MQL5 есть несколько десятков типов — от базовых до сложных структур и классов, — но любой разработчик торговых роботов ежедневно работает с четырьмя из них: int, double, bool и string. Понимание этих четырёх типов открывает дорогу ко всему остальному, потому что на них построены любые выражения, условия и функции.
Целые числа: int
Тип int хранит целые числа — положительные, отрицательные и ноль, без дробной части. Диапазон значений в MQL5 составляет примерно от −2 147 483 648 до 2 147 483 647, чего с огромным запасом хватает для любых торговых задач: количество сделок за год не превысит и миллиона, а номера ордеров укладываются в эти рамки.
В торговом роботе int используется повсеместно:
// ==== Примеры использования int ====int deals = 0; // количество сделокint tf = PERIOD_H1; // таймфрейм H1int ticket = 0; // тикет ордераint magic = 12345; // магический номер
Важное свойство int: при присваивании дробного значения дробная часть отбрасывается без округления. Если записать int x = 2.9;, переменная получит значение 2. Это поведение часто становится источником скрытых ошибок, поэтому никогда не храните цены в целочисленных переменных.
Дробные числа: double
Тип double предназначен для чисел с плавающей точкой — именно так в программировании называют дробные значения. В MQL5 цены, объёмы лота, значения индикаторов, прибыль и убыток хранятся именно в double, потому что рынок оперирует дробными величинами с точностью до пятого знака.
// ==== Примеры использования double ====double price = 1.12345; // цена инструментаdouble volume = 0.10; // объём лотаdouble profit = 12.55; // прибыльdouble lot = 0.01; // минимальный лот
Обратите внимание на два момента. Во-первых, в коде дробные числа записываются через точку, а не через запятую — это требование синтаксиса MQL5. Во-вторых, double — приближённый тип: он хранит значение с конечной точностью, поэтому при сравнении дробных чисел не используют строгое равенство ==, а сравнивают разницу с маленьким допустимым отклонением.
Логические значения: bool
Тип bool хранит всего два значения — true (истина) и false (ложь). Казалось бы, что тут изучать, но именно логические флаги делают код торгового робота читаемым и понятным. Вместо того чтобы запоминать, что переменная равна 1 или 0, вы оперируете осмысленными состояниями: «позиция открыта», «торговля разрешена», «сигнал получен».
// ==== Использование bool в условиях ====bool inPosition = false;bool allowedTrading = true;
if (inPosition) return; // позиция уже открыта, ждём
Логические переменные естественно сочетаются с оператором if, а также с логическими операторами && (и), || (или), ! (не). Любое условие в итоге вычисляется в значение bool — компилятор сам приводит результат сравнения к этому типу.
Текст: string
Тип string хранит произвольный текст: имена символов, комментарии к сделкам, сообщения для журнала и пользователя. Строки активно используются при отладке робота через функцию Print() и при формировании понятных сообщений.
// ==== Работа со строками ====string symbol = "EURUSD";string msg = "Торгуем " + symbol;Print(msg); // в журнал: Торгуем EURUSD
Строки поддерживают склеивание через оператор +, сравнение через == и множество встроенных функций: StringLen() для длины, StringFind() для поиска, StringSubstr() для выделения части. Для форматирования удобно использовать StringFormat(), который подставляет значения разных типов в шаблон по аналогии с printf в языке C.
Как выбрать правильный тип
Главное правило выбора можно сформулировать просто: храните данные в типе, который соответствует их природе.
// =============================================================================================== //// = Таблица-подсказка: какой тип выбрать для типовых данных советника = //// =============================================================================================== //int dealsCount; // счётчики, номера, таймфреймыdouble entryPrice; // цены, лоты, индикаторы, прибыльbool isOpened; // флаги состоянияstring symbolName; // имена, комментарии, сообщения
Цены и расчёты — всегда double, потому что иначе теряется точность. Счётчики и номера — int, они компактнее и быстрее обрабатываются. Состояния — bool, это делает код самодокументируемым. Тексты — string, других вариантов для строк в MQL5 просто нет.
Почему правильный тип — это вопрос не только стиля, но и надёжности? Потому что ошибка типа ведёт к тихой порче данных. Робот продолжает работать, но размер лота вычисляется неверно, уровни стоп-лосса устанавливаются с погрешностью, а строки для отчёта получаются бессмысленными. Обнаруживается такая ошибка не в момент компиляции, а в отчёте тестера или на реальном счёте.
Пример: советник, использующий все четыре типа
Соберём небольшой пример, в котором задействованы все четыре базовых типа. Задача — на каждом тике проверять, открыта ли позиция, считать тики и выводить состояние в журнал.
// =============================================================================================== //// = Глобальные переменные советника = //// =============================================================================================== //int dealsCount = 0; // счётчик сделок (int)double lastAsk = 0.0; // последняя цена Ask (double)bool inPosition = false; // флаг открытой позиции (bool)string tradeSymbol = _Symbol; // текущий символ (string)
// =============================================================================================== //// = Функция: обновляет цены и счётчик, выводит состояние в журнал = //// = ============================================================================================= //void RefreshAndLog() {// === Обновляем цену Ask и счётчик тиков === lastAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK); dealsCount++;
// === Формируем строку из данных разных типов === string msg = StringFormat("Сделок: %d | Ask: %f | Позиция: %s", dealsCount, lastAsk, (inPosition ? "есть" : "нет"));
// === Выводим сообщение в журнал === Print(msg); }
// =============================================================================================== //// = Обработчик нового тика = //// = ============================================================================================= //void OnTick() { RefreshAndLog(); }
Разберём, что происходит в этом коде. Переменная dealsCount типа int увеличивается на каждом тике — это целочисленный счётчик. lastAsk типа double получает текущую цену Ask с точностью до знака. Флаг inPosition типа bool управляет текстовым сообщением: тернарный оператор ? : выбирает, какую строку подставить. Наконец, StringFormat() собирает данные всех типов в одну строку string, которая выводится в журнал.
Обратите внимание на форматные спецификаторы: %d для целого числа, %f для дробного и %s для строки. Это стандартные обозначения функции StringFormat, и их нужно запомнить — они пригодятся в любом советнике.
Преобразование типов данных
В реальном коде данные часто нужно преобразовывать из одного типа в другой. MQL5 делает часть преобразований автоматически, а часть требует явных функций. Например, при сложении int и double результат автоматически станет double — это неявное преобразование, которое работает безопасно. Обратное направление, от double к int, автоматическим не бывает: дробная часть отбрасывается, и о таком преобразовании нужно помнить, чтобы не потерять данные.
Для явных преобразований в MQL5 есть встроенные функции: int() и double() для чисел, StringToInteger(), StringToDouble() и IntegerToString(), DoubleToString() для работы со строками. Типичный пример — вывод цены в сообщение, где дробное значение сначала округляется функцией NormalizeDouble(), а затем превращается в строку с нужным количеством знаков:
// ==== Преобразование double в string с точностью до 5 знаков ====double price = 1.123456;string text = DoubleToString(NormalizeDouble(price, _Digits), _Digits);Print(text);
Особенности double: погрешности плавающей точки
Тип double хранит числа в двоичном виде, и не каждое десятичное значение представимо точно. Классический пример — число 0.1: в памяти компьютера оно хранится как бесконечная двоичная дробь, поэтому вычисления вида 0.1 + 0.2 могут дать не 0.3, а 0.30000000000000004. Для торгового робота это означает одно практическое правило: никогда не сравнивайте цены напрямую через ==, а используйте сравнение с допустимой погрешностью.
// ==== Корректное сравнение дробных цен ====double a = 1.2345;double b = 1.2346;if (MathAbs(a - b) < 0.0001) Print("Цены практически равны");
Понимание этой особенности избавит вас от многих часов отладки: робот, который «иногда не срабатывает», чаще всего спотыкается именно о погрешности плавающей точки.
Где типы встречаются в реальном советнике
Любой эксперт, даже самый простой, использует все четыре типа. Рассмотрим типовой сценарий: робот открывает позицию, когда цена пересекает цену открытия вчерашней свечи. Для этого ему нужны double — текущая цена и уровень вчерашнего бара, int — тикет ордера после открытия, bool — флаг, защищающий от повторного входа, и string — имя символа для запросов к терминалу.
// =============================================================================================== //// = Функция: проверяет условие входа и открывает Buy-позицию = //// = ============================================================================================= //void TryOpenBuy() {// === Получаем цены: вчерашнее открытие и текущий Ask === double prevOpen = iOpen(_Symbol, PERIOD_D1, 1); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
// === Формируем тикет: int возвращается функцией открытия позиции === int ticket = OrderSend(_Symbol, ORDER_TYPE_BUY, 0.1, ask, 0, 0, 0, "Buy", magic);
// === Проверяем результат и выводим строку === if (ticket > 0) Print("Позиция открыта, тикет: ", IntegerToString(ticket)); }
Этот фрагмент наглядно показывает, как типы данных связаны с торговой логикой: каждое значение в коде имеет свою природу, и тип выбран под неё, а не «потому что так написано в чужом примере».
Типичные ошибки начинающих
Первая ошибка — запись дробной цены в int. Робот компилируется без предупреждений, но теряет точность, а вместе с ней — корректность расчётов. Вторая — сравнение дробных чисел через ==: из-за погрешностей double два математически равных значения могут отличаться на микроскопическую величину, и условие не сработает. Третья — использование int для больших чисел и переполнение: хотя в торговле это редкий случай, лучше сразу привыкать к корректному выбору. Четвёртая — путаница между строкой и числом: "100" и 100 — разные значения, и преобразовывать их нужно явно через StringToInteger() или IntegerToString().
Внимательность к типам — это навык, который нарабатывается практикой. Читайте чужой код, обращайте внимание, какие типы выбирают авторы для цен, счётчиков и флагов, и старайтесь объяснить себе, почему выбор именно такой. Постепенно выбор правильного типа станет автоматическим.
Сводная таблица типов данных
Для быстрого повторения сведём всё сказанное в таблицу.
ТипЧто хранитПримерГде используетсяintЦелые числаint deals = 5;Счётчики, тикеты, таймфреймыdoubleДробные числаdouble price = 1.12345;Цены, лоты, индикаторы, прибыльboolИстина/ложьbool ready = true;Флаги состояния, условияstringТекстstring s = "EURUSD";Имена символов, сообщенияЗапомните эту таблицу — она покрывает 90% случаев выбора типа в обычном советнике. Остальные 10% приходятся на специализированные типы вроде datetime для времени и color для цвета, к которым вы перейдёте после освоения базы.
Заключение
int, double, bool и string — четыре базовых типа данных MQL5, на которых построена любая программа для MetaTrader. Целые числа нужны для счётчиков и номеров, дробные — для цен и расчётов, логические — для флагов состояния, строки — для текстов и сообщений. Правильный выбор типа защищает робота от скрытых ошибок и делает код понятным другим разработчикам.
Освоив базовые типы, вы сможете читать чужой код и переходить к более сложным темам: массивам, функциям, классам и созданию полноценных торговых стратегий. Разбору типов данных и другим основам MQL5 посвящены уроки нашего проекта — больше учебных материалов на https://max.ru/channel_mqlmasters, а короткие практические разборы и новости выходят в Телеграме: https://t.me/mqlmasters. Подписывайтесь, чтобы не пропускать новые уроки!
Владимир, опубликовал запись .
С момента публикации зафиксировано 49 просмотров. Сейчас эту запись просматривают 2 незарегистрированных пользователя.
|
|