Commit b13506cf authored by Dr.李's avatar Dr.李

added mean variance builder

parent 5fa76dd3
# -*- coding: utf-8 -*-
"""
Created on 2017-6-27
@author: cheng.li
"""
import numpy as np
from typing import Union
from typing import Tuple
from cvxopt import matrix
from cvxopt import solvers
solvers.options['show_progress'] = False
def mean_variance_builder(er: np.ndarray,
cov: np.ndarray,
bm: np.ndarray,
lbound: Union[np.ndarray, float],
ubound: Union[np.ndarray, float],
risk_exposure: np.ndarray,
risk_target: Tuple[np.ndarray, np.ndarray]):
lbound = lbound - bm
ubound = ubound - bm
transposed_risk_exposure = risk_exposure.T
risk_target = risk_target - transposed_risk_exposure @ bm
# set up problem for net position
n = len(er)
P = matrix(cov)
q = -matrix(er)
G1 = np.zeros((2*n, n))
h1 = np.zeros(2*n)
for i in range(n):
G1[i, i] = 1.
h1[i] = ubound[i]
G1[i+n, i] = -1.
h1[i+n] = -lbound[i]
m = len(transposed_risk_exposure)
G2 = np.concatenate([transposed_risk_exposure, -transposed_risk_exposure])
h2 = np.zeros(2*m)
for i in range(m):
h2[i] = risk_target[1][i]
h2[i+m] = -risk_target[0][i]
G = matrix(np.concatenate([G1, G2]))
h = matrix(np.concatenate([h1, h2]))
sol = solvers.qp(P, q, G, h)
return sol['status'], sol['dual objective'], np.array(sol['x']).flatten() + bm
# -*- coding: utf-8 -*-
"""
Created on 2017-6-27
@author: cheng.li
"""
import unittest
import numpy as np
from alphamind.portfolio.meanvariancebuilder import mean_variance_builder
class TestMeanVarianceBuild(unittest.TestCase):
def test_mean_variance_builder(self):
er = np.random.randint(0, 10, size=3) / 10.
cov = np.array([[0.04, 0.01, 0.02],
[0.01, 0.05, 0.03],
[0.02, 0.03, 0.06]])
ids_var = np.diag(np.random.randint(2, 5, size=3) / 100.)
cov += ids_var
bm = np.array([0.3, 0.3, 0.4])
lbound = np.array([0., 0., 0.])
ubound = np.array([0.4, 0.4, 0.5])
risk_exposure = np.array([[1., 1., 1.],
[1., 0., 1.]]).T
risk_target = (np.array([bm.sum(), 0.3]), np.array([bm.sum(), 0.7]))
status, value, x = mean_variance_builder(er, cov, bm, lbound, ubound, risk_exposure, risk_target)
self.assertTrue(status == 'optimal')
self.assertAlmostEqual(x.sum(), bm.sum())
self.assertTrue(np.all(x <= ubound + 1.e-6))
self.assertTrue(np.all(x >= lbound) - 1.e-6)
self.assertTrue(np.all(x @ risk_exposure <= risk_target[1] + 1.e-6))
self.assertTrue(np.all(x @ risk_exposure >= risk_target[0] - 1.e-6))
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment