NbShare
  • Nbshare Notebooks

  • Table of Contents

  • Python Utilities

    • How To Install Jupyter Notebook
    • How to Upgrade Python Pip
    • How To Use Python Pip
  • Python

    • Python Datetime
    • Python Dictionary
    • Python Generators
    • Python Iterators and Generators
    • Python Lambda
    • Python Sort List
    • String And Literal In Python 3
    • Strftime and Strptime In Python
    • Python Tkinter
    • Python Underscore
    • Python Yield
  • Pandas

    • Aggregating and Grouping
    • DataFrame to CSV
    • DF to Numpy Array
    • Drop Columns of DF
    • Handle Json Data
    • Iterate Over Rows of DataFrame
    • Merge and Join DataFrame
    • Pivot Tables
    • Python List to DataFrame
    • Rename Columns of DataFrame
    • Select Rows and Columns Using iloc, loc and ix
    • Sort DataFrame
  • PySpark

    • Data Analysis With Pyspark
    • Read CSV
    • RDD Basics
  • Data Science

    • Confusion Matrix
    • Decision Tree Regression
    • Logistic Regression
    • Regularization Techniques
    • SVM Sklearn
    • Time Series Analysis Using ARIMA
  • Machine Learning

    • How To Code RNN and LSTM Neural Networks in Python
    • PyTorch Beginner Tutorial Tensors
    • Rectified Linear Unit For Artificial Neural Networks Part 1 Regression
    • Stock Sentiment Analysis Using Autoencoders
  • Natural Language
    Processing

    • Opinion Mining Aspect Level Sentiment Analysis
    • Sentiment Analysis using Autoencoders
    • Understanding Autoencoders With Examples
    • Word Embeddings Transformers In SVM Classifier
  • R

    • DataFrame to CSV
    • How to Create DataFrame in R
    • How To Use Grep In R
    • How To Use R Dplyr Package
    • Introduction To R DataFrames
    • Tidy Data In R
  • A.I. News
NbShare Notebooks
  • Publish Your Post On nbshare.io

  • R Python Pandas Data Science Excel NLP Numpy Pyspark Finance

Calculate Stock Options Max Pain Using Data From Yahoo Finance With Python

Max Pain is a theory that suggests that the price of an option contract will tend to move towards a certain strike price, known as the "max pain" strike price, before the option expires. The idea behind this theory is that the option strike price at which the most options will expire worthless is the strike price that causes the most "pain" to option holders.

In this post, we will get the data from Yahoo finance using yfinance Python package.

Let us do an example first. Let us download the option data for expiry 2023-02-03 for APPLE stock.

In [1]:
import yfinance as yf
import pandas as pd

# Get the options data for a stock
stock = yf.Ticker("AAPL")
options_chain = stock.option_chain(date='2023-02-03')

options_chain contains options_chain.calls and options_chain.puts method.

In [2]:
pd.DataFrame(options_chain.calls).head(1)
Out[2]:
contractSymbol lastTradeDate strike lastPrice bid ask change percentChange volume openInterest impliedVolatility inTheMoney contractSize currency
0 AAPL230203C00060000 2023-01-06 16:03:12+00:00 60.0 67.72 76.7 79.15 0.0 0.0 6.0 6 1.742189 True REGULAR USD

There is stock.options which contains all the expirationDates.

In [3]:
stock.options
Out[3]:
('2023-01-27',
 '2023-02-03',
 '2023-02-10',
 '2023-02-17',
 '2023-02-24',
 '2023-03-03',
 '2023-03-17',
 '2023-04-21',
 '2023-05-19',
 '2023-06-16',
 '2023-07-21',
 '2023-08-18',
 '2023-09-15',
 '2023-10-20',
 '2023-12-15',
 '2024-01-19',
 '2024-03-15',
 '2024-06-21',
 '2025-01-17',
 '2025-06-20')

Let us try to find the max pain for TSLA options using formula given on investopedia.

Options Max Pain From Investopedia.com

To find the max pain price, for each in-the-money strike price for both puts and calls:

1. Calculate the difference between the stock price and the strike price.

2. Multiply that difference by the open interest at that strike.

