過去20年のデータから長期投資の配分を考えてみる

投資について

  • 長期なほど複利で資産を増やしやすい
  • リターンを求めるほどリスクがある(短期的な変動が大きい)

動機

  • できるだけリスクの低くて収益が大きいような資産配分を調べたい
  • 投資の勉強をしていると、株だけでなく債券や金にも分散する必要性を多くの所で目にしたが、具体的にどんな効果があるのか確かめたかったから。

やったこと

  • 過去20年間のETF価格データを取得して、毎日一定額積み立てした場合のシュミレーション

  • 代表的な商品にどう配分したら、効率の良い投資ができるか探索する

  • 一目でわかりやすく、視覚化

使ったデータ

yahoo finance のETF価格データ

pythonで、datareadearライブラリを使って、データをダウンロードする

#描画ライブラリ
import matplotlib.pyplot as plt 
#データのダウンロードライブラリ
import pandas_datareader.data as web 

# US S&P500 index
spy = web.DataReader("SPY","yahoo","1980/1/1").dropna()

#iShares 1-3 Year Treasury Bond Fund (SHY)
shy = web.DataReader("shy","yahoo","1980/1/1").dropna()

#iShares 20+ Year Treasury Bond Fund (TLT)
tlt = web.DataReader("TLT","yahoo","1980/1/1").dropna()

# gold price
gold = web.DataReader("GLD","yahoo","1980/1/1").dropna()

ETFとは?

日本語で上場投資信託

簡単に言うと株式などの詰め合わせ商品で、株と同じように毎日売買できる。

株の場合だと、ある会社が倒産したとしても、全体の割合からすると小さいので、個別株投資よりは倒産による資産価値を減らすリスクを軽減できる。

今回使う商品(4つ)

SPY(株式) 

米国の上位企業の株式に分散して投資する代表的な商品

よくS&P500(指数)と呼ばれる大企業の時価総額加重平均の株価に連動している。

例えば、アップルやアマゾンなどの世界的企業なら5パーセント程度の割合で入っている。

f:id:ms55:20200722041124p:plain
SPY

詳細な割合:SPY 銘柄 - SPDR S&P500 ETF 投資信託(ファンド)情報 - Bloomberg Markets

TLT,SHY(債券)

米国債を所有する商品

直接国債を買うのと違い、元本保証でないが、いつでも売り買いできる

  • TLT 長期(20年)債
    f:id:ms55:20200722041206p:plain
    TLT
  • SHY 短期(1~3年)債
    f:id:ms55:20200722041225p:plain
    SHY
GLD(金)

金価格に連動する商品

f:id:ms55:20200722041238p:plain
GLD

単一商品に積み立てした場合の下落率を可視化

基本となるコード

day_amount = 10 # 1日の積み立て価格($)
unit_sum = [0] # ETFの購入単位数
valuation = [0] # 評価額

# 日数ループ
for i in range(1, len(spy['Adj Close'])):
    unit_sum.append(unit_sum[i-1] + day_amount / spy['Adj Close'][i])
    valuation.append(unit_sum[i]*spy['Adj Close'][i])

max_valuation = valuation.copy() # それまでの評価額の最大値
drop_portion = [0] # 評価額最大値から現在評価額の下落率

#下落率計算
for i in range(1,len(max_valuation)):
    if(max_valuation[i-1] > valuation[i]):
        max_valuation[i] = max_valuation[i-1]
    
    drop_portion.append( valuation[i]/max_valuation[i] - 1.0 )

#下落率を可視化
plt.xlabel("day(1993-2020)")
plt.ylabel("max drop rate")
plt.ylim([-0.6,0])
plt.plot(spy.index, drop_portion)

SPY

f:id:ms55:20200722052546p:plain

TLT

f:id:ms55:20200722053232p:plain

SHY

f:id:ms55:20200722053256p:plain

GLD

f:id:ms55:20200722053430p:plain

複数商品に配分した場合を各商品の割合で全探索

例えばSPY5割,、TLT2割,、SHY1割、GLD1割のように、それぞれを一定割合積み立てていった場合の最終リターンと最大下落率をすべての組み合わせについて調べることで、最大下落率が小さくて最終リターンが大きいような組み合わせを見つけたい。

疑似コード

#1つの組み合わせについて
def calc(割合: SPY, TLT, SHY, GLD)
  積み立て計算をする
  return 最終リターン, 最大下落率

# 4重for文ですべての組み合わせを調べる
for i in 10:
  for j in 10:
    for k in 10:
      for l in 10:
        calc(i, j, k, l)

実際のコード

calc関数

