preview
MQL5 Wizard Techniques you should know (Part 95): Using Disjoint Set Union and Deep Belief Network in a Custom Signal Class

MQL5 Wizard Techniques you should know (Part 95): Using Disjoint Set Union and Deep Belief Network in a Custom Signal Class

MetaTrader 5Trading systems |
119 0
Stephen Njuki
Stephen Njuki

Introduction

In the last MQL5 Wizard article that showcased Custom Signals, we used the pairing of a B-Tree Index algorithm and a Bayesian Network. The system we had then was meant for arbitrage by maneuvering inefficiencies over co-dependent assets. It showed some potential in classifying, multi-symbol market states. That model, though, could be unsuitable for single-asset traders that track momentum in volatile environments. Those who trade the news. A multi-asset index is not helpful in trading breakouts. For that, you could use a time-based noise filter. 

In realizing this, therefore, this article pivots to the Disjoint Set Union (DSU) algorithm that we pair with a Deep Belief Network (DBN). While the last custom signal article had the Bayesian model mapping static relationships, this approach uses generative DBN filters for noise. We are not in any way touting a universal solution; we are proposing an alternative approach to a specific issue some breakout traders face. How to group high-volatility bars into a cluster via a DSU and then identify if the cluster stands for a regime shift or a transient trap.

A Comparison to B-Tree & Bayesian

The B-Tree Index and Bayesian NN that we used in the last custom signal build were helpful in multi-signal triangulation. The B-Tree Index has its strong point in storing high-dimensional data as well as multi-signal lookups; on the other hand the Bayesian network worked with probability-based classification and was used to quantify how uncertain we were of the signals from the B-Tree algorithm. It was a structural solution for mapping static, cross-sectional inefficiencies. 

This model, although promising in its original context, can become a liability when used for localized high-frequency anomalies. The B-Tree Index could be seen as an optimized search directory that is very useful when dealing with tabular data. It will not be as resourceful when dynamically grouping sequential time series based on volatility. When macroeconomic news breaks and one asset is affected, we do not need a database search of correlated assets. We need to measure the localized shockwave within its time window.

The need for classifying time series by volatility therefore means we move from relational indices to Graph-Theory Partitioning. The Disjoint Set Union (DSU) algorithm gives us an easy way of finding connected components within a continuous data stream. Instead of index retrieval, DSU dynamically groups high-volatility price bars into a unified structure without compute-intensive matrix calculations on the live chart. It is a lightweight, time-based tool for grouping that can help in setting apart sudden spikes in momentum.

Trader Profile, Asset Allocation, and Market Environment

In the previous custom signal article, the B-Tree Index and Bayesian NN suited traders seeking arbitrage in co-dependent markets. For this article the DSU-DBN classifier is meant to cater for breakout traders. It's bound to struggle in range-bound choppy environments. Rather it targets spikes in high-liquidity environments such as in NFP news releases. Given the volatility, some traders accept a lower win rate as the price for identifying true regime shifts from transient noise.

The Core Problem: Navigating Chaotic Volatility Clusters

The central issue in breakout trading is separating genuine regime shifts from noise or stop-hunts. Indicators often fail due to 'feature-smearing'—averaging a localized price shock across a preset time window. This leads to lagging 'statistical-ghosts'. A workaround for this would be to stop smoothing data and treat explosive spikes in price as discrete time-based events. By clustering high-variance price bars geometrically, we could be better positioned to map the boundary of a market shock.

The Dual-Engine Paradigm: Algorithmic Set Union + Generative Deep Filtering

We maintain the algorithm-network combination because the network acts as an optional filter when the algorithm is too passive or overly deterministic. In this article the DSU is our algorithm partitioner that dynamically groups adjacent high-volatility bars into discrete sets, and strictly mapping the time-boundary of the momentum shock. Our network, the Deep Belief Network (DBN) serves as a generative supervisor, evaluating internal variance of the DSU cluster. This checks if the momentum is a true trend or a chaotic trap. 

