Русский Português
preview
Neural Networks in Trading: Training Deep Spiking Models (SEW-ResNet)

Neural Networks in Trading: Training Deep Spiking Models (SEW-ResNet)

MetaTrader 5 — Trading systems |
115 0
Dmitriy Gizlyk
Dmitriy Gizlyk

Introduction

Financial markets are an arena where the interests of millions of participants clash, and every decision results in either a profit or a loss. In such circumstances, the ability to quickly extract information from complex data streams becomes a critical factor for success. In recent decades, artificial neural networks have taken the lead in information processing tasks, proving their effectiveness in a wide variety of fields — from computer vision to machine translation. Their success can be attributed to deep learning: the more layers there are in a model's architecture, the more complex and multifaceted the patterns it can detect and describe. In the world of trading, this principle is particularly evident. Deep models are capable of discerning the slightest patterns in price behavior and distinguishing short-term noise from sustained trends.

However, the development of neural network models has run into a paradox. Increasing the depth of the network, which was supposed to be entirely beneficial, led to an unexpected effect at a certain point. Instead of an increase in accuracy, we saw it stagnate and, at times, even decline. The situation was like an overloaded mechanism, where new components didn't make things run more smoothly but instead caused malfunctions. The solution was found in the concept of residual connections — the model learns not simply to extract new features, but to refine those it has already identified by adding minimal adjustments to them. This idea was realized in the ResNet architecture, which proved to be a true breakthrough, making it possible to build very deep models without sacrificing quality.

However, alongside classical architectures, a new field has emerged that is increasingly attracting the attention of researchers and practitioners: spiking neural networks. What makes them unique is that they are more closely aligned with how the brain works. Unlike the models we are familiar with, information in these models is transmitted in the form of discrete pulses or events. This approach is particularly valuable for financial markets, since they, too, are dominated by event-driven dynamics: the release of a report, a statement from a regulator, a sudden surge in activity — all of these are key events to which the system must react instantly. In addition, spiking models promise greater energy efficiency and the ability to process real-time data streams.

However, despite their impressive biological plausibility and new possibilities, spiking models still lagged behind classical neural networks in a number of practical tasks. This was particularly evident with complex datasets that required a high degree of accuracy and depth of analysis. At some point, it became clear that the path to progress lay in integrating deep learning concepts into the architecture of spiking models. This is how the first attempts to adapt ResNet to a spiking format came about. The concept behind Spiking ResNet seemed promising — to carry over the residual blocks from the classic architecture and replace the activation functions with spiking neurons. This approach made it possible to apply the time-tested principle of depth and residual connections in a new, event-driven context.

The results were mixed. On the one hand, models converted from classical neural networks demonstrated outstanding accuracy and set a high standard for other solutions. On the other hand, direct training of Spiking ResNet revealed several issues: a decline in quality as depth increased, vanishing and exploding gradients, and difficulties in implementing a correct identity mapping. All of this left the challenge of constructing truly deep and stable spiking models unresolved.

Against this backdrop, the emergence of the SEW-ResNet framework, presented in the paper "Deep Residual Learning in Spiking Neural Networks," marked a significant step forward. The main idea was to take a fresh look at the mechanism of residual learning as applied to spiking architectures. The framework's authors proposed the Spike-Element-Wise approach, which makes it possible to implement identity mapping naturally while avoiding key issues with gradients. Practical testing confirmed the validity of the concept. SEW-ResNet demonstrated not only higher accuracy but also the ability to scale as the model depth increases — something that had not been achieved before. Moreover, for the first time, researchers succeeded in building a spiking neural network with a depth of over 100 layers that maintained training stability and outperformed many existing solutions.

If we apply this discussion to the field of finance, it becomes clear that such developments open up entirely new horizons. Deep models trained on spike-based data can analyze market events as they actually occur. Not as averaged sequences of numbers, but as a sequence of discrete signals, each of which carries information. This perspective is closer to the nature of the market, where prices rarely move smoothly and steadily, but more often react to surges in liquidity, news, or market sentiment. Technologies such as SEW-ResNet promise to teach algorithms to detect these changes as soon as they occur.

