Back to Community
Hurst Maximizing Portfolio

The Hurst Exponent is an indicator of whether a timeseries is trending, random, or mean reverting. There are many ways to estimate the Hurst Exponent, and many opinions to its utility. Nonetheless I was curious to see if generating a portfolio to maximize the Hurst exponent would yield any interesting results. Since this is purely an mini investigation into the idea I turned commission and slippage off to see if the mathematics behind it are of any use. I'm not making any conclusions about it, just thought it was interesting.

Clone Algorithm
Total Returns
Max Drawdown
Benchmark Returns
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
from scipy.optimize import minimize
import numpy as np
import pandas as pd

def hurst(X):
    """ Compute the Hurst exponent of X. If the output H=0.5,the behavior
    of the time-series is similar to random walk. If H<0.5, the time-series
    cover less "distance" than a random walk, vice verse."""
    X = np.array(X)
    N = X.size
    T = np.arange(1, N + 1)
    Y = np.cumsum(X)
    Ave_T = Y / T

    S_T = np.zeros(N)
    R_T = np.zeros(N)

    for i in range(N):
        S_T[i] = np.std(X[:i + 1])
        X_T = Y - T * Ave_T[i]
        R_T[i] = np.ptp(X_T[:i + 1])

    R_S = R_T / S_T
    R_S = np.log(R_S)[1:]
    n = np.log(T)[1:]
    A = np.column_stack((n, np.ones(n.size)))
    [m, c] = np.linalg.lstsq(A, R_S)[0]
    H = m
    return H

def maximum_hurst_portfolio(returns):
    def _sum_check(x):
        return sum(abs(x)) - 1
    def _hurst(x, returns):
        return -hurst(returns.multiply(x).sum(axis=1))
    num_assets = len(returns.columns)
    guess = np.ones(num_assets) / num_assets
    cons = {'type':'eq', 'fun': _sum_check}
    results = minimize(_hurst, guess, args=returns, constraints=cons)
    return pd.Series(index=returns.columns, data=results.x)

# Put any initialization logic here.  The context object will be passed to
# the other methods in your algorithm.
def initialize(context):
    context.stocks = [
        sid(19662),  # XLY Consumer Discrectionary SPDR Fund   
        sid(19656),  # XLF Financial SPDR Fund  
        sid(19658),  # XLK Technology SPDR Fund  
        sid(19655),  # XLE Energy SPDR Fund  
        sid(19661),  # XLV Health Care SPRD Fund  
        sid(19657),  # XLI Industrial SPDR Fund  
        sid(19659),  # XLP Consumer Staples SPDR Fund   
        sid(19654),  # XLB Materials SPDR Fund  
        sid(19660),  # XLU Utilities SPDR Fund
    schedule_function(rebalance, date_rules.week_start())

# Will be called on every trade event for the securities you specify. 
def handle_data(context, data):

def rebalance(context, data):
    price = history(100, "1d", "price")
    returns = price.pct_change().dropna()
    weights = maximum_hurst_portfolio(returns)
    for security in returns:
            order_target_percent(security, weights[security])
There was a runtime error.

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

1 response

Out-of-sample alpha is -0.03.