May cohort is now open: How to secure your spot:

Use options to predict stock price moves after earnings

Nothing moves the stock price like earnings announcements.

The intersection of the market’s expectations of earnings and reality creates large swings in stock prices.

If the move can be predicted, there is a reliable edge in trading it.

Options traders are well-informed. Their expectations of future stock price moves are often priced into options. We can use options prices to extract the options market’s expectations of stock price moves.

If we know where to look…

After reading today’s newsletter, you’ll have Python code to predict stock price moves using near-expiration option positions.

Use options to predict stock price moves after earnings

A straddle is an options strategy that uses at-the-money (ATM) call and put options with the same expiration.

The price of a straddle can be used to measure the market’s expected stock price move after earnings announcements.

This approach works because the majority of the value of an option at expiration is based on its time value.

The time value represents the premium investors are willing to pay for the potential of the option being in-the-money at expiration.

Traders use straddles with an expiration date right after the earnings release. This lets us determine the options market’s projection of the stock’s price post-earnings.

Imports and set up

We’ll use OpenBB for the options data. To use the Nasdaq provider, set a dummy API key.

from datetime import datetime, timedelta
import pandas as pd
from openbb import obb
obb.user.preferences.output_type = "dataframe"
obb.user.credentials.nasdaq_api_key = "PLACE_HOLDER"

Next, use OpenBB to grab data on earnings announcements.

earnings_calendar = obb.equity.calendar.earnings(
    start_date=(datetime.now()+timedelta(days=1)).date(),
    end_date = (datetime.now()+timedelta(days=14)).date(),
    provider="nasdaq"
)

This code downloads earnings announcement data for companies that are reporting in the next 14 days.

Select the underlying

Inspect the resulting DataFrame and pick a stock that is announcing earnings on an upcoming Thursday. We’ll use COST for this example and download the last traded price.

symbol = "COST"
last_price = (
    obb
    .equity
    .price
    .quote(symbol, provider="yfinance")
    .T
    .loc["last_price", 0]
)

Next, we’ll grab options chains for COST.

options = obb.derivatives.options.chains(symbol, provider="cboe")
expiration = datetime(2024, 3, 8).date()
chain = options.query("`expiration` == @expiration")

This code selects all the options that expire on 8 March, which is the Friday after earnings are announced. That means we can reliably use these options to predict the price move.

Construct the straddle

To construct the straddle, we’ll extract calls and puts with a strike that is at the money for the call options.

strikes = chain.strike.to_frame()
call_strike = (
    strikes
    .loc[strikes.query("`strike` > @last_price").idxmin()]["strike"]
    .iloc[0]
)
atm_call = chain.query("`strike` == @call_strike and `option_type` == 'call'")
atm_put = chain.query("`strike` == @call_strike and `option_type` == 'put'")
atm = pd.concat([atm_call, atm_put])
straddle_price = round(atm.ask.sum(), 2)

This code filters the strike prices and finds the options with the closest strike to the last traded price of COST. We then use this strike price to filter the call and put options at that strike. From there we concatenate the resulting DataFrames and price the straddle.

In this example, we use the ATM call strike. You could opt for using the ATM put strike or even using a strangle. A strangle is like a straddle except it has differing strike prices.

We use the ask to price the straddle since this analysis assumes a purchase.

Calculate the implied move

Finally, we’ll compute the implied price change of the stock based on the straddle price.

days = (atm.expiration.iloc[0] - datetime.now().date()).days
implied_move = ((1 + straddle_price/last_price)**(1/days) - 1)

First, we calculate the number of days until expiration of the ATM options. The implied move is calculated by first adjusting the stock price with the straddle price, annualizing this adjustment based on the days to expiration, and then converting it into a percentage to reflect the market’s expected price volatility.

As of writing on 5 March, the result is an implied move of 1.74% in COST after earnings.

Next steps

As a next step, run the analysis for several stocks with the same options expiration and earnings date. How accurate is the options market in predicting the future move?