3. Add the dollar value for the put and call at that strike.

4. Repeat steps 1-3 for each strike price. Identify the highest value strike price as the max pain price.

In [48]:
import yfinance as yf
import pandas as pd

# Define the stock ticker
ticker = "TSLA"
stockprice = 132.27

# Get the expiration dates for the stock options
expiration_dates = yf.Ticker(ticker).options

# Loop through each expiration date
for date in expiration_dates:
    # Get the option chain data for the current expiration date
    option_chain = yf.Ticker(ticker).option_chain(date)
    # Extract the put and call data
    puts = option_chain.puts
    calls = option_chain.calls
    # Combine the put and call data into a single dataframe
    data = pd.concat([puts, calls])
    # Filter for in-the-money options
    data = data[data['inTheMoney']]
    # Add a column for the difference between the stock price and strike price
    data['diff'] = abs(data['strike'] - stockprice)
    # Multiply the difference by the open interest
    data['dollar_value'] = data['diff'] * data['openInterest']
    # Extract the expiration date from the contractSymbol
    data['expirationDate'] = data['contractSymbol'].str[4:10]
    # Group by expiration date, strike price and sum the dollar value
    data = data.groupby(['expirationDate','strike']).sum()
    # Find the index of the maximum dollar value
    max_index = data['dollar_value'].idxmax()
    # Use the index to access the corresponding strike price
    max_pain_strike_price = max_index[1]
    maxpain.append({max_index[0]:max_pain_strike_price})
    #print("Expiration date:", max_index[0])
    #print("Max Pain Strike Price:", max_pain_strike_price)
In [49]:
maxpain
Out[49]:
[{'230127': 160.0},
 {'230203': 160.0},
 {'230210': 165.0},
 {'230217': 105.0},
 {'230224': 114.0},
 {'230303': 160.0},
 {'230317': 200.0},
 {'230421': 80.0},
 {'230519': 110.0},
 {'230616': 1080.0},
 {'230721': 185.0},
 {'230915': 200.0},
 {'231215': 250.0},
 {'240119': 1800.0},
 {'240315': 200.0},
 {'240621': 1000.0},
 {'240920': 85.0},
 {'250117': 30.0},
 {'250620': 100.0},
 {'230127': 160.0},
 {'230203': 160.0},
 {'230210': 165.0},
 {'230217': 105.0},
 {'230224': 114.0},
 {'230303': 160.0},
 {'230317': 200.0},
 {'230421': 80.0},
 {'230519': 110.0},
 {'230616': 1080.0},
 {'230721': 185.0},
 {'230915': 200.0},
 {'231215': 250.0},
 {'240119': 1800.0},
 {'240315': 200.0},
 {'240621': 1000.0},
 {'240920': 85.0},
 {'250117': 30.0},
 {'250620': 100.0}]

You can also calculate the max pain strike price for a particular stock using pandas and the following steps:

  1. Get the option chain data for the stock in question. This data should include the strike price, expiration date, and open interest for each option contract.

  2. Group the option contracts by expiration date and strike price, and calculate the total open interest for each strike price. Instead of total open Interest, we can also take in account product of open interest and option price for each strike price

  3. For each expiration date, find the strike price with the highest total open interest. This is the max pain strike price for that expiration date.

  4. Plot the max pain strike prices for each expiration date to visualize the max pain theory.

Options Max Pain:Strike with maximum - open interest (calls+puts)

In [4]:
import yfinance as yf
import pandas as pd

stock_ticker = "TSLA"

# Get the list of all available dates for the option chain data
dates = yf.Ticker(stock_ticker).options

# Initialize an empty DataFrame to store the option chain data
all_data = pd.DataFrame()

# Loop through all available dates
for date in dates:
    # Get the option chain data for the specific date
    option_chain = yf.Ticker(stock_ticker).option_chain(date=date)
    # convert the option chain data to a pandas dataframe
    df = option_chain.calls.append(option_chain.puts)
    # Extract the expiration date from the contractSymbol column
    df['Expiry'] = df['contractSymbol'].str[4:10]
    # Append the option chain data for the specific date to the all_data DataFrame
    all_data = all_data.append(df)

