Pythonを使うと、簡単に株価チャートを作ることができます。

データ分析したり、チャートでトレード記録を作るのにも便利ですよね。

株価データ取得

Pythonでデータ分析というとPandasが有名ですよね。

pandas_datareaderというパッケージを使うと、簡単に株価データを取得して Pandas DataFrame を作ってくれます。

まずは、インストール。

pip install pandas-datareader

pandas_datareader でデータの取得元は色々選べますが、日本株を取得したいなら stooq が便利です。yahooはAPI制限があったりで取得できなかったりするようです。

取得したい株のシンボルは、https://stooq.com/ に行って検索すれば出てきます。

stooq_symbol_search

あとは、以下のような感じで、取得期間を設定しつつ、株価データを取得します。

from datetime import date
import pandas_datareader.data as web

# データソース
source = 'stooq'

# 取得期間
dt_s = date(2023, 1, 4)
dt_e = date(2023, 6, 30)

# 株価シンボル
symbol = '9202.JP'  # ANA symbol for stooq

# 株価を取得(DataFrame) 
df = web.DataReader(symbol, source, dt_s, dt_e)
stock_dataframe_example

上のように、Open, High, Low, Close, Volume のカラムをもった DataFrame として、取得できました。

Plotlyでチャート作成

以前も紹介した Plotly というパッケージを使えば、インタラクティブなチャートが簡単に作れます。

Plotly の graph_objects の中で、Candlestick を使うと、ロウソク足チャートを作れます。

シンプルにデフォルト設定でロウソク足チャートを作成すると、以下のようになります。

import plotly.graph_objects as go

# ロウソク足プロットデータ
traceData = [
    go.Candlestick(
        x=df.index,
        open=df['Open'], high=df['High'],
        low=df['Low'], close=df['Close'],
    ),
]

# plotly Figure オブジェクト作成
fig = go.Figure(data=traceData)

# plotly グラフ表示
fig.show()

チャート成形(営業日のみ・移動平均線)

レンジセレクターを消したり、土日週末や祝日を除外して、営業日のみの連続したチャートを作りたいですよね。

ついでに移動平均線なんかも追加してみましょう。

日本の祝日を取得するために、jpholiday というパッケージをインストールしています。
pip install jpholiday

from datetime import timedelta
import jpholiday

# DataFrame 修正
#-- 昇順に並べ替え
df = df.sort_index()
#-- 5日移動平均線
df['SMA'] = df['Close'].rolling(window=5).mean()

# プロットデータ
#-- ロウソク足
traceData = [
    go.Candlestick(
        x=df.index,
        open=df['Open'], high=df['High'],
        low=df['Low'], close=df['Close'],
        name = symbol
    ),
]
#-- 移動平均線
traceData.append( go.Scatter(x=df.index, y=df['SMA'], 
                             line=dict(color='blue', width=1.5),
                             name = "SMA")
                )


# 週末祝日の "bounds" リスト
breakdays = []
#-- 日付をループし、週末と祝日を breakdays に格納
dt = dt_s
while dt < dt_e:
    if dt.weekday() == 5:
      #--- 週末土日
      breakdays.append( {'bounds': 
                        [dt, dt+timedelta(days=2)]} 
                      )
      dt += timedelta(days=1)

    elif jpholiday.is_holiday(dt):
      #--- 祝日
      breakdays.append( {'bounds': 
                        [dt, dt+timedelta(days=1)]} 
                      )
    
    dt += timedelta(days=1)


# plotly Figure
fig = go.Figure(data=traceData)

# plotly X軸設定
fig.update_xaxes(rangebreaks=breakdays, # 週末祝日を非表示
                 rangeslider_visible=False,  # 期間スライダーを非表示
                )

# グラフ表示
fig.show()

きれいな、よく見るロウソク足チャートになりましたね!

ちなみに土日祝日のギャップを除外する方法ですが、上の例では日付を順次ループして曜日と祝日を検出することで bounds リストを作成し、それを X軸レイアウトのrangebreaksパラメータに渡しています。

リストの作成方法は、他のやり方も色々あると思います。
例えば、dfで行ごとの日付間隔を計算して、その間隔が1日より大きなセルを抽出することでも実現可能です。

# 日付ギャップを計算するために、indexをコピーし 'time' カラムを作成
df = df.sort_index()
df['time'] = df.index
#-- 1つ前の行との差分を計算
df['time_gap'] = df['time'] - df['time'].shift()

# 'bounds' リスト
breakdays = []
#-- ギャップが1日より大きい日付をループし、breakdays に除外範囲を格納
for row in df[df['time_gap']>timedelta(days=1)].itertuples():
   breakdays.append( {'bounds': 
                        [(row.time - row.time_gap + timedelta(days=1)), 
                         row.time]
                     } )

time_gap を追加した df はこんな感じになっています。

stock_dataframe_example2

以上、是非試してみてください。

スポンサーリンク