Real-Time Stock Tracker and Data Viewer with SQLite Database

Displaying stock price : real time data

In this two-part tutorial, we explore how to build a Real-Time Stock Tracker and a complementary Stock Data Viewer using Python. These scripts utilize popular libraries like Tkinter, yfinance, SQLite, and Matplotlib, providing a seamless integration of real-time data monitoring and storage.

Part I: Real-Time Stock Tracker

  • Purpose: Tracks stock prices in real time and plots them dynamically on a graph.
  • Key Features:
    • Fetches live stock prices using the yfinance API.
    • Dynamically updates a Matplotlib graph embedded in a Tkinter interface.
    • Stores time-stamped stock data in an SQLite database.

Part II: Stock Data Viewer

  • Purpose: Displays the stored stock data in a clean and interactive table.
  • Key Features:
    • Fetches and displays data from the SQLite database using a dropdown to select the stock.
    • Uses a Treeview widget to display the stock name, price, and timestamp in a tabular format.
    • Ensures flexibility by dynamically updating the dropdown with available stock names.

This project is ideal for beginners and intermediate developers who want to learn:

  • Real-time data fetching and visualization.
  • Integration of SQLite for data storage.
  • Designing a responsive GUI using Tkinter.

By following this tutorial, you’ll not only build a functional stock tracking system but also gain hands-on experience with essential Python libraries.


Real-Time Stock Data Viewer with SQLite and Tkinter | Python GUI Tutorial

Introduction: Real-Time Stock Tracker and Insert Data

Libraries Used in the Script

This script relies on several Python libraries for its functionality. Below is the detailed list with comments:


# Importing necessary libraries

import tkinter as tk  
# Tkinter is used to create the graphical user interface (GUI) of the application

from tkinter import ttk  
# ttk provides themed widgets for modern styling in the Tkinter application

import yfinance as yf  
# yfinance is used to fetch real-time stock data from Yahoo Finance

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg  
# Embeds Matplotlib graphs into the Tkinter GUI

import matplotlib.pyplot as plt  
# Matplotlib is used for creating and customizing graphs

import threading  
# Provides tools for creating and managing threads, enabling real-time data updates

import time  
# Used to introduce delays for periodic updates without overloading the GUI or API

import sqlite3  
# SQLite library is used for handling the database, including creating tables and storing stock data

from datetime import datetime  
# datetime is used to fetch and format the current date and time for timestamps

import os  
# os module ensures the SQLite database is created in the same directory as the script
    

1. Global Variables and Stock Options

This section initializes global variables for tracking stock prices and defines a dictionary of stock options with their corresponding tickers.


# Global variables
times = []  # To store time points for the graph
prices = []  # To store stock prices for the graph
stop_event = threading.Event()  # Event to stop background threads
current_thread = None  # Keep track of the current thread

# Stock list (popular Indian stocks + NSE/BSE indices)
stock_options = {
    "Reliance Industries": "RELIANCE.NS",
    "Tata Consultancy Services (TCS)": "TCS.NS",
    "Infosys": "INFY.NS",
    "HDFC Bank": "HDFCBANK.NS",
    "ICICI Bank": "ICICIBANK.NS",
    "State Bank of India (SBI)": "SBIN.NS",
    "Bharti Airtel": "BHARTIARTL.NS",
    "Adani Enterprises": "ADANIENT.NS",
    "NSE Nifty 50 Index": "^NSEI",
    "BSE Sensex Index": "^BSESN"
}
    

2. Setting Up the SQLite Database

This function ensures the SQLite database and the required table are created if they don’t already exist. It uses the os module to place the database in the same directory as the script.


# Path to the SQLite database
db_path = os.path.join(os.path.dirname(__file__), "stock_data.db")

# Function to create the SQLite database and table
def create_database():
    """Creates the SQLite database and the required table if they do not exist."""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute("""
    CREATE TABLE IF NOT EXISTS stock_prices (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        stock_name TEXT,
        price REAL,
        timestamp TEXT
    )
    """)
    conn.commit()
    conn.close()
    

3. Fetching Stock Prices

