Советники: Программирование на MQL5 для трейдеров — исходные коды из книги. Часть 6

 

Программирование на MQL5 для трейдеров — исходные коды из книги. Часть 6:

В шестой части книги "Программирование на MQL5 для трейдеров" мы изучим ключевую составляющую языка MQL5 — автоматизацию торговли. Начнем с описания основных сущностей, таких как спецификации финансовых инструментов и настройки торгового счета, которые необходимы для создания корректных советников.

Программирование на MQL5 для трейдеров — исходные коды из книги. Часть 6

Автор: MetaQuotes

 
Великий
 

При вставке кода используйтекнопку CODE (Alt-S).

Модератор отформатировал некорректно вставленный код. Обычно такой код удаляется.

@StanislavKorotky Пожалуйста, не могли бы вы помочь разобраться с этой ошибкой, я считаю, что она началась после обновления MT5, потому что я знал, что код работает в предыдущие месяцы без каких-либо изменений.

параметр convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20

преобразование параметров типа 'double[][2]' в 'string[][] &' недопустимо TradeFilter.mqh 332 20
преобразование параметров типа 'long[][2]' в 'string[][] &' недопустимо TradeFilter.mqh 163 17


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

void printSymbols() {
   SymbolFilter f;                      // объект фильтрации
   string symbols[];                    // массив для имен 
   long permissions[][2];               // массив для данных (значений свойств)
   
   // список запрашиваемых свойств символа
   ENUM_SYMBOL_INFO_INTEGER modes[] = {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // применяем фильтр, получаем массивы с результатами
   f.let(SYMBOL_VISIBLE, true).select(true, modes, symbols, permissions);
   
   const int n = ArraySize(symbols);
   PrintFormat("===== Trade permissions for the symbols (%d) ===== ", n);
   for(int i = 0; i < n; ++i)  {
      Print(symbols[i] + ":");
      for(int j = 0; j < ArraySize(modes); ++j) {
         // отображать описания битов и чисел "как есть"
         PrintFormat("  %s (%d)",
            SymbolMonitor::stringify(permissions[i][j], modes[j]),
            permissions[i][j]);
      }
   }
}

Stanislav Korotky - marketeer - Trader's profile
Stanislav Korotky - marketeer - Trader's profile
  • 2025.07.05
  • www.mql5.com
Trader's profile
 
pauldic #:
@StanislavKorotky Пожалуйста, не могли бы вы помочь разобраться с этой ошибкой, я считаю, что она началась после обновления MT5, потому что я знал, что код работает в предыдущие месяцы без каких-либо изменений.

преобразование параметра типа 'long[][2]' в 'string[][] &' не разрешено SymbolFilter.mqh 199 20
преобразование параметров типа 'double[][2]' в 'string[][] &' недопустимо TradeFilter.mqh 332 20
преобразование параметров типа 'long[][2]' в 'string[][] &' недопустимо TradeFilter.mqh 163 17


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


Пожалуйста, найдите строки:

   // нам нужна эта перегрузка, потому что встроенный ArraySort
   // не поддерживает массивы строк
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }

в заголовочных файлах SymbolFilter.mqh и TradeFilter.mqh, и добавьте к ним следующую перегрузку метода:

   // нам нужна эта перегрузка, потому что встроенный ArraySort
   // не поддерживает массивы строк
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }
   
   template<typename T>
   void ArraySort(T &s[][]) const
   {
      ::ArraySort(s);
   }
PS. Этот вопрос, кажется, не имеет отношения к статье.
 
Stanislav Korotky #:

Пожалуйста, найдите эти строки:

в заголовочных файлах SymbolFilter.mqh и TradeFilter.mqh, и добавьте к ним следующую перегрузку метода:

PS. Этот вопрос, кажется, не связан со статьей.

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

parameter convertion type 'double[][2]' to 'string[][] &' is not allowed                TradeFilter.mqh 338     20
cannot convert parameter 'double[][2]' to 'OrderMonitor&[][]'                   TradeFilter.mqh 338     20
parameter convertion type 'double[][2]' to 'string[][] &' is not allowed                TradeFilter.mqh 338     20
cannot convert parameter 'double[][2]' to 'PositionMonitor&[][]'                        TradeFilter.mqh 338     20
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed          TradeFilter.mqh 163     17
cannot convert parameter 'long[][2]' to 'OrderMonitor&[][]'                             TradeFilter.mqh 163     17
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed          TradeFilter.mqh 163     17
cannot convert parameter 'long[][2]' to 'PositionMonitor&[][]'                  TradeFilter.mqh 163     17
etc..

