chottoshitahanashi’s diary

基本的に間違ったことばかり書いてるブログ。検索ひっかかるな

シミュレーションソースコード

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

# ---------------------------------------------

# リターン、リスク、相関係数

years = 30
num_tries = 10000
r = collections.defaultdict(dict)

# ============= 2020年 ============
# 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)

# バランス(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]

# 相関係数
# r[2][1]                         = -0.09
# r[3][1],r[3][2]                 = -0.34, 0.59
# r[4][1],r[4][2],r[4][3]         = -0.33, 0.69, 0.86
# r[5][1],r[5][2],r[5][3],r[5][4] = -0.29, 0.60, 0.74, 0.87

# ============= 2022年 ============
# 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)

# 5%-20%での計算(jpmorganのデータを使っていない)
# 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%(jpmorganのデータは日本国債のみ使っている)
# 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.033, 0.052]
# risk = [0.0214, 0.0626, 0.1795, 0.1924, 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[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

# ============= 2023年 ============
# 2023 https://am.jpmorgan.com/content/dam/jpm-am-aem/asiapacific/jp/ja/insights/portfolio-insights/ltcma/2023/matrix-jpy.pdf
# 日本国債 0.70 2.33
# 先進国国債 1.8 6.21 (-0.04)
# 日本大型株式 7.8 17.47  (-0.22, 0.54)
# 世界株式 5.9 19.11 (-0.17, 0.64, 0.85)
# 新興国株式 7.5  21.89 (-0.18, 0.57, 0.74, 0.89)

# 日本国債3000万(リスク0)+世界株1000万+貯金1000万
ret = [0.007, 0.018, 0.078, 0.059, 0.0]
risk = [0.0, 0.0621, 0.1747, 0.1911, 0.0]
weight = [0.6, 0.0, 0.0, 0.2, 0.2]

# 世界株のみ
# ret = [0.007, 0.018, 0.078, 0.05, 0.075]
# risk = [0.0233, 0.0621, 0.1747, 0.2, 0.2189]
# weight = [0.0, 0.0, 0.0, 1.0, 0.0]

# 相関係数
r[2][1]                         = -0.04
r[3][1],r[3][2]                 = -0.22, 0.54
r[4][1],r[4][2],r[4][3]         = -0.17, 0.64, 0.85
r[5][1],r[5][2],r[5][3],r[5][4] = -0.00, 0.00, 0.00, 0.00

# ---------------------------------------------

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)


# -------------------------------------

print('10 samples')
for year in range(years):
    for j in range(10):
           print(year, '%04f' % result[year][j], end='')
    print()

print()
print()

# -------------------------------------

for i in range(years):
       yresult = result[i]
       yresult.sort()

print('wariai', end=' ')
for i in range(19, years, 5):
       print(i + 1, end=' ')
print()

start, end, step = 0.75, 1.501, 0.05
for j in np.arange(start, end, step):
       print('{:.0f}%~{:.0f}%'.format((j - step) * 100, j * 100), end=' ')
       for i in range(19, years, 5):
              yresult = result[i]
              value = len([x for x in yresult if x < j and x > j - step]) / num_tries
              print(value, 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]))