Thus, the challenge of constructing stable and deep spiking models extends far beyond the realm of academic interest. In the financial industry, where responsiveness and the ability to process complex data determine competitive advantage, the implementation of such solutions can be a key step toward new strategies and tools. Today, we are on the verge of integrating SEW-ResNet concepts into practical algorithmic systems. We will examine this path through the lens of implementing the proposed methods using MQL5. This will provide a better understanding of the architecture itself and allow for an assessment of its practical potential in real-world market conditions.


The SEW-ResNet Algorithm

At the heart of any spiking neural network framework lies a simple yet fundamental idea: the basic computational unit is the spiking neuron. For classical artificial neural networks, such an element can be described as a generalized sum of products, where signals travel along weighted connections and are then transformed by an activation function. However, in a spiking model, things are much more dynamic and closer to biology. Here, information does not flow as a continuous stream but is transmitted in the form of discrete events — pulses or spikes. Each such impulse is similar to an electrical discharge that is transmitted from neuron to neuron in the real brain.

To formalize this process and make it computable, a unified model is introduced. It describes the dynamics of a neuron over time by breaking them down into a sequence of discrete steps. At every step, the system addresses three key tasks:

  1. Calculate the new membrane potential.
  2. Determine whether a spike occurred.
  3. Reset the potential in the event of firing.
These three stages are described by a system of equations that forms the basis of virtually all modern spiking models.

The first equation describes the evolution of the potential.

Here, Vt-1 is the membrane potential at the previous step, and Xt is the input current arriving at the current time. The function f(•) determines how the potential is updated and varies depending on the selected neuron type. In fact, this is the internal physics of a neuron, describing how it responds to an incoming signal.

The next step is to check whether the membrane potential has exceeded the threshold.

If the potential reaches the threshold Vth, the neuron fires and generates a spike. The Heaviside function Θ(•) acts here as a hard switch that returns 1 when the threshold is exceeded and 0 otherwise. In other words, either an event occurs or it does not.

After that, the reset mechanism takes effect.

If a spike occurs, the potential returns to the fixed level VReset. This is similar to the process of a battery discharging: after releasing energy, the system must return to its initial state to prepare for the next signal. If, however, there was no spike, the potential retains its current value and continues to accumulate.

All of this forms a coherent framework that makes it possible to reproduce the dynamics of biological neurons while remaining computationally simple enough. Furthermore, flexibility is provided by the function f(•). For the simplest Integrate-and-Fire model, it takes the following form:

In other words, the potential simply increases by the amount of the input current. In contrast, the more realistic Leaky Integrate-and-Fire model takes into account the leakage of the accumulated charge.

The parameter τ determines the rate of this leakage, reflecting the fact that a neuron cannot store energy indefinitely — it gradually loses its charge if a spike is never generated.

Thus, the researcher has a universal framework in which the basic processes (spike generation and reset) are the same for all models, while fine-tuning is achieved by selecting the function f(•).

However, a significant training-related challenge arises along the way. The classic step function, which determines whether a spike will be generated, is not differentiable. This means that the standard backpropagation method, on which deep learning is based, cannot work here. At first glance, this seems like a major obstacle. If the gradient cannot be calculated, then it becomes impossible to adjust the model's weights.

A solution was found in the so-called surrogate gradient method. The key point is that, for the forward pass, we use the actual step function, since it is precisely this function that reflects the nature of spikes. But when it comes to computing derivatives during the backward pass, we replace it with a smooth approximation — the function σ(•) — which behaves similarly but has a convenient analytical gradient. This dual use of functions makes it possible to train spiking models in a manner similar to conventional deep neural networks, while preserving the event-driven nature of the computations.

This combination — a unified neuron model and the surrogate gradient method — provides a solid foundation for building complex architectures. This is where the story of SEW-ResNet begins.

