Analyze Options in Python: Unusual Trading Volume

NeuralNineAbout 9 min readNov 24, 2025Watch original
THE SUMMARYAI-generated

Key Concepts

  • Options Data Analysis: Utilizing Python for analyzing financial options data.
  • Extended Trading Hours: Focusing on trading activity outside of regular market hours (9:30 AM - 4:00 PM ET).
  • Unusual Trading Volume: Identifying significant trading volume spikes, particularly during extended hours.
  • Volume-to-Open Interest Ratio: Analyzing the relationship between trading volume and open interest as a potential indicator.
  • Theta Data Terminal: A Java application used to access financial data via an API.
  • Python Libraries: Pandas for data manipulation, NumPy for numerical operations, Matplotlib for visualization, and httpx for API requests.
  • Jupyter Lab: An interactive environment for writing and executing Python code cell by cell.
  • API Endpoints: Specific URLs used to request data from the Theta Data API (e.g., historical data, open interest, trading day status).
  • DataFrames: Pandas DataFrames used to structure and analyze tabular data.
  • Quantiles: Statistical measures used to identify outliers or unusual data points (e.g., 95th percentile).
  • Moving Averages: Technical indicators used to smooth out price data and identify trends (e.g., 30-day Simple Moving Average).
  • Expiration Dates: Key dates for options contracts, often the third Friday of each month.

Analysis of Options Data in Python with Extended Trading Hours Focus

This video tutorial demonstrates how to analyze options data in Python, with a specific focus on identifying unusual trading volume during extended trading hours and analyzing the ratio between trading volume and open interest. The content is targeted towards individuals in finance looking to enhance their programming skills and those in programming seeking to apply their expertise to financial data.

Data Acquisition and Setup

  1. Data Source: The primary data source for this tutorial is Theta Data, a sponsor of the video. Users need to download the Theta Data Terminal (a Java application) from theta-data.net.
  2. Prerequisites:
    • Java: Must be installed on the system. Instructions are provided for downloading from java.com or using package managers on Linux.
    • Theta Data Account: A free account is required for authentication.
  3. Running the Theta Data Terminal:
    • Navigate to the downloaded .jar file in the terminal.
    • Execute the command: java -jar theta-data-terminal.jar.
    • Authenticate with Theta Data credentials.
    • The terminal will run on localhost:2553, serving as the local API endpoint.
  4. Development Environment Setup:
    • Python Project: A Python project needs to be set up. The tutorial suggests using uv (a Python version manager) for package management, but standard pip or pip3 can also be used.
    • Required Packages:
      • pandas: For data manipulation and analysis.
      • numpy: For numerical operations.
      • matplotlib: For data visualization.
      • httpx: For making HTTP requests to the Theta Data API.
      • jupyterlab: For an interactive notebook environment.
    • Installation Example (using uv):
      pip install uv
      uv init
      uv add pandas numpy matplotlib httpx jupyterlab
      uv run jupyter lab
      
    • Jupyter Lab Usage: Launching Jupyter Lab opens a web browser interface where users can create and run Python notebooks. Code is executed cell by cell, allowing for modular development and easy iteration.

Data Analysis: Extended Trading Hours Volume

  1. Importing Libraries:

    import io
    import datetime as dt
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import httpx
    
    • io: Used with httpx to handle response content as a file-like object.
    • datetime: For working with dates and times.
    • numpy: For numerical computations.
    • pandas: For data structures and analysis tools.
    • matplotlib.pyplot: For creating plots and visualizations.
    • httpx: For making asynchronous HTTP requests.
  2. Accessing Historical Options Data (OHLCV):

    • API Endpoint: The tutorial focuses on the history endpoint for Open, High, Low, Close, and Volume (OHLCV) data.
    • Parameters:
      • date: The specific date for which data is requested.
      • underlying: The ticker symbol of the asset (e.g., 'AAPL' for Apple, 'SPX' for S&P 500).
      • expiration_date: The expiration date of the option.
      • interval: The granularity of the data (e.g., '1' for 1-minute intervals).
      • start_time: The start time for data retrieval (e.g., '000000' for midnight).
      • end_time: The end time for data retrieval (e.g., '235959' for 11:59:59 PM).
    • Extended Hours Limitation: For individual stocks like Apple ('AAPL'), data outside regular trading hours (9:30 AM - 4:00 PM ET) is not available. This functionality is primarily available for indices like the S&P 500 ('SPX').
    • Code Snippet (Conceptual):
      # Example of fetching data (simplified)
      url = "http://localhost:2553/v3/options/historical" # Example endpoint
      params = {
          "date": "2024-11-07",
          "underlying": "SPX",
          "expiration_date": "2025-01-17",
          "interval": "1",
          "start_time": "000000",
          "end_time": "235959"
      }
      response = httpx.get(url, params=params)
      response.raise_for_status() # Raise an exception for bad status codes
      data_df = pd.read_csv(io.StringIO(response.text))
      
  3. Function for Fetching OHLCV Data:

    • A function get_ocl_data(ticker, date, expiration) is defined to encapsulate the data fetching and DataFrame creation process.
    • It includes parameters for start_time='000000' and end_time='235959' to retrieve data for the entire day.
    • The timestamp column is extracted and converted to a datetime.time object for easier filtering.
  4. Calculating Extended Hours Volume:

    • get_extended_hours_volume(ticker, date, expiration) function:
      • Calls get_ocl_data to fetch the daily OHLCV data.
      • Groups the data by timestamp and right (call/put) and sums the volume.
      • Resets the index to create a flat DataFrame.
      • Filters for rows where the time is before 9:30 AM or after 4:00 PM.
      • Calculates the sum of call_volume, put_volume, and total_volume for extended hours.
      • Returns these three volume figures.
  5. Identifying Trading Days:

    • is_options_trading_day(date) function:
      • Uses the Theta Data API's calendar endpoint to determine if a given date is a trading day.
      • The endpoint returns information about market open/close times.
      • The function checks if the type in the JSON response is 'open' or 'early close', indicating a trading day.
      • Requires format='json' in the API parameters.
  6. Determining Relevant Expiration Dates:

    • The tutorial uses a hardcoded list of expiration dates, specifically the third Friday of each month. This is a common practice for monthly options expirations.
  7. Aggregating Daily Extended Hours Volume:

    • A loop iterates through each day of the year (e.g., 2024).
    • For each day, it checks if it's a trading day using is_options_trading_day.
    • If it's a trading day, it finds the next relevant expiration date.
    • It then calls get_extended_hours_volume for the S&P 500 ('SPX') with the current date and the determined expiration date.
    • The results (date, call volume, put volume, total volume) are stored in a list of dictionaries.
    • This list is then converted into a Pandas DataFrame (data_df).
    • The DataFrame is saved as a CSV file (volume_data.csv) for future use.
  8. Detecting Unusual Volume (Quantile Method):

    • Simple Quantile: The 95th percentile of total_volume is calculated using data_df['total_volume'].quantile(0.95). Days with total_volume exceeding this threshold are identified as unusual.
    • Expanding Quantile: A more robust method uses the expanding() function to calculate a rolling 95th percentile. This means the threshold is based on all data points up to the current day, making it more adaptive.
      • A new column total_volume_q95 is created.
      • Filtering is then performed using data_df[data_df['total_volume'] > data_df['total_volume_q95']].
    • Interpretation: The tutorial notes that unusual spikes can sometimes correlate with significant market events (e.g., "Japan crash," Nvidia earnings). The interpretation of these spikes is left to the user.

