Here is my implementation, in QuantConnect, of Ernie Chan's "Gold vs Gold-Miners Statistical Arbirtage" strategy found in his book Quantitative Trading.

A stationary time-series is mean-reverting by definition since it never drifts far from its initial/mean value. Unfortunately, price series are not stationary as we can model them as geometric brownian motion that does drift from its initial value. However, the market value of a pair (or basket) of assets, often from the same industry, are stationary when they are cointegrated: a linear combination of their prices are integrated of order zero. Why? Because the assets of a pair respond equally to the same shocks (news) and, consequently, the "walk" together.

In the proposed methodology, we do not rely on any statistical metric to select the pair nor we verify that the pair is cointegrated with a statistical test. This is something we can explore in future implementations using, for example, the Universe Selection feature. We just assume their are as Chan did. He has selected GDX (Gold Miners ETF) and GLD (Gold ETF). 

The first step is to define the linear combination: we make a linear regression of the price series using MathNet.Numerics.Fit.Line(x, y), wthere x is GLD price series and y is GDX one to find beta (AKA hedge ratio). The spread is, thus, defined as 

e = x - beta * y

This is important: the spread is our stationary time-series.
Next, we calculate the simple moving average and standard deviation of the spread in order to express it in terms of z score: 

zScore = (e - sma) / std.

This derived stationary time-series is centered at zero and the scaled to the spread standard deviation.

Finally, the trading logic is reduced to a comparison between the z score and a given threshold (+/- 0.5). In the attached project, we enter positions when zscore is higher than 0.5 or lower than -0.5 and close the positions once it returns to its mean (cross zero):

Long trade
Entry condition: zScore < -0.5
Buy 1000 shares of GLD
Sell 1000 * beta shares of GDX
Exit condition: zScore > 0

Short trade
Entry condition: zScore > 0.5
Sell 1000 shares of GLD
Buy 1000 * beta shares of GDX
Exit condition: zScore < 0

We can make some sensibility tests on the threshold. In theory, higher values give us more certainty, but fewer trades. Also, we can change the test window length and how ofter beta is re-evaluated. In this algorithm, we have evaluated beta only once with prices from the first 90 trading days.