← Back to Home
Market Memory A Quantitative Look at Hurst-Adaptive Moving Averages (FRAMA_H)

Market Memory A Quantitative Look at Hurst-Adaptive Moving Averages (FRAMA_H)

Financial markets exhibit shifting personalities, transitioning between periods of directional trending and phases of mean-reverting chop. Traditional moving averages, with their fixed lookback periods, often struggle to keep pace, either lagging in strong trends or generating excessive signals in ranging markets. This article investigates a strategy employing a Fractal Adaptive Moving Average (FRAMA)—specifically, a simplified version driven by the Hurst exponent (FRAMA_H). The core idea is to dynamically adjust the moving average’s responsiveness based on an estimate of the market’s “long-term memory.” We’ll explore its construction using Python, the trading logic based on crossovers, and interpret the findings from a backtest on BTC-USD from 2021 to 2024.

The Hurst Exponent: A Window into Market Persistence

The Hurst exponent (H) is a statistical measure used to classify time series. It quantifies the degree of long-range dependence or “memory” in a series:

By calculating H over a rolling window, we can attempt to gauge the market’s current character. The strategy uses these thresholds:

Snippet 1: Calculating the Rolling Hurst Exponent

The script calculates the Hurst exponent on log-returns using the hurst library. A rolling window of 128 periods is used for BTC-USD.

from hurst import compute_Hc # Ensure 'pip install hurst'

# --- Parameters from the script ---
# hurst_lookback_window = 128

# --- Column Name ---
# hurst_col = f"Hurst_{hurst_lookback_window}d"

def get_hurst(series):
    """
    series: 1D array of log-returns, length >=100 (as per script, though compute_Hc min is lower)
    returns: H
    """
    # compute_Hc needs a series with some variance and sufficient length
    if len(series) < 100 or np.std(series) == 0: # Script uses 100, compute_Hc default min is ~20
        return np.nan
    # Using 'change' for log-returns, 'price' for price series
    H_val, c, data = compute_Hc(series, kind='change', simplified=True)
    return H_val

print("Calculating rolling Hurst exponent (this may take a moment)...")
# Rolling apply on log-returns
log_rets = np.log(df['Close']).diff().dropna() # Calculate log returns
df.loc[log_rets.index, hurst_col] = (
    log_rets
      .rolling(window=hurst_lookback_window)
      .apply(get_hurst, raw=False) # raw=False to pass Series object
)

# Fill start-up NaNs: forward fill, then assume neutral H=0.5
df[hurst_col].fillna(method='ffill', inplace=True)
df[hurst_col].fillna(0.5, inplace=True)

This function is applied to a rolling window of log-returns to generate the hurst_col. Initial NaNs are forward-filled and then any remaining (at the very start) are set to a neutral 0.5.

Constructing FRAMA_H: The Adaptive EMA

Instead of a complex recursive FRAMA formula, this strategy creates an adaptive EMA (FRAMA_H) by selecting one of three pre-defined Exponential Moving Averages (EMAs) based on the previous day’s Hurst exponent:

Snippet 2: Selecting the Adaptive EMA (FRAMA_H)

# --- Parameters from the script ---
# ema_short_window = 7
# ema_medium_window = 30
# ema_long_window = 90
# h_trending_threshold = 0.6
# h_reverting_threshold = 0.4

# --- Column Names ---
# ema_short_col = f"EMA_{ema_short_window}"
# ema_medium_col = f"EMA_{ema_medium_window}"
# ema_long_col = f"EMA_{ema_long_window}"
# frama_h_col = "FRAMA_H"
# hurst_col = ... (previously defined)

# Calculate the three underlying EMAs
df[ema_short_col]  = df['Close'].ewm(span=ema_short_window, adjust=False).mean()
df[ema_medium_col] = df['Close'].ewm(span=ema_medium_window, adjust=False).mean()
df[ema_long_col]   = df['Close'].ewm(span=ema_long_window, adjust=False).mean()

# Create FRAMA_H by selecting EMA based on lagged Hurst Exponent
h_shift = df[hurst_col].shift(1) # Use yesterday's H for today's EMA choice
df[frama_h_col] = np.select(
    [h_shift > h_trending_threshold,  # Condition for trending
     h_shift < h_reverting_threshold], # Condition for mean-reverting
    [df[ema_short_col], df[ema_long_col]], # Choices for these conditions
    default=df[ema_medium_col] # Default choice (medium EMA for neutral H)
)

