In the initialization code, first find out the exchanges for the symbols and accordingly sort them into two buckets:
class SchwabStreamingClient:
#=====================================================================================
def __init__(self):
# All one time initialization should be done here
self.client = schwab.auth.client_from_token_file(
api_key=client_id,
app_secret=client_secret,
token_path=token_path)
self.stream_client = StreamClient(self.client, account_id=(int(account_id)))
# Based on the exchange info, for L2 quote, find out which book should be used for the symbol
self.nyse_book_symbol_list = set()
self.nasdaq_book_symbol_list = set()
# Initialize the exchange symbol list
self.initialize_exchange_symbol_list()
# =====================================================================================
def initialize_exchange_symbol_list(self):
"""Find out which book (NYSE or NASDAQ) should be used for the symbol
"""
# Call Schwab API to get all the instruments - get results in chunks otherwise we get buffer overflow error.
pattern_list = ['[A-Z][A-Z]?[A-Z]?[A-Z]?', '[A-Z][A-Z][A-Z][A-Z][A-Z]']
symbols_count = {}
instruments = []
# Get all the instruments from Schwab with some basic details
for pattern in pattern_list:
symbols = {pattern}
r = self.client.get_instruments(symbols=symbols, projection=schwab.client.Client.Instrument.Projection.SYMBOL_REGEX)
print(f"API get_instruments(f{symbols}) status code = {r.status_code}")
if r.status_code == 200:
data = r.json()
# print(json.dumps(data, indent=4))
symbols_count[pattern] = len(data["instruments"])
instruments.extend(data["instruments"])
else:
print(r.text)
sys.exit(-999)
# Now for each instrument, find out which exchange it belongs to for getting L2 quote
for instrument in instruments:
# Schwab returns these values for Exchange - NYSE, NASDAQ, NYSE American, NYSE Arca, Cboe BZX, OTC Markets, Mutual Fund, Nasdaq OTCBB, Members Exchange LLC, Investors Exchange LLC (IEX)
exchange = instrument["exchange"]
if exchange in ["NYSE", "NYSE American", "NYSE Arca", "Cboe BZX"]:
self.nyse_book_symbol_list.add(instrument["symbol"])
else:
self.nasdaq_book_symbol_list.add(instrument["symbol"])
return
Now when actually subscribing for L2 symbol, you can do something like this:
if symbol in self.nyse_book_symbol_list:
await self.stream_client.nyse_book_subs(nyse_symbols)
else:
await self.stream_client.nasdaq_book_subs(nasdaq_symbols)