Building a Cryptocurrency Portfolio Tracker with PyQt6: A Developer’s Journey
Creating a lightweight cryptocurrency portfolio tracker using the PyQt6 library proved to be an engaging personal project, offering a practical dive into GUI development concepts. The goal was to elevate a basic command-line script into a fully functional desktop application, capable of importing crypto holdings from a CSV, fetching live market prices from Kraken, and presenting a real-time overview in a user-friendly table.
This endeavor served as an excellent playground for exploring key PyQt6 features, including responsive layouts, robust threading for background operations, and efficient event handling.
Project Capabilities
The developed application streamlines portfolio management through three primary functions:
- Load Portfolio: Seamlessly import cryptocurrency holdings from a standard CSV file.
- Refresh Prices: Obtain up-to-the-minute prices for all assets directly from the Kraken API.
- Export CSV: Save the updated portfolio data, including current prices and total values, back to disk.
Beyond these core actions, the project incorporates essential enhancements such as multithreading to ensure a consistently responsive user interface, an integrated logging system for tracking application activity, and a customizable configuration file to map local portfolio symbols to Kraken’s specific trading pairs.
Core User Interface Elements
The application’s main window is thoughtfully designed around a central QTableWidget
to display portfolio data, complemented by clearly labeled QPushButton
s for executing the load, refresh, and export operations.
(Code snippet demonstrating UI setup would typically be included here, as in the original.)
Loading Portfolio Data
The application’s foundation rests on a simple CSV file. When a user clicks “Load Portfolio,” a file dialog appears, allowing them to select their holdings file. This data is then efficiently loaded into a pandas DataFrame, which subsequently populates and updates the QTableWidget
on the display.
(Code snippet for loading CSV and updating table would typically be included here.)
Example portfolio.csv
format:
symbol,amount
BTC,0.05
ETH,0.7
DOGE,1000
Multithreaded Price Fetching
A fundamental principle in GUI programming is to prevent the UI from freezing during long-running operations. Fetching live prices from the Kraken API can introduce such delays. To address this, the application leverages PyQt6’s QThreadPool
in conjunction with a custom Worker
class, ensuring that API calls are executed in separate threads.
(Code snippet for Worker class definition would typically be included here.)
Upon clicking “Refresh Prices,” the application iterates through each cryptocurrency symbol in the portfolio, assigning a dedicated worker thread to fetch its price information.
(Code snippet for refresh_prices
function, demonstrating thread initiation, would typically be included here.)
The config.ini
file facilitates the mapping of common crypto symbols to their corresponding Kraken trading pairs:
[KrakenSymbols]
BTC=XXBTZUSD
ETH=XETHZUSD
DOGE=XDGUSD
USDT=USDTZUSD
SOL=SOLUSD
Dynamic Table Updates
Once new price data is retrieved, both the underlying pandas DataFrame and the visible QTableWidget
are updated.
(Code snippet for update_table
function would typically be included here.)
Each row in the table dynamically presents:
- Symbol: The cryptocurrency’s ticker (e.g., BTC).
- Amount: The quantity held, as sourced from the CSV.
- Price: The live market price retrieved from Kraken.
- Total Value: The calculated product of amount and price.
Integrated Logging System
To maintain visibility into the application’s operations and aid in debugging, a straightforward logging system was implemented. This system directs logs to both an app.log
file and the console, proving invaluable during development and when packaging the application with PyInstaller.
Key Learnings from Development
The development process yielded several important insights:
- Threading is Paramount: Employing multithreading was critical to prevent the UI from becoming unresponsive while waiting for external API responses.
- PyQt6 Layout Flexibility: While PyQt6 offers powerful layout management, mastering nested layouts often requires iterative trial and error.
- PyInstaller Considerations: Successfully bundling the application with PyInstaller necessitates careful handling of bundled resources, often involving techniques like the
sys._MEIPASS
trick. - Pandas and QTableWidget Synergy: The combination of pandas DataFrames with
QTableWidget
provides an elegant and efficient mechanism for keeping the graphical interface synchronized with data changes.
Explore the Project
A demonstration of the Crypto Portfolio Tracker in action can be viewed here. The complete source code for the project is openly available on GitHub at https://github.com/kolyaiks/crypto_tracker.