When it comes to deep architectures, it was the residual block that served as the foundation on which ResNet was built and that made it possible to overcome the main problem of very deep networks — quality degradation. The idea seemed simple, yet revolutionary. If we cannot train all the new layers to exactly replicate the input signal, then let us leave them a fallback path — a straight line along which the information can pass without distortion. That was the concept of an identity mapping. It ensured that the model's depth would not compromise its quality. At worst, the new layers will not make anything worse, and at best, they will enrich the representation of the data.

In a classic ResNet, such a block consists of two consecutive convolutional layers, normalization, and the ReLU activation function. If we denote the block's input as Xl and its output as Yl, then the formula has the following general form:

Here, Fl(•) is an addition to the original signal. If it is equal to zero, the result will simply be Yl = ReLU(Xl). And since the output after ReLU is non-negative, for most values we effectively obtain an identity mapping: the input equals the output. That was the secret behind the success of ResNet.

The attempt to adapt this design to the spiking world seemed quite natural. In papers on Spiking ResNet, the block is arranged in the same way, except that instead of ReLU it uses a spiking neuron.

Here, Sl and Ol represent the block's input and output at time step t, and SN denotes the firing of a spiking neuron.

And this is where the fundamental difference becomes apparent. In classical neural networks, ReLU acts as a smooth filter. It passes positive values through unchanged. Therefore, it is easy to achieve an identity mapping there. But with a spiking neuron, the conditions are much more stringent. To ensure that SN(Slt) = Slt, the last neuron in the block must fire in response to every input spike and remain silent in its absence. For the simplest IF model, this can still be implemented: it is enough to choose the firing threshold and initial conditions so that an input of 1 always produces a spike, while an input of 0 never does. But as soon as we take a more complex model — for example, an LIF model with a trainable time constant τ — the situation becomes more complicated. The potential is updated with a fractional step that depends on τ, making it practically impossible to find a universal threshold for all cases.

Thus, the residual blocks in Spiking ResNet turn out to be limited. They are not suitable for all neuron models, which means that the principle of universality is violated even at the most basic level.

But that's not the only problem. Even if we manage to configure the blocks so that they implement an identity mapping, we face a far more serious threat — vanishing and exploding gradients. In a deep neural network, the propagation of the gradient through a sequence of spiking blocks reduces to the product of factors that are related to the derivative of a step activation function. And since this function itself is discrete, with surrogate approximations its derivative is almost always either very small (leading to vanishing gradients) or, conversely, causes unstable growth (exploding gradients). As a result, as the number of layers increases, the network becomes virtually untrainable. Errors do not propagate deeper into the network, the weights are not adjusted, and the gradients either go to zero or to infinity.

This effect is the notorious degradation; however, in spiking models, it is even more pronounced than in classical ones. And it is precisely for this reason that Spiking ResNet, in its original form, was never able to demonstrate that depth provides a performance advantage. Moreover, a deep spiking model often performed worse than its shallow counterpart.

It is worth noting, however, that such blocks have nevertheless found their place — in the conversion of classical models into spiking ones. The challenge there is different: adapting an existing model to an event-based format. In this case, spiking blocks can be used in combination with additional normalization, and they reproduce the rate characteristics of the original ReLU activations quite successfully.

And this is where the Spike-Element-Wise block comes into play; it essentially plays the same role that the classic residual block once did: it allowed the SNN to grow deeper while maintaining stability.

What makes the SEW block so special? First and foremost, its simplicity. It is based on the element-wise operation g, which combines two information streams — the output of the spiking transformation and the original signal. Thanks to the binary nature of spikes, this design functions as an ideal switch: with the proper settings, the block becomes completely transparent, implementing identity mapping. This is not some kind of fine-tuning that depends on a specific neuron model or membrane dynamics parameters, but a universal technique that works in any configuration. This is precisely where the strength of SEW lies — it is universal.

