私のブログでレラティブストレングス投資の月次シグナルを更新していますが、今まではデータ取得とエクセルでの計算を手作業でやっていました。
この度、月次シグナルを判定するpythonコードを書きました。なにぶんpython歴数か月の初心者なので、見苦しいコードかもしれませんがご容赦ください。私が確認した限りでは、正しく動いているようです。
#1. データのスクレイピング
[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. シグナル判定
[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上に、以下のように表示される(はずです)。
#3. ブログに反映
上記シグナルを反映したブログ記事はこちらです。
↓
【レラティブストレングス投資月次シグナル解説(2020年3月末基準)】
#4. おわりに
月次シグナルエクセル更新手作業の、数十年分の時間をかけてやっと完成ました。
費用対効果を出すには数十年使わなければなりません。
シグナル判定するくだりのコードがいかにも素人臭いです。上達したら改善したいと思います。