Commit graph Warrior_EA/Database/DatabaseOperationsManager.mqh
Author SHA1 Message Date
AnimateDread
47a5ef338b Refactor Warrior EA: Integrate custom signal modules, enhance voting mechanism, and improve management features
- 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.
2026-09-13 14:32:40 -04:00
AnimateDread
af3db90353 feat(journal): the shadow journal - every firing, independently, next to the trades taken
Operator: "meta labeling should drastically change the outcome anyways.
unless the journal logs every patterns independently (I think it should
and also voted trades outcomes for comparison)."

Until now the journal recorded POSITIONS - what the agreement gate let
through - so a meta-labeller would have learned from a few dozen trades
per setup. Every arming is now a virtual trade: a pending order at the
setup's own entry and stop, filled when price reaches it inside the
setup's own window, tracked through the same first-passage ladder as a
real position (one shared AdvanceTrack), closed at the ladder's last
horizon, written to the same table as filterID="Virtual:<setup>". The
parent annotates each bar's firings with agree=N, opposed and the armed
combination. Real trades stay filterID="Book", so the two populations
sit on one table. Closed virtual rows are written 200 per commit.

Context now also carries headroom, minutes to the forced close and the
order type. The `journal` global lives in the header so setups and the
signal base reach the one instance the expert feeds.

Also: SQL identifiers are quoted - "2WD_Pattern_0_Sell" starts with a
digit and every Second Wind pattern table failed to create the moment
the database was on in the tester; an index on the natural key so the
replace-on-key scales to a decade of firings; "no closed trades yet" is
verbose again.

Smoke, BTCUSD H1 one month: 52 firings, 26 filled, 26 rows, annotated,
no database errors.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 18:32:38 -04:00
AnimateDread
ad327735db feat(journal): the tester fills the database, and the journal can skip a categorical loser
Operator: "is there not a meta labeling neural network in the EA? why
did it keep taking a losing pattern? The journal is there for that."

There is no meta-label net (CNNFilter is a loader nobody instantiates;
the offline net was never built), the adaptive layer learns management
only by design, and it could not read anyway: SignalDatabaseActive()
switched the DB off for every tester run on the argument that "a tester
run's DB is written and never read" - a premise AdaptiveExitWriter had
already deleted. Every run ended with 93 verbose-level "journal read
failed - database not initialized" lines and learned nothing.

- The DB is ON in a single tester pass; optimisation and forward stay
  off (12 agents on one FILE_COMMON SQLite file finished zero passes).
- A closed trade REPLACES its own row on the natural key (symbol, open
  minute, side, entry price): tester tickets restart at 1 on every run,
  so a re-run over the same history no longer double-counts.
- AdaptiveExitWriter writes skip_long / skip_short when a setup-side is
  a categorical loser on this chart: n >= 60 and t <= -2.5 on realised
  R x risk in bp, gross of commission. Not ranking - the measurement
  that made selection anti-predictive ranked marginal cells against
  each other; this is the shape Second Wind showed on forex (t -4.0).
  A skipped side never arms, so it never counts toward agreement.
- The reader adopts the flags with the exit, once per server day, and
  prints the verdict when it changes.
- "Could not read" is printed once at normal level with the reason.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 17:36:02 -04:00
AnimateDread
4004c48d1b feat(journal+signals): the journal becomes a research journal, the setup becomes a voter, and the exit adapts
THE VOTER FIX, found in the strategy tester and worth stating plainly because it
will bite the next standalone setup too. CExpertSignalCustom weights each child
by VoteCapableWeight(), which is m_weight only when GetPatternCount() > 0 and
ZERO otherwise: a child with no patterns is a news/session-style VETO with no say
in the consensus. CSignalInsideBarGap declared none, so its first tester run
fired 192 times over 2019-2022 and placed nothing - it voted 100 with a capable
weight of 0 and the accumulator divided by zero into 0.00 on every bar. It now
carries one pattern at weight 100, an ID, and its used-series mask, exactly as
every classic module's constructor does. Tester validation of the fixed build is
in progress; this commit is compile-verified only (0 errors, 0 warnings, in a
scratch copy inside the MQL5 tree - the repo path cannot resolve Network.cl).

THE JOURNAL. Two TEXT columns, added IN PLACE with ALTER TABLE (new
EnsureColumn on the database managers) rather than a dbVersion bump, which wipes
the directory:
  context   key=value;... the setup's view at signal time, the same terms the
            research conditioned on, named identically (PublishContext). Accepted
            by the journal only when published within 180 s of the position
            opening, so an expired order's line cannot be inherited by a later
            position from another signal.
  passages  first-touch MINUTE of every stop and target level on the research
            grid plus signed R at each time-stop horizon - the exact fields
            research/pricing.py prices an exit from. A synthetic round-trip
            proved the live format re-prices the traded exit identically to the
            research (max |diff| 4e-7 R) once the horizons carry six decimals.
One honest limit is written into the file header: a live trade is closed by its
own barriers, so from live rows an exit can only be re-selected TIGHTER.

