日本には少額投資非課税制度、通称「NISA」と呼ばれる制度が存在します。詳しくはググってもらうとして、通常株の利益には20%ほどの税金がかかりますが、NISAだとそれが非課税になります。

現在NISAには一般NISAとつみたてNISAの2種類があり、それぞれ運用できる年数、上限金額などが異なります。どちらを選んだほうが最終的にリターンが高いのか?というのが気になったので、今回はそれぞれ過去のデータを元にシミュレーションしました。

対象とする株式の商品はS&P 500のインデックスファンドとします。なおこの記事は過去のデータを分析したものであり、将来の運用結果などを保証するものではありません。最終的な投資判断は各自で行ってください。

S&P 500年平均リターン

まずS&P 500の年平均リターンを出します。
データは Yahoo! finance からダウンロードしたものを使います。期間は1928年から2019年までと、2000年から2019年までの20年間の2つを見てみます。

def history(csvfile):
    df = pd.read_csv(csvfile, index_col='Date', parse_dates=True)
    df = df.dropna()
    df.index = df.index.to_period('M').to_timestamp('M')
    display(df.head(1).append(df.tail(1)))
    annual_price = df.resample('Y').agg({
        'Open': 'first',
        'Adj Close': 'last',
    })
    monthly_price = df[['Open', 'Adj Close']]
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(14, 4))
    annual_price['Adj Close'].diff().cumsum().plot(ax=axes[0])
    annual_price.loc['2000':'2019', 'Adj Close'].diff().cumsum().plot(ax=axes[1])
    return [
        r.pct_change(axis=1).dropna(axis=1).rename(columns={'Adj Close': 'value'}) 
        for r in (annual_price, monthly_price)
    ]

annual_return, monthly_return = history('./^GSPC.csv')
display(annual_return['value'].mean())
display(annual_return.loc['2000':'2019', 'value'].mean())
plt.show(block=True)

OpenHighLowCloseAdj CloseVolume
Date
1928-01-3117.76000017.76000017.26000017.57000017.5700000
2019-12-313143.8500983247.9299323070.3300783230.7800293230.78002972054000000
0.07677447259284405
0.05639410820846351

1928年からのほうは約7.7%で、2000年からのほうは約5.6%ですね。直近20年を見ると、若干アンダーパフォームしているようです。

NISA運用想定リターン

では一般NISAとつみたてNISAでS&P 500のインデックスファンドを購入し、20年間運用した場合の想定リターンを出してみます。未来のデータは持っていないので、2000年から2019年までの過去20年間のデータを元にシミュレーションします。

対象とするインデックスファンドはNISAで購入可能なもののうち、下記3つとしました。

fund_df = pd.DataFrame({
    'SBIバンガードS&P500': [0.000938],
    'eMAXIS Slim米国株式(S&P500)': [0.000968],
    '農林中金<パートナーズ>つみたてNISA米国株式S&P500': [0.00495],
}, index=['信託報酬年率']).T
display(fund_df)

信託報酬年率
SBIバンガードS&P5000.000938
eMAXIS Slim米国株式(S&P500)0.000968
農林中金<パートナーズ>つみたてNISA米国株式S&P5000.004950

SBIバンガードS&P500 と eMAXIS Slim米国株式(S&P500) は、NISAで購入可能なS&P 500のインデックスファンドで信託報酬が最も安い2つです。信託報酬はそれぞれ年率0.0938%と0.0968%です。
農林中金のものは一般NISAでは購入できないのですが、今回は信託報酬の違いによる差も見てみたかったので信託報酬が年率0.495%と他に比べて高い農林中金のものも対象としました。

また、前提として、一般NISAは5年で終了予定です。2019年12月、一般NISAは2028年まで延長されることが決まりましたが、今回想定している20年もの間、一般NISAが使い続けられるかはわかりませんので、あくまでそうであった場合として計算しています。