Let's imagine a long chain of SEW blocks. In classic ResNet-like architectures, at a certain depth we begin to lose the signal — the gradients become smaller and smaller, and the network stops learning. Or, conversely, in RBA blocks, the signals grow uncontrollably, leading to explosions. In SEW, such a scenario is impossible. Its output is always bounded, the gradients remain equal to one, and training can proceed to a depth of hundreds of blocks. In other words, SEW gives us back the same luxury that ResNet gave to the world of classical neural models.

It is also interesting to see how the downsampling problem is addressed. In classic ResNets, when the dimensions change, the shortcut path is implemented using convolutions without activation. In the SEW block, a spiking neuron is added to the shortcut path, creating a more natural and neurobiologically realistic scheme. As a result, the downsample blocks change dimensionality and continue to operate in spiking mode, preserving the model's biological plausibility.

When viewed from a broader perspective, the SEW block opens the door to an entirely new class of applications. Before that, SNN architectures were more of an academic interest. It was too difficult to strike a balance between depth and trainability. With the advent of SEW, they are beginning to compete seriously with classical neural network models in real-world applications. Yet the advantages of SNNs are obvious: they are energy-efficient, asynchronous, map naturally onto neuromorphic chips, and make it possible to design computations that more closely mimic the brain’s actual dynamics.

As we move from theoretical descriptions to practical experiments, the difference between Spiking ResNet and SEW-ResNet becomes apparent. On static tasks — such as image classification using the CIFAR or ImageNet datasets — both architectures produce similar results, but as soon as you go deeper and increase the number of layers, Spiking ResNet begins to falter. The gradients vanish, the error increases, and instead of improvement, we get a degradation in quality. This is a classic scenario where depth becomes the enemy.

Under such conditions, SEW-ResNet behaves in exactly the opposite way. The deeper the model, the more stable its behavior and the higher its overall accuracy. This is especially important when it comes to tasks where success depends on the model's ability to look far ahead in time. This is exactly the situation we are facing in the financial markets. Rare, sharp bursts of activity, periods of prolonged lull, shifts in market conditions, and long-range temporal dependencies—all of which must be kept in memory.

To understand the value of SEW-ResNet in trading, we can draw an analogy with the market itself. It also has spike signals — unexpected news, sharp price movements, and sudden surges in liquidity. Classical neural network models that work with averaged activations are like a trader who sees only a smoothed chart and misses sharp spikes. Spiking architectures, especially SEW-ResNet, make it possible to perceive the market in its natural, event-driven form, where it is not the smooth trend that matters, but the very moment of the spike and its context.

In comparative tests using datasets that simulate event streams, SEW-ResNet demonstrated a significant advantage in terms of accuracy and convergence speed. Moreover, it proved to be the first approach that made it possible to train SNN models with more than 100 layers without catastrophic degradation.

In practical applications involving financial data, SEW-ResNet opens up new horizons. It makes it possible to build models that can identify local patterns in price quotes and link them to long-range historical dependencies. For example, a model can capture a brief burst of activity in response to economic news while also taking into account that similar spikes in the past have led to a sustained medium-term trend. This is made possible precisely by depth, which now enhances rather than hinders training.

Furthermore, the high energy efficiency and event-driven nature of SNNs make it possible to consider SEW-ResNet in the context of low-latency systems. In high-frequency trading or algorithmic analysis, where every millisecond counts, a model’s ability to quickly process spiking events becomes a critical advantage.

The authors’ visualization of the framework is shown below.


Implementation using MQL5

Now that we have thoroughly examined the theoretical foundations and architectural features of the SEW-ResNet framework, it is time to move on to the next logical step: its practical implementation. Here, it is important to move from the simple to the complex, from the foundation to the higher-level components. The first step in this process is to define the basic mechanism of a spiking neuron.

At first glance, it might seem quite natural to implement the spike generation process as a separate function. Similar to how classical activation functions are implemented in our library. However, spiking neurons impose fundamentally different requirements. Unlike traditional activations, which instantly compute an output value based on the input signal, a spiking neuron evolves over time. It does not merely respond to input, but accumulates information, builds up a membrane potential, and then, upon reaching the firing threshold, generates a spike — a discrete impulse that carries meaningful information.

