Features of the mql5 language, subtleties and tricks - page 292

 

Sometimes you need to look at all the properties of a symbol, chart, position, order, historical trade/order, etc.

There are a ton of property values that can be added, removed, etc.


Basically, you can succinctly get the values of these properties through such a preset.

// https://www.mql5.com/ru/forum/170952/page236#comment_50527599
template <typename T>
bool IsCorrect( const int Index )
{
  ResetLastError();
  
  return((EnumToString((T)Index) != NULL) && !_LastError);
}

#define  PROPERTIES(A)                                                      \
  for (int i = 0; i < 1000; i++)                                           \
    if (IsCorrect<A>(i))                                                   \
      Str += EnumToString((A)i) + " = " + (string)(PROPERTY((A)i)) + "\n";


Application.

This is how we get all the values of a symbol.

// Все свойства символа в строку.
string SymbolToString( const string Symb = NULL )
{
  string Str = NULL;

#define  PROPERTY(A) SymbolInfoString(Symb, A)
  PROPERTIES(ENUM_SYMBOL_INFO_STRING)
#undef  PROPERTY

#define  PROPERTY(A) SymbolInfoInteger(Symb, A)
  PROPERTIES(ENUM_SYMBOL_INFO_INTEGER)
#undef  PROPERTY
  
#define  PROPERTY(A) SymbolInfoDouble(Symb, A)
  PROPERTIES(ENUM_SYMBOL_INFO_DOUBLE)
#undef  PROPERTY

  return(Str);
}


This way - transactions.

// Все свойства сделки в строку.
string DealToString( const long Ticket )
{
  string Str = NULL;

#define  PROPERTY(A) HistoryDealGetString(Ticket, A)
  PROPERTIES(ENUM_DEAL_PROPERTY_STRING)
#undef  PROPERTY

#define  PROPERTY(A) HistoryDealGetInteger(Ticket, A)
  PROPERTIES(ENUM_DEAL_PROPERTY_INTEGER)
#undef  PROPERTY
  
#define  PROPERTY(A) HistoryDealGetDouble(Ticket, A)
  PROPERTIES(ENUM_DEAL_PROPERTY_DOUBLE)
#undef  PROPERTY

  return(Str);
}


In general, the principle should be clear.


Result.

This is how it will be with the symbol.

void OnStart()
{
  Print(SymbolToString());
}


