Tendency to mean revert custom factor?

I am looking for a custom factor that would calculate the tendency for a stock to mean revert over a look back period of window_length. The output is on a range of 0 (no mean reversion tendency) to 1 (always mean reverts within parameters specified).

To keep it simple one way to define it is looking at two moving averages and if the ratio is above or below certain threshold, would then stock mean revert in the next n days.

I am maybe clumsy explaining it but basically the customer factor would check how mean-reverting the asset is by what ever mean-reverting definition.

5 responses

I think you are referring to the hurst exponent? I remember there was a factor in this thread by Luca: https://www.quantopian.com/posts/lets-see-if-technical-analysis-works


class HurstExp(CustomFactor):
inputs = [USEquityPricing.open]
window_length = int(252*0.5)
def Hurst(self, ts):
# Create a range of lag values
lags=np.arange(2,20)
# Calculate variance array of the lagged differences
tau = [np.sqrt(np.std(np.subtract(ts[lag:], ts[:-lag]))) for lag in lags]

# Use a linear fit to estimate
#poly = np.polyfit(np.log(lags), np.log(tau), 1)[0]

# 1st degree polynomial approximation for speed
# source: http://stackoverflow.com/questions/28237428/fully-vectorise-numpy-polyfit
n = len(lags)
x = np.log(lags)
y = np.log(tau)
poly = (n*(x*y).sum() - x.sum()*y.sum()) / (n*(x*x).sum() - x.sum()*x.sum())

# Return the Hurst exponent
return poly*2.0
def compute(self, today, assets, out,  OPEN):
SERIES = np.nan_to_num(OPEN)
hurst_exp_per_asset = map(self.Hurst, [SERIES[:,col_id].flatten() for col_id in np.arange(SERIES.shape[1])])
#print 'Hurst Exp:\n',hurst_exp_per_asset
out[:] = hurst_exp_per_asset



Thank you I didn't know about it and it seems to be what I was looking for.

@vladimir Are you having an issue with the HurstExp Custom Factor constantly timing out before trading start? I get about 10 days worth of backtested results before the time out during most random time periods.

It is a very resource intensive function. So make sure you mask the universe first for example with DollarVolume. It works for me with about 1000 stocks.

yeah this makes sense then, thanks for the feedback