MQL5 Matrix & Vector: High-Performance Math for EAs

Learn to use MQL5's native Matrix and Vector classes for fast linear algebra in Expert Advisors. Covers linear regression, portfolio calculations, and real.

mql5-matrix-vector-high-performance-math-for-eas

Why Matrix and Vector Classes Matter in MQL5

If you've written any half-decent Expert Advisor in MQL4 or MQL5, you've probably used arrays and loops to calculate moving averages, standard deviations, or correlation coefficients. It works, but it's slow — especially when you're iterating over hundreds of bars and multiple instruments. MQL5's native Matrix and Vector classes, introduced in build 2380, change that entirely. They let you write linear algebra operations that run an order of magnitude faster, and when paired with OpenBLAS, they can push that speed even further.

This guide walks you through using these classes for two practical tasks: computing a linear regression slope on price data, and calculating a simple portfolio variance matrix. You'll see exact code, understand the performance trade-offs, and learn how to integrate these operations into your own EAs without reinventing the wheel.

Prerequisites

Before you start, make sure you have:

  • MetaTrader 5 build 2380 or newer — these classes won't work in MT4 or older MT5 builds. Check your version under Help → About.
  • A demo account — you don't need a funded account for development, but you need one attached to the terminal to run the Strategy Tester.
  • MetaEditor — comes with MT5. Open it from the terminal's Tools → MetaQuotes Language Editor or press F4.
  • Optional: OpenBLAS enabled — go to Tools → Options → Expert Advisors and check "Enable OpenBLAS for matrix operations". This accelerates large matrix multiplications. Without it, the classes still work using native MQL5 loops.

You don't need any third-party libraries or DLLs. Everything is built into the standard library.

Understanding the Matrix and Vector Classes

The CMatrixDouble and CVectorDouble classes live in the Math\Alglib namespace, but MQL5 also provides a simpler, more modern wrapper: the matrix and vector types. These are native types, not classes, and they support operator overloading — so you can write C = A * B instead of calling multiplication functions. That's what we'll use.

Here's the core API surface you need to know:

OperationSyntaxReturns
Initialize from arrayvector v = vector::FromArray(arr)vector
Matrix multiplicationmatrix m3 = m1 * m2matrix
Transposematrix mt = m.Transpose()matrix
Inversematrix mi = m.Inv()matrix
Dot product (vector)double d = v1.Dot(v2)double
Meandouble m = v.Mean()double
Standard deviationdouble s = v.Std()double

These types also support slicing with v[from:to] and range-based loops, but for performance-critical code you'll want to avoid creating too many temporary copies. More on that later.

Step-by-Step: Linear Regression Slope Using Vectors

Let's build a practical EA that calculates the linear regression slope over the last 50 closing prices. This is a common input for trend-following systems — a positive slope suggests an uptrend, negative suggests downtrend.

Step 1: Create the EA Skeleton

Open MetaEditor (F4), create a new Expert Advisor: File → New → Expert Advisor → Next. Name it "MatrixLinReg". Replace the generated code with this:

//+------------------------------------------------------------------+
//|                                               MatrixLinReg.mq5  |
//|                                    Copyright 2025, Your Name     |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property link      ""
#property version   "1.00"

input int      LookbackBars = 50;       // Number of bars for regression
input ENUM_TIMEFRAMES Timeframe = PERIOD_CURRENT;

double         ExtLinRegSlope = 0.0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(Bars(_Symbol, Timeframe) < LookbackBars)
      return;

   // Get close prices
   double closeArray[];
   ArraySetAsSeries(closeArray, true);
   CopyClose(_Symbol, Timeframe, 0, LookbackBars, closeArray);

   // Convert to vector
   vector y = vector::FromArray(closeArray);

   // Build x vector: 0, 1, 2, ..., LookbackBars-1
   vector x(LookbackBars);
   for(int i = 0; i < LookbackBars; i++)
      x[i] = (double)i;

   // Calculate means
   double xMean = x.Mean();
   double yMean = y.Mean();

   // Center the vectors
   vector xCentered = x - xMean;
   vector yCentered = y - yMean;

   // Slope = sum(xCentered * yCentered) / sum(xCentered^2)
   double numerator   = xCentered.Dot(yCentered);
   double denominator = xCentered.Dot(xCentered);

   if(denominator != 0.0)
      ExtLinRegSlope = numerator / denominator;

   Comment("Linear Regression Slope: ", ExtLinRegSlope);
  }
