ものすごく適当。
import numpy as np import math import statistics import collections # --------------------------------------------- def monte_carlo(years, num_tries, weight, rnd): result = collections.defaultdict(list) # {year:[interest]} rc = 0 for i in range(num_tries): fukuri = 1.0 for j in range(years): fukuri *= rnd[rc] result[j].append(fukuri) rc += 1 for i in range(years): result[i] = [x * weight for x in result[i]] return result def sum_result(years, r1, r2, r3, r4, r5): tot_result = {} for i in range(years): z = zip(r1[i], r2[i], r3[i], r4[i], r5[i]) tot_result[i] = [sum(x) for x in z] return tot_result # --------------------------------------------- # 2020 https://am.jpmorgan.com/content/dam/jpm-am-aem/asiapacific/jp/ja/insights/portfolio-insights/2020-ltcma-matrix-jpy.pdf # 日本国債 0.30 2.02 # 先進国国債 0.80 6.72 (-0.09) # 日本大型株式 5.50 18.10 (-0.34, 0.59) # 世界株式 4.80 19.12 (-0.33, 0.69, 0.86) # 新興国株式 7.50 23.11 (-0.29, 0.60, 0.74, 0.87) # 2022 https://am.jpmorgan.com/content/dam/jpm-am-aem/asiapacific/jp/ja/insights/portfolio-insights/2022-ltcma-matrix-jpy.pdf # 日本国債 0.70 2.14 # 先進国国債 0.60 6.26 (-0.05) # 日本大型株式 5.00 17.95 (-0.34, 0.59) # 世界株式 3.3 19.24 (-0.29, 0.66, 0.85) # 新興国株式 5.20 22.65 (-0.25, 0.58, 0.75, 0.90) years = 20 num_tries = 10000 # バランス(2020年データ) 注:相関係数変更すること # ret = [0.003, 0.008, 0.055, 0.048, 0.075] # risk = [0.0202, 0.0672, 0.181, 0.1912, 0.2311] # weight = [0.2, 0.2, 0.2, 0.2, 0.2] # 5%-20%での計算 ret = [0.05, 0.006, 0.05, 0.031, 0.052] risk = [0.20, 0.0626, 0.1795, 0.1917, 0.2265] weight = [1.0, 0.0, 0.0, 0.0, 0.0] # 日本国債+5%-20% ret = [0.007, 0.006, 0.05, 0.05, 0.052] risk = [0.0214, 0.0626, 0.1795, 0.20, 0.2265] weight = [0.5, 0.0, 0.0, 0.5, 0.0] # 世界株に全投資 # ret = [0.007, 0.006, 0.05, 0.033, 0.052] # risk = [0.0214, 0.0626, 0.1795, 0.1924, 0.2265] # weight = [0.0, 0.0, 0.0, 1.0, 0.0] # 5等分バランス # ret = [0.007, 0.006, 0.05, 0.031, 0.052] # risk = [0.0214, 0.0626, 0.1795, 0.1917, 0.2265] # weight = [0.2, 0.2, 0.2, 0.2, 0.2] # 日本国債+世界株 # ret = [0.007, 0.006, 0.05, 0.033, 0.052] # risk = [0.0214, 0.0626, 0.1795, 0.1924, 0.2265] # weight = [0.5, 0.0, 0.0, 0.5, 0.0] # 貯金+世界株 # ret = [0.000, 0.006, 0.05, 0.031, 0.052] # risk = [0.0, 0.0626, 0.1795, 0.1917, 0.2265] # weight = [0.3, 0.0, 0.0, 0.7, 0.0] r = collections.defaultdict(dict) r[2][1] = -0.05 r[3][1],r[3][2] = -0.34, 0.59 r[4][1],r[4][2],r[4][3] = -0.29, 0.66, 0.85 r[5][1],r[5][2],r[5][3],r[5][4] = -0.25, 0.58, 0.75, 0.90 # --------------------------------------------- dim = len(weight) cov = [ [ 1.0, r[2][1], r[3][1], r[4][1], r[5][1]], [r[2][1], 1.0, r[3][2], r[4][2], r[5][2]], [r[3][1], r[3][2], 1.0, r[4][3], r[5][3]], [r[4][1], r[4][2], r[4][3], 1.0, r[5][4]], [r[5][1], r[5][2], r[5][3], r[5][4], 1.0], ] v = np.random.multivariate_normal([0.0] * dim, cov, years * num_tries) r = [] for i in range(dim): rr = v[:,i] rr *= risk[i] rr += (1.0 + ret[i]) r.append(list(rr)) r1 = monte_carlo(years, num_tries, weight[0], r[0]) r2 = monte_carlo(years, num_tries, weight[1], r[1]) r3 = monte_carlo(years, num_tries, weight[2], r[2]) r4 = monte_carlo(years, num_tries, weight[3], r[3]) r5 = monte_carlo(years, num_tries, weight[4], r[4]) result = sum_result(years, r1, r2, r3, r4, r5) for year in range(years): for j in range(10): print(year, '%04f' % result[year][j], end='') print() print() print() print('year chuuou <50% <75% <100% stddev mean') for i in range(years): yresult = result[i] yresult.sort() print(i + 1, yresult[int(num_tries / 2)], len([x for x in yresult if x < 0.5]) / num_tries, len([x for x in yresult if x < 0.75]) / num_tries, len([x for x in yresult if x < 1.0]) / num_tries, statistics.stdev(yresult), statistics.mean(yresult)) # print(np.corrcoef(r[0], r[1])) # print(statistics.mean(r4[0]), statistics.stdev(r4[0]))