# intrinio realtime python sdk
SDK for working with Intrinio's realtime OPRA, IEX, delayed SIP, CBOE One, or NASDAQ Basic prices feeds. Get a comprehensive view with increased market volume and enjoy minimized exchange and per user fees.
[Intrinio](https://intrinio.com/) provides real-time stock and option prices via a two-way WebSocket connection. To get started, [subscribe to a real-time equity feed](https://intrinio.com/real-time-multi-exchange), or [subscribe to a real-time options feed](https://intrinio.com/financial-market-data/options-data) and follow the instructions below.
## Requirements
- Python 3.10
- NOTE: You need https://pypi.org/project/websocket-client/, not https://pypi.org/project/websocket/.
## Docker
Add your API key to the example_app_equities.py or example_app_options.py file, comment the correct line (16 or 17) in Dockerfile, then
```
docker compose build
docker compose run client
```
## Features
### Equities
* Receive streaming, real-time pricing (trades, NBBO bid, ask)
* Subscribe to updates from individual securities, individual contracts, or
* Subscribe to updates for all securities (Lobby/Firehose mode)
* Replay a specific day (at actual pace or as fast as it loads) while the servers are down, either for testing or fetching missed data.
### Options
* Receive streaming, real-time option price updates:
* every trade
* conflated bid and ask
* open interest, open, close, high, low
* unusual activity(block trades, sweeps, whale trades, unusual sweeps)
* Subscribe to updates from individual options contracts (or option chains)
* Subscribe to updates for the entire universe of option contracts (~1.5M option contracts)
## Installation
```
pip install intriniorealtime
```
## Handling Quotes and the Queue
There are thousands of securities (and millions of options contracts), each with their own feed of activity. We highly encourage you to make your on-event handlers as short as possible and follow a queue pattern so your app can handle the volume of activity.
Note that quotes (ask and bid updates) comprise 99% of the volume of the entire feed. Be cautious when deciding to receive quote updates.
## Example Equities Usage
```python
import threading
import signal
import time
import sys
import datetime
from threading import Timer,Thread,Event,Lock
from intriniorealtime.equities_client import IntrinioRealtimeEquitiesClient
from intriniorealtime.equities_replay_client import IntrinioReplayEquitiesClient
from intriniorealtime.equities_client import EquitiesQuote
from intriniorealtime.equities_client import EquitiesTrade
trade_count = 0
ask_count = 0
bid_count = 0
backlog_count = 0
def on_quote(quote, backlog):
global ask_count
global bid_count
global backlog_count
backlog_count = backlog
if isinstance(quote, EquitiesQuote) and 'type' in quote.__dict__:
if quote.type == "ask": ask_count += 1
else: bid_count += 1
def on_trade(trade, backlog):
global trade_count
global backlog_count
backlog_count = backlog
trade_count += 1
class Summarize(threading.Thread):
def __init__(self, stop_flag):
threading.Thread.__init__(self, group=None, args=(), kwargs={})
self.daemon = True
self.stop_flag = stop_flag
def run(self):
global trade_count
global bid_count
global ask_count
global backlog_count
while not self.stop_flag.wait(5):
print("trades: " + str(trade_count) + "; asks: " + str(ask_count) + "; bids: " + str(bid_count) + "; backlog: " + str(backlog_count))
configuration = {
'api_key': 'API_KEY_HERE',
'provider': 'IEX' # 'REALTIME' (IEX), or 'IEX', or 'DELAYED_SIP', or 'NASDAQ_BASIC', or 'CBOE_ONE'
# ,'delayed': True # Add this if you have realtime (nondelayed) access and want to force delayed mode. If you only have delayed mode access, this is redundant.
# ,'replay_date': datetime.date.today() - datetime.timedelta(days=1) # needed for ReplayClient. The date to replay.
# ,'with_simulated_delay': False # needed for ReplayClient. This plays back the events at the same rate they happened in market.
# ,'delete_file_when_done': True # needed for ReplayClient
# ,'write_to_csv': False # needed for ReplayClient
# ,'csv_file_path': 'data.csv' # needed for ReplayClient
# ,'bypass_parsing': True # if you want to handle parsing yourself, set this to True. Otherwise, leave it alone.
# ,'debug': True
# ,'max_queue_size': 250000
}
client = IntrinioRealtimeEquitiesClient(configuration, on_trade, on_quote)
# client = IntrinioReplayClient(options, on_trade, on_quote)
stop_event = Event()
def on_kill_process(sig, frame):
print("Stopping")
stop_event.set()
client.disconnect()
sys.exit(0)
signal.signal(signal.SIGINT, on_kill_process)
client.join(['AAPL','GE','MSFT'])
# client.join(['lobby'])
client.connect()
summarize_thread = Summarize(stop_event)
summarize_thread.start()
time.sleep(120)
# sigint, or ctrl+c, during the thread wait will also perform the same below code.
print("Stopping")
stop_event.set()
client.disconnect()
sys.exit(0)
```
## Equities Data Format
### Quote Message
```python
{ 'symbol': 'AAPL',
'type': 'ask',
'price': '102.3',
'size': 100,
'timestamp': 1636395583000000000,
'subprovider': 'UTP',
'market_center': '',
'condition': '' }
```
* **symbol** - the ticker of the security
* **type** - the quote type
* **`ask`** - represents the top-of-book ask price
* **`bid`** - represents the top-of-book bid price
* **price** - the price in USD
* **size** - the size of the `last` trade, or total volume of orders at the top-of-book `bid` or `ask` price
* **timestamp** - a Unix timestamp (nanoseconds since unix epoch)
* **subprovider** - Denotes the detailed source within grouped sources.
* **`NO_SUBPROVIDER`** - No subtype specified.
* **`CTA_A`** - CTA_A in the DELAYED_SIP provider.
* **`CTA_B`** - CTA_B in the DELAYED_SIP provider.
* **`UTP`** - UTP in the DELAYED_SIP provider.
* **`OTC`** - OTC in the DELAYED_SIP provider.
* **`NASDAQ_BASIC`** - NASDAQ Basic in the NASDAQ_BASIC provider.
* **`IEX`** - From the IEX exchange in the REALTIME provider.
* **`CBOE_ONE`** - From the CBOE One exchanges provider.
* **market_center** - Provides the market center
* **condition** - Provides the condition
### Trade Message
```python
{ 'symbol': 'AAPL',
'total_volume': '106812',
'price': '102.3',
'size': 100,
'timestamp': 1636395583000000000,
'subprovider': 'IEX',
'market_center': '',
'condition': '' }
```
* **symbol** - the ticker of the security
* **total_volume** - the total volume of trades for the security so far today.
* **price** - the price in USD
* **size** - the size of the `last` trade, or total volume of orders at the top-of-book `bid` or `ask` price
* **timestamp** - a Unix timestamp (nanoseconds since unix epoch)
* **subprovider** - Denotes the detailed source within grouped sources.
* **`NO_SUBPROVIDER`** - No subtype specified.
* **`CTA_A`** - CTA_A in the DELAYED_SIP provider.
* **`CTA_B`** - CTA_B in the DELAYED_SIP provider.
* **`UTP`** - UTP in the DELAYED_SIP provider.
* **`OTC`** - OTC in the DELAYED_SIP provider.
* **`NASDAQ_BASIC`** - NASDAQ Basic in the NASDAQ_BASIC provider.
* **`IEX`** - From the IEX exchange in the REALTIME provider.
* **`CBOE_ONE`** - From the CBOE One exchanges provider.
* **market_center** - Provides the market center
* **condition** - Provides the condition
### Equities Trade Conditions
| Value | Description |
|-------|---------------------------------------------------|
| @ | Regular Sale |
| A | Acquisition |
| B | Bunched Trade |
| C | Cash Sale |
| D | Distribution |
| E | Placeholder |
| F | Intermarket Sweep |
| G | Bunched Sold Trade |
| H | Priced Variation Trade |
| I | Odd Lot Trade |
| K | Rule 155 Trade (AMEX) |
| L | Sold Last |
| M | Market Center Official Close |
| N | Next Day |
| O | Opening Prints |
| P | Prior Reference Price |
| Q | Market Center Official Open |
| R | Seller |
| S | Split Trade |
| T | Form T |
| U | Extended Trading Hours (Sold Out of Sequence) |
| V | Contingent Trade |
| W | Average Price Trade |
| X | Cross/Periodic Auction Trade |
| Y | Yellow Flag Regular Trade |
| Z | Sold (Out of Sequence) |
| 1 | Stopped Stock (Regular Trade) |
| 4 | Derivatively Priced |
| 5 | Re-Opening Prints |
| 6 | Closing Prints |
| 7 | Qualified Contingent Trade (QCT) |
| 8 | Placeholder for 611 Exempt |
| 9 | Corrected Consolidated Close (Per Listing Market) |
### Equities Trade Conditions (CBOE One)
Trade conditions for CBOE One are represented as the integer representation of a bit flag.
None = 0,
UpdateHighLowConsolidated = 1,
UpdateLastConsolidated = 2,
UpdateHighLowMarketCenter = 4,
UpdateLastMarketCenter = 8,
UpdateVolumeConsolidated = 16,
OpenConsolidated = 32,
OpenMarketCenter = 64,
CloseConsolidated = 128,
CloseMarketCenter = 256,
UpdateVolumeMarketCenter = 512
### Equities Quote Conditions
| Value | Description |
|-------|---------------------------------------------|
| R | Regular |
| A | Slow on Ask |
| B | Slow on Bid |
| C | Closing |
| D | News Dissemination |
| E | Slow on Bid (LRP or Gap Quote) |
| F | Fast Trading |
| G | Trading Range Indication |
| H | Slow on Bid and Ask |
| I | Order Imbalance |
| J | Due to Related - News Dissemination |
| K | Due to Related - News Pending |
| O | Open |
| L | Closed |
| M | Volatility Trading Pause |
| N | Non-Firm Quote |
| O | Opening |
| P | News Pending |
| S | Due to Related |
| T | Resume |
| U | Slow on Bid and Ask (LRP or Gap Quote) |
| V | In View of Common |
| W | Slow on Bid and Ask (Non-Firm) |
| X | Equipment Changeover |
| Y | Sub-Penny Trading |
| Z | No Open / No Resume |
| 1 | Market Wide Circuit Breaker Level 1 |
| 2 | Market Wide Circuit Breaker Level 2 |
| 3 | Market Wide Circuit Breaker Level 3 |
| 4 | On Demand Intraday Auction |
| 45 | Additional Information Required (CTS) |
| 46 | Regulatory Concern (CTS) |
| 47 | Merger Effective |
| 49 | Corporate Action (CTS) |
| 50 | New Security Offering (CTS) |
| 51 | Intraday Indicative Value Unavailable (CTS) |
## Example Options Usage
```python
import threading
import signal
import time
import sys
import logging
from threading import Event, Lock
from intriniorealtime.options_client import IntrinioRealtimeOptionsClient
from intriniorealtime.options_client import OptionsQuote
from intriniorealtime.options_client import OptionsTrade
from intriniorealtime.options_client import OptionsRefresh
from intriniorealtime.options_client import OptionsUnusualActivity
from intriniorealtime.options_client import OptionsUnusualActivityType
from intriniorealtime.options_client import OptionsUnusualActivitySentiment
from intriniorealtime.options_client import log
from intriniorealtime.options_client import Config
from intriniorealtime.options_client import Providers
from intriniorealtime.options_client import LogLevel
options_trade_count = 0
options_trade_count_lock = Lock()
options_quote_count = 0
options_quote_count_lock = Lock()
options_refresh_count = 0
options_refresh_count_lock = Lock()
options_ua_block_count = 0
options_ua_block_count_lock = Lock()
options_ua_sweep_count = 0
options_ua_sweep_count_lock = Lock()
options_ua_large_trade_count = 0
options_ua_large_trade_count_lock = Lock()
options_ua_unusual_sweep_count = 0
options_ua_unusual_sweep_count_lock = Lock()
def on_quote(quote: OptionsQuote):
global options_quote_count
global options_quote_count_lock
with options_quote_count_lock:
options_quote_count += 1
def on_trade(trade: OptionsTrade):
global options_trade_count
global options_trade_count_lock
with options_trade_count_lock:
options_trade_count += 1
def on_refresh(refresh: OptionsRefresh):
global options_refresh_count
global options_refresh_count_lock
with options_refresh_count_lock:
options_refresh_count += 1
def on_unusual_activity(ua: OptionsUnusualActivity):
global options_ua_block_count
global options_ua_block_count_lock
global options_ua_sweep_count
global options_ua_sweep_count_lock
global options_ua_large_trade_count
global options_ua_large_trade_count_lock
global options_ua_unusual_sweep_count
global options_ua_unusual_sweep_count_lock
if ua.activity_type == OptionsUnusualActivityType.BLOCK:
with options_ua_block_count_lock:
options_ua_block_count += 1
elif ua.activity_type == OptionsUnusualActivityType.SWEEP:
with options_ua_sweep_count_lock:
options_ua_sweep_count += 1
elif ua.activity_type == OptionsUnusualActivityType.LARGE:
with options_ua_large_trade_count_lock:
options_ua_large_trade_count += 1
elif ua.activity_type == OptionsUnusualActivityType.UNUSUAL_SWEEP:
with options_ua_unusual_sweep_count_lock:
options_ua_unusual_sweep_count += 1
else:
log("on_unusual_activity - Unknown activity_type {0}", ua.activity_type)
class Summarize(threading.Thread):
def __init__(self, stop_flag: threading.Event, intrinio_client: IntrinioRealtimeOptionsClient):
threading.Thread.__init__(self, group=None, args=(), kwargs={}, daemon=True)
self.__stop_flag: threading.Event = stop_flag
self.__client = intrinio_client
def run(self):
while not self.__stop_flag.is_set():
time.sleep(30.0)
(dataMsgs, txtMsgs, queueDepth) = self.__client.get_stats()
log("Client Stats - Data Messages: {0}, Text Messages: {1}, Queue Depth: {2}".format(dataMsgs, txtMsgs, queueDepth))
log(
"App Stats - Trades: {0}, Quotes: {1}, Refreshes: {2}, Blocks: {3}, Sweeps: {4}, Large Trades: {5}, Unusual Sweeps: {6}"
.format(
options_trade_count,
options_quote_count,
options_refresh_count,
options_ua_block_count,
options_ua_sweep_count,
options_ua_large_trade_count,
options_ua_unusual_sweep_count))
# Your config object MUST include the 'api_key' and 'provider', at a minimum
config: Config = Config(
api_key="API_KEY_HERE",
provider=Providers.OPRA,
num_threads=8,
symbols=["AAPL", "BRKB__230217C00300000"], # this is a static list of symbols (options contracts or option chains) that will automatically be subscribed to when the client starts
log_level=LogLevel.INFO,
delayed=False) #set delayed parameter to true if you have realtime access but want the data delayed 15 minutes anyway
# Register only the callbacks that you want.
# Take special care when registering the 'on_quote' handler as it will increase throughput by ~10x
intrinioRealtimeOptionsClient: IntrinioRealtimeOptionsClient = IntrinioRealtimeOptionsClient(config, on_trade=on_trade, on_quote=on_quote, on_refresh=on_refresh, on_unusual_activity=on_unusual_activity)
stop_event = Event()
def on_kill_process(sig, frame):
log("Sample Application - Stopping")
stop_event.set()
intrinioRealtimeOptionsClient.stop()
sys.exit(0)
signal.signal(signal.SIGINT, on_kill_process)
summarize_thread = Summarize(stop_event, intrinioRealtimeOptionsClient)
summarize_thread.start()
intrinioRealtimeOptionsClient.start()
#use this to join the channels already declared in your config
intrinioRealtimeOptionsClient.join()
# Use this to subscribe to the entire universe of symbols (option contracts). This requires special permission.
# intrinioRealtimeOptionsClient.join_firehose()
# Use this to subscribe, dynamically, to an option chain (all option contracts for a given underlying contract).
# intrinioRealtimeOptionsClient.join("AAPL")
# Use this to subscribe, dynamically, to a specific option contract.
# intrinioRealtimeOptionsClient.join("AAP___230616P00250000")
# Use this to subscribe, dynamically, a list of specific option contracts or option chains.
# intrinioRealtimeOptionsClient.join("GOOG__220408C02870000", "MSFT__220408C00315000", "AAPL__220414C00180000", "TSLA", "GE")
time.sleep(60 * 60)
# sigint, or ctrl+c, during the thread wait will also perform the same below code.
on_kill_process(None, None)
```
## Options Data Format
### Trade Message
```python
class Trade:
def __init__(self, contract: str, exchange: Exchange, price: float, size: int, timestamp: float, total_volume: int, qualifiers: tuple, ask_price_at_execution: float, bid_price_at_execution: float, underlying_price_at_execution: float):
self.contract: str = contract
self.exchange: Exchange = exchange
self.price: float = price
self.size: int = size
self.timestamp: float = timestamp
self.total_volume: int = total_volume
self.qualifiers: tuple = qualifiers
self.ask_price_at_execution = ask_price_at_execution
self.bid_price_at_execution = bid_price_at_execution
self.underlying_price_at_execution = underlying_price_at_execution
```
* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.
* **exchange** - Exchange(IntEnum): the specific exchange through which the trade occurred
* **price** - the price in USD
* **size** - the size of the last trade in hundreds (each contract is for 100 shares).
* **total_volume** - The number of contracts traded so far today.
* **timestamp** - a Unix timestamp (with microsecond precision)
* **qualifiers** - a tuple containing 4 ints: each item represents one trade qualifier. see list of possible [Trade Qualifiers](#trade-qualifiers), below.
* **ask_price_at_execution** - the contract ask price in USD at the time of execution.
* **bid_price_at_execution** - the contract bid price in USD at the time of execution.
* **underlying_price_at_execution** - the contract's underlying security price in USD at the time of execution.
### Trade Qualifiers
### Option Trade Qualifiers
| Value | Description |
|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 0 | Transaction is a regular trade |
| 1 | Out-of-sequence cancellation |
| 2 | Transaction is being reported late and is out-of-sequence |
| 3 | In-sequence cancellation |
| 4 | Transaction is being reported late, but is in correct sequence. |
| 5 | Cancel the first trade of the day |
| 6 | Late report of the opening trade and is out -of-sequence. Send an open price. |
| 7 | Transaction was the only one reported this day for the particular option contract and is now to be cancelled. |
| 8 | Late report of an opening trade and is in correct sequence. Process as regular trade. |
| 9 | Transaction was executed electronically. Process as regular trade. |
| 10 | Re-opening of a contract which was halted earlier. Process as regular trade. |
| 11 | Transaction is a contract for which the terms have been adjusted to reflect stock dividend, stock split or similar event. Process as regular trade. |
| 12 | Transaction represents a trade in two options of same class (a buy and a sell in the same class). Process as regular trade. |
| 13 | Transaction represents a trade in two options of same class (a buy and a sell in a put and a call.). Process as regular trade. |
| 14 | Transaction is the execution of a sale at a price agreed upon by the floor personnel involved, where a condition of the trade is that it reported following a non -stopped trade of the same series at the same price. |
| 15 | Cancel stopped transaction. |
| 16 | Transaction represents the option portion of buy/write (buy stock, sell call options). Process as regular trade. |
| 17 | Transaction represents the buying of a call and selling of a put for same underlying stock or index. Process as regular trade. |
| 18 | Transaction was the execution of an order which was “stopped” at a price that did not constitute a Trade-Through on another market at the time of the stop. Process like a normal transaction. |
| 19 | Transaction was the execution of an order identified as an Intermarket Sweep Order. Updates open, high, low, and last. |
| 20 | Transaction reflects the execution of a “benchmark trade”. A “benchmark trade” is a trade resulting from the matching of “benchmark orders”. A “benchmark order” is an order for which the price is not based, directly or indirectly, on the quoted price of th e option at the time of the order’s execution and for which the material terms were not reasonably determinable at the time a commitment to trade the order was made. Updates open, high, and low, but not last unless the trade is the first of the day. |
| 24 | Transaction is trade through exempt, treat like a regular trade. |
| 27 | “a” (Single leg auction non ISO) |
| 28 | “b” (Single leg auction ISO) |
| 29 | “c” (Single leg cross Non ISO) |
| 30 | “d” (Single leg cross ISO) |
| 31 | “e” (Single leg floor trade) |
| 32 | “f” (Multi leg auto electronic trade) |
| 33 | “g” (Multi leg auction trade) |
| 34 | “h” (Multi leg Cross trade) |
| 35 | “i” (Multi leg floor trade) |
| 36 | “j” (Multi leg auto electronic trade against single leg) |
| 37 | “k” (Stock options Auction) |
| 38 | “l” (Multi leg auction trade against single leg) |
| 39 | “m” (Multi leg floor trade against single leg) |
| 40 | “n” (Stock options auto electronic trade) |
| 41 | “o” (Stock options cross trade) |
| 42 | “p” (Stock options floor trade) |
| 43 | “q” (Stock options auto electronic trade against single leg) |
| 44 | “r” (Stock options auction against single leg) |
| 45 | “s” (Stock options floor trade against single leg) |
| 46 | “t” (Multi leg floor trade of proprietary products) |
| 47 | “u” (Multilateral Compression Trade of Proprietary Data Products)Transaction represents an execution in a proprietary product done as part of a multilateral compression. Trades are executed outside of regular trading hours at prices derived from end of day markets. Trades do not update Open, High, Low, and Closing Prices, but will update total volume. |
| 48 | “v” (Extended Hours Trade )Transaction represents a trade that was executed outside of regular market hours. Trades do not update Open, High, Low, and Closing Prices but will update total volume. |
### Quote Message
```python
class Quote:
def __init__(self, contract: str, ask_price: float, ask_size: int, bid_price: float, bid_size: int, timestamp: float):
self.contract: str = contract
self.ask_price: float = ask_price
self.bid_price: float = bid_price
self.ask_size: int = ask_size
self.bid_size: int = bid_size
self.timestamp: float = timestamp
```
* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.
* **ask_price** - the ask price in USD
* **ask_size** - the size of the last ask in hundreds (each contract is for 100 shares).
* **bid_price** - the bid price in USD
* **bid_size** - the size of the last bid in hundreds (each contract is for 100 shares).
* **timestamp** - a Unix timestamp (with microsecond precision)
### Refresh Message
```python
class Refresh:
def __init__(self, contract: str, open_interest: int, open_price: float, close_price: float, high_price: float, low_price: float):
self.contract: str = contract
self.open_interest: int = open_interest
self.open_price: float = open_price
self.close_price: float = close_price
self.high_price: float = high_price
self.low_price: float = low_price
```
* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.
* **openInterest** - the total quantity of opened contracts as reported at the start of the trading day
* **open_price** - the open price in USD
* **close_price** - the close price in USD
* **high_price** - the daily high price in USD
* **low_price** - the daily low price in USD
### Unusual Activity Message
```python
class UnusualActivity:
def __init__(self,
contract: str,
activity_type: UnusualActivityType,
sentiment: UnusualActivitySentiment,
total_value: float,
total_size: int,
average_price: float,
ask_price_at_execution: float,
bid_price_at_execution: float,
underlying_price_at_execution: float,
timestamp: float):
self.contract: str = contract
self.activity_type: UnusualActivityType = activity_type
self.sentiment: UnusualActivitySentiment = sentiment
self.total_value: float = total_value
self.total_size: int = total_size
self.average_price: float = average_price
self.ask_price_at_execution: float = ask_price_at_execution
self.bid_price_at_execution: float = bid_price_at_execution
self.underlying_price_at_execution: float = underlying_price_at_execution
self.timestamp: float = timestamp
```
* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.
* **activity_type** - The type of unusual activity that was detected
* **`Block`** - represents an 'block' trade
* **`Sweep`** - represents an intermarket sweep
* **`Large`** - represents a trade of at least $100,000
* **`UnusualSweep`** - represents an unusually large sweep near market open
* **sentiment** - The sentiment of the unusual activity event
* **`Neutral`** - Reflects a minimal expected price change
* **`Bullish`** - Reflects an expected positive (upward) change in price
* **`Bearish`** - Reflects an expected negative (downward) change in price
* **total_value** - The total value of the trade in USD. 'Sweeps' and 'blocks' can be comprised of multiple trades. This is the value of the entire event.
* **total_size** - The total size of the trade in number of contracts. 'Sweeps' and 'blocks' can be comprised of multiple trades. This is the total number of contracts exchanged during the event.
* **average_price** - The average price at which the trade was executed. 'Sweeps' and 'blocks' can be comprised of multiple trades. This is the average trade price for the entire event.
* **ask_price_at_execution** - The 'ask' price of the underlying at execution of the trade event.
* **bid_price_at_execution** - The 'bid' price of the underlying at execution of the trade event.
* **underlying_price_at_execution** - The last trade price of the underlying at execution of the trade event.
* **Timestamp** - a Unix timestamp (with microsecond precision).
## API Keys
You will receive your Intrinio API Key after [creating an account](https://intrinio.com/signup). You will need a subscription to a [realtime data feed](https://intrinio.com/real-time-multi-exchange) as well.
## Documentation
### Methods
`client = IntrinioRealtimeEquitiesClient(configuration)` - Creates an Intrinio Realtime client
* **Parameter** `configuration.api_key`: Your Intrinio API Key
* **Parameter** `configuration.provider`: The real-time data provider to use ("IEX"/"REALTIME", or "DELAYED_SIP", or "NASDAQ_BASIC", or "CBOE_ONE")
* **Parameter** `configuration.on_quote(quote, backlog)`: A function that handles received quotes. `backlog` is an integer representing the approximate size of the queue of unhandled quote/trade events.
* **Parameter** `configuration.on_trade(quote, backlog)`: A function that handles received trades. `backlog` is an integer representing the approximate size of the queue of unhandled quote/trade events.
* **Parameter** `configuration.logger`: (optional) A Python Logger instance to use for logging
`client : IntrinioRealtimeOptionsClient = IntrinioRealtimeOptionsClient(config : Config, on_trade : Callable[[Trade], None], on_quote : Callable[[Quote], None] = None, on_refresh : Callable[[Refresh], None] = None, on_unusual_activity : Callable[[UnusualActivity],None] = None)` - Creates an Intrinio Real-Time client.
* **Parameter** `config`: The configuration to be used by the client.
* **Parameter** `on_trade`: The Callable accepting trades. If no `on_trade` callback is provided, you will not receive trade updates from the server.
* **Parameter** `on_quote`: The Callable accepting quotes. If no `on_quote` callback is provided, you will not receive quote (ask, bid) updates from the server.
* **Parameter** `on_refresh`: The Callable accepting refresh messages. If no `on_refresh` callback is provided, you will not receive open interest, high, low, open, or close data from the server. Note: open interest data is only updated at the beginning of every trading day. If this callback is provided you will recieve an update immediately, as well as every 15 minutes (approx).
* **Parameter** `on_unusual_activity`: The Callable accepting unusual activity events. If no `on_unusual_activity` callback is provided, you will not receive unusual activity updates from the server.
#### Equities:
```python
def on_quote(quote, backlog):
print("QUOTE: " , quote, "BACKLOG LENGTH: ", backlog)
def on_trade(trade, backlog):
print("TRADE: " , trade, "BACKLOG LENGTH: ", backlog)
configuration = {
'api_key': '',
'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or DELAYED_SIP or NASDAQ_BASIC
#'delayed': True, # Add this if you have realtime (nondelayed) access and want to force delayed mode. If you only have delayed mode access, this is redundant.
'on_quote': on_quote,
'on_trade': on_trade
}
client = IntrinioRealtimeEquitiesClient(configuration)
```
#### Options:
```python
class Config:
def __init__(self, apiKey : str, provider : Providers, numThreads : int = 4, logLevel : LogLevel = LogLevel.INFO, manualIpAddress : str = None, symbols : set[str] = None):
self.apiKey : str = apiKey
self.provider : Providers = provider # Providers.OPRA or Providers.MANUAL
self.numThreads : int = numThreads # At least 4 threads are recommended for 'FIREHOSE' connections
self.manualIpAddress : str = manualIpAddress
self.symbols : list[str] = symbols # Static list of symbols to use
self.logLevel : LogLevel = logLevel
```
---------
`client.join(channels)` - Joins the given channels. This can be called at any time. The client will automatically register joined channels and establish the proper subscriptions with the WebSocket connection.
* **Parameter** `channels` - A single channel or list of channels. You can also use the special symbol, "lobby" to join the firehose channel and recieved updates for all ticker symbols (you must have a valid "firehose" subscription).
```python
client.join(["AAPL", "MSFT", "GE"])
client.join("GOOG")
client.join("lobby")
```
---------
Equities - `client.connect()` - Retrieves an auth token, opens the WebSocket connection, starts the self-healing and heartbeat intervals, joins requested channels.
Options - `client.start()`
---------
Equities - `client.disconnect()` - Closes the WebSocket, stops the self-healing and heartbeat intervals. You _must_ call this to dispose of the client.
Options - `client.stop()`
---------
`client.on_quote(quote, backlog)` - Changes the quote handler function
```python
def on_quote(quote, backlog):
print("QUOTE: " , quote, "BACKLOG LENGTH: ", backlog)
client.on_quote = on_quote
```
---------
`client.leave(channels)` - Leaves the given channels.
* **Parameter** `channels` - A single channel or list of channels
```python
client.leave(["AAPL", "MSFT", "GE"])
client.leave("GOOG")
```
---------
`client.leave_all()` - Leaves all channels.
---------
## Example Equities Replay Client Usage
```python
def on_quote(quote, backlog):
print("QUOTE: " , quote, "BACKLOG LENGTH: ", backlog)
def on_trade(trade, backlog):
print("TRADE: " , trade, "BACKLOG LENGTH: ", backlog)
options = {
'api_key': '',
'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or DELAYED_SIP or NASDAQ_BASIC
'replay_date': datetime.date.today(),
'with_simulated_delay': False, # This plays back the events at the same rate they happened in market.
'delete_file_when_done': True,
'write_to_csv': False, # needed for ReplayClient
'csv_file_path': 'data.csv' # needed for ReplayClient
}
client = IntrinioReplayClient(options, on_trade, on_quote)
```
### Minimum Hardware Requirements - Trades only
Equities Client:
* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 100 symbols, up to the lobby mode settings. Absolute minimum 2 cores and threads.
* Lobby mode: 4 hardware cores and 4 threads in your configuration
* 5 Mbps connection
* 0.5 ms latency
Options Client:
* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 250 contracts, up to the lobby mode settings. 3 cores and 3 configured threads for each chain, up to the lobby mode settings. Absolute minimum 3 cores and threads.
* Lobby mode: 6 hardware cores and 6 threads in your configuration
* 25 Mbps connection
* 0.5 ms latency
### Minimum Hardware Requirements - Trades and Quotes
Equities Client:
* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 25 symbols, up to the lobby mode settings. Absolute minimum 4 cores and threads.
* Lobby mode: 8 hardware cores and 8 threads in your configuration
* 25 Mbps connection
* 0.5 ms latency
Options Client:
* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 100 contracts, up to the lobby mode settings. 4 cores and 4 configured threads for each chain, up to the lobby mode settings. Absolute minimum 4 cores and threads.
* Lobby mode: 12 hardware cores and 12 threads in your configuration
* 100 Mbps connection
* 0.5 ms latency
Raw data
{
"_id": null,
"home_page": "https://intrinio.com",
"name": "intriniorealtime",
"maintainer": null,
"docs_url": null,
"requires_python": "~=3.10",
"maintainer_email": null,
"keywords": "realtime, stock prices, intrinio, stock market, stock data, financial",
"author": "Intrinio Python SDK for Real-Time Stock Prices",
"author_email": "success@intrinio.com",
"download_url": "https://files.pythonhosted.org/packages/36/43/5168835621f374a499c29da64084963eeb69a5038309f5442be96d686fba/intriniorealtime-6.0.3.tar.gz",
"platform": null,
"description": "# intrinio realtime python sdk\nSDK for working with Intrinio's realtime OPRA, IEX, delayed SIP, CBOE One, or NASDAQ Basic prices feeds. Get a comprehensive view with increased market volume and enjoy minimized exchange and per user fees.\n\n[Intrinio](https://intrinio.com/) provides real-time stock and option prices via a two-way WebSocket connection. To get started, [subscribe to a real-time equity feed](https://intrinio.com/real-time-multi-exchange), or [subscribe to a real-time options feed](https://intrinio.com/financial-market-data/options-data) and follow the instructions below.\n\n## Requirements\n\n- Python 3.10\n- NOTE: You need https://pypi.org/project/websocket-client/, not https://pypi.org/project/websocket/.\n\n## Docker\nAdd your API key to the example_app_equities.py or example_app_options.py file, comment the correct line (16 or 17) in Dockerfile, then\n```\ndocker compose build\ndocker compose run client\n```\n\n## Features\n\n### Equities\n\n* Receive streaming, real-time pricing (trades, NBBO bid, ask)\n* Subscribe to updates from individual securities, individual contracts, or\n* Subscribe to updates for all securities (Lobby/Firehose mode)\n* Replay a specific day (at actual pace or as fast as it loads) while the servers are down, either for testing or fetching missed data.\n\n### Options\n\n* Receive streaming, real-time option price updates:\n * every trade\n * conflated bid and ask\n * open interest, open, close, high, low\n * unusual activity(block trades, sweeps, whale trades, unusual sweeps)\n* Subscribe to updates from individual options contracts (or option chains)\n* Subscribe to updates for the entire universe of option contracts (~1.5M option contracts)\n\n## Installation\n```\npip install intriniorealtime\n```\n\n## Handling Quotes and the Queue\n\nThere are thousands of securities (and millions of options contracts), each with their own feed of activity. We highly encourage you to make your on-event handlers as short as possible and follow a queue pattern so your app can handle the volume of activity. \nNote that quotes (ask and bid updates) comprise 99% of the volume of the entire feed. Be cautious when deciding to receive quote updates.\n\n## Example Equities Usage\n\n```python\nimport threading\nimport signal\nimport time\nimport sys\nimport datetime\nfrom threading import Timer,Thread,Event,Lock\n\nfrom intriniorealtime.equities_client import IntrinioRealtimeEquitiesClient\nfrom intriniorealtime.equities_replay_client import IntrinioReplayEquitiesClient\nfrom intriniorealtime.equities_client import EquitiesQuote\nfrom intriniorealtime.equities_client import EquitiesTrade\n\ntrade_count = 0\nask_count = 0\nbid_count = 0\nbacklog_count = 0\n\ndef on_quote(quote, backlog):\n global ask_count\n global bid_count\n global backlog_count\n backlog_count = backlog\n if isinstance(quote, EquitiesQuote) and 'type' in quote.__dict__:\n if quote.type == \"ask\": ask_count += 1\n else: bid_count += 1\n\ndef on_trade(trade, backlog): \n global trade_count\n global backlog_count\n backlog_count = backlog\n trade_count += 1\n\nclass Summarize(threading.Thread):\n def __init__(self, stop_flag):\n threading.Thread.__init__(self, group=None, args=(), kwargs={})\n self.daemon = True\n self.stop_flag = stop_flag\n\n def run(self):\n global trade_count\n global bid_count\n global ask_count\n global backlog_count\n while not self.stop_flag.wait(5):\n print(\"trades: \" + str(trade_count) + \"; asks: \" + str(ask_count) + \"; bids: \" + str(bid_count) + \"; backlog: \" + str(backlog_count))\n\n\nconfiguration = {\n 'api_key': 'API_KEY_HERE',\n 'provider': 'IEX' # 'REALTIME' (IEX), or 'IEX', or 'DELAYED_SIP', or 'NASDAQ_BASIC', or 'CBOE_ONE'\n # ,'delayed': True # Add this if you have realtime (nondelayed) access and want to force delayed mode. If you only have delayed mode access, this is redundant.\n # ,'replay_date': datetime.date.today() - datetime.timedelta(days=1) # needed for ReplayClient. The date to replay.\n # ,'with_simulated_delay': False # needed for ReplayClient. This plays back the events at the same rate they happened in market.\n # ,'delete_file_when_done': True # needed for ReplayClient\n # ,'write_to_csv': False # needed for ReplayClient\n # ,'csv_file_path': 'data.csv' # needed for ReplayClient\n # ,'bypass_parsing': True # if you want to handle parsing yourself, set this to True. Otherwise, leave it alone.\n # ,'debug': True\n # ,'max_queue_size': 250000\n}\n\n\nclient = IntrinioRealtimeEquitiesClient(configuration, on_trade, on_quote)\n# client = IntrinioReplayClient(options, on_trade, on_quote)\nstop_event = Event()\n\n\ndef on_kill_process(sig, frame):\n print(\"Stopping\")\n stop_event.set()\n client.disconnect()\n sys.exit(0)\n\n\nsignal.signal(signal.SIGINT, on_kill_process)\n\n\nclient.join(['AAPL','GE','MSFT'])\n# client.join(['lobby'])\nclient.connect()\n\nsummarize_thread = Summarize(stop_event)\nsummarize_thread.start()\n\ntime.sleep(120)\n\n# sigint, or ctrl+c, during the thread wait will also perform the same below code.\nprint(\"Stopping\")\nstop_event.set()\nclient.disconnect()\nsys.exit(0)\n```\n\n## Equities Data Format\n\n### Quote Message\n\n```python\n{ 'symbol': 'AAPL',\n 'type': 'ask',\n 'price': '102.3',\n 'size': 100,\n 'timestamp': 1636395583000000000,\n 'subprovider': 'UTP',\n 'market_center': '',\n 'condition': '' }\n```\n\n* **symbol** - the ticker of the security\n* **type** - the quote type\n * **`ask`** - represents the top-of-book ask price\n * **`bid`** - represents the top-of-book bid price\n* **price** - the price in USD\n* **size** - the size of the `last` trade, or total volume of orders at the top-of-book `bid` or `ask` price\n* **timestamp** - a Unix timestamp (nanoseconds since unix epoch)\n* **subprovider** - Denotes the detailed source within grouped sources.\n * **`NO_SUBPROVIDER`** - No subtype specified.\n * **`CTA_A`** - CTA_A in the DELAYED_SIP provider.\n * **`CTA_B`** - CTA_B in the DELAYED_SIP provider.\n * **`UTP`** - UTP in the DELAYED_SIP provider.\n * **`OTC`** - OTC in the DELAYED_SIP provider.\n * **`NASDAQ_BASIC`** - NASDAQ Basic in the NASDAQ_BASIC provider.\n * **`IEX`** - From the IEX exchange in the REALTIME provider.\n * **`CBOE_ONE`** - From the CBOE One exchanges provider.\n* **market_center** - Provides the market center\n* **condition** - Provides the condition\n\n### Trade Message\n\n```python\n{ 'symbol': 'AAPL',\n 'total_volume': '106812',\n 'price': '102.3',\n 'size': 100,\n 'timestamp': 1636395583000000000,\n 'subprovider': 'IEX',\n 'market_center': '',\n 'condition': '' }\n```\n\n* **symbol** - the ticker of the security\n* **total_volume** - the total volume of trades for the security so far today.\n* **price** - the price in USD\n* **size** - the size of the `last` trade, or total volume of orders at the top-of-book `bid` or `ask` price\n* **timestamp** - a Unix timestamp (nanoseconds since unix epoch)\n* **subprovider** - Denotes the detailed source within grouped sources.\n * **`NO_SUBPROVIDER`** - No subtype specified.\n * **`CTA_A`** - CTA_A in the DELAYED_SIP provider.\n * **`CTA_B`** - CTA_B in the DELAYED_SIP provider.\n * **`UTP`** - UTP in the DELAYED_SIP provider.\n * **`OTC`** - OTC in the DELAYED_SIP provider.\n * **`NASDAQ_BASIC`** - NASDAQ Basic in the NASDAQ_BASIC provider.\n * **`IEX`** - From the IEX exchange in the REALTIME provider.\n * **`CBOE_ONE`** - From the CBOE One exchanges provider.\n* **market_center** - Provides the market center\n* **condition** - Provides the condition\n\n### Equities Trade Conditions\n\n| Value | Description |\n|-------|---------------------------------------------------|\n| @ | Regular Sale |\n| A | Acquisition |\n| B | Bunched Trade |\n| C | Cash Sale |\n| D | Distribution |\n| E | Placeholder |\n| F | Intermarket Sweep |\n| G | Bunched Sold Trade |\n| H | Priced Variation Trade |\n| I | Odd Lot Trade |\n| K | Rule 155 Trade (AMEX) |\n| L | Sold Last |\n| M | Market Center Official Close |\n| N | Next Day |\n| O | Opening Prints |\n| P | Prior Reference Price |\n| Q | Market Center Official Open |\n| R | Seller |\n| S | Split Trade |\n| T | Form T |\n| U | Extended Trading Hours (Sold Out of Sequence) |\n| V | Contingent Trade |\n| W | Average Price Trade |\n| X | Cross/Periodic Auction Trade |\n| Y | Yellow Flag Regular Trade |\n| Z | Sold (Out of Sequence) |\n| 1 | Stopped Stock (Regular Trade) |\n| 4 | Derivatively Priced |\n| 5 | Re-Opening Prints |\n| 6 | Closing Prints |\n| 7 | Qualified Contingent Trade (QCT) |\n| 8 | Placeholder for 611 Exempt |\n| 9 | Corrected Consolidated Close (Per Listing Market) |\n\n\n### Equities Trade Conditions (CBOE One)\nTrade conditions for CBOE One are represented as the integer representation of a bit flag.\n\nNone = 0,\nUpdateHighLowConsolidated = 1,\nUpdateLastConsolidated = 2,\nUpdateHighLowMarketCenter = 4,\nUpdateLastMarketCenter = 8,\nUpdateVolumeConsolidated = 16,\nOpenConsolidated = 32,\nOpenMarketCenter = 64,\nCloseConsolidated = 128,\nCloseMarketCenter = 256,\nUpdateVolumeMarketCenter = 512\n\n\n### Equities Quote Conditions\n\n| Value | Description |\n|-------|---------------------------------------------|\n| R | Regular |\n| A | Slow on Ask |\n| B | Slow on Bid |\n| C | Closing |\n| D | News Dissemination |\n| E | Slow on Bid (LRP or Gap Quote) |\n| F | Fast Trading |\n| G | Trading Range Indication |\n| H | Slow on Bid and Ask |\n| I | Order Imbalance |\n| J | Due to Related - News Dissemination |\n| K | Due to Related - News Pending |\n| O | Open |\n| L | Closed |\n| M | Volatility Trading Pause |\n| N | Non-Firm Quote |\n| O | Opening |\n| P | News Pending |\n| S | Due to Related |\n| T | Resume |\n| U | Slow on Bid and Ask (LRP or Gap Quote) |\n| V | In View of Common |\n| W | Slow on Bid and Ask (Non-Firm) |\n| X | Equipment Changeover |\n| Y | Sub-Penny Trading |\n| Z | No Open / No Resume |\n| 1 | Market Wide Circuit Breaker Level 1 |\n| 2 | Market Wide Circuit Breaker Level 2 | \n| 3 | Market Wide Circuit Breaker Level 3 |\n| 4 | On Demand Intraday Auction | \n| 45 | Additional Information Required (CTS) | \n| 46 | Regulatory Concern (CTS) | \n| 47 | Merger Effective | \n| 49 | Corporate Action (CTS) | \n| 50 | New Security Offering (CTS) | \n| 51 | Intraday Indicative Value Unavailable (CTS) |\n\n\n## Example Options Usage\n```python\nimport threading\nimport signal\nimport time\nimport sys\nimport logging\nfrom threading import Event, Lock\n\nfrom intriniorealtime.options_client import IntrinioRealtimeOptionsClient\nfrom intriniorealtime.options_client import OptionsQuote\nfrom intriniorealtime.options_client import OptionsTrade\nfrom intriniorealtime.options_client import OptionsRefresh\nfrom intriniorealtime.options_client import OptionsUnusualActivity\nfrom intriniorealtime.options_client import OptionsUnusualActivityType\nfrom intriniorealtime.options_client import OptionsUnusualActivitySentiment\nfrom intriniorealtime.options_client import log\nfrom intriniorealtime.options_client import Config\nfrom intriniorealtime.options_client import Providers\nfrom intriniorealtime.options_client import LogLevel\n\noptions_trade_count = 0\noptions_trade_count_lock = Lock()\noptions_quote_count = 0\noptions_quote_count_lock = Lock()\noptions_refresh_count = 0\noptions_refresh_count_lock = Lock()\noptions_ua_block_count = 0\noptions_ua_block_count_lock = Lock()\noptions_ua_sweep_count = 0\noptions_ua_sweep_count_lock = Lock()\noptions_ua_large_trade_count = 0\noptions_ua_large_trade_count_lock = Lock()\noptions_ua_unusual_sweep_count = 0\noptions_ua_unusual_sweep_count_lock = Lock()\n\n\ndef on_quote(quote: OptionsQuote):\n global options_quote_count\n global options_quote_count_lock\n with options_quote_count_lock:\n options_quote_count += 1\n\n\ndef on_trade(trade: OptionsTrade):\n global options_trade_count\n global options_trade_count_lock\n with options_trade_count_lock:\n options_trade_count += 1\n\n\ndef on_refresh(refresh: OptionsRefresh):\n global options_refresh_count\n global options_refresh_count_lock\n with options_refresh_count_lock:\n options_refresh_count += 1\n\n\ndef on_unusual_activity(ua: OptionsUnusualActivity):\n global options_ua_block_count\n global options_ua_block_count_lock\n global options_ua_sweep_count\n global options_ua_sweep_count_lock\n global options_ua_large_trade_count\n global options_ua_large_trade_count_lock\n global options_ua_unusual_sweep_count\n global options_ua_unusual_sweep_count_lock\n if ua.activity_type == OptionsUnusualActivityType.BLOCK:\n with options_ua_block_count_lock:\n options_ua_block_count += 1\n elif ua.activity_type == OptionsUnusualActivityType.SWEEP:\n with options_ua_sweep_count_lock:\n options_ua_sweep_count += 1\n elif ua.activity_type == OptionsUnusualActivityType.LARGE:\n with options_ua_large_trade_count_lock:\n options_ua_large_trade_count += 1\n elif ua.activity_type == OptionsUnusualActivityType.UNUSUAL_SWEEP:\n with options_ua_unusual_sweep_count_lock:\n options_ua_unusual_sweep_count += 1\n else:\n log(\"on_unusual_activity - Unknown activity_type {0}\", ua.activity_type)\n\n\nclass Summarize(threading.Thread):\n def __init__(self, stop_flag: threading.Event, intrinio_client: IntrinioRealtimeOptionsClient):\n threading.Thread.__init__(self, group=None, args=(), kwargs={}, daemon=True)\n self.__stop_flag: threading.Event = stop_flag\n self.__client = intrinio_client\n\n def run(self):\n while not self.__stop_flag.is_set():\n time.sleep(30.0)\n (dataMsgs, txtMsgs, queueDepth) = self.__client.get_stats()\n log(\"Client Stats - Data Messages: {0}, Text Messages: {1}, Queue Depth: {2}\".format(dataMsgs, txtMsgs, queueDepth))\n log(\n \"App Stats - Trades: {0}, Quotes: {1}, Refreshes: {2}, Blocks: {3}, Sweeps: {4}, Large Trades: {5}, Unusual Sweeps: {6}\"\n .format(\n options_trade_count,\n options_quote_count,\n options_refresh_count,\n options_ua_block_count,\n options_ua_sweep_count,\n options_ua_large_trade_count,\n options_ua_unusual_sweep_count))\n\n\n# Your config object MUST include the 'api_key' and 'provider', at a minimum\nconfig: Config = Config(\n api_key=\"API_KEY_HERE\",\n provider=Providers.OPRA,\n num_threads=8,\n symbols=[\"AAPL\", \"BRKB__230217C00300000\"], # this is a static list of symbols (options contracts or option chains) that will automatically be subscribed to when the client starts\n log_level=LogLevel.INFO,\n delayed=False) #set delayed parameter to true if you have realtime access but want the data delayed 15 minutes anyway\n\n# Register only the callbacks that you want.\n# Take special care when registering the 'on_quote' handler as it will increase throughput by ~10x\nintrinioRealtimeOptionsClient: IntrinioRealtimeOptionsClient = IntrinioRealtimeOptionsClient(config, on_trade=on_trade, on_quote=on_quote, on_refresh=on_refresh, on_unusual_activity=on_unusual_activity)\n\nstop_event = Event()\n\n\ndef on_kill_process(sig, frame):\n log(\"Sample Application - Stopping\")\n stop_event.set()\n intrinioRealtimeOptionsClient.stop()\n sys.exit(0)\n\n\nsignal.signal(signal.SIGINT, on_kill_process)\n\nsummarize_thread = Summarize(stop_event, intrinioRealtimeOptionsClient)\nsummarize_thread.start()\n\nintrinioRealtimeOptionsClient.start()\n\n#use this to join the channels already declared in your config\nintrinioRealtimeOptionsClient.join()\n\n# Use this to subscribe to the entire universe of symbols (option contracts). This requires special permission.\n# intrinioRealtimeOptionsClient.join_firehose()\n\n# Use this to subscribe, dynamically, to an option chain (all option contracts for a given underlying contract).\n# intrinioRealtimeOptionsClient.join(\"AAPL\")\n\n# Use this to subscribe, dynamically, to a specific option contract.\n# intrinioRealtimeOptionsClient.join(\"AAP___230616P00250000\")\n\n# Use this to subscribe, dynamically, a list of specific option contracts or option chains.\n# intrinioRealtimeOptionsClient.join(\"GOOG__220408C02870000\", \"MSFT__220408C00315000\", \"AAPL__220414C00180000\", \"TSLA\", \"GE\")\n\ntime.sleep(60 * 60)\n# sigint, or ctrl+c, during the thread wait will also perform the same below code.\non_kill_process(None, None)\n\n```\n\n## Options Data Format\n### Trade Message\n\n```python\nclass Trade:\n def __init__(self, contract: str, exchange: Exchange, price: float, size: int, timestamp: float, total_volume: int, qualifiers: tuple, ask_price_at_execution: float, bid_price_at_execution: float, underlying_price_at_execution: float):\n self.contract: str = contract\n self.exchange: Exchange = exchange\n self.price: float = price\n self.size: int = size\n self.timestamp: float = timestamp\n self.total_volume: int = total_volume\n self.qualifiers: tuple = qualifiers\n self.ask_price_at_execution = ask_price_at_execution\n self.bid_price_at_execution = bid_price_at_execution\n self.underlying_price_at_execution = underlying_price_at_execution\n```\n\n* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.\n* **exchange** - Exchange(IntEnum): the specific exchange through which the trade occurred\n* **price** - the price in USD\n* **size** - the size of the last trade in hundreds (each contract is for 100 shares).\n* **total_volume** - The number of contracts traded so far today.\n* **timestamp** - a Unix timestamp (with microsecond precision)\n* **qualifiers** - a tuple containing 4 ints: each item represents one trade qualifier. see list of possible [Trade Qualifiers](#trade-qualifiers), below. \n* **ask_price_at_execution** - the contract ask price in USD at the time of execution.\n* **bid_price_at_execution** - the contract bid price in USD at the time of execution.\n* **underlying_price_at_execution** - the contract's underlying security price in USD at the time of execution.\n\n### Trade Qualifiers\n\n### Option Trade Qualifiers\n\n| Value | Description | \n|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| \n| 0 | Transaction is a regular trade | \n| 1 | Out-of-sequence cancellation |\n| 2 | Transaction is being reported late and is out-of-sequence | \n| 3 | In-sequence cancellation |\n| 4 | Transaction is being reported late, but is in correct sequence. |\n| 5 | Cancel the first trade of the day | \n| 6 | Late report of the opening trade and is out -of-sequence. Send an open price. |\n| 7 | Transaction was the only one reported this day for the particular option contract and is now to be cancelled. |\n| 8 | Late report of an opening trade and is in correct sequence. Process as regular trade. |\n| 9 | Transaction was executed electronically. Process as regular trade. |\n| 10 | Re-opening of a contract which was halted earlier. Process as regular trade. |\n| 11 | Transaction is a contract for which the terms have been adjusted to reflect stock dividend, stock split or similar event. Process as regular trade. |\n| 12 | Transaction represents a trade in two options of same class (a buy and a sell in the same class). Process as regular trade. |\n| 13 | Transaction represents a trade in two options of same class (a buy and a sell in a put and a call.). Process as regular trade. |\n| 14 | Transaction is the execution of a sale at a price agreed upon by the floor personnel involved, where a condition of the trade is that it reported following a non -stopped trade of the same series at the same price. |\n| 15 | Cancel stopped transaction. |\n| 16 | Transaction represents the option portion of buy/write (buy stock, sell call options). Process as regular trade. |\n| 17 | Transaction represents the buying of a call and selling of a put for same underlying stock or index. Process as regular trade. |\n| 18 | Transaction was the execution of an order which was \u201cstopped\u201d at a price that did not constitute a Trade-Through on another market at the time of the stop. Process like a normal transaction. |\n| 19 | Transaction was the execution of an order identified as an Intermarket Sweep Order. Updates open, high, low, and last. |\n| 20 | Transaction reflects the execution of a \u201cbenchmark trade\u201d. A \u201cbenchmark trade\u201d is a trade resulting from the matching of \u201cbenchmark orders\u201d. A \u201cbenchmark order\u201d is an order for which the price is not based, directly or indirectly, on the quoted price of th e option at the time of the order\u2019s execution and for which the material terms were not reasonably determinable at the time a commitment to trade the order was made. Updates open, high, and low, but not last unless the trade is the first of the day. |\n| 24 | Transaction is trade through exempt, treat like a regular trade. |\n| 27 | \u201ca\u201d (Single leg auction non ISO) |\n| 28 | \u201cb\u201d (Single leg auction ISO) |\n| 29 | \u201cc\u201d (Single leg cross Non ISO) |\n| 30 | \u201cd\u201d (Single leg cross ISO) |\n| 31 | \u201ce\u201d (Single leg floor trade) |\n| 32 | \u201cf\u201d (Multi leg auto electronic trade) |\n| 33 | \u201cg\u201d (Multi leg auction trade) |\n| 34 | \u201ch\u201d (Multi leg Cross trade) |\n| 35 | \u201ci\u201d (Multi leg floor trade) |\n| 36 | \u201cj\u201d (Multi leg auto electronic trade against single leg) |\n| 37 | \u201ck\u201d (Stock options Auction) |\n| 38 | \u201cl\u201d (Multi leg auction trade against single leg) |\n| 39 | \u201cm\u201d (Multi leg floor trade against single leg) |\n| 40 | \u201cn\u201d (Stock options auto electronic trade) |\n| 41 | \u201co\u201d (Stock options cross trade) |\n| 42 | \u201cp\u201d (Stock options floor trade) |\n| 43 | \u201cq\u201d (Stock options auto electronic trade against single leg) |\n| 44 | \u201cr\u201d (Stock options auction against single leg) |\n| 45 | \u201cs\u201d (Stock options floor trade against single leg) |\n| 46 | \u201ct\u201d (Multi leg floor trade of proprietary products) |\n| 47 | \u201cu\u201d (Multilateral Compression Trade of Proprietary Data Products)Transaction represents an execution in a proprietary product done as part of a multilateral compression. Trades are executed outside of regular trading hours at prices derived from end of day markets. Trades do not update Open, High, Low, and Closing Prices, but will update total volume. |\n| 48 | \u201cv\u201d (Extended Hours Trade )Transaction represents a trade that was executed outside of regular market hours. Trades do not update Open, High, Low, and Closing Prices but will update total volume. |\n\n\n### Quote Message\n\n```python\nclass Quote:\n def __init__(self, contract: str, ask_price: float, ask_size: int, bid_price: float, bid_size: int, timestamp: float):\n self.contract: str = contract\n self.ask_price: float = ask_price\n self.bid_price: float = bid_price\n self.ask_size: int = ask_size\n self.bid_size: int = bid_size\n self.timestamp: float = timestamp\n```\n\n* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.\n* **ask_price** - the ask price in USD\n* **ask_size** - the size of the last ask in hundreds (each contract is for 100 shares).\n* **bid_price** - the bid price in USD\n* **bid_size** - the size of the last bid in hundreds (each contract is for 100 shares).\n* **timestamp** - a Unix timestamp (with microsecond precision)\n\n\n### Refresh Message\n\n```python\nclass Refresh:\n def __init__(self, contract: str, open_interest: int, open_price: float, close_price: float, high_price: float, low_price: float):\n self.contract: str = contract\n self.open_interest: int = open_interest\n self.open_price: float = open_price\n self.close_price: float = close_price\n self.high_price: float = high_price\n self.low_price: float = low_price\n```\n\n* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.\n* **openInterest** - the total quantity of opened contracts as reported at the start of the trading day\n* **open_price** - the open price in USD\n* **close_price** - the close price in USD\n* **high_price** - the daily high price in USD\n* **low_price** - the daily low price in USD\n\n### Unusual Activity Message\n```python\nclass UnusualActivity:\n def __init__(self,\n contract: str,\n activity_type: UnusualActivityType,\n sentiment: UnusualActivitySentiment,\n total_value: float,\n total_size: int,\n average_price: float,\n ask_price_at_execution: float,\n bid_price_at_execution: float,\n underlying_price_at_execution: float,\n timestamp: float):\n self.contract: str = contract\n self.activity_type: UnusualActivityType = activity_type\n self.sentiment: UnusualActivitySentiment = sentiment\n self.total_value: float = total_value\n self.total_size: int = total_size\n self.average_price: float = average_price\n self.ask_price_at_execution: float = ask_price_at_execution\n self.bid_price_at_execution: float = bid_price_at_execution\n self.underlying_price_at_execution: float = underlying_price_at_execution\n self.timestamp: float = timestamp\n```\n\n* **contract** - Identifier for the options contract. This includes the ticker symbol, put/call, expiry, and strike price.\n* **activity_type** - The type of unusual activity that was detected\n * **`Block`** - represents an 'block' trade\n * **`Sweep`** - represents an intermarket sweep\n * **`Large`** - represents a trade of at least $100,000\n * **`UnusualSweep`** - represents an unusually large sweep near market open\n* **sentiment** - The sentiment of the unusual activity event\n * **`Neutral`** - Reflects a minimal expected price change\n * **`Bullish`** - Reflects an expected positive (upward) change in price\n * **`Bearish`** - Reflects an expected negative (downward) change in price\n* **total_value** - The total value of the trade in USD. 'Sweeps' and 'blocks' can be comprised of multiple trades. This is the value of the entire event.\n* **total_size** - The total size of the trade in number of contracts. 'Sweeps' and 'blocks' can be comprised of multiple trades. This is the total number of contracts exchanged during the event.\n* **average_price** - The average price at which the trade was executed. 'Sweeps' and 'blocks' can be comprised of multiple trades. This is the average trade price for the entire event.\n* **ask_price_at_execution** - The 'ask' price of the underlying at execution of the trade event.\n* **bid_price_at_execution** - The 'bid' price of the underlying at execution of the trade event.\n* **underlying_price_at_execution** - The last trade price of the underlying at execution of the trade event.\n* **Timestamp** - a Unix timestamp (with microsecond precision).\n\n## API Keys\nYou will receive your Intrinio API Key after [creating an account](https://intrinio.com/signup). You will need a subscription to a [realtime data feed](https://intrinio.com/real-time-multi-exchange) as well.\n\n## Documentation\n\n### Methods\n\n`client = IntrinioRealtimeEquitiesClient(configuration)` - Creates an Intrinio Realtime client\n* **Parameter** `configuration.api_key`: Your Intrinio API Key\n* **Parameter** `configuration.provider`: The real-time data provider to use (\"IEX\"/\"REALTIME\", or \"DELAYED_SIP\", or \"NASDAQ_BASIC\", or \"CBOE_ONE\")\n* **Parameter** `configuration.on_quote(quote, backlog)`: A function that handles received quotes. `backlog` is an integer representing the approximate size of the queue of unhandled quote/trade events.\n* **Parameter** `configuration.on_trade(quote, backlog)`: A function that handles received trades. `backlog` is an integer representing the approximate size of the queue of unhandled quote/trade events.\n* **Parameter** `configuration.logger`: (optional) A Python Logger instance to use for logging\n\n`client : IntrinioRealtimeOptionsClient = IntrinioRealtimeOptionsClient(config : Config, on_trade : Callable[[Trade], None], on_quote : Callable[[Quote], None] = None, on_refresh : Callable[[Refresh], None] = None, on_unusual_activity : Callable[[UnusualActivity],None] = None)` - Creates an Intrinio Real-Time client.\n* **Parameter** `config`: The configuration to be used by the client.\n* **Parameter** `on_trade`: The Callable accepting trades. If no `on_trade` callback is provided, you will not receive trade updates from the server.\n* **Parameter** `on_quote`: The Callable accepting quotes. If no `on_quote` callback is provided, you will not receive quote (ask, bid) updates from the server.\n* **Parameter** `on_refresh`: The Callable accepting refresh messages. If no `on_refresh` callback is provided, you will not receive open interest, high, low, open, or close data from the server. Note: open interest data is only updated at the beginning of every trading day. If this callback is provided you will recieve an update immediately, as well as every 15 minutes (approx).\n* **Parameter** `on_unusual_activity`: The Callable accepting unusual activity events. If no `on_unusual_activity` callback is provided, you will not receive unusual activity updates from the server.\n\n#### Equities:\n```python\ndef on_quote(quote, backlog):\n print(\"QUOTE: \" , quote, \"BACKLOG LENGTH: \", backlog)\ndef on_trade(trade, backlog):\n print(\"TRADE: \" , trade, \"BACKLOG LENGTH: \", backlog)\n \nconfiguration = {\n 'api_key': '',\n 'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or DELAYED_SIP or NASDAQ_BASIC\n #'delayed': True, # Add this if you have realtime (nondelayed) access and want to force delayed mode. If you only have delayed mode access, this is redundant.\n 'on_quote': on_quote,\n 'on_trade': on_trade\n}\n\nclient = IntrinioRealtimeEquitiesClient(configuration)\n```\n\n#### Options:\n```python\nclass Config:\n def __init__(self, apiKey : str, provider : Providers, numThreads : int = 4, logLevel : LogLevel = LogLevel.INFO, manualIpAddress : str = None, symbols : set[str] = None):\n self.apiKey : str = apiKey\n self.provider : Providers = provider # Providers.OPRA or Providers.MANUAL\n self.numThreads : int = numThreads # At least 4 threads are recommended for 'FIREHOSE' connections\n self.manualIpAddress : str = manualIpAddress\n self.symbols : list[str] = symbols # Static list of symbols to use\n self.logLevel : LogLevel = logLevel\n```\n\n---------\n\n`client.join(channels)` - Joins the given channels. This can be called at any time. The client will automatically register joined channels and establish the proper subscriptions with the WebSocket connection.\n* **Parameter** `channels` - A single channel or list of channels. You can also use the special symbol, \"lobby\" to join the firehose channel and recieved updates for all ticker symbols (you must have a valid \"firehose\" subscription).\n```python\nclient.join([\"AAPL\", \"MSFT\", \"GE\"])\nclient.join(\"GOOG\")\nclient.join(\"lobby\")\n```\n---------\n\nEquities - `client.connect()` - Retrieves an auth token, opens the WebSocket connection, starts the self-healing and heartbeat intervals, joins requested channels.\nOptions - `client.start()`\n\n---------\n\nEquities - `client.disconnect()` - Closes the WebSocket, stops the self-healing and heartbeat intervals. You _must_ call this to dispose of the client.\nOptions - `client.stop()`\n\n---------\n\n`client.on_quote(quote, backlog)` - Changes the quote handler function\n```python\ndef on_quote(quote, backlog):\n print(\"QUOTE: \" , quote, \"BACKLOG LENGTH: \", backlog)\n \nclient.on_quote = on_quote\n```\n\n---------\n\n`client.leave(channels)` - Leaves the given channels.\n* **Parameter** `channels` - A single channel or list of channels\n```python\nclient.leave([\"AAPL\", \"MSFT\", \"GE\"])\nclient.leave(\"GOOG\")\n```\n\n---------\n\n`client.leave_all()` - Leaves all channels.\n\n---------\n## Example Equities Replay Client Usage\n```python\ndef on_quote(quote, backlog):\n print(\"QUOTE: \" , quote, \"BACKLOG LENGTH: \", backlog)\ndef on_trade(trade, backlog):\n print(\"TRADE: \" , trade, \"BACKLOG LENGTH: \", backlog)\n \noptions = {\n 'api_key': '',\n 'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or DELAYED_SIP or NASDAQ_BASIC\n 'replay_date': datetime.date.today(),\n 'with_simulated_delay': False, # This plays back the events at the same rate they happened in market.\n 'delete_file_when_done': True,\n 'write_to_csv': False, # needed for ReplayClient\n 'csv_file_path': 'data.csv' # needed for ReplayClient\n}\n\nclient = IntrinioReplayClient(options, on_trade, on_quote)\n```\n\n### Minimum Hardware Requirements - Trades only\nEquities Client:\n* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 100 symbols, up to the lobby mode settings. Absolute minimum 2 cores and threads.\n* Lobby mode: 4 hardware cores and 4 threads in your configuration\n* 5 Mbps connection\n* 0.5 ms latency\n\nOptions Client:\n* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 250 contracts, up to the lobby mode settings. 3 cores and 3 configured threads for each chain, up to the lobby mode settings. Absolute minimum 3 cores and threads.\n* Lobby mode: 6 hardware cores and 6 threads in your configuration\n* 25 Mbps connection\n* 0.5 ms latency\n\n### Minimum Hardware Requirements - Trades and Quotes\nEquities Client:\n* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 25 symbols, up to the lobby mode settings. Absolute minimum 4 cores and threads.\n* Lobby mode: 8 hardware cores and 8 threads in your configuration\n* 25 Mbps connection\n* 0.5 ms latency\n\nOptions Client:\n* Non-lobby mode: 1 hardware core and 1 thread in your configuration for roughly every 100 contracts, up to the lobby mode settings. 4 cores and 4 configured threads for each chain, up to the lobby mode settings. Absolute minimum 4 cores and threads.\n* Lobby mode: 12 hardware cores and 12 threads in your configuration\n* 100 Mbps connection\n* 0.5 ms latency\n",
"bugtrack_url": null,
"license": null,
"summary": "Intrinio Python SDK for Real-Time Stock Prices",
"version": "6.0.3",
"project_urls": {
"Download": "https://github.com/intrinio/intrinio-realtime-python-sdk/archive/v6.0.3.tar.gz",
"Homepage": "https://intrinio.com"
},
"split_keywords": [
"realtime",
" stock prices",
" intrinio",
" stock market",
" stock data",
" financial"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "77e88316aecd5ceccf57364810f7ba980ddb62196a80ac8356d98808c07f10ff",
"md5": "b128ea787a2dd38503c26ea7c6d1cfce",
"sha256": "01f9390a7648b3bf15a2db50b4ac526aefb4906179eca2f85e6e24d5ad4437ee"
},
"downloads": -1,
"filename": "intriniorealtime-6.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b128ea787a2dd38503c26ea7c6d1cfce",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "~=3.10",
"size": 42169,
"upload_time": "2025-07-10T03:07:08",
"upload_time_iso_8601": "2025-07-10T03:07:08.976769Z",
"url": "https://files.pythonhosted.org/packages/77/e8/8316aecd5ceccf57364810f7ba980ddb62196a80ac8356d98808c07f10ff/intriniorealtime-6.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "36435168835621f374a499c29da64084963eeb69a5038309f5442be96d686fba",
"md5": "bf5528c936b86c4547b371ed3bfb02ed",
"sha256": "bdc84810bb27a677bcc7b1d6088476573289bf11b5610384c56d9edb3f52def7"
},
"downloads": -1,
"filename": "intriniorealtime-6.0.3.tar.gz",
"has_sig": false,
"md5_digest": "bf5528c936b86c4547b371ed3bfb02ed",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "~=3.10",
"size": 58331,
"upload_time": "2025-07-10T03:07:10",
"upload_time_iso_8601": "2025-07-10T03:07:10.444688Z",
"url": "https://files.pythonhosted.org/packages/36/43/5168835621f374a499c29da64084963eeb69a5038309f5442be96d686fba/intriniorealtime-6.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-10 03:07:10",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "intrinio",
"github_project": "intrinio-realtime-python-sdk",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "intriniorealtime"
}