# Group option contracts by expiration date and strike price
grouped = all_data.groupby(['Expiry', 'strike'])['openInterest'].sum()
# Find the max pain strike price for each expiration date
max_pain = grouped.groupby(level=0).idxmax()
max_pain = max_pain.apply(lambda x: x[1])

# Plot max pain strike prices
max_pain.plot()
Out[4]:
<AxesSubplot:xlabel='Expiry'>
In [5]:
max_pain
Out[5]:
Expiry
230127    160.00
230203    160.00
230210    114.00
230217    120.00
230224    135.00
230303    160.00
230317    666.67
230421     80.00
230519    110.00
230616    200.00
230721    250.00
230915    758.33
231215    250.00
240119    825.00
240315    200.00
240621     83.33
240920     85.00
250117    170.00
250620    100.00
Name: openInterest, dtype: float64

Note the above Code takes in to account sum of OpenInterest Number at each strike. Let us update the above code to take in to account following...
Instead of the sum of the OpenInterest at each strike, we will use sum of the product of option price and open interest at each strike price.

Options Max Pain:Strike with maximum - Product of option price and open interest (calls+puts)

In [19]:
import pandas as pd
import yfinance as yf

ticker = "TSLA"
dates = yf.Ticker(ticker).options

# Initialize an empty list to store the option data
all_data = pd.DataFrame()

# Loop through each expiration date
for date in dates:
    # Retrieve the option chain for the current expiration date
    option_chain = yf.Ticker(ticker).option_chain(date=date)
    df = option_chain.calls.append(option_chain.puts)
    # Extract the expiration date from the contractSymbol column
    df = option_chain.calls.append(option_chain.puts)
    # Extract the expiration date from the contractSymbol column
    df['Expiry'] = df['contractSymbol'].str[4:10]
    # Append the option chain data for the specific date to the all_data DataFrame
    all_data = all_data.append(df)

# Create the pain column 
all_data["pain"] = all_data["bid"] * all_data["openInterest"]

# Group option contracts by expiration date and strike price
grouped = all_data.groupby(['Expiry', 'strike'])['pain'].sum()
# Find the max pain strike price for each expiration date
max_pain = grouped.groupby(level=0).idxmax()
max_pain = max_pain.apply(lambda x: x[1])

# Plot max pain strike prices
max_pain.plot()
Out[19]:
<AxesSubplot:xlabel='Expiry'>
In [20]:
all_data.head(1)
Out[20]:
contractSymbol lastTradeDate strike lastPrice bid ask change percentChange volume openInterest impliedVolatility inTheMoney contractSize currency Expiry pain
0 TSLA230127C00025000 2023-01-10 19:32:51+00:00 25.0 92.8 105.85 110.05 0.0 0.0 2.0 4.0 8.63477 True REGULAR USD 230127 423.4
In [21]:
max_pain
Out[21]:
Expiry
230127    160.00
230203    160.00
230210    165.00
230217    120.00
230224    130.00
230303    160.00
230317    200.00
230421     80.00
230519    110.00
230616    200.00
230721    185.00
230915    200.00
231215    250.00
240119    200.00
240315    200.00
240621     83.33
240920     85.00
250117    170.00
250620    100.00
Name: pain, dtype: float64

Related Notebooks

  • How To Analyze Yahoo Finance Data With R
  • Demystifying Stock Options Vega Using Python
  • Pandas Datareader To Download Stocks Data From Google And Yahoo Finance
  • How To Parse Yahoo Finance News Feed With Python
  • Plot Stock Options Vega Implied Volatility Using Python Matplotlib
  • Calculate Implied Volatility of Stock Option Using Python
  • Data Cleaning With Python Pdpipe
  • Stock Sentiment Analysis Using Autoencoders
  • How to Visualize Data Using Python - Matplotlib

Register

User Already registered.


Login

Login

We didn't find you! Please Register

Wrong Password!


Register
    Top Notebooks:
  • Data Analysis With Pyspark Dataframe
  • Strftime and Strptime In Python
  • Python If Not
  • Python Is Integer
  • Dictionaries in Python
  • How To install Python3.9 With Conda
  • String And Literal In Python 3
  • Privacy Policy
©