Я заметил, что вызов общего QuickSortTm напрямую вместо ArraySort временно решает проблему, хотя я не считаю это оптимальным решением.

QuickSortTm<V> qt(array);
//ArraySort(array);
 
pauldic #:

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

Странно, после предложенного выше исправления я скомпилировал и запустил этот скрипт /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 успешно на билде 5346. Вы не показали свой исходный код.
 
Stanislav Korotky #:
Странно, после предложенного выше исправления я скомпилировал и запустил этот скрипт /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 успешно на билде 5346. Вы не показали свой исходный код.
Простите меня за отсутствие исходного кода, поэтому я вернулась к предложенному вами исправлению, чтобы снова получить ошибки, и похоже, что эти части моего кода являются частями, которые приводят к ошибке, согласно журналу
Я работаю на версии 5 build 5327

.
void printActiveOrders() {
   
   OrderFilter filter;
   ENUM_ORDER_PROPERTY_DOUBLE properties[] = {ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP};
   double d[][4];
   ENUM_ORDER_TYPE types[];
   ulong tickets[], magics[];
   string symbols[], comments[];
   
   filter.select(properties, tickets, d);
   filter.select(ORDER_SYMBOL, tickets, symbols);
   filter.select(ORDER_COMMENT, tickets, comments);
   filter.select(ORDER_TYPE, tickets, types);
   filter.select(ORDER_MAGIC, tickets, magics);
   
   Print("Orders ..................  ", ArraySize(tickets));
   for (int i=0; i < ArraySize(tickets); i++) {
      Print(tickets[i], "\t", magics[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], "\t", comments[i]);
   }
}


void printPositions() {
   PositionFilter filter;
   
   ENUM_POSITION_PROPERTY_DOUBLE properties[] = {POSITION_PRICE_OPEN, POSITION_VOLUME, POSITION_SL, POSITION_TP, POSITION_PROFIT, POSITION_SWAP};
   
   ENUM_POSITION_TYPE types[];
   double d[][6];
   ulong tickets[], extIds[];
   string symbols[], comments[];
   
   filter.let(POSITION_MAGIC, sets.MagicNumber).select(properties, tickets, d);
   filter.select(POSITION_SYMBOL, tickets, symbols);
   filter.select(POSITION_COMMENT, tickets, comments);
   filter.select(POSITION_TYPE, tickets, types);
   filter.select(POSITION_IDENTIFIER, tickets, extIds);

   Print("Tickets\t  Parent Id\tSymbols \t Trade Type \t\t\t\t\t\tEntry \t Lots \t\t SL  \t\t\t TP \t\t\t\t Profit \tSwat \t\tComments");
   for ( int i =0; i < ArraySize(tickets); i++) {
      Print(tickets[i], "\t", extIds[i] == 0 ? "\t\t\t\t\t\t\t\t\t" : (string)extIds[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", (string)NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], " \t", d[i][4], " \t ", d[i][5], "\t", comments[i]);
      //Print(tickets[i], "\t", extIds[i] == 0 ? "\t\t\t\t\t\t\t\t\t" : extIds[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], " \t", d[i][4], " \t ", d[i][5]);
   }
}


На стороне, я часто вижу эти сообщения:

This single line message always shows whenever I attach my EA to a chart:
Unresolved int value as enum: 8 for MonitorInterface<ENUM_POSITION_PROPERTY_INTEGER,ENUM_POSITION_PROPERTY_DOUBLE,ENUM_POSITION_PROPERTY_STRING>::TradeState


While these ones below shows when it is detached

2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   8 leaked strings left
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   2 undeleted dynamic objects found:
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)      1 object of class 'WebSocketConnectionHybi'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)      1 object of class 'MqlWebSocketTransport'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   576 bytes of leaked memory found
Файлы:
log.txt  34 kb
 
pauldic #:
Простите, что я не указал свой источник, поэтому я вернулся к предложенному вами исправлению, чтобы снова получить ошибки, и похоже, что эти части моего кода являются частями, которые приводят к ошибке, согласно журналу

На стороне, я часто вижу эти сообщения:

.

Я упустил из виду, что буква T уже использовалась в качестве typename шаблона класса (странно, что компилятор не выдал ошибку в этом случае), так что замена T на любую другую свободную букву, например X, будет в порядке:

   template<typename X>
   void ArraySort(X &s[][]) const
   {
      ::ArraySort(s);
   }

