The beginner's simple guide to understanding options convexity

The beginner's simple guide to understanding options convexity
Most beginners think about option trades as separate bets.
But this can hide risks and opportunities across strike prices. Options trades are never as isolated as you might think.
Learning to spot how option payoffs connect across strikes makes it easier to put on more profitable trades.
Python can show you where risk jumps between strikes.
By reading today's newsletter, you'll get Python code to visualize convexity in an option’s payoff before expiration.
Let's go!
The beginner's simple guide to understanding options convexity
Convexity describes how the shape of option payoffs changes across strikes, capturing the non-linear relationship between price movements and portfolio value. It explains why risk and return profiles are more complex than what delta or vega alone can convey.
Understanding the roots of convexity gives context to its relevance.
Traditional option models emphasized point estimates—delta at-the-money, gamma near expiry—but traders quickly realized that payoffs evolve across a continuum of strikes. As strategies like vertical spreads and volatility arbitrage grew, so did the need to analyze the curvature of payoffs across the entire strike chain. Books like Jim Gatheral’s The Volatility Surface helped formalize this strike-by-strike interdependence.
Knowing this background shows why modern risk management starts with payoff geometry.
Options professionals today assess how profits and losses bend across the surface, not just shift. They study how skewed order flow or volatility shifts can create kinks or inflection points in the P&L landscape. This strike-level convexity helps them detect where exposures stack, risks compound, and where pricing dislocations may arise.
Let's see how it works with Python.
Imports and set up
We use these libraries to get financial data, analyze data, handle dates, model options, and make clear charts. These tools give us everything we need for pricing and visualizing financial instruments.
1import matplotlib.pyplot as plt
2import numpy as np
3import pandas as pd
4import yfinance as yf
5from QuantLib import *
We collect the most recent year of prices for Apple, then prepare key market data needed for our analysis.
1ticker = "AAPL"
2data = yf.download(ticker, period="1y", multi_level_index=False)
3spot_price = data.Close.iat[-1]
4risk_free_rate = 0.04
5dividend_yield = 0.006
6vol_annual = np.std(np.log(data["Close"] / data["Close"].shift(1)).dropna()) * np.sqrt(
7 252
8)
We download daily price history for the past year. We then pick out the latest closing price. For analysis, we assume fixed values for interest and dividends, and measure volatility for the options model.
This gives us a solid starting point for pricing options.
Define option contracts and set up engine
We set the date for valuation, pick an expiry, and lay out a range of possible payouts for different option strike prices. We also build the financial model needed to estimate option values.
There is a lot of code here. I suggest dropping it into ChatGPT and asking for an explanation.
1valuation_date = Date.todaysDate()
2Settings.instance().evaluationDate = valuation_date
3expiry_days = 60
4expiry_date = TARGET().advance(valuation_date, Period(expiry_days, Days))
5maturity = Actual365Fixed().yearFraction(valuation_date, expiry_date)
6option_type = Option.Call
7
8strikes = np.linspace(spot_price * 0.8, spot_price * 1.2, 61)
9payoffs = [PlainVanillaPayoff(option_type, k) for k in strikes]
10exercise = AmericanExercise(valuation_date, expiry_date)
11option_list = [VanillaOption(payoff, exercise) for payoff in payoffs]
12
13spot_handle = QuoteHandle(SimpleQuote(spot_price))
14flat_ts = YieldTermStructureHandle(
15 FlatForward(valuation_date, risk_free_rate, Actual365Fixed())
16)
17dividend_ts = YieldTermStructureHandle(
18 FlatForward(valuation_date, dividend_yield, Actual365Fixed())
19)
20flat_vol = BlackVolTermStructureHandle(
21 BlackConstantVol(valuation_date, TARGET(), vol_annual, Actual365Fixed())
22)
23bsm_process = BlackScholesMertonProcess(spot_handle, dividend_ts, flat_ts, flat_vol)
24
25for opt in option_list:
26 engine = BinomialVanillaEngine(bsm_process, "crr", 1000)
27 opt.setPricingEngine(engine)
We establish today’s date for analysis, set when the option expires, and create a variety of options with strikes both below and above current price.
Each option has the right to be exercised anytime up to expiry, which is called an American style exercise. We use the Cox-Ross-Rubinstein (CRR) binomial pricing model that values the option before expiration.
Note, we use arbitrary strike prices in this analysis. In practice, you’d pick tradable strike prices.
Calculate and plot option prices
We calculate the estimated value for each different strike, then chart the results to see how value changes across strike prices.
1option_prices = [opt.NPV() for opt in option_list]
2
3plt.figure(figsize=(8, 5))
4plt.plot(strikes, option_prices, label="American Option Price")
5plt.scatter(strikes, option_prices, s=12)
6plt.title(f"{ticker} American {Option.Call} Option Price vs Strike")
7plt.xlabel("Strike Price")
8plt.ylabel("Option Price (60 Days to Expiration)")
9plt.grid(True, alpha=0.3)
10plt.tight_layout()
11plt.show()
We run the pricing model for each option and collect their values. Then, we build a chart with strikes on the x-axis and the corresponding option prices on the y-axis.
.png)
By seeing this in a single chart, we get an intuitive sense of how the option’s price responds to different strike prices.
The chart shows a convex relationship between option price and strike price, where the curve bends downward, reflecting the diminishing marginal value of deeper in-the-money options. This convexity arises because option payoffs are non-linear and become increasingly insensitive to strike as intrinsic value dominates.
For traders, this convexity means that small changes in strike near the money can significantly affect the option's price and greeks. It also highlights how spreads and risk exposures behave differently across the strike surface, informing strike selection and hedging strategies.
Your next steps
You’ve priced a full range of American call options on Apple using real data and visualized how value shifts with strike. Next, swap out "AAPL" for another ticker to compare different stocks. Try adjusting expiry_days to see how time to expiration changes option prices. Play with risk_free_rate or vol_annual to see firsthand how market conditions affect value.