def calculate(return_df, n_div=1, freq='Y'):
    base_dfs = []
    for year_limit, total_limit in (
        (1_200_000, 6_000_000),  # 一般NISA年間上限金額 / 最大金額
        (  400_000, 8_000_000),  # つみたてNISA年間上限金額 / 最大金額
    ):
        df = pd.DataFrame({
            'base': [year_limit / n_div] * len(return_df),
        }, index=return_df.index)
        df = df[df.cumsum() <= total_limit].fillna(0)
        base_dfs.append(df)
    fund_dfs = []
    for fund_name, fee in fund_df.itertuples():
        dfs = []
        for base_df in base_dfs:
            df = pd.DataFrame({'earn': 0}, index=base_df.index)
            for i, index in enumerate(df.index):
                base = base_df.loc[index, 'base']
                earn = df.loc[df.index[i - 1], 'earn']
                ret = return_df.loc[index, 'value']
                df.loc[index, 'earn'] = \
                    (base + earn) * (1 + ret) / (1 + fee / n_div)
            dfs.append(df.astype('int64'))
        df = pd.concat(dfs, keys=['一般', 'つみたて'], axis=1)
        fund_dfs.append(df)
    base_df = pd.concat(
        [df.cumsum() for df in base_dfs],
        keys=fund_dfs[0].columns.get_level_values(0),
        axis=1).astype('int64')
    df = pd.concat(
        [base_df] + fund_dfs,
        keys=['', 'SBIバンガード', 'eMAXIS', '農林中金'], 
        axis=1)
    display(df)
    plot_df = df.copy()
    plot_df.columns = df.columns.to_flat_index()
    ax = plot_df.plot(
        xticks=df.index[::n_div],
        figsize=(12, 6),
        markevery=n_div,
        style=['yo--', 'cs--'])
    ax.xaxis.set_major_formatter(FixedFormatter(df.index.year.unique()))
    plt.show(block=True)
    return df

年初に年間上限金額いっぱいまで買う場合

はじめに、毎年年初にNISA枠の上限金額いっぱいまで買う場合(以下、一括投資)のリターンを見てみます。

annual_df = calculate(return_df=annual_return['2000':'2019'])

SBIバンガードeMAXIS農林中金
一般つみたて一般つみたて一般つみたて一般つみたて
basebaseearnearnearnearnearnearn
Date
2000-12-311200000400000107731935910610772863590951073018357672
2001-12-312400000800000197843965947919783526594501966819655606
2002-12-3136000001200000243348481116124333448111142414908804969
2003-12-3148000001600000458770815292364587394152913145460321515344
2004-12-3160000002000000630231121007706301780210059362319502077316
2005-12-3160000002400000648536225734056484621257314663873552539093
2006-12-3160000002800000736172633752007360665337480472215303322932
2007-12-3160000003200000761587139055297614545390500374410103836081
2008-12-3160000003600000468169626467334680740264633045559422593645
2009-12-3160000004000000577599637588775774644375826755984093678636
2010-12-3160000004400000649971046799716497994467914562747214571352
2011-12-3160000004800000649351550751306491606507415262437154946787
2012-12-3160000005200000734975161970817347370619578970387996027655
2013-12-3160000005600000951644385418879513075853995890774388289289
2014-12-3160000006000000106048369964568106007659962120100752399644423
2015-12-31600000064000001051791610279617105135631027688199527669922325
2016-12-3160000006800000115424191171987111537297117165181087861711282554
2017-12-3160000007200000136931161437816413686629143737551285410513804032
2018-12-3160000007600000127786411379122612772204137866981194777213202517
2019-12-3160000008000000166519801849273516643094184862801550711017654817

まず一般NISAとつみたてNISAのリターンです。パッと見ではつみたてNISAのほうが最終リターンが多いように見えますが、つみたてNISAのほうが上限金額が200万多いことによるもので、600万積み立て時点を見てみると実際には一般NISAのほうがリターンが多いのがわかります。また、つみたてNISAの積立金額が600万になったあとに上限の800万までさらに200万を積み立てるよりも、一般NISAの最終リターン + 200万のほうが大きいことが見て取れます。

annual_df[annual_df[('', 'つみたて', 'base')] >= 6000000]

SBIバンガードeMAXIS農林中金
一般つみたて一般つみたて一般つみたて一般つみたて
basebaseearnearnearnearnearnearn
Date
2014-12-3160000006000000106048369964568106007659962120100752399644423
2015-12-31600000064000001051791610279617105135631027688199527669922325
2016-12-3160000006800000115424191171987111537297117165181087861711282554
2017-12-3160000007200000136931161437816413686629143737551285410513804032
2018-12-3160000007600000127786411379122612772204137866981194777213202517
2019-12-3160000008000000166519801849273516643094184862801550711017654817

SBIバンガードを例にすると、最終リターンを見ても

last = annual_df.last('Y')
base, earn = last[''], last['SBIバンガード']
base.columns = earn.columns = ['一般NISA投資利益率', 'つみたてNISA投資利益率']
display(earn.T / base.T)

