Real-Time Stock Market Data Streaming and Display Using WebSocket API and Streamlit
In today’s fast-paced financial markets, access to real-time stock market data is crucial for informed decision-making. Whether you're a day trader, financial analyst, or someone who wants to stay updated with market trends, streaming live stock data can offer a competitive edge. In this blog, I’ll walk you through how to build a real-time stock market data streaming application using WebSockets, the Alpaca API, and Streamlit.
We will harness the power of WebSockets to receive continuous updates on stock prices and other market metrics, ensuring that our dashboard stays up-to-the-minute. By using Alpaca’s API, we gain access to rich and reliable financial data, while Streamlit helps us quickly create an interactive and responsive dashboard for seamless data visualization. Whether you're building this for personal use or as a stepping stone for a larger project, this guide will provide a clear path to set up and display real-time stock market data efficiently.
To access Alpaca’s API, sign up at Alpaca and generate your API key from the dashboard. I used Python 3.10 with alpaca-trade-api, websockets, streamlit, pandas, and numpy. For the sake of time, I won’t go into the details of installing these libraries, expecting you to be familiar with it—feel free to message me if you need help!
Lets start and dive into the first part of the code where this section imports necessary libraries, loads environment variables (like API keys), and initializes Streamlit session state for real-time stock data updates. It sets up placeholders to display live stock symbol, price, size, and time in the dashboard that will be used later.
import streamlit as st
import websocket
import json
import threading
import os
from dotenv import load_dotenv
load_dotenv()
# Initialize Streamlit session state for real-time updates if not already set
if 'symbol' not in st.session_state:
st.session_state.symbol = ""
if 'price' not in st.session_state:
st.session_state.price = 0.0
if 'size' not in st.session_state:
st.session_state.size = 0
if 'time' not in st.session_state:
st.session_state.time = ""
# Streamlit placeholders for real-time updates
symbol_placeholder = st.empty()
price_placeholder = st.empty()
size_placeholder = st.empty()
time_placeholder = st.empty()
Next, the code snippet provided below defines WebSocket callback functions to handle real-time stock data. on_open subscribes to AAPL trades when the connection opens. on_message processes incoming messages, extracting stock symbol, price, size, and time, then updates the Streamlit session and UI. on_error logs any connection issues, while on_close handles disconnections. The connect_to_alpaca_websocket function establishes the connection using API keys.
# Define WebSocket callback functions
def on_open(ws):
st.write("WebSocket connection opened")
# Subscribe to AAPL trades
ws.send(json.dumps({
"action": "subscribe",
"trades": ["AAPL"]
}))
def on_message(ws, message):
data = json.loads(message)
for msg in data:
if msg.get("T") == "t": # Trade message
# Extract data from message
symbol = msg.get("S") # Stock symbol
price = msg.get("p") # Trade price
size = msg.get("s") # Trade size (number of shares)
trade_time = msg.get("t") # Trade time
# Update Streamlit session state with the real-time data
st.session_state.symbol = symbol
st.session_state.price = price
st.session_state.size = size
st.session_state.time = trade_time
# Update Streamlit UI
symbol_placeholder.write(f"Symbol: {st.session_state.symbol}")
price_placeholder.write(f"Price: {st.session_state.price}")
size_placeholder.write(f"Size: {st.session_state.size}")
time_placeholder.write(f"Time: {st.session_state.time}")
def on_error(ws, error):
st.error(f"WebSocket Error: {error}")
print(f"Error: {error}") # Add this to log errors to the console
def on_close(ws, close_status_code, close_msg):
st.write("### WebSocket connection closed ###")
# Function to create WebSocket connection
def connect_to_alpaca_websocket(api_key, api_secret):
ws = websocket.WebSocketApp(
"wss://stream.data.alpaca.markets/v2/iex",
header=[
f"APCA-API-KEY-ID: {api_key}",
f"APCA-API-SECRET-KEY: {api_secret}"
],
on_message=on_message,
on_error=on_error,
on_close=on_close,
on_open=on_open # Add this line to handle the subscription on connection open
)
ws.run_forever()
This run_dashboard function sets up the Streamlit dashboard, displays the title, and starts the WebSocket in a separate thread to keep the UI responsive. Finally, the API keys are fetched from environment variables, and the dashboard is launched. Now, simply run your code with streamlit run your_script.py to see the real-time stock data.
# Fetch API keys from environment
api_key = os.getenv("APCA_API_KEY_ID")
api_secret = os.getenv("APCA_API_SECRET_KEY")
# Button to start WebSocket connection
if st.button("Start WebSocket"):
connect_to_alpaca_websocket(api_key, api_secret)
Here you can see how the data is displayed on a live dashboard. While I haven’t focused on making it visually appealing yet, it serves the purpose of streaming real-time stock data effectively. However, we can definitely add more appeal by customizing the design, adding charts, or incorporating additional features to enhance the overall user experience.

I hope you’ll love how this setup enables you to incorporate real-time stock data streaming into your projects effortlessly. I’d appreciate your feedback on how this can be improved or made more useful—feel free to share your thoughts!