{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cf1415df",
   "metadata": {},
   "source": [
    "<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
   ]
  },
  {
   "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": [
    "<a href=\"https://pyquantnews.com/\">PyQuant News</a> 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 <a href=\"https://gettingstartedwithpythonforquantfinance.com/\">get started with Python for quant finance</a>. 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
}
