積立投資で売却せず最適なリバランスを目指すツール公開 - pythonで解く制約付き最小二乗問題
はじめに
積立投資している投資信託のリバランスをしたいけど、売却はしたくない。
合計購入金額はいつもと同じにしたい。そんな悩みを抱えていませんか?
ここで紹介するツールを使うと、最適な構成になる購入金額が分かります。
↓ツールはこちらです↓
colab.research.google.com
目次
1, 使用前の留意
当ツールでは、資産クラス別の目標構成比に最も近づけることを目標とします。
ツールに合計購入金額や最低購入金額を設定し制約条件とすることで、
目標構成比と完全一致はしないものの、最適な構成を目指してリバランスします。
2, 使い方
2-1, 設定
下図にあるように、以下4つを設定してください。
1, 次回予定している合計購入金額
2, 1資産クラスあたりの最低購入金額
3, 各資産クラス別の目標構成比(%) ... 合計100%になるように
4, 現在運用している資産の時価総額
※ 上図の資産クラスを運用していない場合、レコードを削除するか、目標構成比(%)と運用時価総額をゼロにしてください。
※ 逆に資産クラスを増やしたい場合、レコードを追加してください。
2-2, 実行
ツール上部のメニューバーにある「ランタイム」から「すべてのセルを実行」を押してください。
2-3, 結果確認
ツール最下方セルの可視化データにおける列「リバランス新規購入」を参照してください。
以上です!
お読み頂きありがとうございました。ただ、裏側のロジックが気になる場合、以下もお読みください。
3, 詳細
3-1, 用いるパッケージ
当ツールではcvxpyというpython packageを利用しています。
これは、凸最適化問題を解くための Python 製モデリングツールであり、
ソルバーとしてECOS, OSQP, SCSなるものを用いているそうです。
以下が公式ドキュメントになります。
www.cvxpy.org
3-2, 変数設定
資産クラス別の新規購入金額を変数とします。資産の数だけ準備します。
x = cvxpy.Variable(len(df))
この1文で、1行8列の型をもつ変数xを定義できます。お手軽ですね。
3-3, 目的関数
資産クラス別の目標構成比と、新規購入後の時価構成比の二乗誤差の最小化を目的関数とします。
market_cap = np.array(df["時価総額"]) object_ratio = np.array(df["目標構成比(%)"]) objective = cvxpy.sum_squares(100*(market_cap + x)/(sum(market_cap)+NEW_PURCHASE) - object_ratio) * 0.5
資産クラス別の新規購入金額を示す変数xは未知ですが、上記3行目のように値が入っている
定義済みの変数のように数式に挿入可能です。これで目的関数objectiveを定義できました。
3-4, 制約関数
合計新規購入金額と、1資産クラスあたりの最低新規購入金額を制約関数とします。
constraints = [cvxpy.sum(x)==NEW_PURCHASE, x>=MIN_PURCHASE]
この1文で、複数の制約を持つ関数constraintsを定義できます。またもお手軽ですね。
※ 蛇足 ... 最低新規購入金額をマイナスに設定すれば、1資産クラスあたり最大その金額まで売却可能になりますが、
売却資産がある場合は合計新規購入金額が売却額の分だけ増加するので注意してください。
3-5, 結果の見方
cvxpyによって得られた変数xの最適解は、下図のカラム「リバランス新規購入」になります。
例えば「目標構成比(%)」に対して大きなプラスの「構成比差分(%)」が見られた [先進国株式] は、
「リバランス新規購入」が1資産あたりの最低購入金額に抑えられた一方、マイナスの差分が
見られた [先進国リート] は最大の新規購入金額が設定されています。
3-6, 結果の解釈
リバランス前後で資産クラス別の目標構成比と時価構成比が、どう変化したのか確認しましょう。
すると、いずれの指標の誤差も小さくなっていることが分かります。嬉しいですね。
おわりに
積み立てている投資信託のリバランスを現実的に最適に行う方法を紹介しました。
世に出回るツールでは、目標構成比を達成するため売却したり大金を投じたりする必要に迫られますが、
当ツールでは「ノーセル・ノーマル・リバランス」ができます。ご利用・活用頂けると幸いです。