Experts: MQL5 Programming for Traders – Source Codes from the Book. Part 6

 

MQL5 Programming for Traders – Source Codes from the Book. Part 6:

In Part 6 of the "MQL5 Programming for Traders", we will study a key component of the MQL5 language – trading automation. We will start with a description of the fundamental entities, such as financial instrument specifications and trading account settings. These are prerequisites for creating properly operating Expert Advisors.

MQL5 Programming for Traders – Source Codes from the Book. Part 6

Author: MetaQuotes

 
Great
 

Use the CODE button (Alt-S) when inserting code.

A moderator formatted the incorrectly pasted code. Usually, such code is removed.

@Stanislav Korotky Please can you help look into this error, I believe it started after MT5 updates because I knew the code works in the previous months without any modifications.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20

parameter convertion type 'double[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 332 20
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 163 17


I suspect the code below will help to replicate the issue:

void printSymbols() {
   SymbolFilter f;                      // filter object
   string symbols[];                    // array for names 
   long permissions[][2];               // array for data (property values)
   
   // list of requested symbol properties
   ENUM_SYMBOL_INFO_INTEGER modes[] = {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // apply the filter, get arrays with results
   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) {
         // display bit and number descriptions "as is"
         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 #:
@Stanislav Korotky Please can you help look into this error, I believe it started after MT5 updates because I knew the code works in the previous months without any modifications.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20
parameter convertion type 'double[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 332 20
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 163 17


I suspect the code below will help to replicate the issue:


Please find the lines:

   // we need this overload because built-in ArraySort
   // does not support arrays of strings
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }

in the header files SymbolFilter.mqh and TradeFilter.mqh, and add the following method overload next to them:

   // we need this overload because built-in ArraySort
   // does not support arrays of strings
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }
   
   template<typename T>
   void ArraySort(T &s[][]) const
   {
      ::ArraySort(s);
   }
PS. This question seems unrelated to the article.
 
Stanislav Korotky #:

Please find the lines:

in the header files SymbolFilter.mqh and TradeFilter.mqh, and add the following method overload next to them:

PS. This question seems unrelated to the article.

Thank you for your quick response, after making the update, I got more errors saying:

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..

I noticed that calling the generic QuickSortTm directly instead of the the ArraySort temporarily fixes the issue though I do not believe it is the optimal solution

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

Thank you for your quick response, after making the update, I got more errors saying:

That's strange, after the suggested fix above I have compiled and run this script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 successfully on build 5346. You did not show your source code.
 
Stanislav Korotky #:
That's strange, after the suggested fix above I have compiled and run this script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 successfully on build 5346. You did not show your source code.
Forgive me for omitting my source, so I reverted to your suggested fix so I can get the errors again and it looks like these parts of my code are the parts that lead to the error according to the log
I am running on Version 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]);
   }
}


On the side, I often see these messages:

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 (1s) Index.0,M15)   8 leaked strings left
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1s) Index.0,M15)   2 undeleted dynamic objects found:
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1s) Index.0,M15)      1 object of class 'WebSocketConnectionHybi'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1s) Index.0,M15)      1 object of class 'MqlWebSocketTransport'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1s) Index.0,M15)   576 bytes of leaked memory found
Files:
log.txt  34 kb
 
pauldic #:
Forgive me for omitting my source, so I reverted to your suggested fix so I can get the errors again and it looks like these parts of my code are the parts that lead to the error according to the log

On the side, I often see these messages:

I overlooked that the letter T was already used as the class template typename (it's strange that the compiler did not produce an error in this case), so changing T to any other free letter will be ok, for example X:

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

As for the first warning, here is an explanation from the forums (which I gave to you earlier):

Forum on trading, automated trading systems and testing trading strategies

Experts: MQL5 Programming for Traders – Source Codes from the Book. Part 7

Stanislav Korotky, 2025.06.14 16:26

This is just a warning caused by the fact that the corresponding built-in enumeration of MQL5 has a gap in the constants which are normally assigned consecutively. This gap is occured because MQL5 is constantly changing, and some constants can become obsolete and then be eliminated. You can edit the source code to prevent such warnings.

And about the leaked memory - I'm afraid there is an omission in your custom source code, the book did not show such things. You should provide a complete test code to reproduce the problem.

PS. It's more efficient to run a single select for all properties of your interest:

   // EXAMPLE: request profit, symbol, ticket for positions
   //          by specific magic-number, sorted by profit
   
   #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: I think moderators should move all questions and answers about the book (starting from #41) to appropriate thread, for example, here - https://www.mql5.com/en/forum/459067.

Experts: MQL5 Programming for Traders – Source Codes from the Book. Part 6
Experts: MQL5 Programming for Traders – Source Codes from the Book. Part 6
  • 2023.12.15
  • www.mql5.com
MQL5 Programming for Traders – Source Codes from the Book. Part 6 : Author: MetaQuotes...
 
Stanislav Korotky #:

I overlooked that the letter T was already used as the class template typename (it's strange that the compiler did not produce an error in this case), so changing T to any other free letter will be ok, for example X:

As for the first warning, here is an explanation from the forums (which I gave to you earlier):

And about the leaked memory - I'm afraid there is an omission in your custom source code, the book did not show such things. You should provide a complete test code to reproduce the problem.

PS. It's more efficient to run a single select for all properties of your interest:



NB: I think moderators should move all questions and answers about the book (starting from #41) to appropriate thread, for example, here - https://www.mql5.com/en/forum/459067.

Thank you so much that little change T -> X did the magic. And thank you again for the pointer to my previous question (i forgot I have asked before) and your reminder helped see the update on toyjson3.mqh which I missed previously and for the 'select' am I will make the corrections.

I believe you are right about the leak, I think I already have an idea where it is coming from.

Thank you so much brother.
 
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); // Filter by time
   Print("\nFound:  ", ArraySize(data), " Deals\nTIME, SYMBOL, TICKET, TYPE, VOLUME, PRICE, COMMISSION, PROFIT");
   ArrayPrint(data);
}

@Stanislav Korotky
I am can access the Deals and Orders and with this code but I have not been able to figure out how to access same for a specific timeframe. Please can you guide me on any doc or sample on how to do same for a specified timeframe

 
pauldic #:

I am can access the Deals and Orders and with this code but I have not been able to figure out how to access same for a specific timeframe. Please can you guide me on any doc or sample on how to do same for a specified timeframe

Orders, deals, positions are not related to timeframes anyhow. You either misunderstood something or your wording is incorrect.