I am using a couple of resources (here and here) to calculate the mean reversion half-life of a time series. This method of calculating it is also presented in Ernest Chan's Algorithmic Trading on page 47.

The method, as I understand it, is to use the formula: halflife = -log(2)/G

Where G is the coefficient of a linear regression where the dependent variable is the differenced series (Yt - Y(t-1)) and the dependent variable is the lagged series (Y(t-1)).

Here is my code:

a <- sin(0.2*seq(1, 100, 0.25))
y <- diff(a)
x <- a[1:(length(a)-1)]
lm <- lm(y~x)
halflife <- -log(2)/lm$coefficients[2]

I wanted to try it out with a clearly cyclical series, so I used a sine function. Here is a graph of the function: enter image description here

The result I get, however, is: -1064 .

How is this possible? First of all, the value should be positive. This means that my coefficient is not negative, which suggests the series is not mean reverting. But it clearly is, right?

I'd greatly appreciate any assistance with understanding what's going on here.

  • 2
    $\begingroup$ A sin function isn't mean reverting. The SDE of a mean reverting (to zero) stochastic process looks like $dX_t=-\beta X_t\,dt+\sigma dW_t$. If you ignore the Brownian fluctuations the solution is $X_t=X_0e^{-\beta t}$. $\endgroup$
    – Kurt G.
    Mar 28, 2022 at 19:04
  • $\begingroup$ @KurtG. So are you saying that I should generate a function using that last formula you gave, and try to apply the method I have tried to test/ensure it gives a reasonable "mean reversion" time? $\endgroup$ Mar 29, 2022 at 16:34
  • $\begingroup$ All I am saying is that mean reverting to zero is exponential decay (or increase if $X_0<0$). Not something that "looks" mean reverting because it oscillates around the long term mean. If you want to test how a certain statistical method detects the right mean reversion in a time series you could simulate correctly a mean reverting time series and then let loose your method on it. $\endgroup$
    – Kurt G.
    Mar 29, 2022 at 17:12
  • $\begingroup$ @KurtG. Got it. I have a question, though - the solution you suggested is simply a single exponential decay. How could I actually make a repeatedly reverting series from it? Also, does mean reversion have to be exponential decay? I feel that many mean reversion series have sharp reversions, not slow decays. (By the way, if you post an answer, I'll be happy to accept it). $\endgroup$ Mar 29, 2022 at 18:39
  • $\begingroup$ @VladimirBelik, exponential can also be fast/sharp, just pick the right parameter. $\endgroup$ Mar 29, 2022 at 18:51

1 Answer 1


I think the main problem is that, as @KurtG says, your example sine function exhibits strong momentum (albeit with reversals) and fitting an Ornstein-Uhlenbeck process to it results in strange parameters.

However, it might be nice to check that your code is correct. To do so, let's simulate a process that we know to be OU with an obvious half-life:

e <- rnorm(n, 0, 1)
a <- array(data = NA, dim = n)
a[1] = 0
for (i in 2:n) { a[i] <- 0.5 * a[i - 1] + 0.1 * e[i] }

Now a contains a large sample from an OU process with mean 0 and half-life of 1.

We run your fitting code:

y <- diff(a)
x <- a[1:(length(a)-1)]
lm <- lm(y~x)
halflife <- -log(2)/lm$coefficients[2]

and get a halflife of (with my random numbers) about 1.38. Which is close, but wrong and too far from the true value to be explained by just randomness because of the large sample size.

Let's revisit the formulas for halflife. First, and easiest to derive, if we have the OU process (with mean zero) $$ dX_t = -\theta X_t dt + \sigma dW_t $$ with $\theta > 0$ and $\sigma > 0$ then the half-life is $$ h = \frac{\log \left( 2 \right)}{\theta} $$ If we write this in discrete time we have: $$ X_t = \phi X_{t-1} + \epsilon $$ with $0 < \phi < 1$. Then the half-life is $$ h = -\frac{\log \left( 2 \right)}{\log \left( \phi \right)} $$ But your regression uses the differenced form of: $$ X_t - X_{t-1} = \left(\phi - 1 \right) X_{t-1} + \epsilon $$ We can define $\beta = \phi - 1$ (and hence $\phi = 1 + \beta$) to get: $$ X_t - X_{t-1} = \beta X_{t-1} + \epsilon $$ which is the regression you are running. Specifically, lm$coefficients[2] is giving you $\beta$. Rewriting a previous formula we get: $$ h = -\frac{\log \left( 2 \right)}{\log \left( 1 + \beta \right)} $$ If we try that:

halflife <- -log(2)/log(1 + lm$coefficients[2])

we get a number that is almost exactly 1, as expected. So that formula is probably the best one to use.

Where did your original formula come from? Well, the function $\beta \mapsto \log \left( 1 + \beta \right)$ is approximately linear near zero, so replacing $\log \left( 1 + \beta \right)$ with $\beta$ is a reasonable approximation. Nevertheless, using the more exact formula is probably worth it most of the time since it isn't expensive to evaluate.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.