Let's solve the portfolio with continuous optimization
--There are 365 data for each of the three stocks (A, B, C). ――There is a correlation between each issue. ――The purchase price today is 99 yen. --Let's find a portfolio (percentage of stocks) that minimizes risk --Ignore fees.
Let's assume that 365 data are 365 scenarios. Suppose that when you sell a purchased brand, there are 365 possible selling prices. A common risk is variability, which makes it non-linear and difficult to solve. Here we consider maximizing the worst-case returns in the scenario.
First, create random number data.
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)
#Create data with random numbers
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])
On average, stock B is the highest, albeit slightly. Let's look at the correlation.
python3
plt.subplot(131)
plt.title('Correlation between stocks(A-B)')
plt.scatter(a[:, 0], a[:, 1])
plt.subplot(132)
plt.title('Correlation between stocks(A-C)')
plt.scatter(a[:, 0], a[:, 2])
plt.subplot(133)
plt.title('Correlation between stocks(B-C)')
plt.scatter(a[:, 1], a[:, 2]);
--A and B are positively correlated --A and C are negatively correlated --B and C are almost uncorrelated
Defines a function solve that solves an optimization problem. Checked separately, the maximum threshold (guaranteed value in the worst case) was 98.58. Let's see the result at that time.
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])
The first 1 represents the "optimal solution" and the next array represents the purchase rate of each stock.
Since B is high on average, let's look at the histograms for each scenario of the case where only B is purchased (maximum profit) and the case solved earlier (minimum maximum).
python3
plt.rcParams['figure.figsize'] = 6, 4
plt.title('Histogram of profits by purpose')
plt.hist(a.dot([0,1,0]), bins=12, range=(97, 103), alpha=0.5, label='Maximum profit')
plt.hist(a.dot(r[1]), bins=12, range=(97, 103), alpha=0.5, label='Minimum Maximum')
plt.legend();
It is possible to reduce the variation in price movements by combining the inversely correlated stocks rather than purchasing only one stock.
Even if you look at the graph, you can see that the width of the distribution is narrower in the "minimum maximum" case.
Let's also take a look at the portfolio when the threshold is changed.
python3
x = np.linspace(97, 98.58, 10)
y = np.array([solve(a, th)[1] for th in x])
plt.title('Percentage of changes in threshold')
plt.plot(x, y)
plt.legend(['A','B','C']);
On average, B is the best, so if you ignore the risks, only B is the best. At maximum risk assessment, A and C are inversely correlated, so it is better to combine A and C. As you can see, the percentage of B changes from 1 to 0.
that's all
Recommended Posts