Data Visualization

  1. Plotting Total Volume with SMA and Expiration Dates:

    • Style: plt.style.use('bmh') is applied for a visually appealing plot.
    • 30-Day Simple Moving Average (SMA): A SMA30 column is calculated using data_df['total_volume'].rolling(window=30).mean().
    • Bar Color: A bar_color column is created to highlight expiration dates with a specific red color (#FF6666) and other days with a blue-green color (#00AFFF). This requires converting date objects to ISO format for comparison.
    • Plotting:
      • A bar chart of total_volume is created, with colors determined by bar_color.
      • The SMA30 is plotted as a purple line.
      • X-axis Ticks: To avoid overcrowding, x-axis ticks are set at intervals (e.g., every 5 or 10 days) using plt.xticks and data_df['date'].iloc[indices], with rotation for readability.
    • Observations: The plot often shows increased volume leading up to expiration dates. Spikes not associated with expiration dates are highlighted as potentially more significant.
  2. Plotting Call and Put Volumes Separately (Overlaid Bars):

    • put_back Column: A boolean column put_back is created to determine which volume (call or put) is higher for each day. This is used to control the layering of bars.
    • Conditional Plotting:
      • Bars are plotted conditionally based on put_back. If put_back is True (put volume > call volume), the put bar is plotted first (in red), and then the call bar is plotted on top (in green).
      • If put_back is False (call volume > put volume), the call bar is plotted first (in green), and then the put bar is plotted on top (in red).
      • This creates an overlaid effect where the dominant volume is visually more prominent.
    • Observations: For index options (like SPX), put volume often exceeds call volume.
    • SMA for Call/Put: SMA lines for call and put volumes are also plotted with distinct colors.

Analysis of Volume-to-Open Interest Ratio

  1. Getting Full Day Volume:

    • A modified function get_full_volume is created by removing the time constraints from get_extended_hours_volume. This function calculates the total volume for the entire trading day.
  2. Getting Open Interest Data:

    • API Endpoint: The open_interest endpoint is used.
    • get_open_interest_data(ticker, date, expiration) function:
      • Fetches open interest data similarly to how OHLCV data is fetched.
      • It aggregates open interest by timestamp and right (call/put), summing the open_interest values.
      • The function is designed to return calls_open, puts_open, and total_open.
  3. Calculating Volume-to-Open Interest Ratio:

    • The tutorial iterates through trading days again, this time collecting both full day volume and open interest data.
    • This data is stored in a new DataFrame (data_2_df).
    • A volume_to_open ratio is calculated: data_2_df['total_volume'] / data_2_df['total_open'].
    • Unusual Ratio Detection: Similar to volume analysis, the 95th percentile of the volume_to_open ratio is calculated (using both simple and expanding quantiles) to identify days with unusual ratios.
    • Interpretation: The tutorial acknowledges that the interpretation of this metric is complex and may not always be straightforward. The focus remains on the technical process of data retrieval and analysis.

Conclusion and Takeaways

The video provides a comprehensive guide on how to programmatically analyze options data using Python, with a strong emphasis on practical implementation. Key takeaways include:

  • Data Access: Demonstrates how to use APIs (specifically Theta Data) to fetch financial data.
  • Data Manipulation: Leverages Pandas for cleaning, transforming, and aggregating data.
  • Identifying Anomalies: Explains methods for detecting unusual trading activity, such as volume spikes during extended hours and high volume-to-open interest ratios, using quantile analysis.
  • Data Visualization: Shows how to create informative plots using Matplotlib to visualize trends, moving averages, and highlight specific events like expiration dates.
  • Technical Skills Application: Bridges the gap between finance and programming by showing how to apply data science tools to financial markets.
  • Actionable Insights: While not providing financial advice, the tutorial equips users with the tools to perform their own data-driven investigations into market behavior.

The presenter reiterates that the primary goal is to teach data analysis techniques with financial data, rather than providing financial expertise. Users are encouraged to explore the data and draw their own conclusions.

AI summaries can miss context or contain errors. Check important details against the original video.

Go a little deeper.

Have a question about this video? Load its transcript to open the video chat.