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

added target_vol_builder

parent ec78228e
...@@ -8,7 +8,40 @@ Created on 2017-6-27 ...@@ -8,7 +8,40 @@ Created on 2017-6-27
import numpy as np import numpy as np
from typing import Union from typing import Union
from typing import Tuple from typing import Tuple
from typing import Optional
from alphamind.cython.optimizers import QPOptimizer from alphamind.cython.optimizers import QPOptimizer
from alphamind.cython.optimizers import CVOptimizer
def _create_bounds(lbound,
ubound,
bm,
risk_exposure,
risk_target):
lbound = lbound - bm
ubound = ubound - bm
if risk_exposure is not None:
cons_mat = risk_exposure.T
bm_risk = cons_mat @ bm
clbound = risk_target[0] - bm_risk
cubound = risk_target[1] - bm_risk
else:
cons_mat = None
clbound = None
cubound = None
return lbound, ubound, cons_mat, clbound, cubound
def _create_result(optimizer, bm):
if optimizer.status() == 0 or optimizer.status() == 1:
status = 'optimal'
else:
status = optimizer.status()
return status, optimizer.feval(), optimizer.x_value() + bm
def mean_variance_builder(er: np.ndarray, def mean_variance_builder(er: np.ndarray,
...@@ -16,33 +49,45 @@ def mean_variance_builder(er: np.ndarray, ...@@ -16,33 +49,45 @@ def mean_variance_builder(er: np.ndarray,
bm: np.ndarray, bm: np.ndarray,
lbound: Union[np.ndarray, float], lbound: Union[np.ndarray, float],
ubound: Union[np.ndarray, float], ubound: Union[np.ndarray, float],
risk_exposure: np.ndarray, risk_exposure: Optional[np.ndarray],
risk_target: Tuple[np.ndarray, np.ndarray], risk_target: Optional[Tuple[np.ndarray, np.ndarray]],
lam: float=1.) -> Tuple[str, float, 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)
lbound = lbound - bm
ubound = ubound - bm
bm_risk = risk_exposure.T @ bm
clbound = risk_target[0] - bm_risk
cubound = risk_target[1] - bm_risk
optimizer = QPOptimizer(er, optimizer = QPOptimizer(er,
cov, cov,
lbound, lbound,
ubound, ubound,
risk_exposure.T, cons_mat,
clbound, clbound,
cubound, cubound,
lam) lam)
if optimizer.status() == 0 or optimizer.status() == 1: return _create_result(optimizer, bm)
status = 'optimal'
else:
status = optimizer.status()
return status, optimizer.feval(), optimizer.x_value() + bm
def target_vol_builder(er: np.ndarray,
cov: np.ndarray,
bm: np.ndarray,
lbound: Union[np.ndarray, float],
ubound: Union[np.ndarray, float],
risk_exposure: Optional[np.ndarray],
risk_target: Optional[Tuple[np.ndarray, np.ndarray]],
vol_low: float = 0.,
vol_high: float = 1.):
lbound, ubound, cons_mat, clbound, cubound = _create_bounds(lbound, ubound, bm, risk_exposure, risk_target)
optimizer = CVOptimizer(er,
cov,
lbound,
ubound,
cons_mat,
clbound,
cubound,
vol_low,
vol_high)
return _create_result(optimizer, bm)
...@@ -77,10 +77,6 @@ class TestOptimizers(unittest.TestCase): ...@@ -77,10 +77,6 @@ class TestOptimizers(unittest.TestCase):
[0.02, 0.03, 0.07]]) [0.02, 0.03, 0.07]])
lbound = np.array([-0.3, -0.3, -0.3]) lbound = np.array([-0.3, -0.3, -0.3])
ubound = np.array([0.5, 0.5, 0.5]) ubound = np.array([0.5, 0.5, 0.5])
cons = np.array([[1., 1., 1.]])
clbound = np.array([0.])
cubound = np.array([0.])
target_vol = 0.1 target_vol = 0.1
optimizer = CVOptimizer(objective, optimizer = CVOptimizer(objective,
......
...@@ -8,6 +8,7 @@ Created on 2017-6-27 ...@@ -8,6 +8,7 @@ Created on 2017-6-27
import unittest import unittest
import numpy as np import numpy as np
from alphamind.portfolio.meanvariancebuilder import mean_variance_builder from alphamind.portfolio.meanvariancebuilder import mean_variance_builder
from alphamind.portfolio.meanvariancebuilder import target_vol_builder
class TestMeanVarianceBuild(unittest.TestCase): class TestMeanVarianceBuild(unittest.TestCase):
...@@ -62,4 +63,25 @@ class TestMeanVarianceBuild(unittest.TestCase): ...@@ -62,4 +63,25 @@ class TestMeanVarianceBuild(unittest.TestCase):
self.assertTrue(np.all(x >= lbound) - 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[1] + 1.e-6))
self.assertTrue(np.all(x @ risk_exposure >= risk_target[0] - 1.e-6)) self.assertTrue(np.all(x @ risk_exposure >= risk_target[0] - 1.e-6))
np.testing.assert_array_almost_equal(x, [0.2950, 0.3000, 0.4050]) np.testing.assert_array_almost_equal(x, [0.2950, 0.3000, 0.4050])
\ No newline at end of file
def test_target_vol_builder(self):
er = np.array([0.1, 0.2, 0.3])
cov = np.array([[0.05, 0.01, 0.02],
[0.01, 0.06, 0.03],
[0.02, 0.03, 0.07]])
lbound = np.array([0., 0., 0.])
ubound = np.array([0.8, 0.8, 0.8])
bm = np.array([0.3, 0.3, 0.3])
risk_exposure = np.array([[1., 1., 1.]]).T
risk_target = (np.array([bm.sum()]), np.array([bm.sum()]))
status, _, x = target_vol_builder(er, cov, bm, lbound, ubound, risk_exposure, risk_target, 0.1, 0.1)
self.assertTrue(status == 'optimal')
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))
np.testing.assert_array_almost_equal(x, [-0.3, -0.10919033, 0.40919033] + bm)
\ No newline at end of file
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