These temporal dynamics cannot be reduced to a single static function. Accurate modeling requires dedicated memory — potential accumulation buffers — which, in essence, resemble the hidden states of recurrent models. And that is precisely where the main challenge lies. Using spiking activation as a simple function would automatically require modifying all previously created layer objects. In fact, we would undermine the library's architectural compatibility and lose the modularity we've built.

Therefore, we arrived at a different, more sophisticated solution: we implement spike generation as a separate neural layer object. At first glance, this step may seem unnecessary, but in reality, it is a strategic move. A layer object can be integrated into any existing architecture without affecting the operation of the other components. It becomes a standalone building block that can be combined with other layers to increase the model's complexity.

But before we move on to the code itself, it is worth taking a moment to review the key principles of our implementation. In their theoretical description of the SEW-ResNet framework, the authors laid out the basic ideas — a foundation that opens up a vast field for experimentation, but without specific engineering solutions. It is precisely these solutions that allow us to build genuinely trainable deep spiking models.

The first principle concerns the accumulation of a neuron's membrane potential. To do this, we borrowed the gated update mechanism for state from recurrent models. Each spiking neuron now has its own gate that controls how quickly or slowly the membrane potential responds to incoming signals. And, most importantly, this gate is implemented as a trainable parameter that is independent of the input data.

The practical significance of this approach can be easily illustrated using the analogy of a trader in the market. Each neuron learns to develop its own strategy for responding to events. If the signal is noisy and unstable, the neuron behaves conservatively, accumulates information, and responds only to truly significant changes. If, on the other hand, the signal is clear and predictable, the neuron is able to instantly generate a spike, capturing an important impulse. As a result, each element becomes unique, and the entire model gains the flexibility needed to handle different types of input sequences.

This approach is particularly relevant for financial markets, where data often consists of alternating periods of calm and sharp bursts of activity. Some events call for a cautious response, while others require a swift and decisive reaction. The ability to configure each neuron for the specific nature of the input signal allows the model to adapt to these conditions while maintaining the accuracy and stability of training.

In addition, we will borrow from the SpikingBrain framework an effective mechanism for adaptive threshold training, implemented in the FloatToSpike kernel. This mechanism allows neurons to flexibly adjust their firing threshold based on the statistics of the input signals, which is particularly important when working with heterogeneous and noisy data. However, in our implementation, we have made a small but crucial change that enhances the model's capabilities.

Now, when a spike is generated, the neuron's accumulated potential is reduced by the firing threshold.

__kernel void FloatToSpike(__global float* values,
                           __global const float* levels,
                           __global float* outputs
                          )
  {
   const size_t id = get_global_id(0);
   float val = IsNaNOrInf(values[id], 0.0f);
   if(val == 0.0f)
      outputs[id] = 0.0f;
   else
     {
      const float lev = IsNaNOrInf(levels[id], 0.0f);
      if(fabs(val) < lev)
         outputs[id] = 0.0f;
      else
        {
         outputs[id] = (float)sign(val);
         values[id] = IsNaNOrInf(sign(val)*(fabs(val)-lev), 0.0f);
        }
     }
  }

We deliberately chose not to reset the potential to a fixed value of VReset. At first glance, this may seem like a minor detail, but in practice it opens up a whole new level of flexibility. This approach makes it possible to form a kind of gradation of spikes. A stronger signal leaves a longer afterglow in the membrane potential, influencing subsequent events. In other words, the neuron is now capable of accumulating a history of significant spikes, creating an effect of temporal inertia.

In the context of financial markets, this takes on particular practical significance. Market events are rarely isolated or one-off occurrences. The price movement of a single instrument often continues as a series of related impulses, and the market's reaction to news can extend over time. A neuron's ability to retain part of its accumulated potential allows the model to remember significant events and respond appropriately to their consequences, thereby creating an internal dynamic memory. This organization of neuron operation makes SEW-ResNet more sensitive to true market patterns while reducing the impact of random noise.

