Thanks all for the help! I think I have a good starting point to develop a short/put portfolio.
James thank you for the advice as well. I don’t currently have strong conviction on the market going into a recession so I am not comfortable going all cash. But I also don’t want to do nothing if that makes sense…
Anyway here is some python code that will go through a list of tickers and print out put option info for those that are interested!
Example output:
Ticker: LWLG, Strike date: 2024-03-15, strike price: 4.0, stock price: 4.34, IV/HV Ratio: 1.34, IV: 0.80, premium ratio: 10.60%
*Notes:
- The HV does not match what I am seeing on Fidelity, but otherwise the numbers look right.
- Premium ratio is option price over stock price * 100
Code: note that the inputs you would provide are at the bottom of the code block
*Edited to improve format and info
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta
def get_ratio(ticker_symbol, exp_days, diff_days, hv_days):
# Define the target expiration date
target_expiration_date = (datetime.today() + timedelta(days=exp_days)).strftime("%Y-%m-%d")
# Retrieve the current stock price
ticker = yf.Ticker(ticker_symbol)
current_stock_price = ticker.history(period="1d")["Close"].iloc[0]
# Get the available expiration dates for options
expiration_dates = ticker.options
# Define a function to find the nearest available expiration date within a reasonable range
def find_nearest_expiration(expiration_dates, target_date, max_days_difference=diff_days):
target_date = pd.Timestamp(target_date)
valid_expiration_dates = [date for date in expiration_dates if
pd.Timestamp(date) - target_date <= timedelta(days=max_days_difference)]
if not valid_expiration_dates:
print(f"No validate dates for ticker: {ticker_symbol}")
return None
nearest_date = min(valid_expiration_dates, key=lambda x: abs(pd.Timestamp(x) - target_date))
return nearest_date
# Find the nearest available expiration date to the target date (within a 30-day range)
try:
nearest_expiration_date = find_nearest_expiration(expiration_dates, target_expiration_date,
max_days_difference=diff_days)
except ValueError as e:
print(e)
nearest_expiration_date = None
if nearest_expiration_date:
# Calculate the strike price that is approximately 10% out of the money
otm_strike_price = current_stock_price * 0.9
# Retrieve the options data for the selected expiration date
options_data = ticker.option_chain(nearest_expiration_date)
if not options_data.puts.empty:
otm_put_option = options_data.puts.iloc[(options_data.puts['strike'] - otm_strike_price).abs().idxmin()]
else:
print(
f"No put options available for ticker: {ticker_symbol} for expiration date: {nearest_expiration_date}")
return None
# Calculate Historical Volatility (HV)
lookback_period = hv_days
historical_volatility = ticker.history(period=f"{lookback_period}d")["Close"].pct_change().std() * (252 ** 0.5)
# Calculate IV/HV ratio for the selected OTM put option
current_iv = otm_put_option["impliedVolatility"]
iv_hv_ratio = current_iv / historical_volatility
mid_price = (otm_put_option["bid"] + otm_put_option["ask"])/2
premium_ratio = mid_price/current_stock_price*100
strike = otm_put_option["strike"]
# Display the selected OTM put option and its IV/HV ratio
# print(f"Selected OTM Put Option:\n{otm_put_option}\n") # This can be used to see all info
print(f"Ticker: {ticker_symbol}, Strike date: {nearest_expiration_date}, strike price: {strike}, stock price: {current_stock_price:.2f}, IV/HV Ratio: {iv_hv_ratio:.2f}, IV: {current_iv:.2f}, premium ratio: {premium_ratio:.2f}%, option price: {mid_price}")
return [ticker_symbol, nearest_expiration_date, strike, current_stock_price, iv_hv_ratio, current_iv, premium_ratio, mid_price]
input_string = '''NMRA
HRYU
LWLG
ZJYL
KVUE'''
ticker_list = input_string.split("\n")
string_list = [s.strip() for s in ticker_list if s.strip()]
results = [0]*len(ticker_list)
for i in range(len(ticker_list)):
# inputs: ticker list, number of days out to look for put, number of days expiration can vary by, and HV look back
result = get_ratio(ticker_list[i], 120, 60, 30)
results[i] = result
print("Ticker, expiration, strike, stock_price, IV/HV, IV, premium_ratio, option_cost")
for row in results:
if row:
print(f"{row[0]}, {row[1]}, {row[2]}, {row[3]:.2f}, {row[4]:.2f}, {row[5]:.2f}, {row[6]:.2f}, {row[7]:.2f}")