# Statistical Arbitrage, Avellaneda & Lee - Estimation of the Residual Process

I am trying to calculate the trade signal outlined in Avellaneda & Lee paper "Statistical Arbitrage in the US Equities Market".

They describe their approach in appendix. Here is my attempt on simulated data:

# Simulate returns
window = 60
np.random.seed(42)
stock_returns = np.random.normal(0.0005, 0.01, window)
etf_returns = np.random.normal(0.0004, 0.008, window)

# Standardize
stock_returns_standardised = (stock_returns - stock_returns.mean())/stock_returns.std()
etf_returns_standardised = (etf_returns - etf_returns.mean())/etf_returns.std()

# Run regression of stock returns on ETF returns
model = sm.OLS(stock_returns_standardised, etf_returns_with_const)
results = model.fit()

# Calculate the residuals from the regression (idiosyncratic returns)
residuals = results.resid

# Fit an AR(1) model to the residuals
ar_model = AutoReg(residuals, lags=1)
ar_results = ar_model.fit()

# Obtain the autocorrelation coefficients 'a' and 'b' from the AR(1) model
a = ar_results.params[0]
b = ar_results.params[1]

# Calculate the signal
s_score = -a * np.sqrt(1 - b**2) / ((1 - b) * np.sqrt(np.var(residuals)))


There is some issue with this calculation as visually the signals time series does not make sense to me when I apply the logic to my actual data.

As many of the concepts here are new to me, I would appreciate any help with correcting my approach.

• Please provide a DOI link to the paper Commented Dec 9, 2023 at 17:49
• What programming language is that? Commented Dec 9, 2023 at 17:50
• Just follow this post, it's very nicely written. Commented Jun 1 at 14:30

• @arkon Look at the CIR process. Any type of process that has a random walk + mean reversion component will be type of mean reverting process. All you need basically is $dx_t = \alpha (\mu - x_t) d_t + \beta dW_t$. The $\alpha (\mu - x_t) d_t$ component makes the process revert to $\mu$ at the rate of $\alpha$. Commented Dec 8, 2023 at 0:02