SYMBOL_BANK = 
SYMBOL_DESCRIPTION = Euro vs US Dollar
SYMBOL_PATH = Forex\EURUSD
SYMBOL_CURRENCY_BASE = EUR
SYMBOL_CURRENCY_PROFIT = USD
SYMBOL_CURRENCY_MARGIN = EUR
SYMBOL_ISIN = 
SYMBOL_BASIS = 
SYMBOL_PAGE = 
SYMBOL_FORMULA = 
SYMBOL_CATEGORY = 
SYMBOL_EXCHANGE = 
SYMBOL_COUNTRY = 
SYMBOL_SECTOR_NAME = Currency
SYMBOL_INDUSTRY_NAME = Undefined
SYMBOL_SELECT = 1
SYMBOL_VOLUME = 0
SYMBOL_VOLUMEHIGH = 0
SYMBOL_VOLUMELOW = 0
SYMBOL_TIME = 1739406769
SYMBOL_DIGITS = 5
SYMBOL_SPREAD = 43
SYMBOL_TICKS_BOOKDEPTH = 10
SYMBOL_TRADE_CALC_MODE = 0
SYMBOL_TRADE_MODE = 4
SYMBOL_TRADE_STOPS_LEVEL = 0
SYMBOL_TRADE_FREEZE_LEVEL = 0
SYMBOL_TRADE_EXEMODE = 2
SYMBOL_SWAP_MODE = 1
SYMBOL_SWAP_ROLLOVER3DAYS = 3
SYMBOL_SPREAD_FLOAT = 1
SYMBOL_EXPIRATION_MODE = 15
SYMBOL_FILLING_MODE = 3
SYMBOL_START_TIME = 0
SYMBOL_EXPIRATION_TIME = 0
SYMBOL_SESSION_DEALS = 0
SYMBOL_SESSION_BUY_ORDERS = 0
SYMBOL_SESSION_SELL_ORDERS = 0
SYMBOL_ORDER_MODE = 127
SYMBOL_OPTION_RIGHT = 0
SYMBOL_OPTION_MODE = 0
SYMBOL_VISIBLE = 1
SYMBOL_CUSTOM = 0
SYMBOL_BACKGROUND_COLOR = 12058551
SYMBOL_CHART_MODE = 0
SYMBOL_ORDER_GTC_MODE = 0
SYMBOL_MARGIN_HEDGED_USE_LEG = 0
SYMBOL_EXIST = 1
SYMBOL_TIME_MSC = 1739406769168
SYMBOL_SECTOR = 12
SYMBOL_INDUSTRY = 0
SYMBOL_SUBSCRIPTION_DELAY = 0
SYMBOL_BID = 1.0384
SYMBOL_BIDHIGH = 1.03857
SYMBOL_BIDLOW = 1.03784
SYMBOL_ASK = 1.03883
SYMBOL_ASKHIGH = 1.03917
SYMBOL_ASKLOW = 1.03862
SYMBOL_LAST = 0.0
SYMBOL_LASTHIGH = 0.0
SYMBOL_LASTLOW = 0.0
SYMBOL_VOLUME_REAL = 0.0
SYMBOL_VOLUMEHIGH_REAL = 0.0
SYMBOL_VOLUMELOW_REAL = 0.0
SYMBOL_POINT = 0.00001
SYMBOL_TRADE_TICK_VALUE = 1.5918243899333024
SYMBOL_TRADE_TICK_SIZE = 0.00001
SYMBOL_TRADE_CONTRACT_SIZE = 100000.0
SYMBOL_VOLUME_MIN = 0.01
SYMBOL_VOLUME_MAX = 100.0
SYMBOL_VOLUME_STEP = 0.01
SYMBOL_SWAP_LONG = -7.71
SYMBOL_SWAP_SHORT = 1.85
SYMBOL_MARGIN_INITIAL = 100000.0
SYMBOL_MARGIN_MAINTENANCE = 0.0
SYMBOL_MARGIN_LONG = 0.0
SYMBOL_MARGIN_SHORT = 0.0
SYMBOL_MARGIN_LIMIT = 0.0
SYMBOL_MARGIN_STOP = 0.0
SYMBOL_MARGIN_STOPLIMIT = 0.0
SYMBOL_TRADE_TICK_VALUE_PROFIT = 1.5918243899333024
SYMBOL_TRADE_TICK_VALUE_LOSS = 1.5927624872579003
SYMBOL_VOLUME_LIMIT = 0.0
SYMBOL_SESSION_VOLUME = 0.0
SYMBOL_SESSION_TURNOVER = 0.0
SYMBOL_SESSION_INTEREST = 0.0
SYMBOL_SESSION_BUY_ORDERS_VOLUME = 0.0
SYMBOL_SESSION_SELL_ORDERS_VOLUME = 0.0
SYMBOL_SESSION_OPEN = 1.03798
SYMBOL_SESSION_CLOSE = 1.0383
SYMBOL_SESSION_AW = 0.0
SYMBOL_SESSION_PRICE_SETTLEMENT = 0.0
SYMBOL_SESSION_PRICE_LIMIT_MIN = 0.0
SYMBOL_SESSION_PRICE_LIMIT_MAX = 0.0
SYMBOL_OPTION_STRIKE = 0.0
SYMBOL_MARGIN_HEDGED = 0.0
SYMBOL_TRADE_LIQUIDITY_RATE = 0.0
SYMBOL_TRADE_FACE_VALUE = 0.0
SYMBOL_TRADE_ACCRUED_INTEREST = 0.0
SYMBOL_PRICE_CHANGE = 0.0096
SYMBOL_PRICE_VOLATILITY = 0.0
SYMBOL_PRICE_THEORETICAL = 0.0
SYMBOL_PRICE_DELTA = 0.0
SYMBOL_PRICE_THETA = 0.0
SYMBOL_PRICE_GAMMA = 0.0
SYMBOL_PRICE_VEGA = 0.0
SYMBOL_PRICE_RHO = 0.0
SYMBOL_PRICE_OMEGA = 0.0
SYMBOL_PRICE_SENSITIVITY = 0.0
SYMBOL_SWAP_SUNDAY = 0.0
SYMBOL_SWAP_MONDAY = 1.0
SYMBOL_SWAP_TUESDAY = 1.0
SYMBOL_SWAP_WEDNESDAY = 3.0
SYMBOL_SWAP_THURSDAY = 1.0
SYMBOL_SWAP_FRIDAY = 1.0
SYMBOL_SWAP_SATURDAY = 0.0


If, suddenly, MQ decide to give access to commissions in the trading platform (this year 18 years since the beginning of development), the script will show it at once....

 
fxsaber #:
// All properties of the deal into a string. string DealToString( const long Ticket )

