レラティブストレングス投資の月次シグナルを判定するpythonコード

[私のブログ](https://hiroshi-ichihara.hatenablog.com/)で[レラティブストレングス投資](http://etftrendfollow.seesaa.net/article/152055593.html)の月次シグナルを更新していますが、今まではデータ取得とエクセルでの計算を手作業でやっていました。

この度、月次シグナルを判定するpythonコードを書きました。なにぶんpython歴数か月の初心者なので、見苦しいコードかもしれませんがご容赦ください。私が確認した限りでは、正しく動いているようです。

#1. データのスクレイピング


```python:[Monthly_check]RS_signal.ipynb
import numpy as np
import pandas as pd
from datetime import datetime
import urllib.request

#SMTAMウェブサイトから投信データcsvを取得して保存。
#スクレイピングを最小限に抑えるため、一度スクレイピングしたらcsvファイルとして保存。

＃JE:日本株、EE:新興国株、IE:先進国株、JB:日本債券、EB:新興国債券、IB:先進国債券、IR:先進国リート、JR:日本リート
url_list = {'JE':'https://www.smtam.jp/chart_data/140833/140833.csv',
            'EE':'https://www.smtam.jp/chart_data/140841/140841.csv',
            'IE':'https://www.smtam.jp/chart_data/140834/140834.csv',
            'JB':'https://www.smtam.jp/chart_data/140835/140835.csv',
            'EB':'https://www.smtam.jp/chart_data/140842/140842.csv',
            'IB':'https://www.smtam.jp/chart_data/140836/140836.csv',
            'IR':'https://www.smtam.jp/chart_data/140838/140838.csv',
            'JR':'https://www.smtam.jp/chart_data/140837/140837.csv'} 

for key in url_list:
    url = url_list[key]
    title = "{0}.csv".format(key)
    urllib.request.urlretrieve(url,title)

```

#2. シグナル判定

```python:[Monthly_check]RS_signal.ipynb
#全ファンドの累積基準価額をひとつにまとめたデータを作成
assets = ['JE','EE','IE','JB','EB','IB','JR','IR']
df_all = pd.DataFrame()
for asset in assets:
    asset_file = "{0}.csv".format(asset)
    df = pd.read_csv(asset_file, skiprows = [0], names = ['date','nav', 'div', 'aum'],
                    parse_dates = True, index_col = 0)

    df['div'] = pd.to_numeric(df['div'],errors='coerce')
    df['div'] = df['div'].fillna(0)
    
    df['cum_nav'] = (df['nav'] + df['div']) / df['nav'].shift(1)
    df[asset] = df['cum_nav'].cumprod()
    df_all[asset] = df[asset]


#日次データを月次データに変換してシグナル判定
dfm = df_all.resample('M').ffill()
dfm = dfm[dfm.index < datetime.now()] 

calc = pd.DataFrame(columns = ['JE','EE','IE','JB','EB','IB','JR','IR'])
calc.loc['asset class'] = ['日本株','新興国株','先進国株','日本債券','新興国債券',
                          '先進国債券','日本リート','先進国リート']
calc.loc['3 months'] = (dfm.iloc[-1] / dfm.iloc[-4] -1)*100
calc.loc['6 months'] = (dfm.iloc[-1] / dfm.iloc[-7] -1)*100
calc.loc['12 months'] = (dfm.iloc[-1] / dfm.iloc[-13] -1)*100
calc.loc['mean'] = (calc.loc['3 months']+calc.loc['6 months']+calc.loc['12 months'])/3
calc.loc['rank'] = calc.loc['mean'].rank(ascending = False).astype(int)
calc.loc['latest nav'] = dfm.iloc[-1]
calc.loc['12ma NAV'] = dfm.iloc[-12:].mean()
calc.loc['Buy/Sell'] = np.where(calc.loc['latest nav'] > calc.loc['12ma NAV'], 'Buy', 'Sell')

#月次シグナル判定結果を表示
date = dfm.index.max()
print(str(date.year) + '年' + str(date.month) + '月末のシグナルは以下の通りとなりました。')
calc.T.set_index('rank')[['asset class', 'Buy/Sell']].sort_index()

```
実行するとJupyter Notebook上に、以下のように表示される（はずです）。
<img width="576" alt="output.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341224/0b6d435d-8524-e327-2b9d-9fd8bd917415.png">
#3. ブログに反映
上記シグナルを反映したブログ記事はこちらです。
　↓
[【レラティブストレングス投資月次シグナル解説（2020年3月末基準）】](https://hiroshi-ichihara.hatenablog.com/entry/2020/04/01/200000)

#4. おわりに
月次シグナルエクセル更新手作業の、数十年分の時間をかけてやっと完成ました。
費用対効果を出すには数十年使わなければなりません。

シグナル判定するくだりのコードがいかにも素人臭いです。上達したら改善したいと思います。