465 lines
13 KiB
MQL5
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;
|
|
}
|