{ "cells": [ { "cell_type": "markdown", "id": "cf1415df", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "id": "b9fd5ee6", "metadata": {}, "source": [ "This notebook analyzes the Hurst exponent of the S&P 500 index to measure market trends and randomness. It loads historical S&P 500 data using the OpenBB SDK and calculates the Hurst exponent for various time lags. The Hurst exponent helps in understanding the nature of time series, whether it is mean-reverting, trending, or a random walk. This information is valuable for financial analysts and quant traders for making informed decisions. Additionally, it plots rolling volatility to observe changes in market volatility over time." ] }, { "cell_type": "code", "execution_count": null, "id": "d89701d0", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "id": "c475ecc1", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "from openbb_terminal.sdk import openbb" ] }, { "cell_type": "markdown", "id": "883862a7", "metadata": {}, "source": [ "Load historical S&P 500 data from 2000 to 2019 using the OpenBB SDK and select the adjusted close prices" ] }, { "cell_type": "code", "execution_count": null, "id": "00be2ba2", "metadata": {}, "outputs": [], "source": [ "df = openbb.stocks.load(\"^GSPC\", start_date=\"2000-01-01\", end_date=\"2019-12-31\")[\"Adj Close\"]" ] }, { "cell_type": "markdown", "id": "8dd5f150", "metadata": {}, "source": [ "Plot the S&P 500 adjusted close prices to visualize the historical data" ] }, { "cell_type": "code", "execution_count": null, "id": "ab7ba936", "metadata": {}, "outputs": [], "source": [ "df.plot(title=\"S&P 500\")" ] }, { "cell_type": "code", "execution_count": null, "id": "9a9e6e7d", "metadata": {}, "outputs": [], "source": [ "def get_hurst_exponent(ts, max_lag=20):\n", " \"\"\"Calculate the Hurst exponent of a time series\n", " \n", " Parameters\n", " ----------\n", " ts : np.ndarray\n", " Time series data\n", " max_lag : int, optional\n", " Maximum lag to consider, by default 20\n", " \n", " Returns\n", " -------\n", " float\n", " Estimated Hurst exponent\n", " \n", " Notes\n", " -----\n", " The Hurst exponent is used to determine the \n", " long-term memory of time series data.\n", " \"\"\"\n", "\n", " # Define the range of lags to be used in the calculation\n", " lags = range(2, max_lag)\n", "\n", " # Calculate the standard deviation of differences for each lag\n", " tau = [np.std(np.subtract(ts[lag:], ts[:-lag])) for lag in lags]\n", "\n", " # Perform a linear fit to estimate the Hurst exponent\n", " return np.polyfit(np.log(lags), np.log(tau), 1)[0]" ] }, { "cell_type": "markdown", "id": "fc132efc", "metadata": {}, "source": [ "Calculate and print the Hurst exponent for various lags using the full dataset" ] }, { "cell_type": "code", "execution_count": null, "id": "7a1872d6", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "for lag in [20, 100, 250, 500, 1000]:\n", " hurst_exp = get_hurst_exponent(df.values, lag)\n", " print(f\"{lag} lags: {hurst_exp:.4f}\")" ] }, { "cell_type": "markdown", "id": "d51dc23f", "metadata": {}, "source": [ "Select a shorter series from 2005 to 2007 and calculate the Hurst exponent for various lags" ] }, { "cell_type": "code", "execution_count": null, "id": "3cd6e2df", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "shorter_series = df.loc[\"2005\":\"2007\"].values\n", "for lag in [20, 100, 250, 500]:\n", " hurst_exp = get_hurst_exponent(shorter_series, lag)\n", " print(f\"{lag} lags: {hurst_exp:.4f}\")" ] }, { "cell_type": "markdown", "id": "0a623fcf", "metadata": {}, "source": [ "Calculate rolling volatility using a 30-day window and plot the results to observe changes over time" ] }, { "cell_type": "code", "execution_count": null, "id": "100403dc", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "rv = df.rolling(30).apply(np.std)\n", "rv.plot()" ] }, { "cell_type": "markdown", "id": "a021555b", "metadata": {}, "source": [ "Calculate and print the Hurst exponent for various lags using the rolling volatility data" ] }, { "cell_type": "code", "execution_count": null, "id": "2175669f", "metadata": {}, "outputs": [], "source": [ "for lag in [20, 100, 250, 500, 1000]:\n", " hurst_exp = get_hurst_exponent(rv.dropna().values, lag)\n", " print(f\"{lag} lags: {hurst_exp:.4f}\")" ] }, { "cell_type": "markdown", "id": "dfb39650", "metadata": {}, "source": [ "PyQuant News is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to get started with Python for quant finance. For educational purposes. Not investment advise. Use at your own risk." ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" } }, "nbformat": 4, "nbformat_minor": 5 }