How to stream options data

Overview

In this guide, we will get you streaming Realtime Options data in minutes using Intrinio's Python SDK. That is assuming of course that you've already completed the prerequisites. Why is it that the prerequisites always take more time than the actual task?

Prerequisites to stream options data with Intrinio

  1. Create an account to get an API key
  2. Contact sales@intrinio.com to sign up for a free trial.
  3. Choose which SDK you wish to use Go, Python, C#, orJava.

Prerequisites for this how to guide

  1. Install Docker

Disclaimer

Of our Options SDKs, Python is the least performant. Shocking, I know. We got it to work well enough but you will get better performance using Java, .Net, or Go.

Procedure

Let's start by pulling down the Intrinio Options Python by cloning the repository.

git clone https://github.com/intrinio/intrinio-realtime-options-python-sdk.git

Open up the folder in shell. Run the following command to build and run the docker container. Using the --build flag automatically rebuilds the docker container each time preventing the container from getting stale. For the rest of this guide, run this command to run your code.

docker compose up --build

If all went well, you'll receive an error message that you didn't provide a valid API key. I know, I have a strange idea of what it means to "go well". Open up the example_app.py file and delete everything. Really, let's start from scratch so you actually understand what it all means bit by bit.  Add the following code, but with your api_key in the configuration section and run the application again.

# Import python libraries
import signal
import time
import sys
from threading import Event
import client

# Configuration
config: client.Config = client.Config(
    api_key="YOUR_API_KEY",
    provider=client.Providers.OPRA,
    num_threads=8,
    log_level=client.LogLevel.INFO)

# Trade handler
def on_trade(trade: client.Trade):
    client.log(trade)

# Initializing the options client
intrinioRealtimeOptionsClient: client.Client = client.Client(config, on_trade=on_trade)
intrinioRealtimeOptionsClient.start()

# Subscribing to specific contracts
intrinioRealtimeOptionsClient.join("AAPL")

# Clean up and gracefully exiting
stop_event = Event()
def on_kill_process(sig, frame):
    client.log("Sample Application - Stopping")
    stop_event.set()
    intrinioRealtimeOptionsClient.stop()
    sys.exit(0)

signal.signal(signal.SIGINT, on_kill_process)

while not stop_event.is_set():
    time.sleep(10.0)
    print(client.log("Heartbeat..."));

You should start seeing trades for AAPL option contracts output to the console! Your specific output will vary greatly depending on whether markets are open, market volume, and if you put in your api key correctly. Hopefully the above code isn't too hard to decipher. Take a minute to read it over. You will probably be spending most of your time fine tuning your event handlers and managing your subscriptions so let me show some examples of that. Our web socket provides you several different ways to subscribe to different contracts. If you already know exactly which contracts you are looking you at and you want to subscribe to an individual contract it would look like this:

# Subscribing to specific contracts
intrinioRealtimeOptionsClient.join("AAPL__231027P00170000")
# Leaving a specific subscription
intrinioRealtimeOptionsClient.leave("AAPL__231027P00170000")
# Leaving all subscriptions
intrinioRealtimeOptionsClient.leave()

Go ahead and add that to your example python script and test it out. So that is cool but what if you want to subscribe to everything. Do you have to specify each ticker one by one? No, we already walked uphill to the exchange both ways so you don't have to. We have something called the firehose and we can use that to get everything. Try this:

# Join Firehose
intrinioRealtimeOptionsClient.join_firehose()

# Let it run for 10 seconds
time.sleep(10.0)

# Make mom proud
intrinioRealtimeOptionsClient.leave_firehose()
intrinioRealtimeOptionsClient.stop()

Before you ask, no, you don't have to, but yes it is a good idea to explicitly leave your subscriptions and gracefully exit. It's cleaning up after yourself, your mom would be proud. Alright so subscriptions seem easy enough, but what about Asks, Bids?

def on_quote_handler(quote: client.Quote):
    client.log(quote)

# The on trade callback is required but we can pass None if we don't need it
intrinioRealtimeOptionsClient: client.Client = client.Client(config, on_trade=None, on_quote=on_quote_handler)

And what about Open Interest? Open, High, Low? Use our refresh handler:

def on_refresh_handler(refresh: client.Refresh):
    client.log(refresh)

intrinioRealtimeOptionsClient: client.Client = client.Client(config, on_trade=None, on_refresh=on_refresh_handler)

Unusual activity? Use the unusual activity handler:

def on_unusual_activity_handler(refresh: client.Refresh):
    client.log(refresh)
    
intrinioRealtimeOptionsClient: client.Client = client.Client(config, on_trade=None, on_unusual_activity=on_unusual_activity_handler)

Of course you can specify all of the event handlers if you want, it's up to you!

Conclusion

That probably felt like an abrupt ending but that's it! These how to guides are designed to be like a good video game tutorial. We show you the basics, get you excited, and then the rest is up to you to explore. Unlike a video game where you don't get access to the developers, we are always here to help in case you get stuck. Reach out on chat or email us at sales@intrinio.com with any questions or if you'd like to start a trial.