Date2019-12-31
一般NISA投資利益率2.775330
つみたてNISA投資利益率2.311592

と、このように一般NISAのほうがROIが高いです。
次に信託報酬の違いによるリターンへの影響を見てみます。

pd.concat([
    annual_df.last('Y').loc[:, pd.IndexSlice[:, c, 'earn']].diff(axis=1).fillna(0)
    for c in annual_df.columns.get_level_values(1).unique()
], axis=1)

SBIバンガードeMAXIS農林中金SBIバンガードeMAXIS農林中金
一般一般一般つみたてつみたてつみたて
earnearnearnearnearnearn
Date
2019-12-310.0-8886.0-1135984.00.0-6455.0-831463.0

一番信託報酬の低いSBIバンガードに対して、0.003%高いeMAXISは20年で6,455円から8,886円低く、約0.4%高い農林中金は831,463円から1,135,984円低いようです。信託報酬が0.4%違うと20年で80万から110万円ほどの差が出るようです。

年間上限金額まで毎月均等に積み立てる場合

つぎに、年間上限金額まで毎月均等に積み立てる場合(以下、積立投資)のリターンを見てみます。

monthly_df = calculate(return_df=monthly_return['2000':'2019'], n_div=12, freq='M')

SBIバンガードeMAXIS農林中金
一般つみたて一般つみたて一般つみたて一般つみたて
basebaseearnearnearnearnearnearn
Date
2000-01-3110000033333949023163494901316339487031623
2000-02-2920000066666190968636561909676365519087363624
2000-03-31300000100000319085106361319084106361318874106291
2000-04-30400000133333406147135382406145135381405808135269
2000-05-31500000166666495016165005495013165004494519164839
...........................
2019-08-3160000007866666140030601499547213995892149904931307670714347296
2019-09-3060000007899999143279711537751714320601153723831337565214709383
2019-10-3160000007933333145855201568786514577982156826001361153315002706
2019-11-3060000007966666150158811618506715008082161796071400847215474519
2019-12-3160000007999999154298751666555015421823166598971438988115930085

240 rows × 8 columns

display(monthly_df[monthly_df[('', 'つみたて', 'base')] == 5999999])

SBIバンガードeMAXIS農林中金
一般つみたて一般つみたて一般つみたて一般つみたて
basebaseearnearnearnearnearnearn
Date
2014-12-3160000005999999106979319782212106939529779903101789839479568

一般NISAとつみたてNISAのリターンの差は一括投資と傾向は同じようです。気になる一括投資と積立投資の差を見てみます。

annual_last = annual_df.last('Y')
monthly_last = monthly_df.last('M')
pd.concat([annual_last, monthly_last, annual_last - monthly_last])

SBIバンガードeMAXIS農林中金
一般つみたて一般つみたて一般つみたて一般つみたて
basebaseearnearnearnearnearnearn
Date
2019-12-3160000008000000166519801849273516643094184862801550711017654817
2019-12-3160000007999999154298751666555015421823166598971438988115930085
2019-12-3101122210518271851221271182638311172291724732

一番下が一括投資とのリターンの差です。いずれも一括投資のほうがリターンが高いようです。巷でよく言われているドルコスト平均法によるメリットは、少なくともS&P 500については享受できないようです。まぁドルコスト平均法は価格が下がった場合に平均取得価額を下げることによってダメージを少なくする、あるいは全く無くするものなので、右肩上がりのS&P 500に対しては無力というのもわからなくはないです。

まとめ

過去のデータを使ったシミュレーションでは、一般NISAを年初に上限金額まで買うのが一番リターンが良いという結果になりました。積み立てる金額によりますが、NISAの年間上限金額まで積み立てるという前提においては、つみたてNISAは一般NISAをアウトパフォームしないので、年間上限金額まで積み立てられるのであれば一般NISAのほうがよいでしょう。

また、今回シミュレーション対象に選んだS&P 500ですが、今後も同じように右肩上がりになるかどうかはわかりません。ですが少なくとも日経平均株価のインデックスファンドを買うより、よほど期待値は高いと個人的には思います。

あと、こういうのはスプレッドシート使って出したほうが早いと思いますが、今回はコードを書いて載せることによる再現性を重視しました。この記事はすべてJupyter Notebookを使って書かれています。コードをコピペするか、 https://github.com/naoina/kuune.org/blob/master/content/text/nisa/index.ipynb から持ってくれば容易に手元で再現できるので、気になる方は試してみてください。