This function fetches the latest stock price using the yfinance API. It extracts the most recent closing price from the retrieved data.


# Function to fetch the current stock price
def fetch_stock_price(ticker):
    """Fetches the latest stock price using the yfinance API."""
    try:
        stock = yf.Ticker(ticker)
        data = stock.history(period="1d", interval="1m")
        price = data['Close'].iloc[-1]
        return round(price, 2)
    except Exception as e:
        print("Error fetching data:", e)
        return None
    

4. Updating the Graph and Storing Data

This function updates the graph in real time and stores the fetched stock data into the SQLite database. It uses a separate database connection for thread safety.


# Function to update the graph dynamically
def update_graph(ticker, stock_name):
    global times, prices
    conn = sqlite3.connect(db_path)  # Separate connection for this thread
    cursor = conn.cursor()
    while not stop_event.is_set():
        price = fetch_stock_price(ticker)
        if price:
            prices.append(price)
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            times.append(current_time)
            save_to_database(cursor, stock_name, price, current_time)
            conn.commit()
            plot_graph(stock_name)
        time.sleep(5)  # Update every 5 seconds
    conn.close()
    

5. Saving Data to the Database

The save_to_database function inserts the stock price, name, and timestamp into the SQLite database.


# Function to save data to SQLite database
def save_to_database(cursor, stock_name, price, timestamp):
    cursor.execute("INSERT INTO stock_prices (stock_name, price, timestamp) VALUES (?, ?, ?)",
                   (stock_name, price, timestamp))
    

6. Plotting the Graph

This function plots the stock price graph using Matplotlib. It includes labels and formatting for better visualization.


# Function to plot the graph
def plot_graph(stock_name):
    ax.clear()
    ax.plot(times, prices, color="blue", label=f"{stock_name} Price")
    ax.set_title(f"Real-Time Stock Price Graph ({stock_name})")
    ax.set_xlabel("Time")
    ax.set_ylabel("Price (INR)")
    ax.legend(loc="upper left")
    ax.grid()
    ax.tick_params(axis="x", rotation=45)
    canvas.draw()
    

7. Starting the Tracking

This function starts tracking the selected stock in a new thread. It resets the graph data and handles thread management to ensure only one thread runs at a time.


# Function to start tracking a stock
def start_tracking():
    """Starts tracking the selected stock in a new thread."""
    global current_thread, stop_event, times, prices

    # Stop the previous thread if it's running
    if current_thread and current_thread.is_alive()():
        stop_event.set()  # Signal the thread to stop
        current_thread.join()  # Wait for the thread to finish

    # Reset the graph data
    times = []
    prices = []

    # Clear the stop_event for the new thread
    stop_event.clear()

    # Start a new thread for the selected stock
    selected_stock = stock_var.get()
    ticker = stock_options[selected_stock]
    current_thread = threading.Thread(target=update_graph, args=(ticker, selected_stock), daemon=True)
    current_thread.start()
    

8. Handling Window Closure

This function handles the application’s clean-up process when the window is closed. It ensures all threads are terminated gracefully and resources are released.


# Function to handle the window close event
def on_close():
    """Stops the background thread and closes the Tkinter window."""
    global stop_event, current_thread
    
    # Signal the background thread to stop
    stop_event.set()  
    
    # Wait for the thread to finish if it's still running
    if current_thread and current_thread.is_alive()():
        current_thread.join()
    
    # Close all Matplotlib resources
    plt.close('all')
    
    # Destroy the Tkinter window
    root.destroy()
    


import tkinter as tk
from tkinter import ttk
import yfinance as yf
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import threading
import time
import sqlite3
from datetime import datetime
import os

# Global variables
times = []  # To store time points for the graph
prices = []  # To store stock prices for the graph
stop_event = threading.Event()  # Event to stop background threads
current_thread = None  # Keep track of the current thread for stock tracking

# Stock list (popular Indian stocks + NSE/BSE indices)
stock_options = {
    "Reliance Industries": "RELIANCE.NS",
    "Tata Consultancy Services (TCS)": "TCS.NS",
    "Infosys": "INFY.NS",
    "HDFC Bank": "HDFCBANK.NS",
    "ICICI Bank": "ICICIBANK.NS",
    "State Bank of India (SBI)": "SBIN.NS",
    "Bharti Airtel": "BHARTIARTL.NS",
    "Adani Enterprises": "ADANIENT.NS",
    "NSE Nifty 50 Index": "^NSEI",
    "BSE Sensex Index": "^BSESN"
}

# Path to the SQLite database (same directory as the script)
db_path = os.path.join(os.path.dirname(__file__), "stock_data.db")

# Function to create the SQLite database and table
def create_database():
    """Creates the SQLite database and the required table if they do not exist."""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute("""
    CREATE TABLE IF NOT EXISTS stock_prices (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        stock_name TEXT,
        price REAL,
        timestamp TEXT
    )
    """)
    conn.commit()
    conn.close()

# Function to fetch the current stock price
def fetch_stock_price(ticker):
    """Fetches the latest stock price using the yfinance API."""
    try:
        stock = yf.Ticker(ticker)
        data = stock.history(period="1d", interval="1m")
        price = data['Close'].iloc[-1]
        return round(price, 2)
    except Exception as e:
        print("Error fetching data:", e)
        return None

# Function to update the graph dynamically
def update_graph(ticker, stock_name):
    """
    Updates the graph with the stock price in real-time.
    Stores the data in the database as well.
    """
    global times, prices
    conn = sqlite3.connect(db_path)  # Separate connection for this thread
    cursor = conn.cursor()
    while not stop_event.is_set():
        price = fetch_stock_price(ticker)
        if price:
            prices.append(price)
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            times.append(current_time)
            save_to_database(cursor, stock_name, price, current_time)
            conn.commit()
            plot_graph(stock_name)
        time.sleep(5)  # Update every 5 seconds
    conn.close()

# Function to save data to the SQLite database
def save_to_database(cursor, stock_name, price, timestamp):
    """Inserts the stock price data into the database."""
    cursor.execute("INSERT INTO stock_prices (stock_name, price, timestamp) VALUES (?, ?, ?)",
                   (stock_name, price, timestamp))

# Function to plot the graph
def plot_graph(stock_name):
    """Plots the stock price graph using Matplotlib."""
    ax.clear()
    ax.plot(times, prices, color='blue', label=f"{stock_name} Price")
    ax.set_title(f"Real-Time Stock Price Graph ({stock_name})")
    ax.set_xlabel("Time")
    ax.set_ylabel("Price (INR)")
    ax.legend(loc="upper left")
    ax.grid()
    ax.tick_params(axis='x', rotation=45)
    canvas.draw()

# Function to start tracking a stock
def start_tracking():
    """Starts tracking the selected stock in a new thread."""
    global current_thread, stop_event, times, prices

    # Stop the previous thread if it's running
    if current_thread and current_thread.is_alive():
        stop_event.set()  # Signal the thread to stop
        current_thread.join()  # Wait for the thread to finish

    # Reset the graph data
    times = []
    prices = []

    # Clear the stop_event for the new thread
    stop_event.clear()

    # Start a new thread for the selected stock
    selected_stock = stock_var.get()
    ticker = stock_options[selected_stock]
    current_thread = threading.Thread(target=update_graph, args=(ticker, selected_stock), daemon=True)
    current_thread.start()

# Function to handle the window close event
def on_close():
    """Stops the background thread and closes the Tkinter window."""
    global stop_event, current_thread
    stop_event.set()  # Signal the thread to stop
    if current_thread and current_thread.is_alive():
        current_thread.join()  # Wait for the thread to finish
    plt.close('all')  # Close matplotlib resources
    root.destroy()  # Destroy the Tkinter window

# Tkinter window setup
root = tk.Tk()
root.title("plus2net.com Indian Stock Price Tracker")
root.geometry("800x600")

# Create the database (if it doesn't exist)
create_database()

# Bind the close event to the on_close function
root.protocol("WM_DELETE_WINDOW", on_close)

# Title label
title_label = tk.Label(root, text="Indian Stock Price Tracker", font=("Arial", 16, "bold"), fg="#007bff")
title_label.pack(pady=10)

