yfinance [1] [2] は、Yahoo Inc. が公開している API を利用した、Yahoo Finance の株価などの金融情報にアクセスしてデータを取得するために開発されたオープンソースの Python ライブラリです。
本ブログで yfinance を利用して1分足の為替データを取得、mplfinance でローソク足チャートを作成する方法を紹介しました [3]。今回は、紹介したスクリプトをベースにして、PySide6 で GUI 化しました。
- Python で yfinance パッケージを利用して、3時間前から現在までの、ドル・円の為替レートの1分足のデータを取得してチャートにし、1分間隔で更新する GUI アプリを作ります。
下記の OS 環境で動作確認をしています。
![]() |
RHEL 9.4 | x86_64 |
Python | 3.12.1 | |
PySide6 | 6.7.2 | |
mplfinance | 0.12.10b0 | |
yfinance | 0.2.41 |
サンプルを以下に示しました。
import datetime as dt | |
import mplfinance as mpf | |
import pandas as pd | |
import sys | |
import yfinance as yf | |
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas | |
from matplotlib.figure import Figure | |
from PySide6.QtCore import QTimer | |
from PySide6.QtWidgets import ( | |
QApplication, | |
QMainWindow, | |
) | |
class MyChart(FigureCanvas): | |
def __init__(self): | |
self.fig = Figure() | |
self.fig.subplots_adjust(left=0.2, right=0.95, top=0.9, bottom=0.15) | |
self.ax = self.fig.add_subplot(111) | |
super().__init__(self.fig) | |
def clearAxes(self): | |
axs = self.fig.axes | |
for ax in axs: | |
ax.cla() | |
def refreshDraw(self): | |
self.fig.canvas.draw() | |
def removeAxes(self): | |
axs = self.fig.axes | |
for ax in axs: | |
ax.remove() | |
class Example(QMainWindow): | |
def __init__(self): | |
super().__init__() | |
self.setWindowTitle('Exchange') | |
self.setFixedSize(400, 400) | |
self.ticker = yf.Ticker('USDJPY=X') | |
self.chart = MyChart() | |
self.setCentralWidget(self.chart) | |
self.draw_chart() | |
timer = QTimer(self) | |
timer.timeout.connect(self.draw_chart) | |
timer.start(60000) | |
def draw_chart(self): | |
df = self.get_exchange() | |
if len(df) == 0: | |
return | |
self.chart.clearAxes() | |
mpf.plot(df, type='candle', style='binance', ax=self.chart.ax, ) | |
df0 = df.tail(1) | |
title = '%.3f JPY at %s' % (df0['Close'].iloc[0], str(df0.index[0].time())) | |
self.chart.ax.set_title(title) | |
self.chart.ax.set_ylabel('USD - JPY') | |
self.chart.ax.grid() | |
self.chart.refreshDraw() | |
def get_exchange(self) -> pd.DataFrame: | |
end = dt.datetime.now(dt.timezone(dt.timedelta(hours=9))) | |
delta = dt.timedelta(hours=3) | |
start = end - delta | |
df = self.ticker.history(start=start, end=end, interval='1m') | |
if len(df) > 0: | |
df.index = df.index.tz_convert('Asia/Tokyo') | |
return df | |
def main(): | |
app = QApplication() | |
ex = Example() | |
ex.show() | |
sys.exit(app.exec()) | |
if __name__ == '__main__': | |
main() |
以下に実行例を示しました。
サンプルの説明
最初の MyChart クラスは、PySide6 で Matplotlib のチャートを PySide6 側でウィジェットとして扱えるようにする FigureCanvas を継承したクラスです。
class MyChart(FigureCanvas): def __init__( self ): self .fig = Figure() self .fig.subplots_adjust(left = 0.2 , right = 0.95 , top = 0.9 , bottom = 0.15 ) self .ax = self .fig.add_subplot( 111 ) super ().__init__( self .fig) def clearAxes( self ): axs = self .fig.axes for ax in axs: ax.cla() def refreshDraw( self ): self .fig.canvas.draw() def removeAxes( self ): axs = self .fig.axes for ax in axs: ax.remove() |
次の Example クラスは、ドル・円の為替レートの1分足のデータを取得してチャートに表示するメインプログラムです。
クラスの初期化メソッド(コンストラクタ)では、次の処理をしています。
- ウィンドウのタイトル、サイズを設定
- yfinance の Ticker クラスのインスタンス self.ticker を定義
- 60,000 ミリ秒(= 1分)毎に self.draw_chart メソッドを実行するタイマーを起動
class Example(QMainWindow): def __init__( self ): super ().__init__() self .setWindowTitle( 'Exchange' ) self .setFixedSize( 400 , 400 ) self .ticker = yf.Ticker( 'USDJPY=X' ) self .chart = MyChart() self .setCentralWidget( self .chart) self .draw_chart() timer = QTimer( self ) timer.timeout.connect( self .draw_chart) timer.start( 60000 ) |
self.draw_chart メソッドでは、self.get_exchange メソッドでドル・円の為替レートの1分足のデータフレームを取得して、mplfinance パッケージ (= mpf) でローソク足チャートを描画しています。
def draw_chart( self ): df = self .get_exchange() if len (df) = = 0 : return self .chart.clearAxes() mpf.plot(df, type = 'candle' , style = 'binance' , ax = self .chart.ax, ) df0 = df.tail( 1 ) title = '%.3f JPY at %s' % (df0[ 'Close' ].iloc[ 0 ], str (df0.index[ 0 ].time())) self .chart.ax.set_title(title) self .chart.ax.set_ylabel( 'USD - JPY' ) self .chart.ax.grid() self .chart.refreshDraw() |
self.draw_chart メソッドでは、現在時刻と3時間前の時刻から、Ticker クラスのインスタンス self.ticker の history メソッドで過去3時間のドル・円の為替レートの1分足のデータフレームを取得して、インデクスの時刻データのタイムゾーンを日本に変換して返します。
取引時間外で取得したデータフレームが空の場合は何もせずにそのまま空のデータフレームを返します。
def get_exchange( self ) - > pd.DataFrame: end = dt.datetime.now(dt.timezone(dt.timedelta(hours = 9 ))) delta = dt.timedelta(hours = 3 ) start = end - delta df = self .ticker.history(start = start, end = end, interval = '1m' ) if len (df) > 0 : df.index = df.index.tz_convert( 'Asia/Tokyo' ) return df |
取得するデータ量を最小限にする工夫をするべきですが、ここではアプリ側の処理をシンプルにするため。毎回、過去3時間のデータを全て取ってきてしまっています。
参考サイト
- ranaroussi/yfinance: Download market data from Yahoo! Finance's API
- yfinance · PyPI
- bitWalk's: yfinance で1分足の為替データを取得 [2024-08-01]
- QTimer - Qt for Python

にほんブログ村
#オープンソース

0 件のコメント:
コメントを投稿