【Python】東証上場銘柄の株価データを取得する（その２）

## はじめに

前回の[【Python】東証上場銘柄の株価データを取得する（その１）](https://qiita.com/tnozoo/items/b7d95867a3e4aa421731)では
[日本取引所グループ](https://www.jpx.co.jp/markets/statistics-equities/misc/01.html)にある東証上場銘柄の一覧ファイルを Pandas を使って銘柄抽出してみた

今回は，pandas_datareaderを使って，直近の株価データを取得してみる

## 自分銘柄

トヨタ，日産，ホンダ，ＡＮＡ，ＪＡＬを保有しているとする

下図のような Excel ファイルを my.xlsx という名前で用意した

列は，コードと銘柄名だ（日本取引所グループにある東証上場銘柄の一覧ファイルのそれと合わせた）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385512/ca9b4323-fabf-cbb3-ecce-717176ef5c00.png)

## 事前準備

[前回](https://qiita.com/tnozoo/items/b7d95867a3e4aa421731)書き忘れたが，
東証上場銘柄の一覧ファイルは data_j.xls という拡張子 xls ファイルなので，
xlrd をインストール必要がある
conda や pip で自分の環境に入れる必要がある

conda の場合

```
conda install xlrd
```

pip の場合

```
pip install xlrd
```

## 本論

必要なライブラリをインポートする

```python
import pandas as pd
import pandas_datareader.data as pdr
import datetime
from dateutil.relativedelta import relativedelta
```

自分銘柄一覧（my.xlsx）と東証上場銘柄一覧（date_j.xls）を読み込む


```python
my_df = pd.read_excel('my.xlsx', sheet_name = 'Sheet1', dtype = str)
topix_df = pd.read_excel('data_j.xls', dtype = str)
```

東証上場銘柄をTOPIX Core30に絞る
ちゃんと30行なっている


```python
topix_core30_df = topix_df[topix_df['規模区分']=='TOPIX Core30']
len(topix_core30_df)
```

    30


TOPIX Core30銘柄のコードと自分銘柄のコードを集合にする（重複排除される）
自分銘柄の，日産とＡＮＡがTOPIX Large70，ＪＡＬがTOPIX Mid400で，トヨタとホンダはTOPIX Core30銘柄なので
３銘柄増え ３０＋３＝３３銘柄になっていれば正解


```python
code_set = set(topix_core30_df['コード'].tolist()) | set(my_df['コード'].tolist())
len(code_set)
```

    33


集合の中にある銘柄コードだけを，TOPIX の DataFrame から抽出する
isin を使うと，リストや集合の要素に一致する行が抽出できる


```python
df = topix_df[topix_df['コード'].isin(code_set)]
df
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>日付</th>
      <th>コード</th>
      <th>銘柄名</th>
      <th>市場・商品区分</th>
      <th>33業種コード</th>
      <th>33業種区分</th>
      <th>17業種コード</th>
      <th>17業種区分</th>
      <th>規模コード</th>
      <th>規模区分</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>1025</th>
      <td>20211029</td>
      <td>3382</td>
      <td>セブン＆アイ・ホールディングス</td>
      <td>市場第一部（内国株）</td>
      <td>6100</td>
      <td>小売業</td>
      <td>14</td>
      <td>小売</td>
      <td>1</td>
      <td>TOPIX Core30</td>
    </tr>
    <tr>
      <th>1434</th>
      <td>20211029</td>
      <td>4063</td>
      <td>信越化学工業</td>
      <td>市場第一部（内国株）</td>
      <td>3200</td>
      <td>化学</td>
      <td>4</td>
      <td>素材・化学</td>
      <td>1</td>
      <td>TOPIX Core30</td>
    </tr>
    <tr>
      <th>1645</th>
      <td>20211029</td>
      <td>4452</td>
      <td>花王</td>
      <td>市場第一部（内国株）</td>
      <td>3200</td>
      <td>化学</td>
      <td>4</td>
      <td>素材・化学</td>
      <td>1</td>
      <td>TOPIX Core30</td>
    </tr>
  </tbody>
</table>
</div>
以降省略


リストにしておく


```python
codeList = df['コード'].tolist()
companyList = df['銘柄名'].tolist()
```

取得期間終了日（本日）と取得期間開始日（本日から７日前）

```python
ed = datetime.datetime.now() # 本日
st = ed - relativedelta(days = 7) # 7日前
```

コードに '.T' を付加し，DataReader で株価データを取得する
株価データは DataFrame で取得できる
直近のデータは DataFrame の最終行なので，
日付（Index）と終値（Close列）の最終行のデータを表示する

```python
for code, company in zip(codeList, companyList):
    df = pdr.DataReader(code + '.T', 'yahoo', st, ed)
    dates = df.index  # 日付はindexになっている
    closes = df['Close']
    print(f'[{company}] date=[{dates[-1]}] close=[{closes[-1]}]')
```

    [セブン＆アイ・ホールディングス] date=[2021-11-22 00:00:00] close=[4777]
    [信越化学工業] date=[2021-11-22 00:00:00] close=[20070]
    [花王] date=[2021-11-22 00:00:00] close=[6219]
    以降省略

## まとめ

まとめると，次のようなコードになる

```python:topix.py
import pandas as pd
import pandas_datareader.data as pdr
import datetime
from dateutil.relativedelta import relativedelta

"""
事前にここから東証上場銘柄一覧ファイル(data_j.xls)をダウンロードしておきます
https://www.jpx.co.jp/markets/statistics-equities/misc/01.html
あと，my.xlsx を用意します
"""
my_df = pd.read_excel('my.xlsx', sheet_name = 'Sheet1', dtype = str)
topix_df = pd.read_excel('data_j.xls', dtype = str)
topix_core30_df = topix_df[topix_df['規模区分']=='TOPIX Core30']

"""
TOPIX Core30 銘柄と自分銘柄の一覧を作る
"""
# TOPIX Core30 銘柄のコードと自分銘柄のコードを集合にする（重複排除される）
code_set = set(topix_core30_df['コード'].tolist()) | set(my_df['コード'].tolist())
# 集合の中にあるコードだけを，TOPIX の DataFrame から抽出する
## isin を使うと，リストや集合の要素に一致する行が抽出できる
df = topix_df[topix_df['コード'].isin(code_set)]
# リストにする
codeList = df['コード'].tolist()
companyList = df['銘柄名'].tolist()

"""
指定期間の株価データを取得し表示する
"""
ed = datetime.datetime.now() # 本日
st = ed - relativedelta(days = 7) # 7日前

for code, company in zip(codeList, companyList):
    df = pdr.DataReader(code + '.T', 'yahoo', st, ed)
    dates = df.index  # 日付はindexになっている
    closes = df['Close']
    print(f'[{company}] date=[{dates[-1]}] close=[{closes[-1]}]')
```

## おわりに

楽しい，便利すぎるぜ，Python

次回は，ローソク足チャートを描く予定