{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0f1af07e",
   "metadata": {},
   "source": [
    "<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da69000c",
   "metadata": {},
   "source": [
    "This code uses the OpenBB Terminal SDK to analyze option chains for the SPY ETF. It fetches option chains and expiration dates from the Yahoo Finance source, and identifies the at-the-money (ATM) strike price for SPY options. It then plots the implied volatility (IV) term structure for ATM call options and the IV skew for call options with a specific expiration date. This is useful for visualizing how implied volatility varies across different strike prices and expiration dates, aiding in options trading strategies."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "efc8d575",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openbb_terminal.sdk import openbb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f875e54b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.rc(\"font\", size=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d7114f0",
   "metadata": {},
   "source": [
    "Fetch option chains for SPY from Yahoo Finance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7b96161",
   "metadata": {},
   "outputs": [],
   "source": [
    "chains = openbb.stocks.options.chains(\n",
    "    symbol=\"SPY\", \n",
    "    source=\"YahooFinance\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d05e985",
   "metadata": {},
   "source": [
    "Fetch expiration dates for SPY options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb360b93",
   "metadata": {},
   "outputs": [],
   "source": [
    "expirations = openbb.stocks.options.expirations(\"SPY\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "318a8b30",
   "metadata": {},
   "source": [
    "Retrieve the last adjusted closing price for SPY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b027826",
   "metadata": {},
   "outputs": [],
   "source": [
    "last = (\n",
    "    openbb\n",
    "    .stocks\n",
    "    .load(\"SPY\")\n",
    "    .iloc[-1][\"Adj Close\"]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cdf8e3c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "last"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d17254b4",
   "metadata": {},
   "source": [
    "Identify the index of the strike price closest to the last adjusted closing price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0063ef3",
   "metadata": {},
   "outputs": [],
   "source": [
    "idx = (\n",
    "    (chains.strike - last)\n",
    "    .abs()\n",
    "    .sort_values()\n",
    "    .index[0]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ef7cbf1",
   "metadata": {},
   "source": [
    "Retrieve the at-the-money (ATM) strike price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7432cf1b",
   "metadata": {},
   "outputs": [],
   "source": [
    "atm_strike = (\n",
    "    chains\n",
    "    .iloc[idx]\n",
    "    .strike\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00624270",
   "metadata": {},
   "source": [
    "Filter the option chains to get only the ATM call options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9fbe0cd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "calls = (\n",
    "    chains[\n",
    "        (chains.strike == atm_strike) \n",
    "        & (chains.optionType == \"call\")\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17ad09bb",
   "metadata": {},
   "source": [
    "Plot the implied volatility term structure for ATM call options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a776685a",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    calls\n",
    "    .set_index(\"expiration\")\n",
    "    .impliedVolatility.plot(title=\"IV term structure for ATM call options\")\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "742dc7cf",
   "metadata": {},
   "source": [
    "Filter the option chains to get call options expiring on a specific date"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ea22fc4c",
   "metadata": {},
   "outputs": [],
   "source": [
    "calls = (\n",
    "    chains[\n",
    "        (chains.expiration == expirations[4]) \n",
    "        & (chains.optionType == \"call\")\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40ba8471",
   "metadata": {},
   "source": [
    "Plot the implied volatility skew for call options with the specified expiration date"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2219e7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    calls\n",
    "    .set_index(\"strike\")\n",
    "    .impliedVolatility\n",
    "    .plot(title=f\"IV term structure for call options expiring {expirations[1]}\")\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c4f7488",
   "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"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