THE ADAPTIVE EXIT. CSignalInsideBarGap reads
Common\Files\Warrior_EA\Adapt\{SYMBOL}_{PERIOD}_inside_bar_u.cfg once per server
day, written by research/journal_adapt.py with the research's discipline (choose
on the older trades, confirm on the newer, placeable stop, stable after dropping
the best 5%). No file means the validated defaults; a file outside the research
grid is refused and logged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 11:23:27 -04:00
AnimateDread
b2784b5a4d Enhance Feature and Topology Interfaces with Bulk Operations and Cache Management
- Added bulk read/write methods for feature caches in IFeaturesView and its implementations to optimize performance.
- Introduced LabelCacheInvalidateAll method to manage label cache invalidation alongside feature cache.
- Implemented PooledIndependentBars method in topology interfaces to account for additional independent observations.
- Enhanced risk budget management with throttling for peak-equity updates to reduce unnecessary file operations.
- Improved error handling and logging for ATR trailing stops to ensure better visibility of issues.
- Updated alt-data handling to prevent unnecessary operations during testing and optimization phases.
2026-08-25 22:51:50 -04:00
AnimateDread
31ad2952f3 refactor(db): dedupe the column-list comma-join loop
InsertTradeRecord and UpdateTradeRecord each hand-rolled the same
"append, comma unless last" loop for building SQL column/placeholder
lists. Extract JoinWithCommas()/PlaceholderList() private helpers so
that shape exists once; pure text-building, no query semantics change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 03:04:23 -04:00
AnimateDread
defab3b2c7 refactor(db): dedupe the identifier-validation guard in CDatabaseOperationsManager
CreateTable/DeleteTable/InsertTradeRecord/FetchRecordCount/FetchOpenTradeEntry/
FetchNewestTimeKey/FetchWinLossCounts/FetchTradeRecords/UpdateTradeRecord/
DeleteOldestEntry each repeated the same three-line "if(!IsValidIdentifier)
{ Print(...); return false; }" block, differing only in the verb printed.
Replaced with one private RequireValidIdentifier(tableName, verb) helper that
does the check + Print + returns the bool; each call site is now a single
guard line. Pure mechanical dedup - every Print message text and control-flow
path is unchanged, no call-site signature changes since it's all internal to
this one class.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 00:58:45 -04:00
AnimateDread
68459208bf fix(meta): make the stale-DB corpus warning unmissable in the tester
The warning lived inside the VerboseMode-gated corpus report, so a
forgotten wipe silently voided an entire 18-year corpus run - the
outdated-row guard rejected the whole replay against leftover rows
and the run appended 35 rows instead of building a corpus. The check
now runs unconditionally at tester OnInit (MetaCorpusStaleCheck): 52
quiet one-row newest-key probes vs the test start, with a loud stop-
wipe-rerun instruction when the DB is newer than the test. Absent
tables probe quietly via FetchNewestTimeKey''s new quiet flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 23:56:26 -04:00
AnimateDread
6819bb4133 perf(db): targeted SQL lookups replace full-table fetches per signal
The historical 1000-row cap existed for a real reason: ProcessSignal
pulled BOTH full tables into MQL struct arrays on every buffered
signal, and UpdateSignalsWeights pulled all 52 per cycle -
materializing thousands of string-bearing structs per event is the
practical limit the cap protected against (SQLite itself has none).
Raising the cap for an 18-year meta-label corpus build would have
made runs crawl; sharding across databases would re-read the same
rows and inherit the same cost.

Every question is now answered inside SQLite, one row or one number
per query, flat in table size:
- FetchOpenTradeEntry: the open (NA) trade''s entryPrice for
  pattern+direction, LIMIT 1
- FetchNewestTimeKey: newest row''s yyyymmddhhmm via max ROWID
  (rows insert chronologically) - the duplicate/outdated guard
- FetchWinLossCounts: COALESCE''d SUM aggregates with the
  before-now bound applied in SQL, replacing the tester-only array
  trim (now also active live, where it is harmless by construction)

ProcessSignal semantics preserved exactly: prune -> close opposite
(stop-and-reverse still registers its own row) -> duplicate/outdated
-> one-open-trade -> register. CalculatePatternWinRate''s array walk
becomes WinRateFromCounts; the private FetchTradeRecords wrapper and
ShouldDeleteOldestEntry are gone. DB_MaxRowsPerTable=20000 is now
cheap at any table size.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 18:53:04 -04:00
AnimateDread
83fa5e4d3d fix(db): a completed DML step is not a failure
Every INSERT/UPDATE a backtest journaled printed a phantom "Failed to
execute bound query (error 5126)" + "Failed to insert/update" pair -
11.7k error lines in one tester run - while every row landed
correctly (verified: v5 DB complete and identical in totals to v4,
results populated, zero non-5126 database errors in the whole log).

5126 is ERR_DATABASE_NO_MORE_DATA, SQLite''s DONE: DatabaseRead()
stepped the statement to completion and there is nothing to read back,
which for DML IS the success outcome. The tester agent reports 5126
where the live terminal reports 0 for the same completed step, and
PrepareAndExecuteBound() treated any nonzero code as failure. Success
is now 0 or 5126; genuine failures (busy, locked, constraint, misuse)
surface as other codes and still fail.

No schema or semantics change - the v5 database and its data are
valid as-is; this only stops the misreporting that would bury a real
error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 13:26:40 -04:00
AnimateDread
5247c34fe9 fix: add error logging for buffer failures and reject trades on invalid stop loss 2026-07-26 12:12:14 -04:00
AnimateDread
74c7395127 feat: add max-pooling and convolution OpenCL kernels, clean up barrier and signal code
- Define MAX_WEIGHT constant (1.0e6) for weight limits in clusters
- Remove redundant barrier from FeedForward kernel (prevents sync issues)
- Port FeedForwardProof and CalcInputGradientProof kernels for max-pooling (no weights, sliding max)
- Port FeedForwardConv kernel for convolution layers (shared weights, multiple output channels)
- Remove unused code and refactor signal condition logic (CSignalPAI)
2026-07-13 03:23:39 -04:00
super.admin
0a527b0cf9 convert 2025-05-30 16:35:54 +02:00