def calc_risc_return(stk_per, tlt_per, shy_per, gld_per):
    if(stk_per + tlt_per + shy_per + gld_per != 10):
        raise Exception('Error!')
        
    stk_unit_sum = [0]
    tlt_unit_sum = [0]
    shy_unit_sum = [0]
    gld_unit_sum = [0]
    
    all_valuation = [0]
    all_max_valuation = []
    risk_arr = [0]
    max_risk = 0.0
    
    for i in range(1, len(spy2004['Adj Close'])-1):
 
        stk_unit_sum.append(stk_unit_sum[i-1] + stk_per / spy2004['Adj Close'][i])
        tlt_unit_sum.append(tlt_unit_sum[i-1] + tlt_per / tlt2004['Adj Close'][i])
        shy_unit_sum.append(shy_unit_sum[i-1] + shy_per / shy2004['Adj Close'][i])
        gld_unit_sum.append(gld_unit_sum[i-1] + gld_per / gold2004['Adj Close'][i])

        all_valuation.append(
            stk_unit_sum[i]*spy2004['Adj Close'][i]
            + tlt_unit_sum[i]*tlt2004['Adj Close'][i]
            + shy_unit_sum[i]*shy2004['Adj Close'][i]
            + gld_unit_sum[i]*gold2004['Adj Close'][i]
        ) 
    
    all_max_valuation = all_valuation.copy()
    
    for i in range(1,len(all_max_valuation)):
        if(all_max_valuation[i-1] > all_valuation[i]):
            all_max_valuation[i] = all_max_valuation[i-1]
    
        risk_arr.append( all_valuation[i]/all_max_valuation[i] - 1.0 )
        
        if(risk_arr[i] < max_risk):
            max_risk = risk_arr[i]
        
    return all_valuation[-1], max_risk

すべての組み合わせを4重for文で探索

search_risk = []
search_return = []

for i in range(11):
    for j in range(11-i):
        for k in range(11-(i+j)):
            for l in range(11-(i+j+k)):
                if(i+j+k+l == 10):
                    a, b = calc_risc_return(i,j,k,l)
                    search_risk.append(a)
                    search_return.append(b)

plt.figure(figsize=(7, 5), dpi= 80)
plt.xlabel("max drop rate")
plt.ylabel("final return ($)")
plt.scatter(search_return, search_risk)
plt.grid(True)

結果

f:id:ms55:20200722062741p:plain

  • リターンの高さと最大下落率の大きさに相関がある(当たり前)
  • 同じ最終リターンでも最大下落率に幅がある

考察

投資方針によって、どれくらいリスクをとれるか(どれくらい最大下落率を許容する)は変わるけれども、最大下落率が小さく最終リターンが大きい組み合わせを探すことを考えたとき、一番わかりやすいのは右上に近い点がベストな配分なのではないかと考えた。

グラフ右上の組み合わせを抽出してみると、

// [SPY, TLT, SHY, GLD, final_return, max_risk]
[[3, 6, 0, 1, 81449.76178630826, -0.1525325785995323],
[3, 7, 0, 0, 82413.47054056039, -0.15292410750767071],
[4, 4, 0, 2, 82262.62077868429, -0.16477325138334542],
[4, 5, 0, 1, 83226.32953293648, -0.15875836775653995],
[4, 6, 0, 0, 84190.03828718874, -0.15903440158006432]]

これよりグラフ右上に近い組み合わせ群には、

  • SPYとTLTの割合が同じか、TLTが少し多いくらい
  • GLDは0~2割の少ない割合
  • SHYは0

という共通点があることがわかった。

例として、この中の一つと株式10割の場合の最大下落率を比較してみると、

f:id:ms55:20200722065245p:plain

特に、株式の大きい暴落の時に下落が抑えられていることがわかる。

なぜこのようなことが実現できるかというと、一般的なセオリーとして、景気後退など株式の価値が下がりそうな時には株が売られ、債券が買われることにある。

したがって、株の下落局面で債券を持っておくことで、全体のその時点での評価損失が相殺される可能性がある。

また、なぜ株の割合が少なくても、最終リターンが大きく増えるかというと、長期的には株が債券に対して圧倒的に上昇するからである。

まとめ

株式と債券に分散して持っておくことで、株式の暴落局面での大きな下落を抑えらえるということが視覚的にわかった。

なぜ長期債のほうが短期債よりも必要なのかや、金関連の商品にも分散させる意義があるかはさらに調べてみる必要がある。

注意

当たり前だが、過去20年の結果と将来20年の結果は大きく違う可能性がある。

これらETFはドル建て計算なので、日本円で決済し、日本に住んで資産運用を行う場合は、ドル/円を考えないといけないが、今回は単純化のためにそれを省いた。

米国に関する商品を選んでいるのは、個別企業を見たら良い悪いあるけれども、経済全体でみると過去30年は米国が安定的に成長している一方で、日本は全く成長できていないため、日経平均TOPIXは投資対象として魅力的ではない。

もっと大きい期間(100年)でみると、両者の株価のパフォーマンスに現在ほどの差はない(1~2パーセント程度)らしい。

途中に超長期の国別投資リターンの分かりやすい図がある。 「全世界株式」を推奨する3つの理由 1900年当時と現在の「国別時価総額」をシェアします。 | マネーの達人

実際に投資で生かすとしたら

上の例の一部を視覚化する。

f:id:ms55:20200722054924p:plain

このような配分をするのにおすすめなのは次のような人が挙げられる。

  • 一時的な暴落リスク許容度が低い人(高齢など)
  • もうある程度まとまった資産(数千万~, 数億~)がある人

