- Replaced standard library signal modules with custom implementations to allow for named patterns and improved voting.
- Added new input parameters for module weights, allowing for optimization of individual signal contributions.
- Enhanced the management of trades with new options for breakeven and management cut.
- Introduced a mechanism for dynamic ranking of signal weights based on historical performance.
- Improved initialization logic to ensure proper registration of filters and handling of trading conditions.
- Added detailed logging for trading permissions and account status during initialization.
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>
CExpertCustom and CExpertSignalCustom each defined their own
stops-level order-type decision against the same TCStopsLevel()
helper, identical except CExpertSignalCustom's guard skipped the
EMPTY_VALUE check (a huge finite double would fall through into the
ask/bid comparison and misclassify as a pending order instead of a
market order). Moved the logic into TCResolveOrderType() in
System/TradeChecks.mqh, keeping the more defensive guard; both
classes now delegate. ask/bid are still passed in from each class's
own m_symbol so routing keeps using whatever RefreshRates() snapshot
that class already had - only the duplicated arithmetic moved.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The //| box blocks were excluded from 0b06f8e and 5efdb48 and were what
remained: 160 of them ran to 10+ lines, the longest to 88. Compressed to their
leading topic sentences - 5 lines for a function header, 8 for a file header -
keeping the box format and the standard MQL5 name/author lines verbatim.
Verified at the BYTE level this time, across every in-scope file: the list of
non-comment lines is byte-identical to HEAD and braces balance. The first check
compared a locale-decoded 'git show' against a UTF-8 read and flagged 25 files
that had not changed at all - every BOM and every non-ASCII line mismatched.
47,696 -> 40,665 lines in scope; comment share 38% -> 26%.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Six checks each fetched bid/ask and rejected a non-positive pair with their
own wording. TCLiveQuote() now owns that rule, so what counts as a usable
quote is defined once and every rejection reads the same way. The one
message that said only "no live quote for <symbol>" now names what it was
about to do, like the other five.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
In inference-only backtests, dtStudied could be ahead of the test range, causing new-bar detection to freeze. Replaced with m_lastBarTime to keep detection aligned with runtime history. Added diagnostic logging when a non-neutral softmax output is neutralized by prior correction. Also added validation for order_price, sl, and tp in stop-checking functions to catch non-finite or negative values.
Add freeze-level checks, no-change modification skipping, entry price routing, and per-tick/memory budget monitoring. Override trade actions (Open, Close, Reverse, TrailingStop, TrailingOrder) to validate at the final gate before sending orders.