Loading…

Ensemble Signal Allocator

Running several strategies or signal sources together and combining their votes is a common way to smooth out any one method's weaknesses, but most homemade ensembles use a fixed weight per stream, set once by hand and never revisited. That weight is only ever as good as the backtest it was chosen from - it does not adapt when a stream that used to work stops working, and it has no mechanism to notice a stream that has quietly started performing well. This header tracks each stream's own recent results in a small ring buffer (SSignalStream.pnlHistory, capped at 64 entries) and derives its weight from ONLY a rolling out-of-sample window of that history - RecomputeWeights sums the most recent N results per stream (N is the caller's lookback, not the whole lifetime total), and assigns weight proportional to that rolling sum among the streams currently positive. A stream with zero or negative rolling performance gets weight exactly 0.0, not a small negative number that would fight the others' vote - and if every stream is currently non-positive (early on, or a genuinely bad stretch for the whole ensemble), every stream falls back to an equal share rather than the combined signal collapsing to zero. CombineSignals then blends a raw signal vector (one value per stream, any scale the caller likes - direction flags, confidence scores, whatever the underlying strategies emit) using the current weights, normalising by the actual weight total rather than assuming it sums to exactly 1.0 - useful when testing with hand-set weights or mid-way through a weight update. The ring buffer is a fixed-size array member of SSignalStream rather than a dynamic one specifically so the struct remains an ordinary, safely-copyable value - a struct holding a dynamic array has no safe default assignment in MQL4, and this one needs to sit in a plain array and be passed around by reference without that hazard. Notes and limitations - The ring buffer holds at most 64 results per stream (ENSEMBLE_MAX_HISTORY). A lookback larger than that is silently capped to whatever is actually stored - it does not read stale or out-of-range memory. - Weighting uses a plain sum of the lookback window, not a Sharpe-style risk-adjusted score - two streams with identical total P/L but very different volatility receive the same weight. Feed a risk-adjusted score instead of raw P/L into RecordStreamResult if that distinction matters to your ensemble. - RecomputeWeights should be called on a schedule the caller controls (once per closed trade, once per day, etc) - this header does not call itself automatically on a timer. - This header never opens or closes a trade and never reads market data - it only combines numbers the caller already has.

Script · MT4 · v1.0 · Free

About Ensemble Signal Allocator

Ensemble Signal Allocator is a script for MetaTrader 4. It has 1 setting, such as Lookback. MQL source code included.

Files in the download: EnsembleSignalAllocator.mqh, EnsembleSignalAllocator.txt, EnsembleSignalAllocatorDemo.mq4.

Settings

SettingDefaultWhat it does
Lookback20Rolling window, in results, used to recompute weights

How to install

  1. Download the ZIP from your PolyMaria library and unzip it.
  2. In MetaTrader 4 open File → Open Data Folder, then go to MQL4 → Scripts.
  3. Copy the .mq4 file(s) there. Put any .mqh files in MQL4 → Include.
  4. Open the .mq4 file in MetaEditor and press Compile (F7) if MetaTrader does not show it.
  5. Drag the script onto a chart to run it once.

Download the PDF guide

Tags: Buy/Sell Arrows · MT4 Script · MQL4 Source Code

MQL4 & MQL5 scripts · PolyMaria