かゆい所に手が届く積立シミュレーションをpythonで#3
積立シミュレーションで毎月の積立額を途中で1回変更するプログラムを前回完成させましたが、次はせっかくのプログラミングであるので、1回変更するだけ、というのは寂しいものがあります。
ganbaruengineer.hatenablog.com
そもそも積立というものは人それぞれのライフステージのもとに計画的に決めていくわけで、単身生活、夫婦2人暮らし、子ども家族、子どもの受験、などなど、例えば下図のようにライフステージは何回も何回も目まぐるしく変わります。そのステージに合わせて細かくシミュレーションしていくことで、将来の不安が軽減するというものです。
そこで、前回のプログラムをさらに拡張して「積立額変更1回」から「積立額の変更を任意のn回実施できる」シミュレーションにしたいと思います。
変数の設定
積立額、積立期間を複数(n回)実施することになるため、それらの変数を複数個設定する必要がありますが、何回やるかはその都度設定したいために、プログラムの中で何回変更するかをあらかじめ決めておくわけにはいきませんから、単独の変数ではなくリストに格納しようと思います。
変数 | 内容 | 型 |
---|---|---|
seed_money | 初期投資金額 | 整数型(int) |
amount_accum | 毎月の積立額 | リスト型 |
num_years | 積立年数 | リスト型 |
annual_rate | 年利 | 整数型(int) |
「毎月の積立額」「積立年数」を積立変更回数分の長さリストで作成し、2つのリストを同じ長さにすることで、変更回数と積立額、積立年数を同時に設定できます。
たとえば、毎月の積立額推移を(10万、5万、3万)として、それぞれの積立期間を(5年、10年、3年)としたとすると、以下のようにします。
amount_accum = [10, 5, 3] num_years = [5, 10, 3]
その時に、変更回数を「nth」として、
nth = len(amount_accum)
として計算できます。
積立額累積値のリスト化
n回変更した積立額の累積値(deposit)をあとでグラフにするために、リストに格納しておきます。
deposit = [0] for i in range(nth): deposit.append(deposit[i] + amount_accum[i]*12*num_years[i])
積立変更回数(n回)分のループ計算
今では単独の積立期間に対して、年数ごとのループ計算をしていましたが、それをさらにn回分分けてループ計算する必要があるので、ループを入れ子にしてn回分のループを回します。
for j in range(nth): for i in range(num_years[j]): asset_now = npf.fv(annual_rate/12/100, 12, -amount_accum[j], -asset_now) lst_total.append(int(asset_now)) lst_gain.append(lst_total[-1] - seed_money - deposit[j] - (i+1)*amount_accum[j]*12) lst_deposit.append(deposit[j]+(i+1)*amount_accum[j]*12)
まあ変更点はこれだけです、なんと第2回目のコードより短くなりました。プログラミングって感じがしますね。
例えば、初期投資100万円、毎月の積立額(10万、5万、3万)、積立年数(5年、10年、3年)、年利5%としたとすると、
変数 | 内容 | 数値 |
---|---|---|
seed_money | 初期投資金額 | 100 |
amount_accum | 毎月の積立額 | [10, 5, 3] |
num_years | 積立年数 | [5, 10, 3] |
annual_rate | 年利 | 5 |
で計算してみると、
ちゃんと計算できている感じですね。
全コード
import numpy as np import numpy_financial as npf import matplotlib.pyplot as plt def calc(seed_money, amount_accum, num_years, annual_rate=5): nth = len(amount_accum) asset_now = seed_money lst_seed = [seed_money]*(sum(num_years)+1) lst_gain = [0] lst_deposit = [0] lst_total = [seed_money] deposit = [0] for i in range(nth): deposit.append(deposit[i] + amount_accum[i]*12*num_years[i]) for j in range(nth): for i in range(num_years[j]): asset_now = npf.fv(annual_rate/12/100, 12, -amount_accum[j], -asset_now) lst_total.append(int(asset_now)) lst_gain.append(lst_total[-1] - seed_money - deposit[j] - (i+1)*amount_accum[j]*12) lst_deposit.append(deposit[j]+(i+1)*amount_accum[j]*12) t = [i for i in range(sum(num_years) + 1)] fig, ax = plt.subplots(figsize=(10,5)) ax.bar(t, lst_seed,label="initial investment") ax.bar(t, lst_deposit,bottom=lst_seed,label="amount of deposit") ax.bar(t,lst_gain,bottom=[i+j for i,j in zip(lst_seed,lst_deposit)],label="gain") text_y1 = [0.4 * i+seed_money for i in lst_deposit] text_y2 = [0.3 * j + i + seed_money for i,j in zip(lst_deposit,lst_gain)] for i in range(len(lst_deposit)): ax.text(t[i],seed_money*0.4,seed_money, ha="center",size=9) ax.text(t[i],text_y1[i],lst_deposit[i], ha="center", size=9) ax.text(t[i],text_y2[i],lst_gain[i], ha="center", size=9) ax.text(t[i],lst_total[i]+lst_total[-1]/50,lst_total[i],ha="center", size=10, color="k") plt.grid(axis='y') plt.xticks([i for i in range(sum(num_years)+1)]) plt.xlabel("Number of Years") plt.ylabel("Amount of money(10,000yen)") plt.legend() plt.show() annual_rate = 5 seed_money = 100 amount_accum = [10,5,3] num_years = [5,10,3] calc(seed_money, amount_accum, num_years, annual_rate)