見出し画像

積み立て投資検証(毎日・毎週・毎月)

こんにちわ!トミィ(@toushi_tommy)です!積み立て投資の検証ですが、「正直変わらないから毎月で良いよ」って声をよく聞きます。私としてはできるだけ瞬発的な下落を取りたいので、基本的に毎日積み立てをやってます。もちろん、つみたてNISAは毎月積み立てですが、毎日積み立ては積みあがっている感覚がより大きく、毎日アプリを見るのが楽しくなるため、活用しております。毎日積み立ては100円から可能ですし、SBIの「かんたん積立」アプリが非常に使いやすいのでお勧めです。今回は毎日積み立てのやり方毎日・毎週・毎月で投資を行った場合の検証を行ってみました。

記事内容は無料です。記事が気に入っていただけましたら、私にジュースでをおごっていただけますと、今後の活動の励みになります。

毎日積み立てのやりかた

通常の投資信託で毎日積み立てができるのはSBI証券、マネックス証券になります。楽天証券では毎月積み立てしかできませんが、唯一つみたてNISAのみは、証券口座払いで毎日積み立てができます。つみたてNISAは楽天カード払いがお得ですので、毎日積み立てをやりたい場合は、是非SBI証券を使ってください。パソコンで積み立て設定をする場合は、投資信託を選択し、「積立買付」を選択します。今回は、SBI証券での毎日積み立てを解説します。

画像2

その後、毎日を選びますが、クレジットカード払いは毎月しかできませんので、現金で決済してください。

画像3

また、もっと簡単なやり方として、アプリを使う方法があります。「かんたん積立」アプリをダウンロードしてください。こちらになります。

画像3

ダウンロード後、投資信託を選択してください。「積立する」を選びます。

画像4

その後、「毎日」を選ぶのみになります。

画像5

このように簡単に出来、さらに毎日100円から購入できますので、毎日のジュースを1杯我慢して、投資信託を購入してみてください。また、少額であれば、リスク資産への投資も面白いと思います。いろいろと銘柄を探して、興味ある銘柄に少額から投資してみることで、毎日の楽しみが増えますので、是非、挑戦してみてください。

毎日・毎週・毎月積み立て比較

今回、主要インデックスである「S&P500」の過去の値動きを使って、毎日、毎週、毎月積み立てでどのやり方が一番良いかの検証を行ってみました。投資金額元本は600万円に統一し、20年、10年、5年の期間で検証しました。また、今回の値動きはドルですが、為替を考慮せず、円で購入したと仮定して計算しております。結果はこちら。。。

画像6

これを見ると、毎日投資の方がより良いパフォーマンスを出しております。ただし、年の利益率をみると、週投資と比べると0.02%、月投資と比べると0.05%-0.19%になりますので、気にする程度ではございません。可能であれば毎日投資の方が良いかと思います。ちなみに、他の指数でも検証いたしました。結果はこちらです。

S&P500

画像7

ナスダック

画像8

ラッセル

画像9

ダウ

画像10

日経平均

画像11

どの場合に関しても毎日投資が有利ですが、切り取る場所によって多少変わりそうです。今回パフォーマンスを見てみると

ナスダック > S&P500 > ラッセル > ダウ > 日経平均

であることが分かると思います。

バックテストに用いたプログラム

今回pythonにてプログラムを作りました。修正したい方やどのような計算をしているかを見たい方は是非、こちらをごらんください。実行するにはGoogle Colab環境やYahooモジュールの環境が必要ですので、ご興味がありましたら、こちらをご一読ください。特に0章の環境設定は必要になります。

##############################################
# PATH
module_dir = '/content/drive/MyDrive/module'
img_dir    = '/content/drive/MyDrive/input/'
output_dir = '/content/drive/MyDrive/output/'
font_dir   = '/content/drive/MyDrive/fonts/'
##############################################
import os
if not os.path.isdir(output_dir): os.makedirs(output_dir)
import sys
sys.path.append(module_dir)
import datetime as datetime
import pytz
from PIL import Image, ImageDraw, ImageFont
import IPython
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.simplefilter('ignore')
import yfinance as yf
import itertools

## 設定個所 ###################################
# 投資合計600万円
sougaku = 6000000
# バックテスト用 Ticker
test_ticker = {'^GSPC':'S&P500'}
# test_ticker = {'^IXIC':'ナスダック'}
# test_ticker = {'^RUT':'ラッセル'}
# test_ticker = {'^DJI':'ダウ'}
# test_ticker = {'^N225':'日経平均'}

