Seeing the same issue as others reported.
There seems to be a limit of ~3500 stocks per websocket client. If you try to open a second connection and stream batches of tickers, the second connection returns an error like @alpalpalpa reported.
It does not seem possible to stream all nasdaq tickers using a single “unlimited” account. If this is intentional, perhaps add a feature to pay another $x dollars for more websocket connections in the same account?
This is using an SIP unlimited account. Tried on both paper-api and api endpoints.
Examples:
...
tickers = [el.symbol for el in api.list_assets(status='active')]
...
# Try to subscribe to 4k tickers
@stream.on_bar(*tickers[0:4000])
async def _(bar):
...
Here’s the error you get:
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=<Opcode.CLOSE: 8>, data=b'\x03\xf1read limited at 16385 bytes', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = connection_lost(None)
DEBUG:websockets.protocol:client - state = CLOSED
DEBUG:websockets.protocol:client x code = 1009, reason = read limited at 16385 bytes
WARNING:alpaca_trade_api.stream:websocket error, restarting connection: code = 1009 (message too big), reason = read limited at 16385 bytes
DEBUG:websockets.protocol:client x closing TCP connection
If you try to open a second connection and stream batches of tickers in two processes, the second process never initiates. Here’s an output from debug mode using python sdk:
DEBUG:asyncio:Using selector: KqueueSelector
INFO:alpaca_trade_api.stream:started data stream
DEBUG:websockets.protocol:client - state = CONNECTING
DEBUG:websockets.protocol:client - event = connection_made(<asyncio.sslproto._SSLProtocolTransport object at 0x1239abbe0>)
DEBUG:websockets.server:client > GET /v2/sip HTTP/1.1
DEBUG:websockets.server:client > Headers([('Host', 'stream.data.alpaca.markets'), ('Upgrade', 'websocket'), ('Connection', 'Upgrade'), ('Sec-WebSocket-Key', '************'), ('Sec-WebSocket-Version', '13'), ('Sec-WebSocket-Extensions', 'permessage-deflate; client_max_window_bits'), ('Content-Type', 'application/msgpack'), ('User-Agent', 'Python/3.9 websockets/9.1')])
DEBUG:websockets.protocol:client - event = data_received(<276 bytes>)
DEBUG:websockets.server:client < HTTP/1.1 101 Switching Protocols
DEBUG:websockets.server:client < Headers([('Date', 'Thu, 23 Sep 2021 18:25:47 GMT'), ('Connection', 'upgrade'), ('Sec-Websocket-Accept', '******'), ('Sec-Websocket-Extensions', 'permessage-deflate'), ('Upgrade', 'websocket'), ('Strict-Transport-Security', 'max-age=15724800; includeSubDomains')])
DEBUG:websockets.protocol:client - state = OPEN
DEBUG:websockets.protocol:client - event = data_received(<30 bytes>)
DEBUG:websockets.protocol:client < Frame(fin=False, opcode=<Opcode.BINARY: 2>, data=b'\x91\x82\xa1T\xa7success\xa3msg\xa9connected', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=<Opcode.CONT: 0>, data=b'', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=<Opcode.BINARY: 2>, data=b'\x83\xa6action\xa4auth\xa3key\************\xa6secret\xd9********', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = data_received(<54 bytes>)
DEBUG:websockets.protocol:client < Frame(fin=False, opcode=<Opcode.BINARY: 2>, data=b'\x91\x83\xa1T\xa5error\xa4code\xce\x00\x00\x01\x96\xa3msg\xb9connection limit exceeded', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=<Opcode.CONT: 0>, data=b'', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = data_received(<3 bytes>)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=<Opcode.PING: 9>, data=b'1', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - received ping, sending pong: 31
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=<Opcode.PONG: 10>, data=b'1', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = data_received(<45 bytes>)
DEBUG:websockets.protocol:client < Frame(fin=False, opcode=<Opcode.BINARY: 2>, data=b'\x91\x83\xa1T\xa5error\xa4code\xce\x00\x00\x01\x94\xa3msg\xacauth timeout', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=<Opcode.CONT: 0>, data=b'', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=<Opcode.CLOSE: 8>, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - state = CLOSING
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=<Opcode.CLOSE: 8>, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = connection_lost(None)
DEBUG:websockets.protocol:client - state = CLOSED
DEBUG:websockets.protocol:client x code = 1000, reason = [no reason]
DEBUG:websockets.protocol:client x closing TCP connection
I also looked for a way to create multiple keys as a workaround, but it seems like there is just a single key per account.
Maybe I missed something?
Is there a way to stream more stocks or establish a second connection with the ‘unlimited’ account?
Thanks