# Frame for dropdown and button
selection_frame = tk.Frame(root)
selection_frame.pack(pady=10)

# Stock selection dropdown
stock_var = tk.StringVar(value="Reliance Industries")
stock_dropdown = ttk.Combobox(selection_frame, textvariable=stock_var, values=list(stock_options.keys()), state="readonly", font=("Arial", 12))
stock_dropdown.pack(side=tk.LEFT, padx=5)

# Start button next to the dropdown
start_button = ttk.Button(selection_frame, text="Start Tracking", command=start_tracking)
start_button.pack(side=tk.LEFT, padx=5)

# Matplotlib figure and canvas for the graph
fig, ax = plt.subplots()
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

# Run the Tkinter event loop
root.mainloop()

Part II : Displaying stored stock data from Database table


Displaying stock price data from SQLite database


This script uses Tkinter and SQLite to display stored stock data in a graphical interface. Below is the code broken into sections:

1. Importing Libraries


# Importing necessary libraries
import tkinter as tk  
# Tkinter is used to create the graphical user interface (GUI)
from tkinter import ttk  
# ttk provides themed widgets for better styling
import sqlite3  
# SQLite library is used for database operations
import os  
# os module ensures the database is created in the same directory as the script
    

2. Database Path Setup


# Path to the SQLite database
db_path = os.path.join(os.path.dirname(__file__), "stock_data.db")
    

3. Fetching and Displaying Data

The display_data function fetches data for the selected stock from the SQLite database and displays it in a Treeview widget.


# Function to fetch and display data for the selected stock
def display_data():
    """
    Fetches and displays data for the selected stock from the SQLite database.
    Populates the Treeview with the fetched records.
    """
    # Clear any existing data in the Treeview
    for row in tree.get_children():
        tree.delete(row)

    # Connect to the SQLite database
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Get the selected stock from the dropdown
    selected_stock = stock_var.get()

    # Fetch data for the selected stock
    cursor.execute("SELECT stock_name, price, timestamp FROM stock_prices WHERE stock_name = ? ORDER BY id DESC", 
                   (selected_stock,))
    records = cursor.fetchall()
    conn.close()

    # Populate the Treeview with fetched data
    for record in records:
        tree.insert("", tk.END, values=record)
    

4. Populating the Dropdown

The populate_dropdown function populates the dropdown with unique stock names fetched from the database.


# Function to populate the dropdown with unique stock names
def populate_dropdown():
    """
    Populates the stock selection dropdown with unique stock names
    from the SQLite database.
    """
    # Connect to the SQLite database
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Fetch unique stock names from the database
    cursor.execute("SELECT DISTINCT stock_name FROM stock_prices")
    stocks = cursor.fetchall()
    conn.close()

    # Update the dropdown with stock names
    stock_names = [stock[0] for stock in stocks]
    stock_var.set(stock_names[0] if stock_names else "No Data")
    stock_dropdown['values'] = stock_names
    

5. Tkinter GUI Setup

This section sets up the Tkinter window and widgets, including the dropdown, button, and Treeview widget for displaying data.


# Tkinter window setup
root = tk.Tk()
root.title("View Stored Stock Data")
root.geometry("800x400")

# Title label
title_label = tk.Label(root, text="Stored Stock Data", font=("Arial", 16, "bold"), fg="#007bff")
title_label.pack(pady=10)

# Frame for dropdown and button
selection_frame = tk.Frame(root)
selection_frame.pack(pady=10)

# Dropdown to select stock
stock_var = tk.StringVar()
stock_dropdown = ttk.Combobox(selection_frame, textvariable=stock_var, state="readonly", font=("Arial", 12))
stock_dropdown.pack(side=tk.LEFT, padx=5)

# Button to fetch and display data
fetch_button = tk.Button(selection_frame, text="Load Data", command=display_data, font=("Arial", 12))
fetch_button.pack(side=tk.LEFT, padx=5)

# Treeview widget to display stored data
columns = ("Stock Name", "Price", "Timestamp")
tree = ttk.Treeview(root, columns=columns, show="headings")
tree.heading("Stock Name", text="Stock Name")
tree.heading("Price", text="Price")
tree.heading("Timestamp", text="Timestamp")
tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