icon_img = img_dir+"tommy_icon2.png"
txt_comm = 'トミィ @toushi_tommy'
title = '毎日・毎週・毎月つみたて比較('+list(test_ticker.values())[0]+')'
###############################################
# フォント
jap_font = '/content/drive/MyDrive/module/japanize_matplotlib/fonts/ipaexg.ttf'
jap2_font = font_dir+'meiryo.ttc'
japb_font = '/content/drive/MyDrive/module/japanize_matplotlib/fonts/ipaexg.ttf'
jap3_font = font_dir+'meiryob.ttc'
if os.path.exists(jap2_font): jap_font = jap2_font
if os.path.exists(jap3_font): japb_font = jap3_font

######################################################
def xycenter(xp, yp, xw, yw, tx, fn):
 x,y = draw.textsize(tx,fn)
 return xp+(xw-x)/2, yp+(yw-y)/2
ycenter = lambda yp,yw,tx,fn : yp+(yw-draw.textsize(tx,fn)[1])/2
xcenter = lambda xp,xw,tx,fn : xp+(xw-draw.textsize(tx,fn)[0])/2
######################################################

###############################################
x_height_all = 1080
y_height_all = 1350
###############################################
# 色
col_back = 'white' # heatmap (38,41,49)
col_txt  = 'black'  # heatmap 'white'
col_line =  'black'  # heatmap 'white'
col_head = (231, 239, 252)

###############################################
im = Image.new('RGB', (x_height_all, y_height_all), col_back)
draw = ImageDraw.Draw(im)
today_j = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
# フォント ####################################
font_date   = ImageFont.truetype(jap_font, 30)
font_header = ImageFont.truetype(japb_font, 30)
font_subtit = ImageFont.truetype(jap_font, 28)
font_subtit2 = ImageFont.truetype(jap_font, 20)
font_sign   = ImageFont.truetype(jap_font, 16)
font_att   = ImageFont.truetype(japb_font, 16)

###############################################
# ヘッダ作成
len_title=draw.textsize(title, font_header)[0]
draw.rectangle([(10, 10), (x_height_all-10, 120)], fill=col_head)
draw.rectangle([(10, 10), (x_height_all-10, y_height_all-10)], outline=col_line, width=5)
if os.path.exists(icon_img):im.paste(Image.open(icon_img).resize((80, 80)).copy(), (30, 30))
x_pos = x_height_all/2-len_title/2
draw.line((x_pos, 70, x_pos+len_title,70), fill='yellow', width=25)
draw.text((x_pos, 45),title,col_txt,font=font_header)
draw.text((x_height_all-220, 20),txt_comm,col_txt,font=font_sign)
draw.text((x_height_all-260, 90),"更新日時:"+today_j.strftime("%Y/%m/%d %H:%M"),col_txt,font=font_sign)
draw.line((20,120, x_height_all-20,120), fill=col_line, width=1)
###############################################

draw.text((30, 130),"比較条件",'black',font=ImageFont.truetype(japb_font, 24))
draw.text((60, 160),'投資金額は'+'{:,.0f}万円'.format(sougaku/10000)+'固定、過去20年・10年・5年の'+list(test_ticker.values())[0]+'の値動きを元に試算。(為替は考慮しない)','black',font=ImageFont.truetype(jap_font, 20))

col1 = (112,163,255)
str_col1 = '#70A3FF'
col2 = (188,217,249)
str_col2 = '#BCD9F9'

xoff = lambda xw,tx,fn : (xw-draw.textsize(tx,fn)[0])

fnt20b=ImageFont.truetype(japb_font, 20)
fnt20 = ImageFont.truetype(jap_font, 20)
fntttl = ImageFont.truetype(japb_font, 23)
fnt16b=ImageFont.truetype(japb_font, 16)
fnt16 = ImageFont.truetype(jap_font, 16)