The best metaphor for this can be drawn from weather systems. The DSU could be understood as a Doppler radar network that outlines the precise boundary of an incoming storm, which for our purposes is equivalent to a volatility cluster (or period). The DBN on the other hand can be seen as the atmospheric analyst that establishes if this incoming storm has a sufficient amount of pressure to become a hurricane. So one bounds physical chaos while the other verifies the real intent.

Mathematical Formulations & Statistical Boundaries

To make the bridge between concept and MQL5 code we usually need to lay down the definitions, mathematically, on how the temporal data points are grouped and eventually validated. This system depends on two separate frameworks. The Graph-Theory Partitioning and energy-based probability modeling.

Graph Theory Partitioning

The Disjoint Set Union (DSU) engine builds our time-based graphs by processing the incoming price-bars in a time series as a universe of discrete elements. These then get organized in three core operations. First is MakeSet(x), which initializes a price bar x as a stand-alone cluster; Find(x), which spots the 'root' representative of the set that has x; and Union(x,y), which merges disjoint sets with adjacent price bars x and y into a single cluster structure. A geometric union is deemed if the tape shows a statistically plausible shock. Our boundary conditions are defined across two major indicator domains:


  • First, Absolute Volatility Expansion (ATR): Here we track the current variance V against a historical baseline that is still in memory. This is obtained as follows:

f11

 

  • Second, Relative Structural Compression (Bollinger Bands Mode): In order to register volatility breakouts especially from a tight consolidation of liquidity, we track the actual increase in variance relative to the average historical Bands' width. This is got as follows:

f2

Energy-Based Neural Validation

Once the DSU has done its graphing and established the boundary of a cluster, the Deep Belief Network (DBN) would evaluate how valid this cluster is. The DBN we use is built from a stacked Restricted Boltzmann Machine (RBM) architecture. These RBMs score the "truthfulness" of a breakout using an Energy function. The collective energy of a joint configuration is given by the formula:

f3

Where:

i and bj stand for the respective layer biases

w and ij, stand for structural synaptic weight connecting them. If the overall energy is lower, this often means that momentum  regime could be sustainable as opposed to an artificial, high-frequency, stop-hunting environment. The generative probability of an isolated cluster representing a valid structural shift is ruled by the conditional activation probability:

f4

In the MQL5 implementation below, instead of depending on the regular sigmoid activation function, this probability distribution is mapped directly through a hyperbolic tangent function (MathTanh). This gives us a uniform final output by enforcing a strict non-linear distribution that is bounded between -1 and 1. A trade is only cleared for execution if this output is more than the tuned input parameter m_dbn_threshold.

MQL5 Implementation: Codebase Anatomy & Indicator Selections

Most of the regular MQL5 signal classes that are compatible with the MQL5 Wizard work by 'staring fixedly' into the rearview mirror. They are designed and coded around the idea of smoothing data, waiting for moving average cross overs or waiting for momentum oscillators to re-enter a designated neutral zone. When these do eventually get smoothed, lagging conditions are met, finally, and logged by the Expert Advisor, the actual breakout would already be underway - and with highly liquid assets often already concluded. It could be argued that these signal classes are at their core reactive and force the Expert Advisor to trade the statistical ghost of a market move instead of the primary explosive move itself.

When trying to meet requirements of rigid drawdown limits and other strict consistency parameters that are now often required by modern proprietary trading desks, depending on lagging indicators can be a liability. For macro-event traders, one cannot afford to get into a trend when the initial liquidity shock is exhausting. Our 'CSignalDSUDBN' custom signal class that inherits from the library 'CExpertSignal' base class, seeks to stop lagging dependencies all together.