With and without HistoryDealSelect( Ticket ) different results, I checked.

 
trader6_1 #:

With and without HistoryDealSelect( Ticket ) different results, checked.

Placing a transaction in the available history table and printing transaction properties are functionalities that do not overlap.

 
Aleksandr Slavskii #:

Running the script without HistoryDealSelect()

I add HistoryDealSelect() and run the script

The worst thing you can do in the function of printing a deal is to put HistoryDealSelect into it.

 
fxsaber #:

The worst thing you can do in a transaction printout function is to put a HistoryDealSelect in it.

What do you suggest?

To be satisfied with zeros in the printout?

The script prints zeros in this form

//+------------------------------------------------------------------+
template <typename T>
bool IsCorrect(const int Index)
  {
   ResetLastError();

   return((EnumToString((T)Index) != NULL) && !_LastError);
  }

#define  PROPERTIES(A)                                                      \
  for (int i = 0; i < 1000; i++)                                           \
    if (IsCorrect<A>(i))                                                   \
      Str += EnumToString((A)i) + " = " + (string)(PROPERTY((A)i)) + "\n";
//+------------------------------------------------------------------+
void OnStart()
  {
   //HistoryDealSelect(24406356);
   Print(DealToString(24406356));
  }
//+------------------------------------------------------------------+
// Все свойства сделки в строку.
string DealToString(const long Ticket)
  {
   string Str = NULL;

#define  PROPERTY(A) HistoryDealGetString(Ticket, A)
   PROPERTIES(ENUM_DEAL_PROPERTY_STRING)
#undef  PROPERTY

#define  PROPERTY(A) HistoryDealGetInteger(Ticket, A)
   PROPERTIES(ENUM_DEAL_PROPERTY_INTEGER)
#undef  PROPERTY

#define  PROPERTY(A) HistoryDealGetDouble(Ticket, A)
   PROPERTIES(ENUM_DEAL_PROPERTY_DOUBLE)
#undef  PROPERTY

   return(Str);
  }
//+------------------------------------------------------------------+

If HistoryDealSelect is uncommented, it prints all fields correctly.

 

Forum on trading, automated trading systems and testing trading strategies

Features of mql5 language, subtleties and techniques of work

Aleksandr Slavskii, 2025.02.13 13:18

The script prints zeros in this form

void OnStart()
  {
   //HistoryDealSelect(24406356);
   Print(DealToString(24406356));
  }

If HistoryDealSelect is uncommented, it prints all fields correctly.

Has such a script been published? Try to fix DealToString, we'll discuss it. It is not clear to me at all what we are talking about.

 
fxsaber #:

Has such a script been published? Try fixing DealToString, we'll discuss it. I don't understand at all what we are talking about.

Okay. Never posted.

Someone else did.

void OnStart()
{
  Print(SymbolToString());
}

Well, we're not suckers, we know how to use analogies. But here's the catch, the analogy doesn't work. Not good.


And seriously, I don't understand how to use your code to print all the fields of a transaction.

Let's take an example of a specific task. Let's say we have saved a ticket of a deal in the Expert Advisor and after some time we need to print out everything related to this deal.

HistoryDealSelect is the right way to do it, and you say that it is a mauvais thing to do. How would it not be mauvais?
 
Aleksandr Slavskii #:

how would that not be considered voguish?

Like in the script above.


At most, you can insert it into a function, but I wouldn't recommend it.

if (HistoryDealGetInteger(Ticket, DEAL_TICKET) != Ticket)
  HistoryDealSelect(Ticket);
 
fxsaber #:

Sometimes you need to look at all the properties of a symbol, chart, position, order, historical trade/order, etc.

There are a ton of property values that can be added, removed, etc.

Here is my attempt using these 2 little macros:

#define PROPERTIES1(function, enumtype) \
   for(int i=-2; i<USHORT_MAX+1000; ++i) \
     { \
      enumtype prop_id = (enumtype)i; \
      if(StringFind(EnumToString(prop_id),"::")<0) \
         Print(EnumToString(prop_id),"=",function(prop_id)); \
     }


#define PROPERTIES2(function, param, enumtype) \
   for(int i=-2; i<USHORT_MAX+1000; ++i) \
     { \
      enumtype prop_id = (enumtype)i; \
      if(StringFind(EnumToString(prop_id),"::")<0) \
         Print(EnumToString(prop_id),"=",function(param,prop_id)); \
     }