########################################################################
def calc_data(x_loc,y_loc, ticker, per, intv, name, df2):
 str_term = str(per)+'y'
 name2 = name+'('+str(per)+'年)'
 data = yf.download(ticker, period = str_term, interval = intv)[['Close']]
 data = data.pct_change()
 data = data.rename(columns={'Close':'Rate'})
 data = data[:len(data)-1]
 df = data.copy()

 df['積立']=sougaku/len(df)
 df['元本']=df['積立'].cumsum()
 df['総額']=list(itertools.accumulate([df['積立'][0]]+list(range(1,len(df))), func=lambda x,y:x*(1+df['Rate'][y])+df['積立'][y]))
 df['総利益']=df['総額']-df['元本']

 plt.figure(figsize=(7, 4), dpi=50)
 plt.xticks(fontsize=20)
 plt.yticks(fontsize=20)
 plt.bar(df.index, df['元本'], color=str_col1,width=50.0)
 plt.bar(df.index, df['総利益'], bottom=df['元本'], color=str_col2,width=50.0)
 outfile = output_dir+'graph.png'
 plt.savefig(outfile, bbox_inches="tight")
 plt.close()
 im.paste(Image.open(outfile).copy(), (x_loc, y_loc+30))

 pos = 210
 xpos = x_loc+40
 draw.text((xpos+10, y_loc+10),name+"積立:" + '{:,.2f}円'.format(df['積立'][0]) +'('+'{:,}'.format(len(df))+'回)','black',font=fnt16b)
 draw.rectangle([(xpos, y_loc+pos+5), (xpos+20, y_loc+pos+5+12)], fill=col1)
 draw.text((xpos+30, y_loc+pos),"投資元本:",'black',font=fnt16)
 num='{:,.2f}万円'.format(int(df['元本'].iat[-1])/10000)
 draw.text((xpos+100+xoff(160,num,fnt16b), y_loc+pos),num,'black',font=fnt16b)
 pos +=20
 draw.rectangle([(xpos, y_loc+pos+5), (xpos+20, y_loc+pos+5+12)], fill=col2)
 draw.text((xpos+30, y_loc+pos),"利益:",'black',font=fnt16)
 num='{:,.2f}万円'.format(int(df['総利益'].iat[-1])/10000)
 draw.text((xpos+100+xoff(160,num,fnt16b), y_loc+pos),num,'black',font=fnt16b)
 pos +=20
 draw.rectangle([(xpos, y_loc+pos+5), (xpos+20, y_loc+pos+5+6)], fill=col2)
 draw.rectangle([(xpos, y_loc+pos+5+6), (xpos+20, y_loc+pos+5+12)], fill=col1)
 draw.text((xpos+30, y_loc+pos),"総額:",'black',font=fnt16)
 num='{:,.2f}万円'.format(int(df['総額'].iat[-1])/10000)
 draw.text((xpos+100+xoff(160,num,fnt16b), y_loc+pos),num,'black',font=fnt16b)

 df2.loc['積立金額',name2] = sougaku/len(df)
 df2.loc['積立回数',name2] = len(df)
 df2.loc['利益',name2] = df['総利益'].iat[-1]
 df2.loc['年利益率',name2] = (df['総利益'].iat[-1]/sougaku)/per
 df2.loc['評価金額',name2] = df['総額'].iat[-1]
 return

########################################################################
def display_data(check_term,y_loc):
 draw.line((20, y_loc-30, x_height_all-20, y_loc-30), fill=col_line, width=1)
 x_loc = 30
 draw.text((30, y_loc-20),'過去'+str(check_term)+'年','blue',font=fnt20b)
 calc_data(x_loc,y_loc, check_ticker, check_term, '1d', '毎日',df2)
 x_loc = x_loc+350
 calc_data(x_loc,y_loc, check_ticker, check_term, '1wk', '毎週',df2)
 x_loc = x_loc+350
 calc_data(x_loc,y_loc, check_ticker, check_term, '1mo', '毎月',df2)
 return
########################################################################

y_start = 230
y_offset = 310

df2 = pd.DataFrame(
{ "項目" : ['積立金額','積立回数','利益','年利益率','評価金額'],
"毎日(20年)" : [0,0,0,0,0],
"毎週(20年)" :  [0,0,0,0,0], 
"毎月(20年)" :  [0,0,0,0,0],
"毎日(10年)" :  [0,0,0,0,0],
"毎週(10年)" :  [0,0,0,0,0],
"毎月(10年)" :  [0,0,0,0,0],
"毎日(5年)" :   [0,0,0,0,0],
"毎週(5年)" :   [0,0,0,0,0],
"毎月(5年)" :   [0,0,0,0,0] }
)
df2["idx"]=df2["項目"]
df2.set_index('idx',inplace=True)
check_ticker = list(test_ticker.keys())[0]
########################################################################
display_data(20,y_start)
display_data(10,y_start+y_offset)
display_data(5 ,y_start+y_offset*2)

y_loc = y_start+y_offset*3
draw.line((20, y_loc-30, x_height_all-20, y_loc-30), fill=col_line, width=1)

######################################################
split_line = [1,4,7,10] # 枠線作成時に縦に線を引く場所
# カラム毎の横サイズ
x_width = {"項目" :80,
          "毎日(20年)" :105,"毎週(20年)" :105,"毎月(20年)" :105,
      "毎日(10年)" :105,"毎週(10年)" :105,"毎月(10年)" :105,
      "毎日(5年)" :105,"毎週(5年)" :105,"毎月(5年)" :105
}
y_height_hd = 30 # ヘッダ用 縦サイズ
y_height = 30 # 縦サイズ
######################################################
x_start = 25
y_start = y_loc-20
xpos = x_start
ypos = y_start

# ヘッダ出力 #####
font_head=ImageFont.truetype(japb_font, 16)
for i in x_width:
 draw.rectangle([(xpos, ypos), (xpos+x_width[i], ypos+y_height_hd)], fill=(247, 203, 77), outline=(0,0,0),  width=1)
 draw.text((xycenter(xpos,ypos,x_width[i],y_height_hd,i,font_head)),i, (0,0,0),font=font_head)
 xpos+=x_width[i]

# データ出力 ####
font_txt=ImageFont.truetype(jap_font, 16)
font_txb=ImageFont.truetype(japb_font, 16)
ypos+=y_height_hd
for i in range(len(df2)):
 xpos = x_start
 draw.rectangle([(xpos, ypos), (xpos+sum(x_width.values()), ypos+y_height)], outline=(0,0,0),  width=1
   , fill=((255,255,255) if i%2 == 0 else (254, 248, 227)))

 # データ ####
 for j in x_width:
   draw.rectangle([(xpos, ypos), (xpos+x_width[j], ypos+y_height)], outline=(0,0,0),  width=1)
   if j =='項目':
     str_num = df2[j][i]
   else:
     if i==0: str_num = '{:,}円'.format(int(df2[j][i]))
     if i==1: str_num = '{:,}回'.format(int(df2[j][i]))
     if i==2: str_num = '{:,.1f}万円'.format(df2[j][i]/10000)
     if i==3: str_num = '{:,.2%}'.format(df2[j][i])
     if i==4: str_num = '{:,.1f}万円'.format(df2[j][i]/10000)
   if i==4:
     draw.text((xycenter(xpos,ypos,x_width[j],y_height,str(str_num),font_txb)),str(str_num), 'black',font=font_txb)
   else:
     draw.text((xycenter(xpos,ypos,x_width[j],y_height,str(str_num),font_txt)),str(str_num), 'black',font=font_txt)
   xpos+=x_width[j]
 ypos+=y_height

######################################################
draw.rectangle([(x_start, y_start), (xpos, y_start+y_height_hd)], outline='black', width=3)
# ヘッダ枠
draw.rectangle([(x_start, y_start), (xpos, ypos)], outline='black', width=3)
for i in split_line:
 draw.line((x_start+sum(list(x_width.values())[0:i]), y_start, x_start+sum(list(x_width.values())[0:i]), ypos), fill='black', width=3)

draw.rectangle([(x_start, ypos-y_height), (xpos, ypos)], outline='black', width=3)

loc_pos = 1
if df2.loc['評価金額','毎日(20年)'] < df2.loc['評価金額','毎週(20年)']: 
 loc_pos +=1
 if df2.loc['評価金額','毎週(20年)'] < df2.loc['評価金額','毎月(20年)']: loc_pos +=1
draw.line((x_start+sum(list(x_width.values())[0:loc_pos])+10, ypos-5, x_start+sum(list(x_width.values())[0:loc_pos+1])-10, ypos-5), fill='red', width=3)
loc_pos = 4
if df2.loc['評価金額','毎日(10年)'] < df2.loc['評価金額','毎週(10年)']: 
 loc_pos +=1
 if df2.loc['評価金額','毎週(10年)'] < df2.loc['評価金額','毎月(10年)']: loc_pos +=1
draw.line((x_start+sum(list(x_width.values())[0:loc_pos])+10, ypos-5, x_start+sum(list(x_width.values())[0:loc_pos+1])-10, ypos-5), fill='red', width=3)
loc_pos = 7
if df2.loc['評価金額','毎日(5年)'] < df2.loc['評価金額','毎週(5年)']: 
 loc_pos +=1
 if df2.loc['評価金額','毎週(5年)'] < df2.loc['評価金額','毎月(5年)']: loc_pos +=1
draw.line((x_start+sum(list(x_width.values())[0:loc_pos])+10, ypos-5, x_start+sum(list(x_width.values())[0:loc_pos+1])-10, ypos-5), fill='red', width=3)

###############################################
outfile = output_dir+'test.png'
im.save(outfile)
IPython.display.Image(outfile)


以上です

ここから先は

0字

¥ 150

期間限定 PayPay支払いすると抽選でお得に!

サポートいただけますと、うれしいです。より良い記事を書く励みになります!