PySide (Qt for Python) は、Qt(キュート)の Python バインディングで、GUI などを構築するためのクロスプラットフォームなライブラリです。Linux/X11, macOS および Microsoft Windows をサポートしています。配布ライセンスは LGPL で公開されています。
以前、本ブログで PySide2 と mplfinance を組み合わせた GUI サンプルを紹介しました [1]。また、PySide6 に GUI ライブラリを更新したサンプルも既に紹介しています [2]。
今回は yfinance の API を利用して株価データを取得する部分を、QThreadPool / QRunnable で別スレッドにして読み込むようにしました。データの読み込みにそれほど時間が掛かるわけでもないのですが、スレッドの練習題材にしたくて、ローソク足チャートのサンプルを再び取り上げました。
下記の OS 環境で動作確認をしています。
Fedora Workstation 39 | x86_64 | |
Python | 3.12.1 | |
PySide6 | 6.6.1 | |
matplotlib | 3.8.2 | |
mplfinance | 0.12.10b0 | |
pandas | 2.2.0 | |
yfinance | 0.2.36 |
サンプル
サンプルはあまりコンパクトにできなかったので、下記の4つのファイルに分けました。
- qt_mpl_finance_2.py
- GUI サンプルのメイン
- qt_mpl_finance_2_func.py
- 関数処理
- qt_mpl_finance_2_sub.py
- GUI のサブ・コンポーネント
- qt_mpl_finance_2_thread.py
- QRunner によるスレッド処理
qt_mpl_finance_2.py は、本サンプルのメイン部分で、下記の GUI を QMainWindow で構成しています。
qt_mpl_finance_2_func.py は、yfinance で株価データを読み込む処理と、mplfinance でデータフレームをキャンバス上に描画する処理を関数としてまとめてあります。
qt_mpl_finance_2_sub.py は、メインの QMainWindow の GUI を構成する、ツールバー、中心部のチャート用のキャンバス、Matplotlib のナビゲーション・ツールバーを表示する下部のドックを記述しています。
qt_mpl_finance_2_thread.py は、yfinance で株価データを読み込む処理を別スレッドで実行する QRunnable クラスを継承した ThreadWorker クラスです。
QRunnable クラスを継承した ThreadWorker のインスタンスでは、別スレッドで処理を実行させることができますが、そのままでは、処理の終了や結果を Signal を発して親スレッドへ送ることができません。そのため、このサンプルでは、QObject を継承したシグナル専用のクラス ThreadWorkerSignal を作成しておいて、QRunnable と一緒に多重継承して、ThreadWorkerSignal で定義したシグナルを利用できるようにしています。
class ThreadWorkerSignal(QObject): finished = Signal(str, pd.DataFrame) class ThreadWorker(QRunnable, ThreadWorkerSignal): def __init__(self, ticker: str): super().__init__() self.ticker = ticker def run(self): df = get_trade_info(self.ticker) self.finished.emit(self.ticker, df)
この ThreadWorker は、本体 qt_mpl_finance_2.py 側で、下記のメソッド内でインスタンス worker を生成して、QThreadPool のインスタンス self.threadpool の start メソッドにインスタンス worker を渡します。この start メソッドが実行されると、別スレッドで worker.run() が実行されます。
def on_ticker_entered(self, ticker: str): worker = ThreadWorker(ticker) worker.finished.connect(self.on_draw_chart) self.threadpool.start(worker)
worker の処理が終わると、finished シグナルが発せられるので、これを self.on_draw_chart メソッド(スロット)で処理します。
def on_draw_chart(self, ticker: str, df: pd.DataFrame): chart: QWidget | StockChart = self.centralWidget() draw_chart(chart, ticker, df)
サンプルの使い方
東証に上場している銘柄であれば、ツールボックスの QLineEdit のインスタンスに、銘柄コードに .T を付加した文字列(例 1301.T)を入力して Enter すると、過去3ヶ月分の日足チャートが出力されます。
日経平均の指数は ^N255 と入力して Enter します。米国銘柄はアルファベットのシンボルを入力します。
サンプルということで、存在しないコードを入力したときなどのエラー処理は一切していません。🙇🏻
参考サイト
- bitWalk's: ローソク足チャート ~ python/mplfinance [2021-05-02]
- bitWalk's: ローソク足チャート ~ PySide6, mplfinance [2023-08-15]
- QThreadPool - Qt for Python
- QRunnable - Qt for Python
- ranaroussi/yfinance: Download market data from Yahoo! Finance's API
- matplotlib/mplfinance: Financial Markets Data Visualization using Matplotlib
にほんブログ村
#オープンソース
0 件のコメント:
コメントを投稿