Charting Market Rhythms: The Rolling Hurst Exponent in Python
Ever tried catching the rhythm of the stock market? If you have, you’d know trends aren’t just about rising and falling arrows on a graph. They’re the pulse of market sentiment, the stories of gains and losses. In such environment, navigating the stock market can be likened to sailing turbulent waters, where understanding currents — or in this case, trends — can be a game changer. But how can we transition from a qualitative understanding to a quantitative measure of these trends? Here’s where the Hurst exponent enters the spotlight.
A concept that’s often reserved for scholarly articles and niche financial discussions, the Hurst exponent offers a robust measure of a stock’s propensity to trend or mean-revert. While typically estimated as a point-in-time metric, what if we could gauge the Hurst exponent on a rolling basis?Using Python, we can implement the Rolling Hurst Exponent to analyze, visualize, and eventually leverage market trends in our decision-making process.
1. Basic of the Hurst Exponent
The Hurst Exponent, denoted as H, is a statistical measure that gives us a window into the behavior of time series data. Whether it’s the price of a stock, the flow rate of a river, or even internet traffic, H seeks to determine the nature of its behavior. Put simply, the interpretation of the Hurst Exponent is as follows
- If H=0.5, the process is akin to a random walk, like the flipping of a coin.
- If H<0.5, it suggests a series that tends to mean-revert. In the context of stocks, this might hint at an oscillatory behavior where if the stock price rises, it’s likely to fall back to its mean and vice-versa.
- If H>0.5, it indicates a trending series. This would mean that if a stock price rises, it’s likely to continue on that upward trajectory.
Equation. 1: Hurst Exponent Formula
Where:
- R(t) is the range of cumulative sum deviations. The broad idea behind R(t) is to determine how volatile a time series is
- S(t) is the standard deviation of the series. It represents the standard deviation of the series, capturing its average dispersion from the mean.
The Rolling Hurst Exponent:
Traditionally, the Hurst exponent offers a snapshot, a point-in-time insight. But markets are dynamic, evolving with news, policies, and global events. Thus, a rolling computation, where the Hurst exponent is continually recalculated over a moving window, offers fresher, more timely insights. It’s akin to watching a movie frame-by-frame, where each frame offers a unique perspective.
The Link with Fractal Dimension:
The fractal dimension is another fascinating concept, rooted in the idea of measuring the ‘roughness’ or complexity of a series. It’s intrinsically tied to the Hurst exponent and can be determined as:
Equation. 2: Fractal Dimenension Formula.
Where D is the fractal dimension. A higher D indicates a more complex, irregular series, whereas a value close to 1 suggests a smoother series.
Figure. 1: Contrasting Temporal Patterns: The left plot showcases a relatively smooth time series characterized by a lower fractal dimension, hinting at less complexity. Conversely, the right plot depicts a volatile series with higher complexity, evident from its erratic behavior and indicative of a higher fractal dimension.
A Fractal dimension close to 1 indicates the time series is relatively smooth and simple, suggesting that it can be easily modeled using conventional time series methods. Fractal dimension close to 2 on the contrary indicates that the time series is very rough and complex, suggesting that it has a higher degree of irregularity and may be challenging to model using conventional methods. Just note that the interpretation might vary depending on the context and the financial instrument being analyzed.
2. Rolling Hurst Exponent Python Implementation
Given the inherent dynamism of the stock market, assessing the Hurst Exponent at a single point in time might not provide a comprehensive picture. Instead, evaluating it on a rolling basis offers a frame-by-frame analysis of how a stock’s behavior evolves over time. The same goes for the fractal dimension.
The computation of both the Hurst exponent and the fractal dimension in a rolling fashion demands a blend of time series manipulation and statistical techniques. Thankfully, Python’s vast libraries make this task relatively straightforward.
Essential Libraries & Data Acquisition
We commence by importing the necessary libraries:
numpy
andpandas
: Fundamental for numerical and data frame operations.yfinance
: Enables us to fetch stock data directly from Yahoo Finance.matplotlib
: Our go-to tool for plotting and visualizing data.
The stock data is fetched for the ticker symbol “ASML.AS” within aspecific date range.
import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
symbol = "ASML.AS"
start_date = "2018-01-01"
end_date = "2023-12-31"
df = yf.download(symbol, start=start_date, end=end_date)
Hurst and Fractal Dimension Calculations
The heart of our script is the hurst_fd
function, which computes both the Hurst Exponent and Fractal Dimension using the log returns of a given price series. The function uses a resampling approach for more robust estimates.
We also have rolling_hurst
and rolling_fractal_dimension
functions that employ hurst_fd
to calculate these metrics on a rolling basis across our dataset.
def hurst_fd(price_series, min_window=10, max_window=100, num_windows=20, num_samples=100):
log_returns = np.diff(np.log(price_series))
window_sizes = np.linspace(min_window, max_window, num_windows, dtype=int)
R_S = []
for w in window_sizes:
R, S = [], []
for _ in range(num_samples):
start = np.random.randint(0, len(log_returns) - w)
seq = log_returns[start:start + w]
R.append(np.max(seq) - np.min(seq))
S.append(np.std(seq))
R_S.append(np.mean(R) / np.mean(S))
log_window_sizes = np.log(window_sizes)
log_R_S = np.log(R_S)
coeffs = np.polyfit(log_window_sizes, log_R_S, 1)
hurst_exponent = coeffs[0]
fractal_dimension = 2 - hurst_exponent
return hurst_exponent, fractal_dimension
def rolling_hurst(price_series, window, min_window=10, max_window=100, num_windows=20, num_samples=100):
return price_series.rolling(window=window).apply(lambda x: hurst_fd(x, min_window, max_window, num_windows, num_samples)[0], raw=True)
def rolling_fractal_dimension(price_series, window, min_window=10, max_window=100, num_windows=20, num_samples=100):
return price_series.rolling(window=window).apply(lambda x: hurst_fd(x, min_window, max_window, num_windows, num_samples)[1], raw=True)
Visualization & Insights
With our metrics in hand, the next step is visualization. We aim to render three plots:
- Stock Price & SMA: The stock price plotted alongside its Simple Moving Average and mean price.
- Rolling Hurst Exponent: Offers a dynamic view of the Hurst exponent over time.
- Rolling Fractal Dimension: Reveals the changing fractal nature of the stock price.
This series of plots paints a holistic picture, illustrating the relationship between price movements, market trends, and fractal characteristics.
Putting it all together, we get:
Newsletter