はじめに
連続最適化でポートフォリオを解いてみよう
- 3つの銘柄(A,B,C)に対し、それぞれ365個のデータがあります。
- 各銘柄間には、相関があります。
- 今日の購入価格は、どれも 99円とします。
- リスクを最小にするポートフォリオ(銘柄の割合)を求めてみましょう
- 手数料は無視します。
考え方
365個のデータを365個のシナリオとします。
購入した銘柄を販売するとき、365通りの販売価格になる可能性があるとします。
一般的なリスクは、ばらつきを見るのですが、そうすると非線形になり、解きづらくなります。
ここでは、シナリオの中の最悪ケースのリターンを最大化することを考えます。
Python で実行してみる。
まず、乱数データを作成します。
%matplotlib inline
import numpy as np, matplotlib.pyplot as plt
from pulp import *
from ortoolpy import addvars
plt.rcParams['figure.figsize'] = 16, 4
plt.rcParams['font.family'] = 'IPAexGothic'
N = 365
np.random.seed(1)
# 乱数でデータ作成
a = np.random.multivariate_normal([100, 100, 100],
[[1, 0.5, -0.5],[0.5, 1, 0.2], [-0.5, -0.1, 1]], N)
a.mean(axis=0)
>>>
array([ 99.99327092, 100.06971451, 100.03864796])
平均を見ると、わずかですが、銘柄 Bが最も高いです。
相関を見てみましょう。
plt.subplot(131)
plt.title('銘柄間の相関(A-B)')
plt.scatter(a[:, 0], a[:, 1])
plt.subplot(132)
plt.title('銘柄間の相関(A-C)')
plt.scatter(a[:, 0], a[:, 2])
plt.subplot(133)
plt.title('銘柄間の相関(B-C)')
plt.scatter(a[:, 1], a[:, 2]);
- A と B は正の相関
- A と C は負の相関
- B と C はほぼ相関なし
最適化問題を解く関数 solve を定義します。
別途確認して、しきい値(最悪ケースの保証値)の最大は、98.58でした。
そのときの結果を見てみましょう。
def solve(a, th):
m = LpProblem()
x = addvars(3)
m += lpSum(x) == 1
for e in a * np.array(x):
m += lpSum(e) >= th
m.solve()
return m.status, [value(i) for i in x]
r = solve(a, 98.58)
r
>>>
(1, [0.4815265, 0.00026221562, 0.51821129])
最初の1は"最適解であること"を、次の配列は各銘柄の購入割合を表しています。
平均は B が高いので、Bだけ購入するケース(収益最大)と、先ほど解いたケース(最小最大)のシナリオごとのヒストグラムを見てみましょう。
plt.rcParams['figure.figsize'] = 6, 4
plt.title('目的別の利益のヒストグラム')
plt.hist(a.dot([0,1,0]), bins=12, range=(97, 103), alpha=0.5, label='収益最大')
plt.hist(a.dot(r[1]), bins=12, range=(97, 103), alpha=0.5, label='最小最大')
plt.legend();
1銘柄だけ購入するより、逆相関の銘柄を組合せた方が、値動きのばらつきを抑えることができます。
グラフで見ても、"最小最大"ケースで分布の幅が小さくなっているのがわかります。
しきい値を変えた時の、ポートフォリオも見てみましょう。
x = np.linspace(97, 98.58, 10)
y = np.array([solve(a, th)[1] for th in x])
plt.title('しきい値の変化に対する割合')
plt.plot(x, y)
plt.legend(['A','B','C']);
平均で見ると B が最もよいので、リスクを無視すれば B だけが最もよいです。
リスクを最大限に評価すると、AとCが逆相関なので、AとCを組合せる方がよいです。
このように、Bの割合が 1 から 0 まで変化しているのがわかります。
以上