Building a Real-Time Binance BTC/USDT Spot and Futures Data Dashboard using Tkinter and WebSockets

Building a Real-Time Binance BTC/USDT Spot and Futures Data Dashboard using Tkinter and WebSockets

When working with financial applications, it’s critical to have a user interface that updates in real-time with market data. Python’s tkinter library, combined with websocket, allows us to achieve just that. In this article, we’ll explore how to create a GUI-based application to display live Binance BTC/USDT Spot and Futures data. This application shows the best bid and ask prices, calculates the difference between Spot and Futures markets, and tracks the maximum and minimum price differences.

Introduction to Tkinter

Tkinter is Python’s standard GUI library. It’s easy to use and works across all major platforms, making it a great choice for building desktop applications. In our project, tkinter handles the interface design, while websocket connects to Binance’s real-time WebSocket data feed to fetch price information.

Overview of the Project

Our application will:

  1. Connect to Binance’s Spot and Futures BTC/USDT WebSocket streams.
  2. Display important trading information such as symbol, bid prices, ask prices, and quantities.
  3. Dynamically update the interface with live data as it comes in.
  4. Calculate and display the price difference between Spot Ask and Futures Bid prices.
  5. Track and display the maximum and minimum recorded price differences.

Step-by-Step Code Explanation

1. Imports

import tkinter as tk
import websocket
import json
import threading
from datetime import datetime, timezone        

We import the necessary modules for building the GUI (tkinter), handling WebSocket communication (websocket), parsing data (json), running WebSocket connections on separate threads (threading), and managing timestamps (datetime).

2. Global Variables

spot_ask_price = None
futures_bid_price = None
difference_list = []  # Store price differences        

These global variables are used to store the latest Spot Ask price, Futures Bid price, and a list of all differences between the two. These values will be updated dynamically as the application receives new data.

3. Utility Functions

Formatting Timestamps:

def format_timestamp(ts):
    return datetime.fromtimestamp(ts / 1000, tz=timezone.utc).strftime('%Y-%m-%d %H:%M:%S')        

Binance provides timestamps in milliseconds. This function converts those timestamps into human-readable format (e.g., “YYYY-MM-DD HH:MM“).

Formatting Prices:

def format_price(price):
    return f"{float(price):.2f}"        

Prices are formatted to two decimal places for clarity.

4. Calculating and Displaying Price Differences

def update_price_difference():
    global difference_list
    if spot_ask_price is not None and futures_bid_price is not None:
        difference = float(spot_ask_price) - float(futures_bid_price)
        difference_label_value.config(text=f"{difference:.2f}")
        difference_list.append(difference)
        max_difference_label_value.config(text=f"{max(difference_list):.2f}")
        min_difference_label_value.config(text=f"{min(difference_list):.2f}")        

This function calculates the price difference between the Spot Ask and Futures Bid prices. It updates the corresponding label with the difference and tracks the maximum and minimum recorded differences in the difference_list.

5. WebSocket Handlers

WebSocket handlers process incoming messages from Binance and update the relevant price labels in the GUI.

Spot WebSocket Message Handler:

def on_message_binance_spot(ws, message):
    global spot_ask_price
    data = json.loads(message)
    spot_ask_price = format_price(data.get("a", "N/A"))  # Best ask price
    update_price_difference()        

This handler listens for messages from Binance’s Spot market WebSocket, extracts the Spot Ask price, and updates the price difference calculation.

Futures WebSocket Message Handler:

def on_message_binance_futures(ws, message):
    global futures_bid_price
    data = json.loads(message)
    futures_bid_price = format_price(data.get("b", "N/A"))  # Best bid price
    update_price_difference()        

Similarly, this handler listens for messages from Binance’s Futures market WebSocket and updates the Futures Bid price.

6. Connecting to WebSockets

Each WebSocket connection runs on its own thread so that the GUI remains responsive while receiving real-time data.

def run_websocket_binance_spot():
    socket = "wss://stream.binance.com/ws/btcusdt@bookTicker"
    ws = websocket.WebSocketApp(socket, on_message=on_message_binance_spot)
    ws.run_forever()