Getting a ton of information from the platform:

//+------------------------------------------------------------------+
//| Prints the account specification to the Experts tab.             |
//+------------------------------------------------------------------+
void PrintAccount()
  {
   if(AccountInfoInteger(ACCOUNT_LOGIN))
     {
      PROPERTIES1(AccountInfoInteger,ENUM_ACCOUNT_INFO_INTEGER);
      PROPERTIES1(AccountInfoDouble,ENUM_ACCOUNT_INFO_DOUBLE);
      PROPERTIES1(AccountInfoString,ENUM_ACCOUNT_INFO_STRING);
     }
  }

Terminal info:

//+------------------------------------------------------------------+
//| Prints the terminal properties to the Experts tab.               |
//+------------------------------------------------------------------+
void PrintTerminal()
  {
   if(TerminalInfoString(TERMINAL_COMPANY)!="")
     {
      PROPERTIES1(TerminalInfoInteger,ENUM_TERMINAL_INFO_INTEGER);
      PROPERTIES1(TerminalInfoDouble,ENUM_TERMINAL_INFO_DOUBLE);
      PROPERTIES1(TerminalInfoString,ENUM_TERMINAL_INFO_STRING);
     }
  }

Chart info:

//+------------------------------------------------------------------+
//| Prints the chart properties to the Experts tab.                  |
//+------------------------------------------------------------------+
void PrintChart(const long chart_id)  // 0 means the current chart
  {
   if(ChartSymbol(chart_id)!="")
     {
      PROPERTIES2(ChartGetInteger,chart_id,ENUM_CHART_PROPERTY_INTEGER);
      PROPERTIES2(ChartGetDouble,chart_id,ENUM_CHART_PROPERTY_DOUBLE);
      PROPERTIES2(ChartGetString,chart_id,ENUM_CHART_PROPERTY_STRING);
     }
  }

Symbol info:

//+------------------------------------------------------------------+
//| Prints the symbol specification to the Experts tab.              |
//+------------------------------------------------------------------+
void PrintSymbol(const string symbol)
  {
   Print(Symbol(),", ",SymbolInfoString(Symbol(),SYMBOL_DESCRIPTION));
   if(SymbolSelect(symbol,true))
     {
      PROPERTIES2(SymbolInfoInteger,symbol,ENUM_SYMBOL_INFO_INTEGER);
      PROPERTIES2(SymbolInfoDouble,symbol,ENUM_SYMBOL_INFO_DOUBLE);
      PROPERTIES2(SymbolInfoString,symbol,ENUM_SYMBOL_INFO_STRING);
     }
  }

Positions and deals:

//+------------------------------------------------------------------+
//| Prints the position properties to the Experts tab.               |
//+------------------------------------------------------------------+
void PrintPosition(const ulong pos_ticket)
  {
   if(PositionSelectByTicket(pos_ticket))
     {
      PROPERTIES1(PositionGetInteger,ENUM_POSITION_PROPERTY_INTEGER);
      PROPERTIES1(PositionGetDouble,ENUM_POSITION_PROPERTY_DOUBLE);
      PROPERTIES1(PositionGetString,ENUM_POSITION_PROPERTY_STRING);
     }
  }
//+------------------------------------------------------------------+
//| Prints the history deal properties to the Experts tab.           |
//+------------------------------------------------------------------+
void PrintDeal(const ulong deal_ticket)
  {
   if(HistoryDealSelect(deal_ticket))
     {
      PROPERTIES2(HistoryDealGetInteger,deal_ticket,ENUM_DEAL_PROPERTY_INTEGER);
      PROPERTIES2(HistoryDealGetDouble,deal_ticket,ENUM_DEAL_PROPERTY_DOUBLE);
      PROPERTIES2(HistoryDealGetString,deal_ticket,ENUM_DEAL_PROPERTY_STRING);
     }
  }

Orders:

//+------------------------------------------------------------------+
//| Prints the order properties to the Experts tab.                  |
//+------------------------------------------------------------------+
void PrintOrder(const ulong order_ticket)
  {
   if(OrderSelect(order_ticket))
     {
      PROPERTIES1(OrderGetInteger,ENUM_ORDER_PROPERTY_INTEGER);
      PROPERTIES1(OrderGetDouble,ENUM_ORDER_PROPERTY_DOUBLE);
      PROPERTIES1(OrderGetString,ENUM_ORDER_PROPERTY_STRING);
     }
  }
