Warrior_EA/System/PrintVerbose.mqh
AnimateDread 0686410b42 refactor(logs): two verbosity levels, and a throttle that works in the tester
The operator's complaint that "the logs get filled" is measurable, so it was measured. The
2026-09-06 tester log is 1,570,535 lines and FOUR print statements are 86.6% of it:

   556,732  35.4%  "Starting direction calculation with total filters: N"
   556,731  35.5%  "Final directional result: N"
   247,146  15.7%  the two "open rejected" traces

None of the four is a decision. Direction() runs on every tick and recurses into every filter -
about eight calls a tick on this fleet - and emits two lines carrying a filter count and a
number. The rejection traces fire on every tick a side is blocked, which on a one-sided chart
is forever.

They were all on the same switch as everything else, so turning VerboseMode on to diagnose one
thing produced a journal too large to search. Added a second level, TraceMode, off by default,
and moved exactly those four sites to it. PrintVerbose() keeps its meaning and none of its ~40
call sites changed.

TCLog's throttle was near-inert where it mattered most. It measured its window with
TimeCurrent(), which in the Strategy Tester is SIMULATED time: a pass over years of history
crosses sixty simulated seconds many times a second, so the throttle admitted nearly every call.
That is why 247,146 lines got through a function whose whole purpose is collapsing them. Now
GetTickCount64(), which is real elapsed milliseconds and behaves identically in both worlds -
unchanged in live trading, genuinely one line per key per minute of run time in a tester pass.
Suppressed calls are counted and reported on the next line through, so nothing is hidden.

Compiled clean in the stage copy: 0 errors, 0 warnings, against a 0/0 baseline taken first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 15:44:31 -04:00

57 lines
3 KiB
MQL5

//+------------------------------------------------------------------+
//| PrintVerbose.mqh |
//| AnimateDread |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//| TWO LEVELS, BECAUSE ONE SWITCH MADE VERBOSE UNUSABLE. |
//| |
//| `VerboseMode` was all-or-nothing, so turning on ANY diagnostic |
//| also turned on the per-tick tracing, and the journal stopped |
//| being readable at exactly the moment someone needed to read it. |
//| Measured on the 2026-09-06 tester log, 1,570,535 lines: |
//| |
//| 556,732 35.4% "Starting direction calculation..." |
//| 556,731 35.5% "Final directional result: ..." |
//| 247,146 15.7% the two open-rejected traces |
//| ------------------------------------------------------------ |
//| 1,360,609 86.6% of the log, from FOUR print statements. |
//| |
//| None of those four is a decision. Direction() runs on every tick |
//| and recurses into every filter, so on this fleet it is ~8 calls a |
//| tick; the two lines it emits carry a filter count and a number. |
//| The rejection traces fire whenever the direction policy blocks a |
//| side, which on a one-sided chart is every tick, forever. |
//| |
//| So: PrintVerbose() keeps its exact meaning and every one of its |
//| ~40 call sites is untouched. PrintTrace() is the new, noisier |
//| level for anything that can fire per tick, and it is OFF unless |
//| the operator asks for it with TraceMode. |
//| |
//| BUILD THE ARGUMENT BEHIND THE GATE, NOT INSIDE THE CALL. These |
//| are plain functions, so an argument is concatenated and formatted |
//| on every call whether or not the level is on. The hot sites |
//| therefore test WarriorTraceEnabled() themselves before building |
//| a string, exactly as the existing sites test VerboseMode. |
//+------------------------------------------------------------------+
#property copyright "AnimateDread"
#property link "https://www.mql5.com"
//--- Level 1: decisions, transitions, per-era summaries. Readable by a human.
void PrintVerbose(string message)
{
if(VerboseMode)
Print(message);
}
//--- Is the per-tick trace level on? Test this before building a trace string.
bool WarriorTraceEnabled(void)
{
return TraceMode;
}
//--- Level 2: per-tick internals. Hundreds of thousands of lines per tester pass.
void PrintTrace(string message)
{
if(TraceMode)
Print(message);
}