Skip to content

Instantly share code, notes, and snippets.

@hn4002
Created April 6, 2025 01:57
Show Gist options
  • Select an option

  • Save hn4002/34604d42e159741ee0469d220095daee to your computer and use it in GitHub Desktop.

Select an option

Save hn4002/34604d42e159741ee0469d220095daee to your computer and use it in GitHub Desktop.
Schwab L2 Streaming: Subscribing to NYSE_BOOK or NASDAQ_BOOK?

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment