PrintXYZ/PrintXYZ.mqh
2025-09-19 20:24:21 +00:00

438 lines
43 KiB
MQL5

//+------------------------------------------------------------------+
//| PrintXYZ.mqh |
//| Copyright © 2018, Amr Ali |
//| https://www.mql5.com/en/users/amrali |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2024, Amr Ali"
#property link "https://www.mql5.com/en/users/amrali"
#property version "1.50"
#property description "PrintXYZ() library to print massive information from the terminal."
// Updates:
// 2025.02.15 - v.1.20 : Initial release.
// 2025.02.17 - v.1.30 : Added function PrintTesterStatistics(). Output more information from the existing functions.
// 2025.02.20 - v.1.40 : Added function PrintOpenCL() - Prints the OpenCL device properties to the Experts tab.
// 2025.02.21 - v.1.50 : Added function-like macro PrintExpr() - Prints a stringified expression along with its value.
// 2025.02.22 - v.1.52 : Printing enumeration parameter in the function information output.
#ifndef PRINT_XYZ_UNIQUE_HEADER_ID_H
#define PRINT_XYZ_UNIQUE_HEADER_ID_H
//+------------------------------------------------------------------+
//| Functions in the 'PrintXYZ' library. |
//+------------------------------------------------------------------+
/*
void PrintAccount();
void PrintTerminal();
void PrintMQLInfo();
void PrintChart( long chart_id );
void PrintObject( long chart_id, string name );
void PrintSymbol( string symbol );
void PrintSeries( string symbol, ENUM_TIMEFRAMES timeframe );
void PrintPosition( ulong pos_ticket );
void PrintOrder( ulong order_ticket );
void PrintDeal( ulong deal_ticket );
void PrintHistoryOrder( ulong order_ticket );
void PrintOpenCL( int device );
void PrintTesterStatistics();
void PrintEnum<T> ();
void PrintStruct<T> (T& struct_var);
PrintExpr(x); // macro
*/
//+------------------------------------------------------------------+
//| Print enumeration definition. |
//+------------------------------------------------------------------+
//| 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(" };");
}
//+------------------------------------------------------------------+
//| Print sructure variable. |
//+------------------------------------------------------------------+
template <typename T>
void PrintStruct(T& struct_var)
{
T arr[1]; // one-element array
arr[0] = struct_var;
ArrayPrint(arr);
}
//+------------------------------------------------------------------+
//| Print a stringified expression along with its value and type. |
//| Used mainly to debug expressions, variables or function calls. |
//+------------------------------------------------------------------+
#define PrintExpr(x) Print(#x, " = ", x, " ["+typename(x)+"]")
//+------------------------------------------------------------------+
//| Helper macros to print a lot of information from the terminal. |
//+------------------------------------------------------------------+
#define PROPERTIES(func_invocation, enumtype) \
do { \
string func_info=#func_invocation; \
StringReplace(func_info,"prop_id",#enumtype); \
Print(func_info+":"); \
for(int i=0; i<4600; ++i) { \
enumtype prop_id = (enumtype)i; \
string prop_str = EnumToString(prop_id); \
if(StringFind(prop_str,"::")<0) \
{ \ /* if valid enum value 'i' */
if(StringFind(func_info,"Integer")<0) \
Print(" ",prop_str," = ",func_invocation); \
else \
PrintProp(prop_str,(long)func_invocation); \
} \
} \
} while (0)
void PrintProp(string prop_str, long result)
{
if(prop_str=="ACCOUNT_MARGIN_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_ACCOUNT_MARGIN_MODE)result),"(",result,")");
else if(prop_str=="ACCOUNT_MARGIN_SO_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_ACCOUNT_STOPOUT_MODE)result),"(",result,")");
else if(prop_str=="ACCOUNT_TRADE_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_ACCOUNT_TRADE_MODE)result),"(",result,")");
else if(prop_str=="CHART_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_CHART_MODE)result),"(",result,")");
else if(prop_str=="CHART_SHOW_VOLUMES")
Print(" ",prop_str," = ",EnumToString((ENUM_CHART_VOLUME_MODE)result),"(",result,")");
else if(prop_str=="CL_DEVICE_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_CL_DEVICE_TYPE)result),"(",result,")");
else if(prop_str=="DEAL_ENTRY")
Print(" ",prop_str," = ",EnumToString((ENUM_DEAL_ENTRY)result),"(",result,")");
else if(prop_str=="DEAL_REASON")
Print(" ",prop_str," = ",EnumToString((ENUM_DEAL_REASON)result),"(",result,")");
else if(prop_str=="DEAL_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_DEAL_TYPE)result),"(",result,")");
else if(prop_str=="MQL_LICENSE_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_LICENSE_TYPE)result),"(",result,")");
else if(prop_str=="MQL_PROGRAM_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_PROGRAM_TYPE)result),"(",result,")");
else if(prop_str=="OBJPROP_ALIGN")
Print(" ",prop_str," = ",EnumToString((ENUM_ALIGN_MODE)result),"(",result,")");
else if(prop_str=="OBJPROP_BORDER_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_BORDER_TYPE)result),"(",result,")");
else if(prop_str=="OBJPROP_CORNER")
Print(" ",prop_str," = ",EnumToString((ENUM_BASE_CORNER)result),"(",result,")");
else if(prop_str=="OBJPROP_DEGREE")
Print(" ",prop_str," = ",EnumToString((ENUM_ELLIOT_WAVE_DEGREE)result),"(",result,")");
else if(prop_str=="OBJPROP_DIRECTION")
Print(" ",prop_str," = ",EnumToString((ENUM_GANN_DIRECTION)result),"(",result,")");
else if(prop_str=="OBJPROP_LEVELSTYLE")
Print(" ",prop_str," = ",EnumToString((ENUM_LINE_STYLE)result),"(",result,")");
else if(prop_str=="OBJPROP_PERIOD")
Print(" ",prop_str," = ",EnumToString((ENUM_TIMEFRAMES)result),"(",result,")");
else if(prop_str=="OBJPROP_STYLE")
Print(" ",prop_str," = ",EnumToString((ENUM_LINE_STYLE)result),"(",result,")");
else if(prop_str=="OBJPROP_TIMEFRAMES")
Print(" ",prop_str," = ",result==0x001fffff?("OBJ_ALL_PERIODS("+(string)result+")"):(string)result);
else if(prop_str=="OBJPROP_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_OBJECT)result),"(",result,")");
else if(prop_str=="ORDER_REASON")
Print(" ",prop_str," = ",EnumToString((ENUM_ORDER_REASON)result),"(",result,")");
else if(prop_str=="ORDER_STATE")
Print(" ",prop_str," = ",EnumToString((ENUM_ORDER_STATE)result),"(",result,")");
else if(prop_str=="ORDER_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_ORDER_TYPE)result),"(",result,")");
else if(prop_str=="ORDER_TYPE_FILLING")
Print(" ",prop_str," = ",EnumToString((ENUM_ORDER_TYPE_FILLING)result),"(",result,")");
else if(prop_str=="ORDER_TYPE_TIME")
Print(" ",prop_str," = ",EnumToString((ENUM_ORDER_TYPE_TIME)result),"(",result,")");
else if(prop_str=="POSITION_REASON")
Print(" ",prop_str," = ",EnumToString((ENUM_POSITION_REASON)result),"(",result,")");
else if(prop_str=="POSITION_TYPE")
Print(" ",prop_str," = ",EnumToString((ENUM_POSITION_TYPE)result),"(",result,")");
else if(prop_str=="SYMBOL_CHART_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_CHART_MODE)result),"(",result,")");
else if(prop_str=="SYMBOL_EXPIRATION_MODE")
Print(" ",prop_str," = ",result==15?("SYMBOL_EXPIRATION_ALL("+(string)result+")"):(string)result);
else if(prop_str=="SYMBOL_FILLING_MODE")
{
string str_filling="";
if(result==0) str_filling="RETURN";
if((result&SYMBOL_FILLING_IOC)!=0) str_filling+="SYMBOL_FILLING_IOC";
if((result&SYMBOL_FILLING_FOK)!=0) str_filling+="|SYMBOL_FILLING_FOK";
Print(" ",prop_str," = ",str_filling,"(",result,")");
}
else if(prop_str=="SYMBOL_INDUSTRY")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_INDUSTRY)result),"(",result,")");
else if(prop_str=="SYMBOL_OPTION_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_OPTION_MODE)result),"(",result,")");
else if(prop_str=="SYMBOL_OPTION_RIGHT")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_OPTION_RIGHT)result),"(",result,")");
else if(prop_str=="SYMBOL_ORDER_GTC_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_ORDER_GTC_MODE)result),"(",result,")");
else if(prop_str=="SYMBOL_ORDER_MODE")
Print(" ",prop_str," = ",result==127?("SYMBOL_ALL_ORDERS("+(string)result+")"):(string)result);
else if(prop_str=="SYMBOL_SECTOR")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_SECTOR)result),"(",result,")");
else if(prop_str=="SYMBOL_SWAP_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_SWAP_MODE)result),"(",result,")");
else if(prop_str=="SYMBOL_SWAP_ROLLOVER3DAYS")
Print(" ",prop_str," = ",EnumToString((ENUM_DAY_OF_WEEK)result),"(",result,")");
else if(prop_str=="SYMBOL_TRADE_CALC_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_CALC_MODE)result),"(",result,")");
else if(prop_str=="SYMBOL_TRADE_EXEMODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_TRADE_EXECUTION)result),"(",result,")");
else if(prop_str=="SYMBOL_TRADE_MODE")
Print(" ",prop_str," = ",EnumToString((ENUM_SYMBOL_TRADE_MODE)result),"(",result,")");
else if(StringFind(prop_str,"_MSC")>=0)
Print(" ",prop_str," = ",TimeToString((datetime)result/1000,TIME_DATE|TIME_SECONDS),".",IntegerToString(result%1000, 3, '0'));
else if(StringFind(prop_str,"TIME")>=0||(StringFind(prop_str,"SERIES_")>=0&&StringFind(prop_str,"DATE")>=0))
Print(" ",prop_str," = ",TimeToString((datetime)result,TIME_DATE|TIME_SECONDS));
else if(StringFind(prop_str,"COLOR")>=0)
Print(" ",prop_str," = ",ColorToString((color)result,true));
else
Print(" ",prop_str," = ",result);
}
//+------------------------------------------------------------------+
//| Prints the account specification to the Experts tab. |
//+------------------------------------------------------------------+
void PrintAccount(void)
{
if(AccountInfoInteger(ACCOUNT_LOGIN))
{
Print("ACCOUNT INFORMATION <<==============================");
PROPERTIES(AccountInfoInteger(prop_id),ENUM_ACCOUNT_INFO_INTEGER);
PROPERTIES(AccountInfoDouble(prop_id),ENUM_ACCOUNT_INFO_DOUBLE);
PROPERTIES(AccountInfoString(prop_id),ENUM_ACCOUNT_INFO_STRING);
}
//--- additional account info
PrintExpr(SymbolsTotal(true));
PrintExpr(SymbolsTotal(false));
PrintExpr(PositionsTotal());
PrintExpr(OrdersTotal());
HistorySelect(0,INT_MAX);
PrintExpr(HistoryDealsTotal());
PrintExpr(HistoryOrdersTotal());
}
//+------------------------------------------------------------------+
//| Prints the terminal properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintTerminal(void)
{
if(TerminalInfoString(TERMINAL_COMPANY)!="")
{
Print("TERMINAL INFORMATION <<==============================");
PROPERTIES(TerminalInfoInteger(prop_id),ENUM_TERMINAL_INFO_INTEGER);
PROPERTIES(TerminalInfoDouble(prop_id),ENUM_TERMINAL_INFO_DOUBLE);
PROPERTIES(TerminalInfoString(prop_id),ENUM_TERMINAL_INFO_STRING);
}
Print("TIME ZONE INFORMATION <<==============================");
PrintExpr(TimeTradeServer());
PrintExpr(TimeCurrent());
PrintExpr(TimeGMT());
PrintExpr(TimeLocal());
PrintExpr(TimeGMTOffset());
PrintExpr(TimeDaylightSavings());
}
//+------------------------------------------------------------------+
//| Prints the running mql5 program properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintMQLInfo(void)
{
if(TerminalInfoString(TERMINAL_COMPANY)!="")
{
Print("PROGRAM INFORMATION <<==============================");
printf("Compiler Version: %d (__MQLBUILD__), %s (__CPU_ARCHITECTURE__)", __MQLBUILD__, __CPU_ARCHITECTURE__);
PROPERTIES(MQLInfoInteger(prop_id),ENUM_MQL_INFO_INTEGER);
PROPERTIES(MQLInfoString(prop_id),ENUM_MQL_INFO_STRING);
}
}
//+------------------------------------------------------------------+
//| Prints the chart properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintChart(const long chart_id) // 0 means the current chart
{
if(ChartSymbol(chart_id)!="")
{
Print("CHART INFORMATION <<==============================");
string period=StringSubstr(EnumToString(ChartPeriod(chart_id)),7);
PrintFormat("Chart(%s,%s)",ChartSymbol(chart_id),period);
PROPERTIES(ChartGetInteger(chart_id,prop_id),ENUM_CHART_PROPERTY_INTEGER);
PROPERTIES(ChartGetDouble(chart_id,prop_id),ENUM_CHART_PROPERTY_DOUBLE);
PROPERTIES(ChartGetString(chart_id,prop_id),ENUM_CHART_PROPERTY_STRING);
//--- print the indicator list
for(int w=0;w<(int)ChartGetInteger(chart_id,CHART_WINDOWS_TOTAL);w++)
for(int i=0;i<ChartIndicatorsTotal(chart_id,w);i++)
PrintFormat("ChartIndicatorName(%d,%d) = \"%s\"",w,i,ChartIndicatorName(chart_id,w,i));
}
}
//+------------------------------------------------------------------+
//| Prints the graphic object properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintObject(const long chart_id, const string objname) // 0 means the current chart
{
if(ObjectFind(chart_id,objname)>=0)
{
Print("OBJECT INFORMATION <<==============================");
PROPERTIES(ObjectGetInteger(chart_id,objname,prop_id),ENUM_OBJECT_PROPERTY_INTEGER);
PROPERTIES(ObjectGetDouble(chart_id,objname,prop_id),ENUM_OBJECT_PROPERTY_DOUBLE);
PROPERTIES(ObjectGetString(chart_id,objname,prop_id),ENUM_OBJECT_PROPERTY_STRING);
}
}
//+------------------------------------------------------------------+
//| Prints the symbol specification to the Experts tab. |
//+------------------------------------------------------------------+
void PrintSymbol(const string symbol)
{
if(SymbolSelect(symbol,true))
{
Print("SYMBOL INFORMATION <<==============================");
Print(symbol,", ",SymbolInfoString(symbol,SYMBOL_DESCRIPTION));
PROPERTIES(SymbolInfoInteger(symbol,prop_id),ENUM_SYMBOL_INFO_INTEGER);
PROPERTIES(SymbolInfoDouble(symbol,prop_id),ENUM_SYMBOL_INFO_DOUBLE);
PROPERTIES(SymbolInfoString(symbol,prop_id),ENUM_SYMBOL_INFO_STRING);
Print("SymbolInfoSessionTrade(): symbol trading sessions");
for(int i = 0; i < 7; i++) {
string str="";
int session=0;
datetime from,to;
while(SymbolInfoSessionTrade(symbol,(ENUM_DAY_OF_WEEK)i,session++,from,to))
str+=TimeToString(from,TIME_MINUTES)+"-"+TimeToString(to,TIME_MINUTES)+" ";
PrintFormat("%10s: %s",EnumToString((ENUM_DAY_OF_WEEK)i),str);
}
//--- additional symbol info
double margin_lot=-1;
if(OrderCalcMargin(ORDER_TYPE_BUY,symbol,1.0,SymbolInfoDouble(symbol,SYMBOL_ASK),margin_lot))
Print("OrderCalcMargin(Buy, 1.0 Lot) = ", DoubleToString(margin_lot,2)," ",AccountInfoString(ACCOUNT_CURRENCY));
PrintExpr(SymbolIsSynchronized(symbol));
}
}
//+------------------------------------------------------------------+
//| Prints the historical data properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintSeries(const string symbol, const ENUM_TIMEFRAMES timeframe)
{
if(SymbolSelect(symbol,true))
{
Print("SERIES INFORMATION <<==============================");
PROPERTIES(SeriesInfoInteger(symbol,timeframe,prop_id),ENUM_SERIES_INFO_INTEGER);
}
}
//+------------------------------------------------------------------+
//| Prints the position properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintPosition(const ulong pos_ticket)
{
if((PositionGetInteger(POSITION_TICKET) == pos_ticket && pos_ticket != 0)
|| PositionSelectByTicket(pos_ticket))
{
Print("POSITION INFORMATION <<==============================");
PROPERTIES(PositionGetInteger(prop_id),ENUM_POSITION_PROPERTY_INTEGER);
PROPERTIES(PositionGetDouble(prop_id),ENUM_POSITION_PROPERTY_DOUBLE);
PROPERTIES(PositionGetString(prop_id),ENUM_POSITION_PROPERTY_STRING);
}
}
//+------------------------------------------------------------------+
//| Prints the order properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintOrder(const ulong order_ticket)
{
if((OrderGetInteger(ORDER_TICKET) == order_ticket && order_ticket != 0)
|| OrderSelect(order_ticket))
{
Print("ORDER INFORMATION <<==============================");
PROPERTIES(OrderGetInteger(prop_id),ENUM_ORDER_PROPERTY_INTEGER);
PROPERTIES(OrderGetDouble(prop_id),ENUM_ORDER_PROPERTY_DOUBLE);
PROPERTIES(OrderGetString(prop_id),ENUM_ORDER_PROPERTY_STRING);
}
}
//+------------------------------------------------------------------+
//| Prints the history deal properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintDeal(const ulong deal_ticket)
{
if((HistoryDealGetInteger(deal_ticket,DEAL_TICKET) == deal_ticket && deal_ticket != 0)
|| HistoryDealSelect(deal_ticket))
{
Print("DEAL INFORMATION <<==============================");
PROPERTIES(HistoryDealGetInteger(deal_ticket,prop_id),ENUM_DEAL_PROPERTY_INTEGER);
PROPERTIES(HistoryDealGetDouble(deal_ticket,prop_id),ENUM_DEAL_PROPERTY_DOUBLE);
PROPERTIES(HistoryDealGetString(deal_ticket,prop_id),ENUM_DEAL_PROPERTY_STRING);
}
}
//+------------------------------------------------------------------+
//| Prints the history order properties to the Experts tab. |
//+------------------------------------------------------------------+
void PrintHistoryOrder(const ulong order_ticket)
{
if((HistoryOrderGetInteger(order_ticket,ORDER_TICKET) == order_ticket && order_ticket != 0)
|| HistoryOrderSelect(order_ticket))
{
Print("HISTORY ORDER INFORMATION <<==============================");
PROPERTIES(HistoryOrderGetInteger(order_ticket,prop_id),ENUM_ORDER_PROPERTY_INTEGER);
PROPERTIES(HistoryOrderGetDouble(order_ticket,prop_id),ENUM_ORDER_PROPERTY_DOUBLE);
PROPERTIES(HistoryOrderGetString(order_ticket,prop_id),ENUM_ORDER_PROPERTY_STRING);
}
}
//+------------------------------------------------------------------+
//| Prints the tester statistical parameters to the Journal tab. |
//| This can be called inside OnTester() or OnDeinit() in tester. |
//+------------------------------------------------------------------+
void PrintTesterStatistics(void)
{
if(MQLInfoInteger(MQL_TESTER))
{
Print("TESTER STATISTICS <<==============================");
PROPERTIES(TesterStatistics(prop_id),ENUM_STATISTICS);
}
}
//+------------------------------------------------------------------+
//| Prints the OpenCL device properties to the Experts tab. |
//| [in] device : index of the OpenCL device in the system or type. |
//| CL_USE_ANY : any available device with OpenCL support. |
//| CL_USE_CPU_ONLY : only OpenCL emulation on CPU is allowed. |
//| CL_USE_GPU_ONLY : only video cards with OpenCL support. |
//| CL_USE_GPU_DOUBLE_ONLY : only the GPUs that support type double. |
//+------------------------------------------------------------------+
void PrintOpenCL(const int device)
{
int cl_ctx;
if((cl_ctx=CLContextCreate(device))!=INVALID_HANDLE)
{
Print("OpenCL INFORMATION <<==============================");
PROPERTIES(CLGetInfoInteger(cl_ctx,prop_id),ENUM_OPENCL_PROPERTY_INTEGER);
PROPERTIES(CLGetInfoString(cl_ctx,prop_id),ENUM_OPENCL_PROPERTY_STRING);
CLContextFree(cl_ctx);
}
}
//+------------------------------------------------------------------+
//| OpenCL helper function. |
//+------------------------------------------------------------------+
string CLGetInfoString(int handle, ENUM_OPENCL_PROPERTY_STRING prop)
{
string value;
return CLGetInfoString(handle,prop,value)? value : NULL;
}
#undef PROPERTIES
#endif // #ifndef PRINT_XYZ_UNIQUE_HEADER_ID_H