From 3b2baa39c3b7148a1f45c3129b048f3bc6e41fae Mon Sep 17 00:00:00 2001 From: Shawn Snyder Date: Tue, 2 Sep 2025 19:59:42 -0500 Subject: [PATCH 1/2] equities edge --- README.md | 10 ++++++---- example_app_equities.py | 2 +- intriniorealtime/equities_client.py | 14 ++++++++++---- intriniorealtime/equities_replay_client.py | 10 ++++++++-- setup.py | 4 ++-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 05e1217..00efe1f 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ class Summarize(threading.Thread): configuration = { 'api_key': 'API_KEY_HERE', - 'provider': 'IEX' # 'REALTIME' (IEX), or 'IEX', or 'DELAYED_SIP', or 'NASDAQ_BASIC', or 'CBOE_ONE' + 'provider': 'IEX' # 'REALTIME' (IEX), or 'IEX', or 'DELAYED_SIP', or 'NASDAQ_BASIC', or 'CBOE_ONE' or 'EQUITIES_EDGE' # ,'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. @@ -171,6 +171,7 @@ sys.exit(0) * **`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. + * **`EQUITIES_EDGE`** - From the Equities Edge provider. * **market_center** - Provides the market center * **condition** - Provides the condition @@ -201,6 +202,7 @@ sys.exit(0) * **`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. + * **`EQUITIES_EDGE`** - From the Equities Edge provider. * **market_center** - Provides the market center * **condition** - Provides the condition @@ -633,7 +635,7 @@ You will receive your Intrinio API Key after [creating an account](https://intri `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.provider`: The real-time data provider to use ("IEX"/"REALTIME", or "DELAYED_SIP", or "NASDAQ_BASIC", or "CBOE_ONE", or "EQUITIES_EDGE") * **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 @@ -654,7 +656,7 @@ def on_trade(trade, backlog): configuration = { 'api_key': '', - 'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or DELAYED_SIP or NASDAQ_BASIC + 'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or EQUITIES_EDGE 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 @@ -727,7 +729,7 @@ def on_trade(trade, backlog): options = { 'api_key': '', - 'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or DELAYED_SIP or NASDAQ_BASIC + 'provider': 'IEX', # REALTIME (IEX) or IEX or CBOE_ONE or EQUITIES_EDGE 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, diff --git a/example_app_equities.py b/example_app_equities.py index 7f2855b..c8d5cad 100644 --- a/example_app_equities.py +++ b/example_app_equities.py @@ -47,7 +47,7 @@ def run(self): configuration = { 'api_key': 'API_KEY_HERE', - 'provider': 'IEX' # 'REALTIME' (IEX), or 'IEX', or 'DELAYED_SIP', or 'NASDAQ_BASIC', or 'CBOE_ONE' + 'provider': 'IEX' # 'REALTIME' (IEX), or 'IEX', or 'DELAYED_SIP', or 'NASDAQ_BASIC', or 'CBOE_ONE', or 'EQUITIES_EDGE' # ,'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. diff --git a/intriniorealtime/equities_client.py b/intriniorealtime/equities_client.py index b42c43b..d7dedec 100644 --- a/intriniorealtime/equities_client.py +++ b/intriniorealtime/equities_client.py @@ -25,14 +25,15 @@ OTC = "OTC" IEX = "IEX" CBOE_ONE = "CBOE_ONE" -PROVIDERS = [REALTIME, MANUAL, DELAYED_SIP, NASDAQ_BASIC, IEX, CBOE_ONE] -SUB_PROVIDERS = [NO_SUBPROVIDER, CTA_A, CTA_B, UTP, OTC, NASDAQ_BASIC, IEX, CBOE_ONE] +EQUITIES_EDGE = "EQUITIES_EDGE" +PROVIDERS = [REALTIME, MANUAL, DELAYED_SIP, NASDAQ_BASIC, IEX, CBOE_ONE, EQUITIES_EDGE] +SUB_PROVIDERS = [NO_SUBPROVIDER, CTA_A, CTA_B, UTP, OTC, NASDAQ_BASIC, IEX, CBOE_ONE, EQUITIES_EDGE] MAX_QUEUE_SIZE = 250000 DEBUGGING = not (sys.gettrace() is None) HEADER_MESSAGE_FORMAT_KEY = "UseNewEquitiesFormat" HEADER_MESSAGE_FORMAT_VALUE = "v2" HEADER_CLIENT_INFORMATION_KEY = "Client-Information" -HEADER_CLIENT_INFORMATION_VALUE = "IntrinioPythonSDKv6.0.3" +HEADER_CLIENT_INFORMATION_VALUE = "IntrinioPythonSDKv6.1.0" class EquitiesQuote: @@ -184,6 +185,8 @@ def auth_url(self) -> str: auth_url = "https://realtime-nasdaq-basic.intrinio.com/auth" elif self.provider == CBOE_ONE: auth_url = "https://cboe-one.intrinio.com/auth" + elif self.provider == EQUITIES_EDGE: + auth_url = "https://equities-edge.intrinio.com/auth" elif self.provider == MANUAL: auth_url = "http://" + self.ipaddress + "/auth" @@ -213,6 +216,8 @@ def websocket_url(self) -> str: return "wss://realtime-nasdaq-basic.intrinio.com/socket/websocket?vsn=1.0.0&token=" + self.token + delayed_part elif self.provider == CBOE_ONE: return "wss://cboe-one.intrinio.com/socket/websocket?vsn=1.0.0&token=" + self.token + delayed_part + elif self.provider == EQUITIES_EDGE: + return "wss://equities-edge.intrinio.com/socket/websocket?vsn=1.0.0&token=" + self.token + delayed_part elif self.provider == MANUAL: return "ws://" + self.ipaddress + "/socket/websocket?vsn=1.0.0&token=" + self.token + delayed_part else: @@ -470,7 +475,8 @@ def __init__(self, client, bypass_parsing: bool): 4: OTC, 5: NASDAQ_BASIC, 6: IEX, - 7: CBOE_ONE + 7: CBOE_ONE, + 8: EQUITIES_EDGE } def parse_quote(self, quote_bytes: bytes, start_index: int = 0) -> EquitiesQuote: diff --git a/intriniorealtime/equities_replay_client.py b/intriniorealtime/equities_replay_client.py index 8aad41f..cbca231 100644 --- a/intriniorealtime/equities_replay_client.py +++ b/intriniorealtime/equities_replay_client.py @@ -29,8 +29,9 @@ class IntrinioRealtimeConstants: NASDAQ_BASIC = "NASDAQ_BASIC" IEX = "IEX" CBOE_ONE = "CBOE_ONE" - PROVIDERS = [REALTIME, MANUAL, DELAYED_SIP, NASDAQ_BASIC, IEX, CBOE_ONE] - SUB_PROVIDERS = [NO_SUBPROVIDER, CTA_A, CTA_B, UTP, OTC, NASDAQ_BASIC, IEX, CBOE_ONE] + EQUITIES_EDGE = "EQUITIES_EDGE" + PROVIDERS = [REALTIME, MANUAL, DELAYED_SIP, NASDAQ_BASIC, IEX, CBOE_ONE, EQUITIES_EDGE] + SUB_PROVIDERS = [NO_SUBPROVIDER, CTA_A, CTA_B, UTP, OTC, NASDAQ_BASIC, IEX, CBOE_ONE, EQUITIES_EDGE] MAX_QUEUE_SIZE = 1000000 EVENT_BUFFER_SIZE = 100 @@ -278,6 +279,8 @@ def map_subprovider_to_api_value(sub_provider): return "nasdaq_basic" case IntrinioRealtimeConstants.CBOE_ONE: return "cboe_one" + case IntrinioRealtimeConstants.EQUITIES_EDGE: + return "equities_edge" case _: return "iex" @@ -298,6 +301,8 @@ def map_provider_to_subproviders(provider): return [IntrinioRealtimeConstants.NASDAQ_BASIC] case IntrinioRealtimeConstants.CBOE_ONE: return [IntrinioRealtimeConstants.CBOE_ONE] + case IntrinioRealtimeConstants.EQUITIES_EDGE: + return [IntrinioRealtimeConstants.EQUITIES_EDGE] case _: return [] @@ -447,6 +452,7 @@ def __init__(self, client): 5: IntrinioRealtimeConstants.NASDAQ_BASIC, 6: IntrinioRealtimeConstants.IEX, 7: IntrinioRealtimeConstants.CBOE_ONE, + 8: IntrinioRealtimeConstants.EQUITIES_EDGE } def parse_quote(self, quote_bytes, start_index=0): diff --git a/setup.py b/setup.py index 3a2f56c..129eb8d 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ def readme(): setup( name = 'intriniorealtime', packages = ['intriniorealtime'], - version = '6.0.3', + version = '6.1.0', author = 'Intrinio Python SDK for Real-Time Stock Prices', author_email = 'success@intrinio.com', url = 'https://intrinio.com', @@ -16,7 +16,7 @@ def readme(): long_description_content_type = 'text/markdown', install_requires = ['requests>=2.26.0','websocket-client>=1.2.1','wsaccel>=0.6.3', 'intrinio-sdk>=6.26.0'], python_requires = '~=3.10', - download_url = 'https://github.com/intrinio/intrinio-realtime-python-sdk/archive/v6.0.3.tar.gz', + download_url = 'https://github.com/intrinio/intrinio-realtime-python-sdk/archive/v6.1.0.tar.gz', keywords = ['realtime','stock prices','intrinio','stock market','stock data','financial'], classifiers = [ 'Intended Audience :: Financial and Insurance Industry', From d37f6c621e4802f460b0cad772ad2f162f5bc251 Mon Sep 17 00:00:00 2001 From: Shawn Snyder Date: Tue, 2 Sep 2025 20:07:20 -0500 Subject: [PATCH 2/2] options edge --- README.md | 6 +++--- example_app_options.py | 2 +- intriniorealtime/options_client.py | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 00efe1f..873804a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # 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. +SDK for working with Intrinio's realtime OPRA, Options Edge, IEX, delayed SIP, CBOE One, Equities Edge, 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. @@ -412,7 +412,7 @@ class Summarize(threading.Thread): # Your config object MUST include the 'api_key' and 'provider', at a minimum config: Config = Config( api_key="API_KEY_HERE", - provider=Providers.OPRA, + provider=Providers.OPRA, # or Providers.OPTIONS_EDGE 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, @@ -670,7 +670,7 @@ client = IntrinioRealtimeEquitiesClient(configuration) 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.provider : Providers = provider # Providers.OPRA or Providers.OPTIONS_EDGE 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 diff --git a/example_app_options.py b/example_app_options.py index bf8041a..8a9d5fb 100644 --- a/example_app_options.py +++ b/example_app_options.py @@ -105,7 +105,7 @@ def run(self): # Your config object MUST include the 'api_key' and 'provider', at a minimum config: Config = Config( api_key="API_KEY_HERE", - provider=Providers.OPRA, + provider=Providers.OPRA, # or Providers.OPTIONS_EDGE 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, diff --git a/intriniorealtime/options_client.py b/intriniorealtime/options_client.py index 40d40dc..33388cd 100644 --- a/intriniorealtime/options_client.py +++ b/intriniorealtime/options_client.py @@ -45,6 +45,7 @@ def do_backoff(fn: Callable[[None], bool]): class Providers(IntEnum): OPRA = 1 MANUAL = 2 + OPTIONS_EDGE = 3 @unique class LogLevel(IntEnum): @@ -704,6 +705,8 @@ def __get_websocket(self) -> _WebSocket: def __get_auth_url(self) -> str: if self.__provider == Providers.OPRA: return "https://realtime-options.intrinio.com/auth?api_key=" + self.__apiKey + elif self.__provider == Providers.OPTIONS_EDGE: + return "https://options-edge.intrinio.com/auth?api_key=" + self.__apiKey elif self.__provider == Providers.MANUAL: return "http://" + self.__manualIP + "/auth?api_key=" + self.__apiKey else: @@ -713,6 +716,8 @@ def __get_web_socket_url(self, token: str) -> str: delay: str = "&delayed=true" if self.__delayed else "" if self.__provider == Providers.OPRA: return "wss://realtime-options.intrinio.com/socket/websocket?vsn=1.0.0&token=" + token + delay + elif self.__provider == Providers.OPTIONS_EDGE: + return "wss://options-edge.intrinio.com/socket/websocket?vsn=1.0.0&token=" + token + delay elif self.__provider == Providers.MANUAL: return "ws://" + self.__manualIP + "/socket/websocket?vsn=1.0.0&token=" + token + delay else: