TD Ameritrade Streaming API - Message received contains incomplete data after the first couple correct messages

55 Views Asked by At

I'm connecting to TD Ameritrade API and I can successfully login, connect/authenticate, send a data request, and receive a streaming message from the TD Ameritrade API. However, I'll receive all the requested data (ie. time, last price, last size) in the first couple messages, but then the next messages do not contain the requested data in the messages. It may contain the time and price but not the size of the order or price may not be included but order size is.

Does anyone have any ideas why this may be the case?

Below is architecture of my code and am using the following:

  • Using Websockets
  • Asyncio
  • mysql.connector to insert into mysql database (not included in the below code)

Code:

data_request= {"requests": [{"service": "QUOTE", 
                             "requestid": "1", 
                             "command": "SUBS", 
                             "account": userPrincipalsResponse['accounts'][0]['accountId'], 
                             "source": userPrincipalsResponse['streamerInfo']['appId'], 
                             "parameters": {"keys": "AAPL",
                                            "fields": "0,3,9"}}]}
                      

login_encoded = json.dumps(login_request)
data_encoded = json.dumps(data_request)

import websockets
from websockets import client
import asyncio
import mysql.connector


class WebSocketClient():

    def __init__(self):
        pass
        print ("Initiating Websocket...")
    
    
    def database_connect(self):
        
        # define the server and the database, YOU WILL NEED TO CHANGE THIS TO YOUR OWN DATABASE AND SERVER
        host = 'localhost' 
        user = 'root'
        database = 'stock_database'
        password = password_mysql
        
        # define our connection, autocommit MUST BE SET TO TRUE, also we can edit data.
        self.cnxn = mysql.connector.connect(host = host, 
                                            user = user, 
                                            password = password, 
                                            database = database,
                                            )
        
        
        self.mycursor = self.cnxn.cursor()
        print("database connected, good hunting")
            
    def database_insert(self, query, data_tuple):   
        
        # execute the query, commit the changes, and close the connection
        self.mycursor.execute(query, data_tuple,)
        self.cnxn.commit()
        self.cnxn.close()
        
        print('Data has been successfully inserted into the database.')

    async def connect(self):
        
        # define the URI of the data stream, and connect to it.
        uri = "wss://" + userPrincipalsResponse['streamerInfo']['streamerSocketUrl'] + "/ws"
        #uri = "wss://streamer-ws.tdameritrade.com/ws"
        print("trying to connect")
        self.connection = await websockets.client.connect(uri)
        
        
        # if all goes well, let the user know.
        if self.connection.open:
            print('Connection established. Client correctly connected')
            return self.connection
        
        
    async def sendMessage(self, message):
        
        print("trying to send request")
        await self.connection.send(message)
        
        
    async def receiveMessage(self, connection):
        
        while True:
            try:
                
                # grab and decode the message
                message = await connection.recv()                
                message_decoded = json.loads(message, strict=False)
                                                
                print('-'*20)
                print('Received message from server: ' + str(message))
                
                # check if the response contains a key called data if so then it contains the info we want to insert.
                if 'data' in message_decoded.keys():
                    
                    # grab the data and convert string value into dictionary
                    data = message_decoded['data'][0]
                    data_service = (data['content'])
                    data_keys = json.dumps(data_service)
                    
                    keys = json.loads(data_keys)
                    print(keys)
                    #processing of data and extract
                    timestamp = data['timestamp']
                    for key in keys:   
                        
                        data_tuple = (timestamp, float(key['3']), float(key['9']))
                        
                        symbol_returned = str(key['key'])
                    print("message keys successfully returned)
                        
            except websockets.exceptions.ConnectionClosed:            
                print('Connection with server closed')
                break

import asyncio

if __name__ == '__main__':
    
    # Creating client object
    client = WebSocketClient()


    loop = asyncio.get_event_loop()
    
    
    # Start connection and get client connection protocol
    connection = loop.run_until_complete(client.connect())

    # Start listener and heartbeat 
    tasks = [asyncio.ensure_future(client.receiveMessage(connection)),
             asyncio.ensure_future(client.sendMessage(login_encoded)),
             asyncio.ensure_future(client.receiveMessage(connection)),
             asyncio.ensure_future(client.sendMessage(data_encoded)),
             asyncio.ensure_future(client.receiveMessage(connection))]
    
    loop.run_until_complete(asyncio.wait(tasks))
0

There are 0 best solutions below