Rather than wait for a trailing average to signal a crossover that would often be delayed, we build a proactive temporal graph off of a "live chart". We use the Disjoint Set Union (DSU) algorithm to geometrically map and pair raw volatility shocks in real-time as new price bars are logged. Nonetheless running trades solely on raw, surprise volatility can reckless since high-frequency liquidity gaps and stop-hunts usually masquerade as genuine momentum. Thus, we have to combine the algorithmic graphing engine with a Deep Belief Network (DBN). The DSU engine is charged with managing time-based price structure by grouping seemingly chaotic bars into mathematical sets, while the DBN serves as the structural "gatekeeper", ruthlessly cutting off false signals before they get to the broker.

Before the DSU algorithm can effectively partition time-series into sets that are discrete, it needs objective mathematic borders. These help lay down what exactly can be deemed a "shock". Our choice of indicators here thus is very important. Given our hunt for outlier volatility price-action we cannot use standard indicators like the MACD or RSI in this. These oscillators track directional speed which ends up smearing data over a lookback window destroying the important start and end points of the sought volatility anomaly.

Instead, our class loads by initializing two pure variance indicators, thankfully within the MQL5 standard library. These are specifically selected to map structural expansions as opposed to directional drift:

  1. Average True Range ('CiATR'): This oscillator is used to track the absolute non-directional expansions. This oscillator is often preferred to alternatives like the standard-deviation because it accounts for opening gaps between price-bars. When trading assets with high-liquidity feeds like those given by institutional brokerage houses, macroeconomic data releases usually cause the price to gap over liquidity pools. Once a volatility spike runs beyond its historical norm, the ATR will log the shock immediately, and this will give our math the objective boundary to trigger a DSU cluster.
  2. Bollinger Bands ('CiBands'): We also use the Bollinger Bands setup to run an applied price of 'PRICE_CLOSE' with a standard deviation of 2.0. This quantifies relative variance against a moving average. So while the size of physical bars is measured by ATR, the Bollinger Bands allows the algorithm to track structural compression. If a momentum regime change is sustainable, then often it is preceded by an extreme volatility compression aka a liquidity squeeze. We therefore determine the rate of change in the Bandwidth (gap distance between upper and lower bands). With this change measured we are then able to separate volatility clusters that are breaking out with significant momentum, instead of being swayed by every candle stick pattern.

Also, before we dissect the MQL5 code for this model, it may be important to go over the operational sequence that happens whenever a new price bar is logged in the terminal, and calls to the Long Condition are made. This pipeline which can be thought of as a mini-map as follows:

  1. Index Acquisition: We begin by securing the beginning index of the active time series. Locking onto the price action that is current implies our algorithm will get to evaluate the live edge of the market without depending on deep, lag-inducing loops.
  2. DSU Graphing & Routing: We then evaluate the input user mode, 'DSUMode' selected and route the execution thread appropriately, by corresponding to our time-series algorithm, selecting between absolute ATR mapping or Bollinger Bands expansion, and also combining probability or pure price action.
  3. Cluster Scoring: We get a raw vector ('dsu_val') that represents both direction bias and geometric density of the current volatility cluster
  4. Neural Gatekeeping: We feed this DSU vector into a pre-trained Deep Belief Network, in order to evaluate the generative authenticity of the volatility break.
  5. Signal Confirmation: We approve a long position once all the parameters align. We assign a base pattern weight of 100 to trigger an execution command within the Expert Advisor.


Step 1: Initialize the Boundaries of the Graph for all Four Modes

int result = 0;
   int idx = StartIndex();
   double dsu_val = 0.0;
//--- 1. Apply selected Disjoint Set Union Algorithm Mode
   switch(m_dsu_mode)
     {
      case 1:
         dsu_val = DSUClusterATR(idx);
         break;
      case 2:
         dsu_val = DSUClusterBB(idx);
         break;
      case 3:
         dsu_val = DSUClusterCombined(idx);
         break;
      case 4:
         dsu_val = DSUClusterPriceAction(idx);
         break;
      default:
         dsu_val = DSUClusterATR(idx);
         break;
     }

This starting block serves as the command center of the structural grouping phase. We have to declare the start index 'idx' that is necessary for retrieving market data from price buffers and indicators. We restrict DSU lookback to a recent micro-window (about 10 bars, adjustable by the reader), and we ensure that this starting thread remains lightweight and performant. When temporal volatility shocks happen, they are often very rapid, once a breakout would necessitate more than a dozen consecutive bars to make up its structure, we are using the 4-hour timeframe so this figure could be tuned to the tested asset and timeframe, we would deem this a slow drift and not an actionable momentum anomaly.

Rather than work out standard moving average deltas, our switch statement reads user's chosen mode from 'm_dsu_mode' and channels the execution to one of the four specialized iterations. In the background, these methods invoke the custom class functions of 'Find()' and 'Union()' graphing operations. This has an effect of flattening a unified mathematical set and returning the DSU value in the parameter 'dsu_val'. In proposing algorithms for custom classes of the MQL5 Wizard we have been fronting up to four operation modes. This number can always be debugged and tweaked depending on one's perspective and approach to the market, however we cover the thinking behind our chosen four below:

Mode 1: ATR Absolute Volatility Cluster

Our starting mode is meant for situations marked by sudden unrelenting economic shocks. It only focuses on the output of 'CiATR' indicator over a localized rolling window. In this mode we check if the absolute volatility is actually expanding bar over bar. Once the current bar and the immediately preceding bars show an unbroken chain of True Range, the 'Union()' operation would merge them into one directional set. This iteration does not pay attention to historical moving averages completely, but instead dwells on the explosive kinetic energy of the current tape. It is highly responsive, aggressive, and is able to map the exact duration of a news driven liquidity sweep.

Mode 2: Bollinger Bands Expansion Cluster

While with mode 1 we monitor absolute size, mode 2 is after relative release. This iteration is able to get the physical distance from the upper and Lower bands over consecutive bars. A 'Union()' operation is performed only if the bandwidth is widening continuously. The math logic behind this is meant to grab the classic "Volatility Squeeze" breakout. Markets can spend a lot of their time in low-liquidity situations while consolidating, therefore when the bandwidth finally begins to fracture and expand, this mode dynamically clusters particular expansion bars together. We ignore large bars here that happen in already volatile settings and instead hunt for structural transition from low-variance regimes.

Mode 3: Combined Joint Probability Cluster

This could be the most conservative and structurally restrictive mode of the four. It requires overlapping, and concurrent confirmation from both the absolute and relative domains. A 'Union()' operation would combine two bars into an active cluster when the algorithm confirms that the Average True Range is actively expanding and the Bollinger Bandwidth is widening at the same time. In forcing this dual probability agreement, mode 3 severely reduces the number of trade signals and arguably over-filtering conflicting market states. Nonetheless the resulting clusters are structurally dense and stand for the highest likelihood of a genuine sustained directional breakout.

Mode 4: Pure Price-Action Cluster

The final iteration mode does not consider any historical based indicators. The argument here is that strict tape reading algorithm from measuring the absolute open-to-close price bar body size of consecutive candle sticks can be a better metric of immediate or current volatility regime boundaries. When the physical sequence of the body size of the current sequence goes beyond the baseline ATR, the bars get merged into a cluster. This mode is meant for purists or traders who prefer immediate confirmation of the raw price feed without mathematical lag brought about in moving average bands for example.

Step 2: Add the DBN Gatekeeper

This second phase where we introduce the neural network is highlighted by the listing below:

//--- 2. Evaluate with Deep Belief Network (If active)
   if(m_use_dbn)
     {
      double dbn_score = DBNForwardPass(dsu_val);
      if(dbn_score < m_dbn_threshold)
         return(0); // DBN rejected the long signal
     }
   else
     {
      //--- Standalone algorithm check
      if(dsu_val <= 0.0)
         return(0);
     }

