Create a Python project with the following code we have set up for you. Replace the api_key and api_secret with your own CDP API Key and Secret.
You must specify an on_message function that is called when a message is received from the WebSocket API. This function takes in a single argument, which is the raw message received from the WebSocket API.
In the following example, we simply print the message to the console.
Let’s start by opening a connection to the WebSocket API. Add the following call to open to your code, using the same client you just created.
Copy
Ask AI
ws_client.open()
With an open connection, you can now subscribe to channels.
The Heartbeats channel receives heartbeats messages for specific products every second, which is used to keep the connection alive.
The Ticker channel provides real-time price updates every time a match happens for a given product.
Using your same client, send the following message to subscribe to the heartbeats and ticker channels for the BTC-USD product. The received message is printed to the console.
The above code only runs once and then exits. Use the sleep_with_exception_check method to run the client for a specified number of seconds. This method checks for exceptions every second, and exits if an exception is raised.
Run the following code to keep the client open for 10 seconds. It prints all of the messages it receives, then closes the connection:
To keep the client open indefinitely, use the run_forever_with_exception_check method. This method runs the client forever, and exits if an exception is raised.
Let’s call the User channel to receive updates on the order. This channel sends updates on all of a user’s open orders.
First, let’s define the on_message function. This function:
Checks for all messages from the user channel’
Checks if the message is an update on our order.
Sets the order_filled variable to True if the order is filled.
Copy
Ask AI
def on_message(msg): global order_filled global limit_order_id message_data = json.loads(msg) if 'channel' in message_data and message_data['channel'] == 'user': orders = message_data['events'][0]['orders'] for order in orders: order_id = order['order_id'] if order_id == limit_order_id and order['status'] == 'FILLED': order_filled = True
Now, let’s subscribe to the user and heartbeats channels and run the client in a while loop to wait for the order to be filled before closing the connection.
Lastly, let’s put it all together! We will integrate the REST SDK code from the Placing a Limit-buy Order exercise with the WebSocket SDK code from the previous section.
Don’t forget to add your own custom client_order_id. For learning purposes, we’ve pre-filled it to an arbitrary string.
Copy
Ask AI
from coinbase.rest import RESTClientfrom coinbase.websocket import WSClientimport jsonimport mathapi_key = "organizations/{org_id}/apiKeys/{key_id}"api_secret = "-----BEGIN EC PRIVATE KEY-----\nYOUR PRIVATE KEY\n-----END EC PRIVATE KEY-----\n"limit_order_id = ""order_filled = Falsedef on_message(msg): global order_filled global limit_order_id message_data = json.loads(msg) if 'channel' in message_data and message_data['channel'] == 'user': orders = message_data['events'][0]['orders'] for order in orders: order_id = order['order_id'] if order_id == limit_order_id and order['status'] == 'FILLED': order_filled = True# initialize REST and WebSocket clientsrest_client = RESTClient(api_key=api_key, api_secret=api_secret, verbose=True)ws_client = WSClient(api_key=api_key, api_secret=api_secret, on_message=on_message, verbose=True)# open WebSocket connection and subscribe to channelsws_client.open()ws_client.subscribe(["BTC-USD"], ["heartbeats", "user"])# get current price of BTC-USD and place limit-buy order 5% belowproduct = rest_client.get_product("BTC-USD")btc_usd_price = float(product["price"])adjusted_btc_usd_price = str(math.floor(btc_usd_price - (btc_usd_price * 0.05)))limit_order = rest_client.limit_order_gtc_buy( client_order_id="00000003", product_id="BTC-USD", base_size="0.0002", limit_price=adjusted_btc_usd_price)limit_order_id = limit_order["order_id"]# wait for order to fillwhile not order_filled: ws_client.sleep_with_exception_check(1)print(f"order {limit_order_id} filled!")ws_client.close()
And we are done!
You can now use the WebSocket SDK to subscribe to channels and receive real-time updates from the Coinbase Advanced API.