def run_websocket_binance_futures():
    socket = "wss://fstream.binance.com/ws/btcusdt@bookTicker"
    ws = websocket.WebSocketApp(socket, on_message=on_message_binance_futures)
    ws.run_forever()        

The run_forever() method ensures that the WebSocket stays open and listens continuously for new data.

7. GUI Design with Tkinter

Now let’s dive into the core part of the interface, where tkinter helps to display real-time data.

Main Window Setup:

window = tk.Tk()
window.title("BTC/USDT Real-Time Data from Binance Spot & Futures")
window.geometry("1200x600")
window.config(bg="#1f1f1f")        

The Tk() function initializes the main application window, sets its title and dimensions, and applies a dark background color for a modern aesthetic.

8. Creating Dynamic Labels for Displaying Data

Here, various labels are created to display trading information like the symbol, best bid price, best ask price, and quantities. These labels are updated dynamically with incoming data from Binance.

symbol_label_spot_value = tk.Label(table_frame_binance_spot, text="Loading...", font=font_sub, fg=last_color, bg=bg_color)
best_bid_price_label_spot_value = tk.Label(table_frame_binance_spot, text="Loading...", font=font_sub, fg=bid_color, bg=bg_color)
best_bid_qty_label_spot_value = tk.Label(table_frame_binance_spot, text="Loading...", font=font_sub, fg=bid_color, bg=bg_color)
best_ask_price_label_spot_value = tk.Label(table_frame_binance_spot, text="Loading...", font=font_sub, fg=ask_color, bg=bg_color)
best_ask_qty_label_spot_value = tk.Label(table_frame_binance_spot, text="Loading...", font=font_sub, fg=ask_color, bg=bg_color)        

  • Symbol Label: Displays the trading symbol (e.g., “BTCUSDT”).
  • Best Bid Price Label: Shows the highest price a buyer is willing to pay in the current market.
  • Best Ask Price Label: Shows the lowest price a seller is willing to accept.
  • Best Bid/Ask Quantity Labels: Display the respective quantities for bids and asks.

Initially, each label shows “Loading…” until the WebSocket receives data. Once data is received, the labels are dynamically updated to display the latest values.

For example:

  • The Best Bid Price and Best Ask Price fields will show the current market bid and ask prices.
  • The Bid and Ask Quantity fields will display the amount of BTC available for the respective prices.

These labels help users visualize real-time market conditions without refreshing the window or waiting for manual updates.

9. Displaying the Price Difference

difference_label_value = tk.Label(window, text="Loading...", font=font_main, fg=last_color, bg=bg_color)        

This label displays the real-time difference between the Spot Ask and Futures Bid prices. It will update every time new data is received from either WebSocket feed.

10. Maximum and Minimum Price Difference Tracking

max_difference_label_value = tk.Label(window, text="Loading...", font=font_main, fg=last_color, bg=bg_color)
min_difference_label_value = tk.Label(window, text="Loading...", font=font_main, fg=last_color, bg=bg_color)        

These labels display the maximum and minimum recorded differences between the Spot and Futures markets since the application started running.

11. Running the Application

The WebSocket threads are started, and the Tkinter event loop begins, ensuring the application continuously updates with live data:

websocket_thread_binance_spot = threading.Thread(target=run_websocket_binance_spot)
websocket_thread_binance_spot.daemon = True
websocket_thread_binance_spot.start()

websocket_thread_binance_futures = threading.Thread(target=run_websocket_binance_futures)
websocket_thread_binance_futures.daemon = True
websocket_thread_binance_futures.start()

window.mainloop()        

This keeps the interface active and responsive while the WebSocket streams bring in new data in the background.

Conclusion

With Python’s tkinter and websocket, you can create a real-time financial dashboard that displays crucial trading information. By combining a GUI with live WebSocket data feeds from Binance, the application can update dynamically, showing bid and ask prices, calculating price differences, and tracking market trends. This project offers a solid foundation for building more complex trading systems or financial visualizations.


Full Code at Medium

Full Code

要查看或添加评论,请登录

Eurico Paes的更多文章

社区洞察

其他会员也浏览了