This FRAMA_H line then becomes the dynamic reference for our trading signals.

Trading Logic: Crossover and Risk Management

The strategy employs a simple price crossover system with the FRAMA_H:

The backtest loop iterates through each day, checks for stop-loss hits, then evaluates entry/flip conditions, calculates P&L, and updates the trailing stop.

Interpreting the Backtest Results (BTC-USD, 2021-2024)

The provided script output for BTC-USD from January 2021 to December 2024, with a 128-day Hurst window and EMA periods of 7/30/90, yielded the following key metrics:

Observations and Research Insights:

  1. Outperformance: The FRAMA_H strategy, under these specific parameters and historical period, significantly outperformed a buy-and-hold approach for BTC-USD, both in terms of absolute cumulative return and risk-adjusted return (Sharpe ratio). An annualized return of 63.51% with a Sharpe of 1.08 is noteworthy.
  2. Volatility: The strategy’s annualized volatility (58.55%) was very similar to that of buy-and-hold BTC-USD (58.60%), suggesting the outperformance wasn’t achieved by taking on substantially more (or less) overall price risk as measured by standard deviation.
  3. Impact of Hurst Adaptation: The plots (not fully detailed here but part of the script’s output) would be crucial. If the Hurst exponent plot shows meaningful shifts between trending, neutral, and mean-reverting regimes, it would suggest the adaptive mechanism was active. If H remained largely static (e.g., around 0.5), the strategy would have behaved more like a fixed-period EMA crossover. The change to calculating Hurst on log-returns and using kind='change' might provide more dynamic H values than previous iterations.
  4. ATR Stop Multiplier (atr_multiplier_sl = 1.0): This is a very tight stop. While it can cut losses quickly, it can also lead to premature exits from potentially profitable trades, especially in volatile assets like BTC-USD. The high number of trades often resulting from tight stops would also incur significant transaction costs in live trading. The impact of this tight stop on the observed performance is a key area for investigation; it may have fortuitously navigated BTC-USD’s volatility during this period.
  5. Trading Frequency: The “Final Position counts” (Long: 561, Short: 569, Flat: 235 over ~4 years) indicate a very active strategy, averaging more than one trade every two days. This highlights the importance of considering transaction costs.

Discussion and Avenues for Further Research

The FRAMA_H concept, by attempting to tailor the moving average’s lookback period to the market’s diagnosed “memory” state, is an intelligent step beyond static indicators.

Potential Strengths:

Critical Considerations and Future Research Directions:

  1. Robustness of Hurst Estimation: The stability and reliability of rolling Hurst exponent estimates are paramount. The choice of hurst_lookback_window (128 days), the kind parameter in compute_Hc (now 'change' for log-returns), and the minimum series length for get_hurst (100 bars) all influence this. Further research could explore different Hurst estimation techniques or lookback periods.
  2. Parameter Sensitivity: The performance is likely sensitive to:
    • Hurst thresholds (0.6, 0.4).
    • The three EMA window lengths (7, 30, 90).
    • The atr_multiplier_sl (currently 1.0). This is a critical parameter to test with more conventional values (e.g., 1.5, 2.0, 2.5). Rigorous sensitivity analysis and out-of-sample testing across different time periods and assets are essential to gauge true robustness.
  3. Transaction Costs: The high trading frequency necessitates a realistic simulation of commissions and slippage, which could significantly impact net profitability.
  4. Statistical Significance: While the headline figures are impressive, their statistical significance and the possibility of data snooping bias should be considered.
  5. Alternative Adaptive Mechanisms: Comparing this discrete EMA selection approach to a more continuous FRAMA formulation (like Ehlers’) could yield insights.

Conclusion

The Hurst-adaptive EMA (FRAMA_H) crossover strategy, as backtested on BTC-USD for 2021-2024, demonstrates a potentially effective approach to navigating this volatile asset, outperforming a buy-and-hold strategy on both absolute and risk-adjusted terms under the specified parameters. The dynamic adjustment of the moving average based on market memory, as estimated by the Hurst exponent, is the core innovation. However, the promising results, particularly with a very tight stop-loss, warrant careful scrutiny regarding parameter sensitivity, robustness, and the impact of real-world trading frictions. This framework provides a solid foundation for further quantitative research into adaptive trading systems.