#property version "5.03" /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Difference between LIB_DEBUG_MQLAPI_TRACE and LIB_MQLAPI_TRACE // // LIB_MQLAPI_TRACE // // This will activate api tracing independantly of any debugging configuration. // For general tracing, define this macro, as the following is considered an // option-feature for debugging integration. // // // LIB_DEBUG_MQLAPI_TRACE // // Using this macro to activate the api tracer will only include tracing // within lib_debug-enabled function tracing. // // See example above, but you need to have your function // be set up with these macros: // // DBG_MSG_TRACE_BEGIN and DBG_MSG_TRACE_RETURN, DBG_MSG_NOTRACE_RETURN // // respectively. outside of this block, tracing will be disabled. // // // // Additional options for LIB_DEBUG_MQLAPI_TRACE and LIB_MQLAPI_TRACE // // To always print input parameters to a function, define // // LIB_MQLAPI_TRACE_SHOW_PARAMS // // This will force printing of all input parameters // which are not output parameters only. // // // LIB_MQLAPI_TRACE_SHOW_RESULT // // This will force printing of results from the function call, including // current error state // // // LIB_MQLAPI_TRACE_PERFORMANCE // // This option allows you to measure the time an API call takes in microseconds. // // // !!! IMPORTANT NOTE !!! // // LIB_MQLAPI_TRACE and LIB_DEBUG_MQLAPI_TRACE is incompatible with the standard library from MQL. // Work to resolve this issue is underway, but might take quite a while. // // Until then, if you are using any includes from standard library, you cannot activate // the MQLAPI tracer module. - You will get compiler errors. // // Same goes for any function you created on your own, that shares a name with any of // the functions provided by MQL-API. // // The tracer uses macro substitution to replace and intercept the calls to the API. // Therefore any function with the same name as listed in the file // // "MQLplus/lib_debug/lib_debug_mqlapi_tracer_overwrite_macros.mqh" // // will confuse the compiler and library. You will not be able to compile your code. // // If it is mandatory for you to do so anyways, you need to setup a custom config // for your project. - See below. // // !!! END !!! // ///////////////////////////////////////// // // Include the library // #define LIB_MQLAPI_TRACE #include //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { ////////////////////////////////////////////////////////////// // // Simple output macros // // Some initial debug message DBG_MSG("Example how to use lib_debug.mqh MQL-API-Tracer"); // 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)"); // Set timer EventSetTimer(5); // Return return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Destroy timer EventKillTimer(); // Return return; } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Local init int some_var = MathRand(); // Return return; } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { // CLear the timer for demo purposes EventKillTimer(); // test unbraced if statements if(!MathIsValidNumber(1.23)) Print("number is non valid"); else Print("valid"); // test nested api function calls if(MathIsValidNumber(MathRand())) Print("number is valid"); // test unary operators if(!MathIsValidNumber(MathRand())) Print("number is non valid"); // test void api function srand(GetTickCount()); // test complex expressions + operator precedence rules Print(MathRand() + MathRand() * GetTickCount()); // test unbraced for statements + explicit typecast for(int i = 0; i < 2; i++) (int) floor(log10(rand())); // test accuracy of printing doubles Print(MathAbs(0.3)); Print(MathAbs(0.1 + 0.2)); // test accuracy of printing floats Print(MathAbs(0.7f)); Print(MathAbs(0.1f + 0.6f)); // test typename bug for namespace identifiers. Print(typename((GetTickCount()))); Print(sizeof(GetTickCount())); // test error codes from unsuccessful api function calls FileOpen("file.xyz", FILE_READ); int hdbase = DatabaseOpen("db.sqlite", DATABASE_OPEN_READONLY); DatabaseClose(hdbase); // test correct type promotion of ternary operator. #define tern_expr (true ? MathMax(101, 201) : MathMax("a", "b")) Print(tern_expr); // compiler warning: implicit conversion from 'number' to 'string' (This is correct behaviour!) Print(typename(tern_expr)); // test api function that returns an enumerated value int period = Period(); // test overloads of one api function double ask = SymbolInfoDouble(NULL, SYMBOL_ASK); SymbolInfoDouble(NULL, SYMBOL_ASK, ask); // Return return; }