This particular block of code makes up the most important guarding mechanism in our custom signal class. By addressing the fundamental flaw of breakout trading: raw volatility can be very deceiving. Institutional algos can routinely setup high-frequency stop-hunts that copy the price signature of genuine breakouts and this can trap momentum traders that take the bait before a reversal. To work around this, the input parameter 'm_se_dbn' can be toggled as true such that the unvetted cluster vector from the DSU, 'dsu_val', gets to be passed through a stacked neural network with the 'DBNForwardPass()' function. Even though high-level data science as well as off-line training of Deep Belief Networks is handled in Python frameworks, (that can also be coded in Meta Editor IDE), the MQL5 execution needs to be highly responsive. Thus, ideally, this network should run with statically pretrained synaptic weights and biases, that are hard coded into 1D arrays once the class initializes.

The 'DBNForwardPass()' function runs as a Restricted Boltzmann (RBM). This takes geometric density and directional weight of the DSU Cluster and spreads it over a hidden computational layer. In applying weights and processing the final output via a hyperbolic tangent activation function ('MathTanh'), this DBN computes the internal state of energy of the current volatility cluster. It poses a very important question. Does the inner variance of these set of bars match the signature of a sustainable trend or is this similar to fast-reverting noise?

When a DBN deems the sequence is a snare, the resulting 'dbn_score' drops. Should this score fail to match or exceed the tuned input parameter of 'm_dbn_threshold', then the signal class would simply return 0. No compromise. Effectively it vetoes the long signal entirely since the Expert Advisor is prevented from running a statistically doomed trade which, on paper, should help preserve trader's equity.

Step 3: Bypass Confirmation

//--- 3. Confirmation
   result = m_pattern_0;
   return(result);

Any signal, as best practice, needs to provide an operational bypass for the purposes of isolation testing as well as optimizing the strategy. When the trader wants to test the raw forecasting power of the Disjoint Set Union algorithm without the any overhead of neural filtering an 'else' block can provide fall back. When in such a standalone mode, the algorithm would only need to verify the integrity of the direction of a cluster vector that is not adjusted. If such a vector is negative or entirely flat,

dsu_val <= 0.0

this would indicate a lack of structural bullish momentum and a long condition, again would be voided. Finally, when all structural verifications have been checked through the pipeline - whether via strict DBN gatekeeper or through a stand alone DSU the system would assign the result an integer value, preset and stored by the base class parameter 'm_pattern_0'. In the standard library this implies a base pattern weight of 100. This weighted integer then gets passed back to the inherited class function 'Direction(void)' authorizing trade execution.

Complete Signal Logic

If we take a step back and put together our interlocked methods and functions our whole pipeline could be surmised below.

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CSignalDSUDBN::LongCondition(void)
  {
   int result = 0;
   int idx = StartIndex();
   double dsu_val = 0.0;
//--- 1. Apply selected Disjoint Set Union Algorithm Mode
   switch(m_dsu_mode)
     {
      case 1:
         dsu_val = DSUClusterATR(idx);
         break;
      case 2:
         dsu_val = DSUClusterBB(idx);
         break;
      case 3:
         dsu_val = DSUClusterCombined(idx);
         break;
      case 4:
         dsu_val = DSUClusterPriceAction(idx);
         break;
      default:
         dsu_val = DSUClusterATR(idx);
         break;
     }
//--- 2. Evaluate with Deep Belief Network (If active)
   if(m_use_dbn)
     {
      double dbn_score = DBNForwardPass(dsu_val);
      if(dbn_score < m_dbn_threshold)
         return(0); // DBN rejected the long signal
     }
   else
     {
      //--- Standalone algorithm check
      if(dsu_val <= 0.0)
         return(0);
     }
//--- 3. Confirmation
   result = m_pattern_0;
   return(result);
  }


Empirical Validation: Strategy Tester Analysis