(長期的には株のほうが成長するので、若いうちは株式の割合を高めにしてできるだけ資産を増やし、徐々に債券などの安全資産に移動していくのがいいのではないかと、自分は考えている。)

参考

Yahoo Finance USから株価をダウンロードしてみた - Qiita

pandas-datareader — pandas-datareader 0.9.0rc1+2.g427f658 documentation

TODO: アトピー性皮膚炎の情報まとめる

皮膚の水分量

  • アトピー患者は健常者に比べ、皮膚に保持される水分が少ないので、乾燥しやすい。

=> 保湿の必要性

アトピー性皮膚炎患者の皮膚水分率と住環境 | アレルギーの病気について | アレルギー支援ネットワーク

 成人アトピー性皮膚炎患者95名と成人健常者46名の皮膚水分率を比較した結果、患者では水分率が有意に低いことが示された。

 蒸留水を1滴前腕に滴下し、10秒後に拭き取り、30秒毎に皮膚水分率を測定した。その結果、患者では滴下直後およびその後の水分率が有意に低かった。

黄色ブドウ球菌

=> 皮膚を清潔に保つことの必要性

https://www.keio.ac.jp/ja/press_release/2015/osa3qr000000t3i7-att/20150422_nagao.pdf

今回本研究グループは、アトピー性皮膚炎のマウスを作成し、そこで見られる皮膚炎は黄色ブドウ球菌を含む異常細菌巣に起因していることを解明しました。

アトピー性皮膚炎における黄色ブドウ球菌―皮疹部,無疹部における黄ブ菌検出率,ファージ型および薬剤感受性について―

https://www.jstage.jst.go.jp/article/iryo1946/54/2/54_2_62/_article/-char/ja/

黄色ブドウ球菌を抑制・除去するためには、消毒剤や石鹸などが考えるが、肌へのダメージとトレードオフ

当たり前だが、入浴や清潔な服に着替えることが大事。

医師の間で広まる「洗いすぎない」スキンケア術|ヘルスUP|NIKKEI STYLE

ヒトの皮膚は通常、皮膚常在菌により皮脂が「パルミチン酸」や「ステアリン酸」に分解されて弱酸性に保たれている。このため、食中毒や皮膚感染症の原因となる黄色ブドウ球菌や化膿レンサ球菌は、そもそも増殖しにくい環境となっている。

界面活性剤を用いて過剰に皮膚を洗ってしまうと、保湿に必要な皮脂や皮膚常在菌までもが落ちてしまう

お湯だけの洗浄で皮膚症状が改善

ステロイド外用剤の使用

ほとんどのステロイド外用剤は年齢を問わずプラセボよりも効果的

ステロイド外用療法 結果

ステロイドが皮膚に与える副作用には、皮膚萎縮、皮膚線条、紫斑、多毛

Q9 ステロイド長期服用患者の皮膚の菲薄化、どうケアする? : Part3 ハイリスク・スキントラブルへの対処 | アルメディアWEB

同一箇所に毎日、長期に渡って使用する結果に陥ってしまうと、局所的副作用が起こりやすい

薬局でよく聞く!ステロイド外用剤の誤解|田辺三菱製薬|ヒフノコトサイト

汗との関係

健常者に比し軸索反射性発汗量の有意な減少と,発汗に要する時間の有意な延長が皮疹の有無に関わらず認められた

アトピー性皮膚炎における発汗異常の実態:バリア機能への影響を考える

かゆみ

CSVパース

Python

普通にcsv or pandasライブラリを使う

使わない場合

import sys

def main(argv):

    f = open(argv[1])
    line = f.readline()

    content = []

    cols = 0
    while line:
        vec = line.replace('\n', '').split(',')
        content.append(vec)
        line = f.readline()
        cols += 1

    f.close()

if __name__ == '__main__':
    main(sys.argv[1:])

二次元配列で各要素にアクセスできる

C++

std::getlineで文字区切り - Nyampusノートブック「情報技術」

CTF進捗(19/12/13)

cpawCTF

f:id:ms55:20191213221428p:plain f:id:ms55:20191213221517p:plain

picoCTF

f:id:ms55:20191213221620p:plain

これまでに使った知識

  • Linuxコマンド(特に、nc, strings, file)
  • 暗号(特に古典暗号)
  • Atcoder B問題レベルのプログラミング
  • pcap(パケットキャプチャ)ファイルの見方
  • Webサイトの検証(HTML, JavaScript, SQL, ルーティング)
  • ソフトを使ってファイルのバイナリ解析

Atcoderのレーティングが下がり続けても参加し続けられる論理補強

精進を続けても、コンテストで結果を出せない。。。

f:id:ms55:20191209190608p:plain f:id:ms55:20191209191034p:plain

レートを上げることが目的だと、ライバルとの差が広がった時にメンタルがやられる

参加すること自体を目的化する

競プロ用テストケースジェネレータを作った

masa5555.github.io

 

基本的な機能は、サイズと形式をで指定して、テストケース生成と同時にクリップボードへのコピーを行う。

使用した技術は、jQueryでDOM操作?(クラス操作や値取得)をすること

まだ、数列しかつくれないので、他のパターンも追加していきたい