Edited at

エクセルでモンテカルロシミュレーションを実行し投資信託の将来成績を予測する

こんにちは、東北投信という投資関連のウェブサイトを運営しています。

https://blog.tacos-heaven.xyz/

今回は、東北投信で記事を作成する際に利用している、モンテカルロシミュレーションツールの作成について解説します。モンテカルロシミュレーションとは、乱数を用いたシミュレーション方法のことで、東北投信では投資信託の運用成績をランダムに発生させる方法として利用しています。

「投資信託の運用成績が乱数シミュレーションで完全に再現できるか」には限界がありますが、投資信託への理解を深めるためにはとても便利です。今回は簡単に「正規分布」で乱数を発生させる方法について解説します。


乱数を発生させる数式

乱数を発生させる数式はエクセルのセルに用意します。式は以下の通り。

=NORM.INV(RAND(),リターン,リスク)


NORM.INV(確率,平均,標準偏差)

NORM.INV 関数の書式には、次の引数があります。

確率 必ず指定します。 正規分布における確率を指定します。

平均 必ず指定します。 対象となる分布の算術平均 (相加平均) を指定します。

標準偏差 必ず指定します。 対象となる分布の標準偏差を指定します。


https://support.office.com/ja-jp/article/norm-inv-%E9%96%A2%E6%95%B0-54b30935-fee7-493c-bedb-2278a9db7e13

ここでは確率の部分に、0~1の間で数値を乱数生成するRAND関数を与えることで、投資の成績に代用します。

正規分布する乱数の発生の解説はこちらが役立ちます。

http://zellij.hatenablog.com/entry/20111029/p1

今回は毎年の運用成績をこの数式で発生し、運用成績を累積させます。例えば50年間の運用をシミュレーションするならば、このNORM.INV関数も50個(50年分)用意し、毎年の利回りとして運用している金額に掛け算するわけです。

実際に毎年の運用成績を乱数で作ったものがこちらです。

20170426b.png

以下はmyINDEX様にて公開されている、TOPIXの毎年の成績です。

20170426a.png

https://myindex.jp/data_i.php?q=TS1047JPY

なんとなく似ているように感じませんか?


計算回数を増やす

ここまでの話は1回の運用を乱数で再現しただけなので、統計データとしては不十分です。そこで、計算回数を増やすことで、統計的に利用できるようにします。

特に根拠はありませんが、筆者作成のツールでは1万回の計算を行なっており、2回目以降の再計算を行なうためにVBAの出番となります。

計算の流れは、


  1. 最初に運用年数、リターン、リスク、積立額などをインプットする

  2. 計算開始する

  3. NORM.INV(RAND(),リターン,リスク)にて、1回の運用の計算を行なう

  4. VBAで必要なセルから必要なデータを別のセルにコピーする

  5. シートを再計算し、新たな乱数を与える

  6. 再び1回の運用計算を行なう(以後、4→5→6の繰り返し)

  7. 1万回計算を行なったら、1万個のデータから最小値・最大値・平均値・中央値などを取得する

  8. 終わり

です。

VBAで行なうことはデータのコピーと簡単な統計処理ぐらいなので、正直簡単です。実際構文自体もセルの読み込みのほか、For文ぐらいしか使っていません。

For i = 1 To 繰り返し回数

Worksheets("シート名").Calculate 'シートの再計算
Worksheets("シート名").Cells(セル書込位置, セル書込位置).Value = i
Worksheets("シート名").Cells(セル書込位置, セル書込位置).Value = Cells(セル読込位置, セル読込位置).Value
Next

Set Rng = Range(セルスタート位置, セル終了位置)

平均値:WorksheetFunction.Average(Rng)
最大値:WorksheetFunction.Max(Rng)
最少値:WorksheetFunction.Min(Rng)
中央値:WorksheetFunction.Median(Rng)

これで膨大なデータ群ができますので、あとは好きにデータ処理を行ないます。

20181117ab.png

ちなみに、2012年のCore i7マシンにて1万回の乱数計算を行なうと大体10秒ぐらいかかります。計算毎に画面の描画を伴うと時間の浪費に繋がるので、Application.ScreenUpdatingを使うことで高速化可能です。

Application.ScreenUpdating = False '画面に描画しない

Application.ScreenUpdating = True '画面に描画する


今後の課題

投資信託の運用成績は「対数正規分布」に近いとも言われます。

http://www.fund-no-umi.com/blog/2008/12/post-c019.html

このあたりも考慮した話も記事にしたいと思ってます(ファイル自体は作ったので、あとは記事ネタに使うだけ)