//+------------------------------------------------------------------+

Step 2: Compile and Attach

Press F7 to compile. If you get errors about unknown types, check your MT5 build version — older builds don't have the vector and matrix types. On build 2380+, it should compile cleanly.

In the terminal, drag the EA from the Navigator panel onto a EURUSD chart (any timeframe). Make sure the AutoTrading button is green and the EA's smiley face in the top-right corner of the chart is not crossed out.

Step 3: Verify in the Strategy Tester

Open the Strategy Tester (Ctrl+R), select your EA, set symbol to EURUSD, timeframe to H1, and date range to the last year. Under Settings → Optimization, uncheck "Use all symbols" and leave the LookbackBars input at 50. Run a single test (not optimization).

After the test completes, open the Results tab and look at the Journal. You should see no errors. The EA won't trade — it only calculates and displays the slope via Comment(). That's fine; you're here to learn the math, not to trade blindly.

Step-by-Step: Portfolio Variance Matrix

Now let's step up to a matrix operation: calculating the variance-covariance matrix for a portfolio of three symbols. This is useful for position sizing or risk parity strategies.

Step 1: Set Up the EA

Create another EA, call it "MatrixPortfolioVar". We'll hardcode three symbols for simplicity: EURUSD, GBPUSD, and USDJPY. In production, you'd use SymbolsTotal() and a loop.

//+------------------------------------------------------------------+
//|                                           MatrixPortfolioVar.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property version   "1.00"

input int      LookbackBars = 100;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   string symbols[3] = {"EURUSD", "GBPUSD", "USDJPY"};
   int n = ArraySize(symbols);

   // Build a matrix where each column is a symbol's returns
   matrix returns(LookbackBars - 1, n);

   for(int s = 0; s < n; s++)
     {
      double prices[];
      ArraySetAsSeries(prices, true);
      if(CopyClose(symbols[s], PERIOD_D1, 0, LookbackBars, prices) < LookbackBars)
        {
         Print("Not enough data for ", symbols[s]);
         return;
        }

      // Calculate daily log returns
      for(int i = 0; i < LookbackBars - 1; i++)
        {
         returns[i][s] = MathLog(prices[i] / prices[i+1]);
        }
     }

   // Center the returns (subtract column means)
   vector colMeans = returns.Mean(0);  // mean of each column
   matrix centered = returns - colMeans;

   // Covariance matrix = (1/(n-1)) * centered^T * centered
   matrix cov = (1.0 / (LookbackBars - 2)) * centered.Transpose() * centered;

   // Display the covariance matrix
   string output = "Covariance Matrix:\n";
   for(int r = 0; r < n; r++)
     {
      for(int c = 0; c < n; c++)
        {
         output += StringFormat("%.6f ", cov[r][c]);
        }
      output += "\n";
     }
   Comment(output);

   // Example: portfolio variance with equal weights
   vector weights(n);
   weights.Fill(1.0 / n);
   double portfolioVariance = weights.Dot(cov * weights);
   Print("Portfolio Variance (equal weights): ", portfolioVariance);
  }
//+------------------------------------------------------------------+

Step 2: Run and Interpret

Compile this EA and run it on any chart in the Strategy Tester (single test, daily data). Watch the Journal tab for the printed portfolio variance. The covariance matrix will show you which pairs move together — for example, EURUSD and GBPUSD usually have a positive covariance, while USDJPY often has a negative covariance with the EURUSD.

Notice how we used returns.Mean(0) — the argument 0 means "mean along columns." If you pass 1, it averages along rows. This is a common gotcha when you're new to these classes.

Tips and Best Practices from Experience

I've been using these classes for about two years now, and here's what I've learned the hard way:

  • Always pre-allocate vectors and matrices instead of growing them dynamically. The vector(n) constructor creates a fixed-size vector. Avoid vector v; then v.Resize(n) inside loops — it's slower and fragments memory.
  • Use .Fill() for initialization rather than a loop. v.Fill(0.0) is vectorized and faster than a for loop.
  • OpenBLAS matters for large matrices. If you're working with matrices larger than about 50x50, you'll see a 2-4x speedup with OpenBLAS enabled. For small matrices like our 3x3 covariance, the overhead of OpenBLAS dispatch actually makes it slightly slower — so test both ways.
  • Watch out for NaN propagation. If any price data is missing (e.g., EMPTY_VALUE

Community

Clap for the article and open comments only when you want to read them.

0 claps0 comments

Related articles