Thus, a small, targeted change in the mechanism transforms a neuron from a simple spike/no-spike switch into a fully fledged dynamic element with a graded response. This combination of accuracy, adaptability, and the ability to accumulate information over time is one of the key distinguishing features of our implementation and provides a solid foundation for building deep, robust, and adaptive models.

The proposed solution has been implemented as a new object CNeuronSpikeActivation, which inherits from the base class CNeuronBaseOCL. This object captures the entire dynamics of a spiking neuron, including membrane potential buildup, an adaptive threshold, and the mechanism for graded spike generation.

class CNeuronSpikeActivation  :  CNeuronBaseOCL
  {
protected:
   CNeuronBaseOCL    cHV;
   CParams           cLevels;
   CParams           cGates;
   //---
   virtual bool      FloatToSpike(void);
   virtual bool      FloatToSpikeGrad(void);
   //---
   virtual bool      feedForward(CNeuronBaseOCL *NeuronOCL) override;
   virtual bool      updateInputWeights(CNeuronBaseOCL *NeuronOCL) override;
   virtual bool      calcInputGradients(CNeuronBaseOCL *NeuronOCL) override;

public:
                     CNeuronSpikeActivation(void) {};
                    ~CNeuronSpikeActivation(void) {};
   //---
   virtual bool      Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                          uint neurons, ENUM_OPTIMIZATION optimization_type, uint batch);
   //---
   virtual int       Type(void) override const  {  return defNeuronSpikeActivation;   }
   //--- methods for working with files
   virtual bool      Save(const int file_handle) override;
   virtual bool      Load(const int file_handle) override;
   virtual void      SetOpenCL(COpenCLMy *obj)   override;
   //---
   virtual bool      WeightsUpdate(CNeuronBaseOCL *source, float tau) override;
   virtual void      SetActivationFunction(ENUM_ACTIVATION value) override { };
   virtual void      TrainMode(bool flag) override;
   virtual bool      Clear(void) override;
  };

The object contains several key components:

  • cHV is responsible for the neuron's internal dynamics, accumulating the potential and accounting for spiking events;
  • cLevels stores threshold parameters, enabling adaptive training of the threshold;
  • cGates implements the gated update mechanism for the membrane potential, allowing each neuron to regulate its response speed to an input signal individually.

Thus, each neuron can develop a unique strategy for responding to noisy or significant events, which is particularly important for analyzing financial time series.

All internal objects of the new class are declared statically, which made it possible to leave the class's constructor and destructor empty — no additional actions are required when creating or destroying an object. This solution significantly simplifies the architecture, makes it more predictable, and facilitates the integration of the new neuron into the existing library.

The entire process of initializing a new neural layer is handled in the Init method, which serves as the entry point for configuring all of the object's components. This is where the key parameters are set.

bool CNeuronSpikeActivation::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                                  uint numNeurons, ENUM_OPTIMIZATION optimization_type, uint batch)
  {
   if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, numNeurons, optimization_type, batch))
      return false;

