- Implemented sqx_audit.py to audit StrategyQuant X trade lists, focusing on performance metrics and cost analysis.
- Created sqx_portfolio.py to evaluate portfolio performance based on uncorrelated components and their impact on risk and return.
- Developed swing.py to analyze cost ratios across different holding periods and assess swing trading structures.
- Introduced test_management.py to investigate the effectiveness of exit rules on random entries and their impact on expectancy.
- BufferDouble: replace hardcoded "DirectML/CPU-DLL" with dynamic backend name
and add buffer index/element count to all error prints for easier debugging.
- NetPersistence: distinguish missing file from transient lock by probing
FileIsExist before logging, eliminating false "sharing violation" warnings
when no saved model exists on first run.
CNeuronLSTMOCL consumed the whole flattened input in ONE gate computation and
back-propagated a single timestep, which its own class comment stated. Combined
with a conv stage whose window=step=neuronsCount gives it a receptive field of
exactly one bar, no stage in HYBRID mixed information across time - the bars
reached the dense stack as an unordered flat vector, the same thing the plain
MLP sees. That predicted the measured ranking (MLP 31.5%, CONV 32.5%, LSTM
30.6%, HYBRID 14.4%): each extra bottleneck cost accuracy and bought nothing.
The layer now unrolls m_historyBars timesteps, sharing one gate block across
them and carrying h/c forward, with real BPTT carrying dh and dc backward.
Per-step width comes from CLayerDescription::window, which CNet passes to the
new SetStepWidth() - previously dead metadata.
Consequences worth naming:
- Weight count drops from 4H(H+420+1) to 4H(H+21+1). Weight sharing is the
point of a recurrence, so ComputeLstmHiddenSize now budgets on the per-step
width; H goes 16 -> 64 at H1 defaults, and the model is still smaller.
- h/c start at zero per sample. The old buffers persisted across forward
passes, so under shuffled training each sample inherited an unrelated
sample's state.
- .nnw LSTM records are versioned (LSTM_SEQ_SAVE_TAG). The old weight block is
a different shape, so Load REFUSES pre-rewrite models rather than misreading
one and throwing off every later layer's offset. LSTM and HYBRID must retrain.
- Sequence mode has no Network.cl kernel, so it refuses the OpenCL tier loudly
instead of quietly running a different architecture there than on the DLL
tier - the two would train different models from one .cfg.
Legacy single-timestep path kept intact for step width <= 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Introduce an `optimizer` parameter to UpdateWeightsMomentum, UpdateWeightsConvMomentum, and UpdateWeightsAdam kernels. When set to a non-zero value, the gradient used for weight updates is multiplied by ±1 based on the parity of the weight index, implementing a basic feedback alignment signal for experimentation. When zero, the standard gradient is used unchanged. This allows A/B testing of alternative learning signals without modifying the rest of the training pipeline.
In AI/Network.mqh, return early from InitDirectML during
tester/optimization/forward runs to prevent agent-side file-lock
failures caused by rapid stop/restart cycles accessing DLL imports.
In Expert/ExpertSignalAIBase.mqh, add MathIsValidNumber checks in
CalibratedConfidenceMagnitude and SignaledConfidence to safely handle
NaN values, and refactor ShutdownChartCleanup to accept a preserve
flag, avoiding unnecessary chart purges during tester runs for faster
shutdowns. Also add m_purgeChartOnDestruct member.
In AI/NeuronDirectML.mqh, clean up a minor comment formatting issue.
Remove verbose book references from input parameter comments in
Network.mqh for clarity. Add #ifndef guard around ENUM_OPTIMIZATION
to allow inclusion from multiple headers without redefinition.
Document the MQL5 Market DLL restriction in NeuronDirectML.mqh and
introduce WARRIOR_MARKET_BUILD macro to conditionally compile out
DirectML DLL imports for Market-compliant builds.
AI/Network.mqh was 5,805 lines / 18 classes in one file. Investigation
found method implementations for several classes (CNeuronBase/Pool/Conv,
CNeuronBaseOCL) hand-interleaved across thousands of lines - not safe to
split without risky manual reassembly. But 8 classes turned out to be
genuinely self-contained (declaration + every method body physically
contiguous, and only ever depended upon, never depending on anything
declared later): CConnection/CArrayCon, CNeuron, CDirectMLMy (+ its
WarriorDML.dll/WarriorCPU.dll #import blocks), CArrayLayer,
CLayerDescription, CBufferDouble, and CNeuronConvOCL/CNeuronPoolOCL.
Extracted each verbatim, via exact line-range extraction (not manual
retyping) to eliminate transcription risk, into its own AI/*.mqh file,
included from Network.mqh at the exact point each class used to sit -
preserving original declaration order exactly. Mathematically verified
byte-for-byte: reconstructing the original file from the 7 new files'
bodies + Network.mqh's remaining segments is line-for-line identical to
the pre-split git history. Compiled clean (MetaEditor, 0 errors/0
warnings) both before and after.
The remaining tangled classes (CNeuronBase, CNeuronPool, CNeuronConv,
CNet, CNeuronLSTM, CNeuronBaseOCL, CNeuronConvOCL/PoolOCL's shared base,
CNeuronLSTMOCL, COpenCLMy) stay in Network.mqh (now ~4,450 lines) -
splitting those safely needs deliberate per-method surgery, deferred to
a future dedicated pass rather than rushed into this one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>