2 min read

Mastering Volatility: How I Trade Options and Analyze the VIX with Python

How to Generate a VIX Distribution Chart in Python
Mastering Volatility: How I Trade Options and Analyze the VIX with Python
Photo by rc.xyz NFT gallery / Unsplash

I switched from trading stocks to options last year, and I’m not looking back. It makes a lot more sense to me than picking individual stocks for my trading portfolio. Do I still invest for the long term? Yes, but I’ve switched my short-term trading strategy to one that stacks the odds in my favor.

These days, I trade volatility by buying or selling option contracts—mostly selling them. I usually look at the bias for a stock like Reddit (RDDT), Nvidia (NVDA), or various ETFs and then sell a covered call (if I own the stock) or a cash-secured put.

I keep an eye on the market, usually in the mornings around the open, manage any trades that need adjusting, and then go enjoy my day. I do, however, keep a sharp eye on the Volatility Index (VIX. A low VIX means I can sell cash-secured puts (short puts) and generate consistent income.

I check daily to see what the VIX is up to, and as a result, I write Python programs to analyze its closing prices. Below is a script that uses yFinance to extract VIX closing prices and then plots them into a distribution chart using the Seaborn library. I use Kernel Density Estimation (KDE) to visualize the distribution curve.

import yfinance as yf
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

save_path = "./results/vix-distribution.png"

# Fetch VIX data for the last 10 years
vix = yf.Ticker("^VIX")
vix_data = vix.history(period="10y")

# Extract the closing prices
vix_close = vix_data["Close"].dropna()

# Compute mean and median
mean_vix = vix_close.mean()
median_vix = vix_close.median()

# Plot the distribution
plt.figure(figsize=(12, 6))
sns.set_theme(style="whitegrid")

sns.histplot(vix_close, bins=50, kde=True, color="royalblue", edgecolor="black")

# Add mean and median lines
plt.axvline(mean_vix, color='red', linestyle='dashed', linewidth=2, label=f'Mean: {mean_vix:.2f}')
plt.axvline(median_vix, color='green', linestyle='dashed', linewidth=2, label=f'Median: {median_vix:.2f}')

# Add labels and title
plt.title("Distribution of Daily VIX Values (Last 10 Years)", fontsize=16)
plt.xlabel("VIX Value", fontsize=14)
plt.ylabel("Frequency", fontsize=14)

# Add legend
plt.legend()

# Add data source and copyright text
plt.figtext(0.15, 0.00, "Data Source: Yahoo Finance", fontsize=10, color='gray')
plt.figtext(0.75, 0.00, "(c) neuralmarkettrends.com", fontsize=10, color='gray')

# Show the plot
plt.savefig(save_path, dpi=300, bbox_inches="tight")
plt.show()