日経平均株価/個別銘柄の移動平均と出来高を可視化

# Todo
**株価を取得し、分析用データとしてグラフで表示する**
- 日経平均株価をライブラリでダウンロード
- 単純移動平均を計算
- 移動平均・出来高（株取引量）をグラフ化
- 個別銘柄のデータ取得


# 用語

- **ライブラリ**
    - 幾つかのパッケージをまとめたもの
- **パッケージ**
    - 複数のモジュールをまとめたもの
- **モジュール**
    - 関数やクラスなどをひとつのPythonファイルにまとめたもの
    - Python のファイル＝「.py」ファイルのこと

#### Pythonで開発する上で使用される代表的なライブラリ
- ***pandas***（パンダス）
    - [データ解析を支援する機能を提供するライブラリ](https://github.com/pandas-dev/pandas)
    - 一次元のデータを扱う時：**Series**
    - 二次元のデータを扱う時：**DataFrame**
- ***numpy***（ナムパイ）
    - [数値計算ライブラリ](https://github.com/numpy/numpy)
- ***matplotlib***（マット•プロット•リブ）
    - [グラフ描画ライブラリ](https://github.com/matplotlib/matplotlib)


# 前提

JupyterLabをインストールしておく（目安：5分）

https://qiita.com/rexid/items/41353e0f098ad063a3bd

# 1. JupyterLabを起動
```terminal
$ jupyter lab
```
# 2. ライブラリのインストール

## pandas_datareaderをインストール

```terminal
!pip install pandas_datareader
```
![スクリーンショット 2022-10-10 19.21.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/f3677d87-8ad8-052a-22c1-a9e61f448ee3.png)

:::note
`pandas_datareader`を使用すると、日経平均やナスダック、日本の個別銘柄のデータを取得できる
:::

## import

```py
# 日経平均やNASDAQ、個別銘柄の株価データを取得できるライブラリ
from pandas_datareader import data
import pandas as pd
# matplotlibのpyplotモジュールを使用
import matplotlib.pyplot as plt
# JupyterLab上で作成したグラフを表示
%matplotlib inline
import warnings
# すべての警告を表示させない
warnings.simplefilter('ignore')
```

# 3. 日経平均のデータを取得し線グラフとして可視化

```py
start = '2021-10-01'
end = '2022-10-01'

# data.DataReader('取得したいティッカーシンボル', 'データソースの名前', '取得したい期間の開始日付', '終了日付')
df = data.DataReader('^N225', 'yahoo', start, end)
```

## 最初の10件を表示

```py
df.head(10)
```
![スクリーンショット 2022-10-10 20.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/850f7b9d-ced0-de4f-54a8-ede602df89c7.png)

- `High`：高値
- `Low`：安値
- `Open`：始値
- `Close`：終値
- `Volume`：<font color="Magenta">出来高</font>（株取引された量） ←「出来高は株価に先行する」とも言われている
- `Adj Close`：<font color="Magenta">調整後の終値</font>  ←分析に使用

## indexの中身を確認

![スクリーンショット 2022-10-10 20.37.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/d919828b-bebd-7d77-5e17-34f5d7c79b70.png)

- DatetimeIndex
    - 時系列データとして扱うことができる
    - matplotlibでの可視化の際にも便利

## matplotlibで可視化
```py
date = df.index
price = df['Adj Close']

# figsize = (表示する横のサイズ, 縦のサイズ)
plt.figure(figsize=(30, 10))
# plot(X軸, Y軸, label='凡例名')
plt.plot(date, price, label='Adj Close')
# グラフのタイトル
plt.title('N225', color='blue', backgroundcolor='white', size=35, loc='center')
# X軸とY軸の名前
plt.xlabel('Date', color='black', size=30)
plt.ylabel('Price', color='black', size=30)
# 凡例を表示させる
plt.legend()
```

![スクリーンショット 2022-10-10 21.59.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/8266a19f-7dba-5d45-8e31-dbb90e5e49a7.png)



# 4. 単純移動平均を線グラフで可視化
- 移動平均・・・過去〇〇日分の平均
    - pandasの**rolling**メソッドを用いる
    - **mean**メソッドで平均を算出
    - meanではなくmaxにするとその区間の最大値、minにすればその区間の最小値を取得できる

```py
# 過去5日、25日、50日の移動平均を算出する為に定義
span01 = 5
span02 = 25
span03 = 50

# 移動平均を算出
# smaは単純移動平均の略称
df['sma01'] = price.rolling(window=span01).mean()
df['sma02'] = price.rolling(window=span02).mean()
df['sma03'] = price.rolling(window=span03).mean()
```

## 最初の100件を表示
```py
# 行を省略して表示させないようにする
pd.set_option('display.max_rows', None)
df.head(100)
```
![スクリーンショット 2022-10-10 20.54.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/b399e011-83b5-6ee6-93c3-7a6e63c2066c.png)

:::note
sma01は過去5日間の平均なので4日目までNaNと表示されているのはOK。
同様にsma02は過去25日間の平均、sma03は過去50日の平均。
:::

## 移動平均を線グラフで表示
```py
plt.figure(figsize=(30, 10))

plt.plot(date, price, label='Adj Close', color='#99b898')

# 追加
plt.plot(date, df['sma01'], label='sma01', color='#e84a5f')
plt.plot(date, df['sma02'], label='sma02', color='#ff847c')
plt.plot(date, df['sma03'], label='sma03', color='#feceab')

plt.title('N225', color='white', backgroundcolor='grey', size=35, loc='center')
plt.xlabel('Date', color='black', size=30)
plt.ylabel('Price', color='black', size=30)
plt.legend()
```

![スクリーンショット 2022-10-10 22.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/e082c623-8e49-a016-639d-974aa2b0cafe.png)


### いつ売り、いつ買えばよかったかを検討する（データ分析）
株や為替において使われる分析方法
- **ゴールデンクロス**
    - 「短期の移動平均線」が「中期以上の移動平均線」を下から上に抜けること
        - 価格が上昇しているサイン
- **デッドクロス**
    - 「短期の移動平均線」が「中期以上の移動平均線」を上から下に抜けること 
        - 価格が下降しているサイン

:::note
今回作成した表のsma01とsma03の交差している箇所を見ると分かりやすい
:::

# 5. 出来高を棒グラフで表示
株式相場の世界には「**出来高は株価に先行する**」という格言がある

```py
plt.figure(figsize=(30, 15))
# グラフ領域を二分割する
# plt.subplot(縦方向を分割する数, 横方向に分割する数, グラフを配置する位置を示すindex)
plt.subplot(2,1,1)

# 線グラフ(単純移動平均)
plt.plot(date, price, label='Adj Close', color='#99b898')
plt.plot(date, df['sma01'], label='sma01', color='#e84a5f')
plt.plot(date, df['sma02'], label='sma02', color='#ff847c')
plt.plot(date, df['sma03'], label='sma03', color='#feceab')
plt.legend()

# 棒グラフ(出来高)
plt.subplot(2,1,2)
plt.bar(date, df['Volume'], label='Volume', color='gray')
plt.legend()
```

![スクリーンショット 2022-10-10 22.03.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/50f3f473-04d8-6d01-91e1-2ac8e2847251.png)


# おさらい
## 日本企業の個別銘柄の株のデータ取得

https://quote.jpx.co.jp/jpx/template/quote.cgi?F=tmp/stock_search

***例***
- 銘柄名 (会社名)で検索
    - 今回は`ANAホールディングス`
    - 検索結果の証券`コード`を使ってデータ取得を行う

![スクリーンショット 2022-10-10 21.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/276ddbe1-1b33-2ede-0ef4-0503c67a303b.png)

:::note
以下、JupyterLabでセルを順に実行
:::


### 1. pandas_datareaderをインストール

```terminal
!pip install pandas_datareader
```

### 2. import

```py
# 日経平均やNASDAQ、個別銘柄の株価データを取得できるライブラリ
from pandas_datareader import data
import pandas as pd
# matplotlibのpyplotモジュールを使用
import matplotlib.pyplot as plt
# JupyterLab上で作成したグラフを表示
%matplotlib inline
import warnings
# すべての警告を表示させない
warnings.simplefilter('ignore')
```

### 3. 共通処理を関数化

```py
def company_stock(start_date, end_date, company_code):

    # data.DataReader('証券コード', 'データソース')
    df = data.DataReader(company_code, 'stooq')
    # 日付を絞る
    df = df[(df.index>=start_date) & (df.index<=end_date)]

    date = df.index
    price = df['Close']

    # 過去5日、25日、50日の移動平均を算出する為に定義
    span01 = 5
    span02 = 25
    span03 = 50

    # 移動平均を算出
    # smaは単純移動平均の略称
    df['sma01'] = price.rolling(window=span01).mean()
    df['sma02'] = price.rolling(window=span02).mean()
    df['sma03'] = price.rolling(window=span03).mean()

    plt.figure(figsize=(20, 10))

    # グラフ領域を二分割する
    # plt.subplot(縦方向を分割する数,横方向に分割する数,グラフを配置する位置を示すindex)
    plt.subplot(2,1,1)
    
    # 線グラフ(単純移動平均)
    plt.plot(date, price, label='Close', color='#99b898')
    plt.plot(date, df['sma01'], label='sma01', color='#e84a5f')
    plt.plot(date, df['sma02'], label='sma02', color='#ff847c')
    plt.plot(date, df['sma03'], label='sma03', color='#feceab')
    plt.legend()

    # 棒グラフ(出来高)
    plt.subplot(2,1,2)
    plt.bar(date, df['Volume'], label='Volume', color='gray')
    plt.legend()
```

### 4. 実行
```py
start_date = '2022-01-01'
end_date = '2022-10-01'

# ANAホールディングス
company_code = '9202.jp'

company_stock(start_date, end_date, company_code)
```

![スクリーンショット 2022-10-10 22.33.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/e8de06db-46b5-50e7-ca5c-835dc5f256d9.png)


:::note
調べたい期間や証券コードが変わっても引数の値を変えるだけで表示可能に
:::

 # NEXT

https://qiita.com/rexid/items/4c390b3c5a769a26dc88