Initialization begins with a base call to the method of the same name in the parent class, which configures the neuron's fundamental parameters. After it completes successfully, the internal components are created and initialized. cHV is responsible for the dynamics of the membrane potential. It is assigned an activation of zero, and the buffers are cleared so that the neuron starts in a clean state.

   uint index = 0;
   if(!cHV.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
      return false;
   cHV.SetActivationFunction(None);
   cHV.Clear();

Next, a cLevels object is created, which is responsible for adaptive firing thresholds. The SoftPlus activation function is set for it, ensuring smooth and stable threshold updates, and the weights are initialized to -3.0f, creating a conservative initial threshold. This threshold allows a neuron to accumulate input signals and respond only to truly significant events; however, we do not shut down all neurons from the very beginning of training. This is important. Neurons remain capable of generating initial spikes even at the start, which ensures a continuous flow of information in the model and allows gradients to propagate effectively during training.

In other words, we avoid a situation where neurons are completely passive in the early stages — they are immediately involved in the training process, but act cautiously. This balance between conservative initialization and neuron activity creates optimal conditions for gradual model training and stabilizes the early stages of training.

   index++;
   if(!cLevels.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
      return false;
   cLevels.SetActivationFunction(SoftPlus);
   CBufferFloat* temp = cLevels.getWeightsParams();
   if(!temp ||
      !temp.Fill(-3.0f))
      return false;

The next step is to initialize the cGates object, which implements the mechanism for gated updates to the membrane potential. It is assigned a SIGMOID activation function, which allows each neuron to learn an individual response coefficient for new signals. The weights are initialized to zero, which results in neutral behavior at the start of training. At the same time, after the signal passes through the SIGMOID function, the result is approximately 0.5 — the point at which the sigmoid curve is practically linear. This is crucial. In this region, the gradients remain sufficiently large, allowing the gate parameters to be quickly adjusted in the desired direction.

In other words, at the start of training, the neuron receives a balanced state — the gate neither blocks the signal nor lets it pass completely, but leaves room for adaptation. Even in the early stages of training, the model is capable of flexibly adjusting the rate at which the membrane potential builds up for each neuron, adapting to the characteristics of the input data. This is particularly important for financial time series, where signals can range from calm and predictable to sharp and noisy. The correct dynamic response of neurons directly affects prediction accuracy.

   index++;
   if(!cGates.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
      return false;
   cGates.SetActivationFunction(SIGMOID);
   temp = cGates.getWeightsParams();
   if(!temp ||
      !temp.Fill(0.0f))
      return false;
//---
   return true;
  }

Thus, the initialization method configures the neural layer and creates a ready-to-use, flexible, and adaptive structure capable of accumulating information, controlling the firing threshold, and responding individually to input signals.

Once the object has been initialized, the next logical step is to design the forward pass algorithm — that is, how a neuron processes the input data and generates spikes. This process is implemented in the feedForward method, which forms the core of the neuron's operation.

bool CNeuronSpikeActivation::feedForward(CNeuronBaseOCL *NeuronOCL)
  {
   if(!NeuronOCL)
      return false;
//---
   if(!cHV.SwapOutputs())
      return false;

The algorithm begins with a short preparatory step. First, we check that the pointer to the previous layer's NeuronOCL object is valid. This ensures that the data to be processed actually exists. Next, the SwapOutputs method is called for the cHV object, updating the internal membrane potential state. The current values become the previous ones, and the neuron is ready to process the next time step. This step is extremely important for the proper operation of potential accumulation and spike generation, taking into account the signal history.

If the network is in training mode, a forward pass is also run for the internal cLevels and cGates objects. The first is responsible for adjusting the firing threshold, and the second is responsible for updating the membrane potential gate. It is precisely these components that allow a neuron to flexibly adjust its sensitivity to the data being analyzed and to learn effectively from noisy or changing signals.

   if(bTrain)
     {
      if(!cLevels.FeedForward())
         return false;
      if(!cGates.FeedForward())
         return false;
     }

Next, the input signal and the membrane potential are summed element by element, taking the gates into account. This operation implements a key principle of spiking neurons: the input signal is accumulated while taking into account the neuron's state and its individual response to novelty. This approach allows the model to retain dynamic memory and respond flexibly to complex temporal dependencies, which is particularly important for financial time series, where each change can have a lasting impact on subsequent events.

   if(!GateElementMult(NeuronOCL.getOutput(), cHV.getPrevOutput(),
                       cGates.getOutput(), cHV.getOutput()))
      return false;
   return FloatToSpike();
  }

Calling the FloatToSpike method completes the forward pass, generating spikes based on the current state of the membrane and the adaptive threshold. The result of the feedForward method is the neuron's output signal, ready for further processing as part of a deep SEW-ResNet.

As you can see, the algorithm for the forward pass method is linear and predictable. Each action — updating the membrane potential, applying the gate, and generating spikes — is performed sequentially and transparently, without complex branching or conflicting data flows. This approach has an important practical implication: error gradient propagation and model training remain stable and are not complicated by parallel processing of information, which is particularly valuable when working with a deep network and a large number of neurons.

The backward pass methods used to compute gradients and update weights are left for the reader to explore on their own in this implementation. The complete source code for the CNeuronSpikeActivation class and all of its methods is provided in the attachment, allowing readers to study the implementation in detail and use it to build their own models.

Thus, CNeuronSpikeActivation is a versatile and flexible tool for building deep spiking models based on SEW-ResNet in MQL5. Its architecture allows for experimentation with various schemes for potential accumulation, adaptive thresholds, and spike generation, without compromising compatibility with existing neural layer objects. It is precisely this modular and extensible approach that makes it possible to build deep, stable, and adaptive models for analyzing the complex time series characteristic of financial markets.

We have covered a lot in this article, so it is time to take a short break to let the new information sink in. In the next article, we will return to implementing the approaches proposed by the authors of the SEW-ResNet framework, with renewed energy and a fresh perspective, as we continue to build effective and adaptive spiking models using MQL5.


Conclusion

In this article, we explored the SEW-ResNet framework, whose main advantage is the ability to directly implement residual learning in spiking models. This makes it possible to build deep models without degradation in training effectiveness. Using the binary nature of spikes together with element-wise operations provides robustness against vanishing and exploding gradients.

In the practical section, we examined in detail the principles of implementing spiking neurons and building a basic forward pass algorithm using MQL5. We showed how the use of an adaptive threshold, a gated update of the membrane potential, and a potential accumulation mechanism enables neurons to respond effectively to sequential and noisy data.

In the next article, we will continue to expand the functionality of SEW-ResNet to create a full-fledged deep spiking model for analyzing and forecasting financial data.


References


Programs used in the article

# Name Type Description
1 Study.mq5 Expert Advisor Expert Advisor for offline model training
2 StudyOnline.mq5 Expert Advisor Expert Advisor for online model training
3 Test.mq5 Expert Advisor Expert Advisor for model testing
4 Trajectory.mqh Class library Structure describing the system state and model architecture
5 NeuroNet.mqh Class library Class library for building neural networks
6 NeuroNet.cl Library Code library for the OpenCL program


Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/19839

Attached files |
MQL5.zip (3163.98 KB)
Features of Custom Indicators Creation Features of Custom Indicators Creation
Creation of Custom Indicators in the MetaTrader trading system has a number of features.
Foundation Models for Trading (Part III): Running a Generative AI Forecaster Inside MetaTrader 5 Foundation Models for Trading (Part III): Running a Generative AI Forecaster Inside MetaTrader 5
We demonstrate live forecast charting with Kronos in MQL5 and an evaluation pipeline designed to be look‑ahead‑safe. Deterministic dumps are scored per horizon against a random‑walk baseline (15,113 predictions), then fed to a simple Strategy Tester rule on EURUSD H1. The findings show no edge, and illustrate how a high threshold can yield a persuasive but low‑information backtest with very few trades.
Features of Experts Advisors Features of Experts Advisors
Creation of expert advisors in the MetaTrader trading system has a number of features.
Machine Learning Under Constraint (Part 3): De-Risking Near the Profit Target and the News-Window Rule Machine Learning Under Constraint (Part 3): De-Risking Near the Profit Target and the News-Window Rule
Position sizing that ignores proximity to a profit target or the timing of high-impact news exposes banked progress to reversal risk and misstates simulated profit near funded-stage news releases. We implement derisking_factor, a piecewise-linear size reduction keyed to phase progress with a floor set by minimum-trading-days status, and news_window_factor, a phase-gated step function applying FundedNext's news reward-share haircut in a configurable window around correlated events. Both return bounded multipliers combined multiplicatively with the sizer's other modifiers.