Что касается первого предупреждения, то вот объяснение с форумов (которое я давал вам ранее):

Форум о трейдинге, автоматических торговых системах и тестировании торговых стратегий

Эксперты: Программирование на MQL5 для трейдеров - исходные коды из книги. Часть 7

Станислав Короткий, 2025.06.14 16:26

Это просто предупреждение, вызванное тем, что в соответствующем встроенном перечислении MQL5 есть разрыв в константах, которые обычно назначаются последовательно. Этот разрыв возникает из-за того, что MQL5 постоянно меняется, и некоторые константы могут устареть и быть удалены. Вы можете отредактировать исходный код, чтобы предотвратить появление подобных предупреждений.

Что касается утечки памяти - боюсь, что в вашем пользовательском исходном коде есть упущение, в книге это не показано. Вам следует предоставить полный тестовый код для воспроизведения проблемы.

PS. Эффективнее запускать один select для всех интересующих вас свойств:

   // ПРИМЕР: запрос прибыли, символа, тикета для позиций
   // по определенному магическому числу, отсортированные по прибыли
   
   #include <MQL5Book/Tuples.mqh>
   #include <MQL5Book/PositionFilter.mqh>
   #property script_show_inputs
   
   input ulong Magic;
   
   void OnStart()
   {
      int props[] = {POSITION_PROFIT, POSITION_SYMBOL, POSITION_TICKET};
      Tuple3<double,string,ulong> tuples[];
      PositionFilter filter;
      filter.let(POSITION_MAGIC, Magic).select(props, tuples, true);
      ArrayPrint(tuples);
   }



NB: Думаю, модераторам стоит перенести все вопросы и ответы по книге (начиная с #41) в соответствующую тему, например, сюда - https://www.mql5.com/en/forum/459067.

 
Stanislav Korotky #:

Я упустил из виду, что буква T уже использовалась в качестве шаблона класса typename (странно, что компилятор не выдал ошибку в этом случае), так что замена T на любую другую свободную букву, например X, пройдет нормально:

Что касается первого предупреждения, то вот объяснение с форумов (которое я приводил вам ранее):

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

PS. Эффективнее запускать один select для всех интересующих вас свойств:



NB: Думаю, модераторам стоит перенести все вопросы и ответы по книге (начиная с #41) в соответствующую тему, например, сюда - https://www.mql5.com/en/forum/459067.

Большое спасибо, что небольшое изменение T -> X сделало волшебство. И еще раз спасибо за указатель на мой предыдущий вопрос (я забыл, что спрашивал раньше), а ваше напоминание помогло увидеть обновление на toyjson3.mqh, которое я пропустил ранее, а для 'select' am я сделаю исправления.

Я считаю, что вы правы насчет утечки, думаю, я уже имею представление, откуда она происходит.

Спасибо вам большое, брат.
 
void printActiveOrders() {
   int properties[] = {ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP, ORDER_TICKET, ORDER_MAGIC, ORDER_TYPE, ORDER_SYMBOL, ORDER_COMMENT};
   Tuple9<double,double,double,double,long,long,long,string,string> values[]; 
   OrderFilter filter;
   filter.select(properties, values);
   Print("\nFound:  ", ArraySize(values), " Orders\n{ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP, ORDER_TICKET, ORDER_MAGIC, ORDER_TYPE, ORDER_SYMBOL, ORDER_COMMENT}");
   ArrayPrint(values);
}

void printDeals() {
   DealFilter filter;    
   int properties[] = {DEAL_TIME, DEAL_SYMBOL, DEAL_TICKET, DEAL_TYPE, DEAL_VOLUME, DEAL_PRICE, DEAL_COMMISSION, DEAL_PROFIT};
   
   Tuple8<long,string,long,long,double,double,double,double> data[];   
   filter.select(properties, data, true); // Фильтр по времени
   Print("\nFound:  ", ArraySize(data), " Deals\nTIME, SYMBOL, TICKET, TYPE, VOLUME, PRICE, COMMISSION, PROFIT");
   ArrayPrint(data);
}

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

 
pauldic #:

Я могу получить доступ к сделкам и ордерам с помощью этого кода, но я не смог понять, как получить доступ к ним для определенного таймфрейма. Пожалуйста, подскажите мне какой-нибудь документ или пример, как сделать то же самое для определенного таймфрейма.

Ордера, сделки, позиции никак не связаны с таймфреймами. Вы либо что-то не поняли, либо ваша формулировка неверна.