7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

連続最適化でポートフォリオを解いてみよう

Last updated at Posted at 2016-06-03

はじめに

連続最適化でポートフォリオを解いてみよう

  • 3つの銘柄(A,B,C)に対し、それぞれ365個のデータがあります。
  • 各銘柄間には、相関があります。
  • 今日の購入価格は、どれも 99円とします。
  • リスクを最小にするポートフォリオ(銘柄の割合)を求めてみましょう
  • 手数料は無視します。

考え方

365個のデータを365個のシナリオとします。
購入した銘柄を販売するとき、365通りの販売価格になる可能性があるとします。
一般的なリスクは、ばらつきを見るのですが、そうすると非線形になり、解きづらくなります。
ここでは、シナリオの中の最悪ケースのリターンを最大化することを考えます。

Python で実行してみる。

まず、乱数データを作成します。

python3
%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が最も高いです。
相関を見てみましょう。

python3
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]);

image

  • A と B は正の相関
  • A と C は負の相関
  • B と C はほぼ相関なし

最適化問題を解く関数 solve を定義します。
別途確認して、しきい値(最悪ケースの保証値)の最大は、98.58でした。
そのときの結果を見てみましょう。

python3
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だけ購入するケース(収益最大)と、先ほど解いたケース(最小最大)のシナリオごとのヒストグラムを見てみましょう。

python3
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();

image

1銘柄だけ購入するより、逆相関の銘柄を組合せた方が、値動きのばらつきを抑えることができます。

グラフで見ても、"最小最大"ケースで分布の幅が小さくなっているのがわかります。

しきい値を変えた時の、ポートフォリオも見てみましょう。

python3
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']);

image

平均で見ると B が最もよいので、リスクを無視すれば B だけが最もよいです。
リスクを最大限に評価すると、AとCが逆相関なので、AとCを組合せる方がよいです。
このように、Bの割合が 1 から 0 まで変化しているのがわかります。

以上

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?