Skip to content
All library documents

Why Market Option Volatility Smiles May Look Irregular

Article Quant Q&A · Author: Skittles

Summary

The document concerns a scatter plot of Tesla call implied volatilities by strike, built from Yahoo options data. The displayed contracts have stale or missing-looking market information, including zero bids and asks and very low reported implied volatility values. The reply suggests first checking whether the values in the downloaded dataset match those displayed in a spreadsheet, which can help distinguish plotting mistakes from data problems.

It also cautions that market implied volatilities need not form a smooth smile. Options can have uneven liquidity across strikes, and quoted or last-traded prices may be stale or inconsistent with no-arbitrage bounds. These issues can distort calculated volatility points. The question about the risk-free rate is not answered, and the reply offers no worked reconstruction, filtering method, or validation of Yahoo's figures. The plot and sample are limited to one underlying and one expiry, so they do not establish how other markets or maturities behave.

Key ideas

  • Verify downloaded implied volatility values against the source data before debugging the plot.
  • Market volatility smiles may appear irregular because options at different strikes have different liquidity.
  • Stale prices and quotes that violate no-arbitrage bounds can produce misleading implied volatilities.
  • The reply does not specify the risk-free rate used by the data source or provide a quote-cleaning procedure.

Tags

Full text
# Python - yahoo finance options data - volatility smile plot


# Python - yahoo finance options data - volatility smile plot












I have plotted the IV of TSLA options using yahoo options data, but the scatter plot doesn't look right, can anyone advise why the plot looks like this? I would expect to see a vol smile plotted.

EDIT additional question, is the same risk-free rate used to get those options data? and what is the rf used in practice, please?

```
import pandas_datareader.data as web
import pandas as pd
import matplotlib.pyplot as plt

tesla = web.YahooOptions('TSLA')
tesla.headers = {'User-Agent': 'Firefox'}
tesla_calls = tesla.get_call_data(12,2023)

tesla_calls.reset_index(inplace=True)
tesla_calls = tesla_calls[tesla_calls['Expiry'] == '2023-12-01T00:00:00.000000000']
plt.scatter(tesla_calls['Strike'], tesla_calls['IV'])

    Strike     Expiry  Type               Symbol    Last  Bid  Ask  Chg  \
19   100.0 2023-12-01  call  TSLA231201C00100000  107.00  0.0  0.0  0.0   
28   140.0 2023-12-01  call  TSLA231201C00140000   82.30  0.0  0.0  0.0   
30   145.0 2023-12-01  call  TSLA231201C00145000   76.80  0.0  0.0  0.0   
32   150.0 2023-12-01  call  TSLA231201C00150000   58.75  0.0  0.0  0.0   
35   160.0 2023-12-01  call  TSLA231201C00160000   50.22  0.0  0.0  0.0   

    PctChg   Vol  Open_Int       IV  Root  IsNonstandard Underlying  \
19     0.0  11.0       0.0  0.00001  TSLA          False       TSLA   
28     0.0   NaN       0.0  0.00001  TSLA          False       TSLA   
30     0.0   2.0       0.0  0.00001  TSLA          False       TSLA   
32     0.0   6.0       0.0  0.00001  TSLA          False       TSLA   
35     0.0   5.0       0.0  0.00001  TSLA          False       TSLA   

    Underlying_Price          Quote_Time     Last_Trade_Date  \
19            205.76 2023-10-26 20:00:01 2023-10-26 16:17:53   
28            205.76 2023-10-26 20:00:01 2023-10-19 16:58:57   
30            205.76 2023-10-26 20:00:01 2023-10-24 14:04:46   
32            205.76 2023-10-26 20:00:01 2023-10-23 13:33:46   
35            205.76 2023-10-26 20:00:01 2023-10-26 18:42:36   

                                                 JSON  
19  {'contractSymbol': 'TSLA231201C00100000', 'str...  
28  {'contractSymbol': 'TSLA231201C00140000', 'str...  
30  {'contractSymbol': 'TSLA231201C00145000', 'str...  
32  {'contractSymbol': 'TSLA231201C00150000', 'str...  
35  {'contractSymbol': 'TSLA231201C00160000', 'str...
```

## Answer by KaiSqDist (score 0)

https://quant.stackexchange.com/a/77169

I haven't extracted the data using your code, but I suppose there should be nothing wrong with your code, this is a sufficiently simple exercise. Why don't you convert the dataset to Excel and look at the implied volatility values to see if they match? If they do, then it is a data issue.

Usually it is common to not see smooth volatility smiles for market options (last I tried for the S&P500). Also, take note that sometimes its due to options being unequally liquidly traded, meaning that ITM are less liquidly traded than OTM options (for both calls and puts). Sometimes option prices even violate the upper and lower (no arb bounds) in the market.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.