Commit 2161714e authored by wegamekinglc's avatar wegamekinglc

update builder

parent a762b081
......@@ -92,7 +92,7 @@ def linear_builder(er: np.ndarray,
from cvxpy import Problem
from cvxpy import Variable
from cvxpy import multiply
from cvxpy import pnorm
from cvxpy import norm1
from cvxpy import Minimize
w = Variable(n)
......@@ -102,13 +102,13 @@ def linear_builder(er: np.ndarray,
w <= ubound,
current_risk_exposure >= risk_lbound.flatten(),
current_risk_exposure <= risk_ubound.flatten(),
pnorm(w - current_position, 1) <= turn_over_target]
norm1(w - current_position) <= turn_over_target]
objective = Minimize(-w.T * er)
prob = Problem(objective, constraints)
prob.solve(solver='ECOS', feastol=1e-10, abstol=1e-10, reltol=1e-10)
prob.solve(solver='ECOS', feastol=1e-9, abstol=1e-9, reltol=1e-9)
if prob.status == 'optimal':
if prob.status == 'optimal' or prob.status == 'optimal_inaccurate':
return prob.status, prob.value, w.value.flatten()
else:
raise PortfolioBuilderException(prob.status)
......
......@@ -10,6 +10,7 @@ from typing import Union
from typing import Tuple
from typing import Optional
from typing import Dict
import cvxpy
from alphamind.cython.optimizers import QPOptimizer
from alphamind.cython.optimizers import CVOptimizer
from alphamind.exceptions.exceptions import PortfolioBuilderException
......@@ -54,19 +55,41 @@ def mean_variance_builder(er: np.ndarray,
lam: float=1.) -> Tuple[str, float, np.ndarray]:
lbound, ubound, cons_mat, clbound, cubound = _create_bounds(lbound, ubound, bm, risk_exposure, risk_target)
optimizer = QPOptimizer(er,
risk_model['cov'],
lbound,
ubound,
cons_mat,
clbound,
cubound,
lam,
risk_model['factor_cov'],
risk_model['factor_loading'],
risk_model['idsync'])
return _create_result(optimizer, bm)
if np.all(lbound == -np.inf) and np.all(ubound == np.inf) and cons_mat is None:
# using fast path cvxpy
n = len(er)
w = cvxpy.Variable(n)
cov = risk_model['cov']
special_risk = risk_model['idsync']
risk_cov = risk_model['factor_cov']
risk_exposure = risk_model['factor_loading']
if cov is None:
risk = cvxpy.sum_squares(cvxpy.multiply(cvxpy.sqrt(special_risk), w)) \
+ cvxpy.quad_form((w.T * risk_exposure).T, risk_cov)
else:
risk = cvxpy.quad_form(w, cov)
objective = cvxpy.Minimize(-w.T * er + 0.5 * lam * risk)
prob = cvxpy.Problem(objective)
prob.solve(solver='ECOS', feastol=1e-9, abstol=1e-9, reltol=1e-9)
if prob.status == 'optimal' or prob.status == 'optimal_inaccurate':
return 'optimal', prob.value, np.array(w.value) + bm
else:
raise PortfolioBuilderException(prob.status)
else:
optimizer = QPOptimizer(er,
risk_model['cov'],
lbound,
ubound,
cons_mat,
clbound,
cubound,
lam,
risk_model['factor_cov'],
risk_model['factor_loading'],
risk_model['idsync'])
return _create_result(optimizer, bm)
def target_vol_builder(er: np.ndarray,
......
......@@ -41,6 +41,22 @@ class TestMeanVarianceBuild(unittest.TestCase):
self.assertTrue(np.all(x @ risk_exposure >= risk_target[0] - 1.e-6))
np.testing.assert_array_almost_equal(x, [0.1, 0.4, 0.5])
def test_mean_variance_builder_without_constraints(self):
er = np.array([0.01, 0.02, 0.03])
cov = np.array([[0.02, 0.01, 0.02],
[0.01, 0.02, 0.03],
[0.02, 0.03, 0.02]])
ids_var = np.diag([0.01, 0.02, 0.03])
cov += ids_var
bm = np.array([0., 0., 0.])
lbound = np.array([-np.inf, -np.inf, -np.inf])
ubound = np.array([np.inf, np.inf, np.inf])
model = dict(cov=cov, factor_cov=None, factor_loading=None, idsync=None)
status, _, x = mean_variance_builder(er, model, bm, lbound, ubound, None, None, lam=1)
np.testing.assert_array_almost_equal(x, np.linalg.inv(cov) @ er)
def test_mean_variance_builder_with_none_unity_lambda(self):
er = np.array([0.01, 0.02, 0.03])
cov = np.array([[0.02, 0.01, 0.02],
......
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