//+------------------------------------------------------------------+
//| Prints the history order properties to the Experts tab.          |
//+------------------------------------------------------------------+
void PrintHistoryOrder(const ulong order_ticket)
  {
   if(HistoryOrderSelect(order_ticket))
     {
      PROPERTIES2(HistoryOrderGetInteger,order_ticket,ENUM_ORDER_PROPERTY_INTEGER);
      PROPERTIES2(HistoryOrderGetDouble,order_ticket,ENUM_ORDER_PROPERTY_DOUBLE);
      PROPERTIES2(HistoryOrderGetString,order_ticket,ENUM_ORDER_PROPERTY_STRING);
     }
  }

Print enumerations:

//+------------------------------------------------------------------+
//| Print enumeration.                                               |
//+------------------------------------------------------------------+
//| Examples:                                                        |
//|                                                                  |
//|   PrintEnum<ENUM_TIMEFRAMES>();                                  |
//|   PrintEnum<ENUM_ACCOUNT_INFO_DOUBLE>();                         |
//|   PrintEnum<ENUM_FP_CLASS>();      // lowest enum value          |
//|   PrintEnum<ENUM_CHART_EVENT>();   // highest enum value         |
//+------------------------------------------------------------------+
template <typename T>
void PrintEnum(T dummy = -1)
  {
   Print(typename(T));
   Print("  {");
   for(int i = -2; i < USHORT_MAX + 1000; i++)
      if(StringFind(EnumToString((T)i),"::")<0)
         printf("   %s = %d,",EnumToString((T)i),i);
   Print("  };");
  }


Test script:

void OnStart()
  {
   PrintAccount();
   PrintTerminal();
   PrintChart(0);
   PrintSymbol(_Symbol);
   PrintPosition(925571424);
   PrintDeal(609261076);
   PrintHistoryOrder(925571424);

   PrintEnum<ENUM_TIMEFRAMES>();
  }
 

Forum on trading, automated trading systems and testing trading strategies

Peculiarities of mql5 language, subtleties and techniques of work

amrali, 2025.02.14 05:37

//+------------------------------------------------------------------+
//| Prints the history deal properties to the Experts tab.           |
//+------------------------------------------------------------------+
void PrintDeal(const ulong deal_ticket)
  {
   if(HistoryDealSelect(deal_ticket))
     {
      PROPERTIES2(HistoryDealGetInteger,deal_ticket,ENUM_DEAL_PROPERTY_INTEGER);
      PROPERTIES2(HistoryDealGetDouble,deal_ticket,ENUM_DEAL_PROPERTY_DOUBLE);
      PROPERTIES2(HistoryDealGetString,deal_ticket,ENUM_DEAL_PROPERTY_STRING);
     }
  }
//+------------------------------------------------------------------+
//| Prints the history order properties to the Experts tab.          |
//+------------------------------------------------------------------+
void PrintHistoryOrder(const ulong order_ticket)
  {
   if(HistoryOrderSelect(order_ticket))
     {
      PROPERTIES2(HistoryOrderGetInteger,order_ticket,ENUM_ORDER_PROPERTY_INTEGER);
      PROPERTIES2(HistoryOrderGetDouble,order_ticket,ENUM_ORDER_PROPERTY_DOUBLE);
      PROPERTIES2(HistoryOrderGetString,order_ticket,ENUM_ORDER_PROPERTY_STRING);
     }
  }

Have done exactly what I warned about.

Forum on trading, automated trading systems and testing trading strategies

Peculiarities of mql5 language, subtleties and techniques of work

fxsaber, 2025.02.13 13:08

The worst thing you can do in the function of printing a deal is to put HistoryDealSelect in it.


Even that is not done.

Forum on trading, automated trading systems and testing trading strategies

Features of the mql5 language, subtleties and techniques of work

fxsaber, 2025.02.13 14:35

The maximum you can put in a function, but I wouldn't recommend doing that.

if (HistoryDealGetInteger(Ticket, DEAL_TICKET) != Ticket)
  HistoryDealSelect(Ticket);

Example of viciousness.

void OnStart()
{
  if (HistorySelect(0, INT_MAX))
  {
    const int Total = HistoryDealsTotal();
    
    for (int i = MathMax(Total - 5, 0); i < Total; i++)
      PrintDeal(HistoryDealGetTicket(i));
  }
}


Architecture.

Forum on trading, automated trading systems and testing trading strategies

Peculiarities of mql5 language, subtleties and techniques of work

fxsaber, 2025.02.13 10:23 AM

Putting a trade into the available history table and printing out the properties of a trade are functionalities that do not overlap.