//+------------------------------------------------------------------+ //| CkDebug.mqh | //| Copyright 2026, Allan NiƱal | //| https://www.allanninal.dev/mql5 | //+------------------------------------------------------------------+ //| Debug log for bug reports, the same in every product. The input | //| (off by default) stays in the product: | //| input bool InpDebug = false; // Debug log for bug reports (Experts tab) //| CkDebugStart(name,version,on,inputs) prints one "DBG start" line | //| with what a report needs: program, version, terminal build, | //| symbol, timeframe, digits, tick size and value, spread, account | //| currency and type (demo/real), the inputs the product passes. | //| Never the login, name, server, balance or equity: users paste | //| these lines into a public comment. | //| CkDbg(msg) prints "DBG : msg" while on, at most | //| CK_DBG_PER_MIN lines a minute (then one "lines skipped" note), | //| so a busy indicator cannot flood the Experts tab. | //+------------------------------------------------------------------+ #ifndef CK_DEBUG_MQH #define CK_DEBUG_MQH #define CK_DBG_PER_MIN 120 bool g_ck_dbg=false; string g_ck_dbg_name=""; datetime g_ck_dbg_min=0; int g_ck_dbg_n=0,g_ck_dbg_skipped=0; string CkAccountKind(void) { long m=AccountInfoInteger(ACCOUNT_TRADE_MODE); return(m==ACCOUNT_TRADE_MODE_DEMO ? "demo" : (m==ACCOUNT_TRADE_MODE_CONTEST ? "contest" : "real")); } void CkDebugStart(const string name,const string version,const bool on,const string inputs="") { g_ck_dbg=on; g_ck_dbg_name=name; if(!on) return; PrintFormat("DBG start: %s %s, terminal build %d, %s %s, digits %d, tick %s value %s, spread %d pts, %s %s account%s%s", name,version,(int)TerminalInfoInteger(TERMINAL_BUILD),_Symbol,EnumToString((ENUM_TIMEFRAMES)_Period),_Digits, DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE),_Digits), DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE),5),(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD), AccountInfoString(ACCOUNT_CURRENCY),CkAccountKind(),MQLInfoInteger(MQL_TESTER) ? ", Strategy Tester" : "", inputs!="" ? ", inputs: "+inputs : ""); } void CkDbg(const string msg) { if(!g_ck_dbg) return; datetime m=TimeLocal()/60; if(m!=g_ck_dbg_min) { if(g_ck_dbg_skipped>0) PrintFormat("DBG %s: %d lines skipped (more than %d a minute)",g_ck_dbg_name,g_ck_dbg_skipped,CK_DBG_PER_MIN); g_ck_dbg_min=m; g_ck_dbg_n=0; g_ck_dbg_skipped=0; } if(++g_ck_dbg_n>CK_DBG_PER_MIN) { g_ck_dbg_skipped++; return; } Print("DBG "+g_ck_dbg_name+": "+msg); } #endif //+------------------------------------------------------------------+