As per usual, in order to get a sense of how the neural gatekeeper we examined above can be beneficial to our custom signal class, we test the wizard assembled Expert Advisor from in two modes. With only the algorithm and then with both the algorithm and network. Testing is done on the pair USD CAD from 2025.01.01 to 2026.05.01 on the 4-hour timeframe. Optimization was in 2025 with forward walk period being from 2026.01.01 to 2026.05.01

Algorithm-Only

In the first test run, we bypass the neural network by assigning 'UseDBN' as false. From the optimization stint the algorithm's preferred operation mode was mode-2 which is the Bollinger Bands Mode. This setup trades only when there is relative expansion in Bollinger Bands' width. The forward walk report shows a lot of trades, 68 in total with a net profit of about 5% of starting balance off a drawdown that was almost 20% of this balance. With a profit factor of only 1.09, this run may have  been in the green however it came at a huge risk cost. 

r1


Dual Engine Filter

For the second optimization and forward walk we engage the complete model by enabling the DBN and the preferred algorithm mode with the DBN on was mode 3, the combined mode of ATR and Bollinger Bands. Our report shows a huge shift with yes the DBN being a ruthless gatekeeper however the mode-3 selection of the algorithm could also have kept out a significant number of trades. In the end only 4 trades are placed of which only one was in the green. Ironically though, this could be something studying more over longer test horizons and even with various symbols, the relative equity drawdown was still less than that of our first test run. 

r2



Conclusion

The volatile stark nature of the two reports can provide sobering pointers to high impact news traders. Whereas the Disjoint Set Union gave us a relatively fast method  for outlining structural shocks in the market, its 68-trade streak and marginal profit factor demonstrate the vulnerabilities in trading volatility spikes.

name description
wz_95_r2.mq5 Wizard Assembled Expert Advisor
SignalDSUDBN_r2.mqh Custom Signal File used in Wizard Assembly
r1_r.set Input Settings for 1st Test Run
r2_r.set Input Settings for 2nd Test Run

Attached files |
MQL5.zip (7.82 KB)
CSV Data Analysis (Part 3): Engineering a Python Analytics Pipeline for MetaTrader 5 CSV Exports CSV Data Analysis (Part 3): Engineering a Python Analytics Pipeline for MetaTrader 5 CSV Exports
MetaTrader 5 provides rich performance data but limited structural analysis. This article shows how to export results to CSV from MQL5 and build five Python visualizations that expose cross-asset parameter consistency, the lag‑versus‑noise trade-off, walk‑forward decay, drawdown depth and duration, and intraday hour‑by‑day clusters. A unified automation module runs the full pipeline on any new export to deliver repeatable diagnostics.
Implementing a Fluent Interface Builder Pattern for MQL5 Order Construction Implementing a Fluent Interface Builder Pattern for MQL5 Order Construction
Manual population of MqlTradeRequest leaves cross-field rules unchecked, creating silent misconfigurations at execution time. A fluent COrderBuilder for MQL5 adds pointer-based method chaining, per-field validation, and directional SL/TP checks against broker stop‑level constraints. Its Send() method runs a four-stage gate—flag completeness, cross-field consistency, OrderCheck(), then OrderSend()—so configuration errors are caught early and order code stays clear and reusable.
Features of Experts Advisors Features of Experts Advisors
Creation of expert advisors in the MetaTrader trading system has a number of features.
Engineering a Self-Healing Expert Advisor in MQL5 (Part 2): Restart-Safe Virtual Trade Protection Engineering a Self-Healing Expert Advisor in MQL5 (Part 2): Restart-Safe Virtual Trade Protection
Build a restart-aware virtual protection layer on top of the SQLite persistence from Part 1. The EA reconstructs hidden stop-loss and take-profit after restart, verifies current price against recovered exits, and closes or continues positions accordingly. The result is a consistent recovery path that detects managed positions and sustains safe runtime management.