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.

53
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
 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):
pass

def rebalance(context, data):
record(leverage=context.account.leverage,
exposure=context.account.net_leverage)

price = history(100, "1d", "price")
returns = price.pct_change().dropna()

weights = maximum_hurst_portfolio(returns)
print(weights)
for security in returns:
try:
order_target_percent(security, weights[security])
except:
pass


There was a runtime error.
Disclaimer

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.