# Set column widths
tree.column("Stock Name", width=200)
tree.column("Price", width=100)
tree.column("Timestamp", width=200)

# Populate the dropdown with stock names on startup
populate_dropdown()

# Run the Tkinter event loop
root.mainloop()
    


import tkinter as tk
from tkinter import ttk
import sqlite3
import os

# Path to the SQLite database (same directory as the script)
db_path = os.path.join(os.path.dirname(__file__), "stock_data.db")

# Function to fetch and display data for the selected stock
def display_data():
    """
    Fetches and displays data for the selected stock from the SQLite database.
    Populates the Treeview with the fetched records.
    """
    # Clear any existing data in the Treeview
    for row in tree.get_children():
        tree.delete(row)

    # Connect to the SQLite database
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Get the selected stock from the dropdown
    selected_stock = stock_var.get()

    # Fetch data for the selected stock
    cursor.execute("SELECT stock_name, price, timestamp FROM stock_prices WHERE stock_name = ? ORDER BY id DESC", (selected_stock,))
    records = cursor.fetchall()
    conn.close()

    # Populate the Treeview with fetched data
    for record in records:
        tree.insert("", tk.END, values=record)

# Function to populate the dropdown with unique stock names from the database
def populate_dropdown():
    """
    Populates the stock selection dropdown with unique stock names
    from the SQLite database.
    """
    # Connect to the SQLite database
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Fetch unique stock names from the database
    cursor.execute("SELECT DISTINCT stock_name FROM stock_prices")
    stocks = cursor.fetchall()
    conn.close()

    # Update the dropdown with stock names
    stock_names = [stock[0] for stock in stocks]
    stock_var.set(stock_names[0] if stock_names else "No Data")
    stock_dropdown['values'] = stock_names

# Tkinter window setup
root = tk.Tk()
root.title("plus2net.com View Stored Stock Data")
root.geometry("800x400")

# Title label
title_label = tk.Label(root, text="Stored Stock Data", font=("Arial", 16, "bold"), fg="#007bff")
title_label.pack(pady=10)

# Frame for dropdown and button
selection_frame = tk.Frame(root)
selection_frame.pack(pady=10)

# Dropdown to select stock
stock_var = tk.StringVar()
stock_dropdown = ttk.Combobox(selection_frame, textvariable=stock_var, state="readonly", font=("Arial", 12))
stock_dropdown.pack(side=tk.LEFT, padx=5)

# Button to fetch and display data
fetch_button = tk.Button(selection_frame, text="Load Data", command=display_data, font=("Arial", 12))
fetch_button.pack(side=tk.LEFT, padx=5)

# Treeview widget to display stored data
columns = ("Stock Name", "Price", "Timestamp")
tree = ttk.Treeview(root, columns=columns, show="headings")
tree.heading("Stock Name", text="Stock Name")
tree.heading("Price", text="Price")
tree.heading("Timestamp", text="Timestamp")
tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

# Set column widths
tree.column("Stock Name", width=200)
tree.column("Price", width=100)
tree.column("Timestamp", width=200)

# Populate the dropdown with stock names on startup
populate_dropdown()

# Run the Tkinter event loop
root.mainloop()

Conclusion

By combining the power of Tkinter, SQLite, and Matplotlib, this project demonstrates how to create a complete stock tracking and data viewing application. From fetching live stock prices with yfinance to storing and visualizing data dynamically, this tutorial equips you with practical skills to build data-driven desktop applications. With further customization, you can expand this project to track cryptocurrencies, commodities, or implement alert systems. Dive in, experiment, and make it your own!


Subscribe to our YouTube Channel here


Subscribe

* indicates required
Subscribe to plus2net

    plus2net.com







    Python Video Tutorials
    Python SQLite Video Tutorials
    Python MySQL Video Tutorials
    Python Tkinter Video Tutorials
    We use cookies to improve your browsing experience. . Learn more
    HTML MySQL PHP JavaScript ASP Photoshop Articles FORUM . Contact us
    ©2000-2024 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer