253 lines
6.8 KiB
Plaintext
253 lines
6.8 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "06df379f",
|
|
"metadata": {},
|
|
"source": [
|
|
"<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c008466a",
|
|
"metadata": {},
|
|
"source": [
|
|
"This code downloads historical stock data for JPMorgan Chase & Co. (JPM) from Yahoo Finance, covering the year 2020. It calculates realized volatility over various rolling windows (30, 60, 90, 120 days) and analyzes the maximum, minimum, top quantile, median, and bottom quantile of these volatilities. The results are visualized using Matplotlib to show the volatility distribution over different windows. This is useful for understanding the stock's risk profile over different time frames."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "373db843",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import math\n",
|
|
"import yfinance as yf\n",
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "93871d13",
|
|
"metadata": {},
|
|
"source": [
|
|
"Download historical stock data for JPM from Yahoo Finance for the year 2020"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f9af1afc",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"data = yf.download(\"JPM\", start=\"2020-01-01\", end=\"2020-12-31\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "67429a4d",
|
|
"metadata": {},
|
|
"source": [
|
|
"Define rolling windows and quantiles to analyze"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a4139b06",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"windows = [30, 60, 90, 120]\n",
|
|
"quantiles = [0.25, 0.75]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2b183370",
|
|
"metadata": {},
|
|
"source": [
|
|
"Initialize lists to store maximum, minimum, quantiles, median, and realized volatilities"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "3dbec930",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"max_ = []\n",
|
|
"min_ = []\n",
|
|
"top_q = []\n",
|
|
"median = []\n",
|
|
"bottom_q = []\n",
|
|
"realized = []"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3c72c004",
|
|
"metadata": {},
|
|
"source": [
|
|
"Calculate realized volatility using rolling windows"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8f7c79c2",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def realized_vol(price_data, window=30):\n",
|
|
" \"\"\"\n",
|
|
" Calculates realized volatility over a rolling window\n",
|
|
" \n",
|
|
" Parameters\n",
|
|
" ----------\n",
|
|
" price_data : pd.DataFrame\n",
|
|
" DataFrame containing stock price data\n",
|
|
" window : int\n",
|
|
" Rolling window size in days\n",
|
|
" \n",
|
|
" Returns\n",
|
|
" -------\n",
|
|
" realized_vol : pd.Series\n",
|
|
" Series containing realized volatility values\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" # Compute log returns from closing prices\n",
|
|
" log_return = (price_data[\"Close\"] / price_data[\"Close\"].shift(1)).apply(np.log)\n",
|
|
" \n",
|
|
" # Compute rolling standard deviation of log returns and annualize it\n",
|
|
" return log_return.rolling(window=window, center=False).std() * math.sqrt(252)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0d965c51",
|
|
"metadata": {},
|
|
"source": [
|
|
"Loop over each window to calculate and store volatility metrics"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ede0e0e3",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"for window in windows:\n",
|
|
"\n",
|
|
" # Calculate realized volatility for the current window\n",
|
|
" estimator = realized_vol(window=window, price_data=data)\n",
|
|
"\n",
|
|
" # Append the maximum realized volatility to the list\n",
|
|
" max_.append(estimator.max())\n",
|
|
"\n",
|
|
" # Append the top quantile realized volatility to the list\n",
|
|
" top_q.append(estimator.quantile(quantiles[1]))\n",
|
|
"\n",
|
|
" # Append the median realized volatility to the list\n",
|
|
" median.append(estimator.median())\n",
|
|
"\n",
|
|
" # Append the bottom quantile realized volatility to the list\n",
|
|
" bottom_q.append(estimator.quantile(quantiles[0]))\n",
|
|
"\n",
|
|
" # Append the minimum realized volatility to the list\n",
|
|
" min_.append(estimator.min())\n",
|
|
"\n",
|
|
" # Append the last realized volatility to the list\n",
|
|
" realized.append(estimator[-1])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ab0bf7e1",
|
|
"metadata": {},
|
|
"source": [
|
|
"Plot the realized volatility metrics for different rolling windows"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "73b648d5",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.plot(windows, max_, \"-o\", linewidth=1, label=\"Max\")\n",
|
|
"plt.plot(windows, top_q, \"-o\", linewidth=1, label=f\"{quantiles[1] * 100:.0f} Prctl\")\n",
|
|
"plt.plot(windows, median, \"-o\", linewidth=1, label=\"Median\")\n",
|
|
"plt.plot(windows, bottom_q, \"-o\", linewidth=1, label=f\"{quantiles[0] * 100:.0f} Prctl\")\n",
|
|
"plt.plot(windows, min_, \"-o\", linewidth=1, label=\"Min\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "9aa0f64d",
|
|
"metadata": {},
|
|
"source": [
|
|
"Plot the realized volatility calculated from the latest window"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ba1919d4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.plot(windows, realized, \"ro-.\", linewidth=1, label=\"Realized\")\n",
|
|
"plt.xticks(windows)\n",
|
|
"plt.legend(loc=\"upper center\", bbox_to_anchor=(0.5, -0.1), ncol=3)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6a4dfc4b",
|
|
"metadata": {},
|
|
"source": [
|
|
"Plot the closing prices of the stock data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b959f4c8",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"data.Close.plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "011cc534",
|
|
"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
|
|
}
|