MQLplus/lib_debug/example/LibDebug_Simple.mq5
super.admin 466f9ca5c5 convert
2025-05-30 16:09:52 +02:00

465 lines
13 KiB
MQL5

/**********************************************************************************
* Copyright (C) 2020 Dominik Egert <info@freie-netze.de>
*
* This file is the lib_debug demonstration file.
*
* Lisence applied: Free, no license applied to this file.
*
* Author Dominik Egert / Freie Netze UG.
**********************************************************************************
*
* Version: 1.01
* State: public
*
* File information
* ================
*
*/
#property version "1.01"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Additional options for LIB_DEBUG
//
// LIB_DEBUG_AUTOENABLE
//
// This flag will make the library switch between runtime and debugging mode, depending on
// the compiler target. (Automatically also defines LIB_DEBUG)
//
// Runtime mode:
// Any program that is compiled in MetaEditor and then launched in Terminal, rather than
// using "Start/resume debugging" buttons from MetaEditor. (CTRL-F5 or F5)
//
// Debugging mode:
// When compiling the program in MEtaEditor and launching by one of the buttons
// "Start/resume debugging" (CTRL-F5 or F5)
//
// Compiler-Target:
// Depending on where a program has been launched, the target is defined either as
// "debugging" or "runtime" environment.
//
//
// LIB_DEBUG_LOGFILE
//
// Debugging library supports output logging to file. This feature can be enabled by defining
// "LIB_DEBUG_LOGFILE" as shown below. (Automatically also defines LIB_DEBUG)
// Logs will be written to Common/* directory.
//
// This feature supports debug logging within optimizer runs of the program.
//
//
// LIB_DEBUG_NO_JOURNAL_OUTPUT
//
// Additionally the expert-journal output can be surpressed, separating the logs into two
// targets. - This way logging debug output and logging terminal output is separated.
//
// Define "LIB_DEBUG_NO_JOURNAL_OUTPUT" to disable expert-journal output from this library.
// (Can only be used if LIB_DEBUG_LOGFILE is defined)
//
//
/////////////////////////////////////////
//
// Include the library
//
#define LIB_DEBUG
#include <MQLplus/lib_debug.mqh>
///////////////////////////////////////////////////////////////////////
//
// In OnInit you can see a simple usage of the debugging macros.
//
// We will only use some stand-alone macros for quick debugging.
//
// DBG_MSG()
// DBG_MSG_VAR()
// DBG_MSG_BITS()
// DBG_MSG_ERRCODE()
// DBG_MSG_EVAL()
//
// Check example below for some variations.
//
// These macros support all built-in datatypes (also in form of arrays).
// (unsigned) char, short, int, long
// bool, datetime, color, complex, matrix(f/c), vector(f/c),
// float, double,
// string, enum, struct, class and interface as well as pointers.
//
//
// And MQL structures:
// MqlDateTime, MqlRates, MqlTick, MqlParam, MqlBookInfo,
// MqlTradeRequest, MqlTradeCheckResult, MqlTradeResult,
// MqlTradeTransaction,
// MqlCalendarCountry, MqlCalendarEvent, MqlCalendarValue,
// DXVector, DXVertexLayout
//
// How to make a custom enumeration resolvable
//
// This needs to be on global scope, will not work for
// enumerations, you declare inside of a functions body.
//
// This works using namespaces as well.
//
enum custom_enum
{
SOME_ENUM_VAL1,
SOME_ENUM_VAL2
};
DBG_ENUM_RESOLVER(custom_enum);
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//////////////////////////////////////////////////////////////
//
// Simple output macros
//
// Some initial debug message
DBG_MSG("Example how to use lib_debug.mqh simple and quick debugging");
// Output details about current program
// Available in debugging and runtime
printf("%s", DBG_STR_EX45_FILEINFO);
// Keep this message also in runtime builds
DBG_MSG_PERSIST("Persistent message in debug and runtime (Runtime is without debug details)");
//////////////////////////////////////////////////////////////
//
// All basic output macros available
//
//////////////////////////////////////////////////////////////
//
// Direct value printing
//
int test_var = 12345;
DBG_MSG("Test A");
DBG_MSG_PERSIST("Some message");
DBG_MSG_VAR(PRICE_CLOSE);
DBG_MSG_VAR(1);
DBG_MSG_VAR(true);
DBG_MSG_VAR(TimeCurrent());
DBG_MSG_VAR(clrBlue);
DBG_MSG_VAR("Print Me");
DBG_MSG_VAR(test_var);
DBG_MSG_VAR_IF(true, test_var);
DBG_MSG_VAR(_LastError);
DBG_MSG_ERRCODE(5004);
DBG_MSG_BITS((uint)123);
DBG_MSG_BITS(test_var);
//////////////////////////////////////////////////////////////
//
// The flexibility of DBG_MSG_VAR
//
// Output primitive variables
custom_enum my_enum = SOME_ENUM_VAL2;
ENUM_APPLIED_PRICE e_val = PRICE_CLOSE;
char c_val = 1;
uchar uc_val = 2;
short s_val = 3;
int i_val = 4;
long l_val = 5;
bool b_val = true;
datetime d_val = TimeCurrent();
float flt_val = (float)1.61;
double dbl_val = 3.14;
color clr_val = clrAqua;
string str_val = "Some string";
DBG_MSG_VAR(my_enum);
DBG_MSG_VAR(e_val);
DBG_MSG_VAR(c_val);
DBG_MSG_VAR(uc_val);
DBG_MSG_VAR(s_val);
DBG_MSG_VAR(i_val);
DBG_MSG_VAR(l_val);
DBG_MSG_VAR(b_val);
DBG_MSG_VAR(d_val);
DBG_MSG_VAR(flt_val);
DBG_MSG_VAR(dbl_val);
DBG_MSG_VAR(clr_val);
DBG_MSG_VAR(str_val);
#ifdef __MQL5__
complex cmplx_val = { 0.1, 0.2 };
vector v_val = { 0, 1, 2, 3 };
vectorf vf_val = { (float)0.1, (float)1.1, (float)2.1, (float)3.1 };
matrix m_val (1, 2);
matrixf mf_val (1.3, 2.3);
complex c1 = { DBL_MIN, 0.2 };
complex c2 = { 0.3, DBL_MAX };
complex c3 = { 0.5, 0.6 };
complex c4 = { 0.6, 0.7 };
matrixc mc_val {{c1, c2}, {c3, c4}};
vectorc vc_val = { c1, c2, c3, c4 };
DBG_MSG_VAR(cmplx_val);
DBG_MSG_VAR(m_val);
DBG_MSG_VAR(mf_val);
DBG_MSG_VAR(mc_val);
DBG_MSG_VAR(v_val);
DBG_MSG_VAR(vf_val);
DBG_MSG_VAR(vc_val);
#endif
//////////////////////////////////////////////////////////////
//
// Print unknown objects, see function at the end.
//
// Example of printing objects
class CObj
{
public:
int test;
CObj() :
test(NULL)
{ };
CObj(const CObj& p_in)
{ test = p_in.test; };
} test_obj;
DBG_MSG_VAR(test_obj);
DBG_MSG_VAR(GetPointer(test_obj));
//////////////////////////////////////////////////////////////
//
// Conditional execution of DBG_MSG() and DBG_MSG_VAR() macro
//
// Use DBG_MSG_IF() as shown below.
// Use DBG_MSG_VAR_IF() as shown below.
//
// NOTE: The fist statement is a boolean evaluation.
// It is encapuslated properly and therefore can
// be anything that evaluates to "true" or "false".
// Same rules apply as for an "if()" statement.
bool printme = true;
DBG_MSG_IF(printme, "This will only show, if a condition is true!");
DBG_MSG_VAR_IF(printme, TimeLocal());
//////////////////////////////////////////////////////////////
//
// Print arrays
//
// Output arrays
int i_arr[50];
for(int cnt = NULL; (cnt < 50) && !_StopFlag; cnt++)
{ i_arr[cnt] = MathRand(); }
DBG_MSG_VAR(i_arr);
string str_val_arr[3];
DBG_MSG_VAR(str_val_arr);
#ifdef __MQL5__
matrixc mc_val1 {{c1, c2}, {c3, c4}};
matrixc mc_val2 {{c2, c1}, {c3, c4}};
matrixc mc_val3 {{c1, c2}, {c4, c3}};
matrixc mc_val_arr[3];
mc_val_arr[0] = mc_val1;
mc_val_arr[1] = mc_val2;
mc_val_arr[2] = mc_val3;
DBG_MSG_VAR(mc_val_arr);
#endif
// Output two arrays side by side
double d_arr[50];
for(int cnt = NULL; (cnt < 50) && !_StopFlag; cnt++)
{ d_arr[cnt] = MathRand(); }
DBG_MSG_LISTDUMP(i_arr, d_arr);
/////////////////////////////////////
//
// Access an array
//
// Check if it is accessible
//
// These macros will be replaced
// for runtime environment to their
// normal usage. - No overhead applied.
//
DBG_MSG_ARRAY_OUT_OF_RANGE(i_arr, 50);
//////////////////////////////////////////////////////////////
//
// Print structures and arrays of structures
//
// Output MQL structures
MqlDateTime mql_dtm;
MqlRates mql_rates;
MqlTick mql_tick;
MqlParam mql_param;
MqlBookInfo mql_book;
DBG_MSG_VAR(mql_dtm);
DBG_MSG_VAR(mql_rates);
DBG_MSG_VAR(mql_tick);
DBG_MSG_VAR(mql_param);
DBG_MSG_VAR(mql_book);
#ifdef __MQL5__
MqlTradeRequest mql_trade_request;
MqlTradeCheckResult mql_tradecheckresult;
MqlTradeResult mql_trade_result;
MqlTradeTransaction mql_transaction;
MqlCalendarCountry mql_cal_cntry;
MqlCalendarEvent mql_cal_event;
MqlCalendarValue mql_cal_value;
DXVector mql_dxvector;
DXVertexLayout mql_dxvertex;
DBG_MSG_VAR(mql_trade_request);
DBG_MSG_VAR(mql_tradecheckresult);
DBG_MSG_VAR(mql_trade_result);
DBG_MSG_VAR(mql_transaction);
DBG_MSG_VAR(mql_cal_cntry);
DBG_MSG_VAR(mql_cal_event);
DBG_MSG_VAR(mql_cal_value);
DBG_MSG_VAR(mql_dxvector);
DBG_MSG_VAR(mql_dxvertex);
#endif
// See the difference in type printed
DBG_MSG_VAR(EnumToString(mql_param.type));
DBG_MSG_VAR(mql_param.type);
DBG_MSG_VAR(mql_param.integer_value);
DBG_MSG_VAR(mql_param.double_value);
// Output arrays of structures
MqlDateTime arr_mql_dtm[3];
MqlRates arr_mql_rates[3];
MqlTick arr_mql_tick[3];
MqlParam arr_mql_param[3];
MqlBookInfo arr_mql_book[3];
DBG_MSG_VAR(arr_mql_dtm);
DBG_MSG_VAR(arr_mql_rates);
DBG_MSG_VAR(arr_mql_tick);
DBG_MSG_VAR(arr_mql_param);
DBG_MSG_VAR(arr_mql_book);
#ifdef __MQL5__
MqlTradeRequest arr_mql_trade_request[3];
MqlTradeCheckResult arr_mql_tradecheckresult[3];
MqlTradeResult arr_mql_trade_result[3];
MqlTradeTransaction arr_mql_transaction[3];
MqlCalendarCountry arr_mql_cal_cntry[3];
MqlCalendarEvent arr_mql_cal_event[3];
MqlCalendarValue arr_mql_cal_value[3];
DBG_MSG_VAR(arr_mql_trade_request);
DBG_MSG_VAR(arr_mql_tradecheckresult);
DBG_MSG_VAR(arr_mql_trade_result);
DBG_MSG_VAR(arr_mql_transaction);
DBG_MSG_VAR(arr_mql_cal_cntry);
DBG_MSG_VAR(arr_mql_cal_event);
DBG_MSG_VAR(arr_mql_cal_value);
#endif
//////////////////////////////////////////////////////////////
//
// Analyze condition statements
//
// Any complexity is supported.
// Applicable to all condition evaluations.
// if(), while(), for(), () ? : ; ....
//
// The last parameter will be always your condition,
// you would have in your original ()-statement.
//
// All combinations are possible.
//
// Here are the available macros:
if( (DBG_MSG_EVAL(0.1 + 0.2 == 0.3))
|| (DBG_MSG_EVAL(0.7 - 0.4 == 0.3)) )
{ Print("true"); }
else
{ Print("false"); }
if(DBG_MSG_EVAL_IF(printme, 0.1 + 0.2 == 0.3))
{ Print("true"); }
else
{ Print("false"); }
if(DBG_MSG_EVAL_CMNT("Check equality", 0.1 + 0.2 == 0.3))
{ Print("true"); }
else
{ Print("false"); }
if(DBG_MSG_EVAL_IF_CMNT(printme, "Check equality", 0.1 + 0.2 == 0.3))
{ Print("true"); }
else
{ Print("false"); }
printme = false;
if(DBG_MSG_EVAL_IF(printme, 0.1 + 0.2 == 0.3))
{ Print("true"); }
else
{ Print("false"); }
if(DBG_MSG_EVAL_IF_CMNT(printme, "Check equality", 0.1 + 0.2 == 0.3))
{ Print("true"); }
else
{ Print("false"); }
// Return
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert OnTick function |
//+------------------------------------------------------------------+
void OnTIck()
{
return;
}