Commit 94e6ee52 authored by Dr.李's avatar Dr.李

merge 2 implementation

parent 2c94271e
...@@ -15,19 +15,18 @@ def linear_build(er: np.ndarray, ...@@ -15,19 +15,18 @@ def linear_build(er: np.ndarray,
lbound: Union[np.ndarray, float], lbound: Union[np.ndarray, float],
ubound: Union[np.ndarray, float], ubound: Union[np.ndarray, float],
risk_constraints: np.ndarray, risk_constraints: np.ndarray,
risk_target: Tuple[np.ndarray, np.ndarray]) -> Tuple[str, np.ndarray, np.ndarray]: risk_target: Tuple[np.ndarray, np.ndarray],
turn_over_target: float = None,
current_position: np.ndarray = None) -> Tuple[str, np.ndarray, np.ndarray]:
er = er.flatten() er = er.flatten()
n, m = risk_constraints.shape n, m = risk_constraints.shape
if not risk_target: if not risk_target:
risk_lbound = -np.inf * np.ones(m) risk_lbound = -np.inf * np.ones((m, 1))
risk_ubound = np.inf * np.ones(m) risk_ubound = np.inf * np.ones((m, 1))
cons_matrix = np.concatenate((risk_constraints.T, risk_lbound.reshape((-1, 1)), risk_ubound.reshape((-1, 1))),
axis=1)
else: else:
cons_matrix = np.concatenate( risk_lbound = risk_target[0].reshape((-1, 1))
(risk_constraints.T, risk_target[0].reshape((-1, 1)), risk_target[1].reshape((-1, 1))), risk_ubound = risk_target[1].reshape((-1, 1))
axis=1)
if isinstance(lbound, float): if isinstance(lbound, float):
lbound = np.ones(n) * lbound lbound = np.ones(n) * lbound
...@@ -35,78 +34,57 @@ def linear_build(er: np.ndarray, ...@@ -35,78 +34,57 @@ def linear_build(er: np.ndarray,
if isinstance(ubound, float): if isinstance(ubound, float):
ubound = np.ones(n) * ubound ubound = np.ones(n) * ubound
opt = LPOptimizer(cons_matrix, lbound, ubound, -er) if not turn_over_target:
cons_matrix = np.concatenate((risk_constraints.T, risk_lbound, risk_ubound), axis=1)
status = opt.status() opt = LPOptimizer(cons_matrix, lbound, ubound, -er)
if status == 0: status = opt.status()
status = 'optimal'
return status, opt.feval(), opt.x_value() if status == 0:
status = 'optimal'
return status, opt.feval(), opt.x_value()
def linear_build_with_to_constraint(er: np.ndarray,
lbound: Union[np.ndarray, float],
ubound: Union[np.ndarray, float],
risk_constraints: np.ndarray,
risk_target: Tuple[np.ndarray, np.ndarray],
turn_over_target: float,
current_position: np.ndarray):
er = er.flatten()
current_position = current_position.reshape((-1, 1))
n, m = risk_constraints.shape
if not risk_target:
risk_lbound = -np.inf * np.ones((m, 1))
risk_ubound = np.inf * np.ones((m, 1))
else: else:
risk_lbound = risk_target[0].reshape((-1, 1)) current_position = current_position.reshape((-1, 1))
risk_ubound = risk_target[1].reshape((-1, 1))
if isinstance(lbound, float):
lbound = np.ones(n) * lbound
if isinstance(ubound, float):
ubound = np.ones(n) * ubound
# we need to expand bounded condition and constraint matrix to handle L1 bound # we need to expand bounded condition and constraint matrix to handle L1 bound
lbound = np.concatenate((lbound, np.zeros(n)), axis=0) lbound = np.concatenate((lbound, np.zeros(n)), axis=0)
ubound = np.concatenate((ubound, np.inf * np.ones(n)), axis=0) ubound = np.concatenate((ubound, np.inf * np.ones(n)), axis=0)
risk_lbound = np.concatenate((risk_lbound, [[0.]]), axis=0) risk_lbound = np.concatenate((risk_lbound, [[0.]]), axis=0)
risk_ubound = np.concatenate((risk_ubound, [[turn_over_target]]), axis=0) risk_ubound = np.concatenate((risk_ubound, [[turn_over_target]]), axis=0)
risk_constraints = np.concatenate((risk_constraints.T, np.zeros((m, n))), axis=1) risk_constraints = np.concatenate((risk_constraints.T, np.zeros((m, n))), axis=1)
er = np.concatenate((er, np.zeros(n)), axis=0) er = np.concatenate((er, np.zeros(n)), axis=0)
turn_over_row = np.zeros(2 * n) turn_over_row = np.zeros(2 * n)
turn_over_row[n:] = 1. turn_over_row[n:] = 1.
risk_constraints = np.concatenate((risk_constraints, [turn_over_row]), axis=0) risk_constraints = np.concatenate((risk_constraints, [turn_over_row]), axis=0)
turn_over_matrix = np.zeros((2 * n, 2 * n)) turn_over_matrix = np.zeros((2 * n, 2 * n))
for i in range(n): for i in range(n):
turn_over_matrix[i, i] = 1. turn_over_matrix[i, i] = 1.
turn_over_matrix[i, i + n] = -1. turn_over_matrix[i, i + n] = -1.
turn_over_matrix[i + n, i] = 1. turn_over_matrix[i + n, i] = 1.
turn_over_matrix[i + n, i + n] = 1. turn_over_matrix[i + n, i + n] = 1.
risk_constraints = np.concatenate((risk_constraints, turn_over_matrix), axis=0) risk_constraints = np.concatenate((risk_constraints, turn_over_matrix), axis=0)
risk_lbound = np.concatenate((risk_lbound, -np.inf * np.ones((n, 1))), axis=0) risk_lbound = np.concatenate((risk_lbound, -np.inf * np.ones((n, 1))), axis=0)
risk_lbound = np.concatenate((risk_lbound, current_position), axis=0) risk_lbound = np.concatenate((risk_lbound, current_position), axis=0)
risk_ubound = np.concatenate((risk_ubound, current_position), axis=0) risk_ubound = np.concatenate((risk_ubound, current_position), axis=0)
risk_ubound = np.concatenate((risk_ubound, np.inf * np.ones((n, 1))), axis=0) risk_ubound = np.concatenate((risk_ubound, np.inf * np.ones((n, 1))), axis=0)
cons_matrix = np.concatenate((risk_constraints, risk_lbound, risk_ubound), axis=1) cons_matrix = np.concatenate((risk_constraints, risk_lbound, risk_ubound), axis=1)
opt = LPOptimizer(cons_matrix, lbound, ubound, -er) opt = LPOptimizer(cons_matrix, lbound, ubound, -er)
status = opt.status() status = opt.status()
if status == 0: if status == 0:
status = 'optimal' status = 'optimal'
return status, opt.feval(), opt.x_value()[:n] return status, opt.feval(), opt.x_value()[:n]
if __name__ == '__main__': if __name__ == '__main__':
...@@ -122,13 +100,13 @@ if __name__ == '__main__': ...@@ -122,13 +100,13 @@ if __name__ == '__main__':
risk_lbound = np.ones(1) risk_lbound = np.ones(1)
risk_ubound = np.ones(1) risk_ubound = np.ones(1)
status, fvalue, x_values = linear_build_with_to_constraint(er, status, fvalue, x_values = linear_build(er,
lb, lb,
ub, ub,
cons, cons,
(risk_lbound, risk_ubound), (risk_lbound, risk_ubound),
turn_over_target, turn_over_target,
current_pos) current_pos)
print(status) print(status)
print(fvalue) print(fvalue)
......
...@@ -8,7 +8,6 @@ Created on 2017-5-5 ...@@ -8,7 +8,6 @@ Created on 2017-5-5
import unittest import unittest
import numpy as np import numpy as np
from alphamind.portfolio.linearbuilder import linear_build from alphamind.portfolio.linearbuilder import linear_build
from alphamind.portfolio.linearbuilder import linear_build_with_to_constraint
class TestLinearBuild(unittest.TestCase): class TestLinearBuild(unittest.TestCase):
...@@ -76,13 +75,13 @@ class TestLinearBuild(unittest.TestCase): ...@@ -76,13 +75,13 @@ class TestLinearBuild(unittest.TestCase):
risk_lbound[:-1] = risk_lbound[:-1] - risk_tolerance risk_lbound[:-1] = risk_lbound[:-1] - risk_tolerance
risk_ubound[:-1] = risk_ubound[:-1] + risk_tolerance risk_ubound[:-1] = risk_ubound[:-1] + risk_tolerance
status, _, w = linear_build_with_to_constraint(self.er, status, _, w = linear_build(self.er,
0., 0.,
0.01, 0.01,
self.risk_exp, self.risk_exp,
risk_target=(risk_lbound, risk_ubound), risk_target=(risk_lbound, risk_ubound),
turn_over_target=turn_over_target, turn_over_target=turn_over_target,
current_position=self.current_pos) current_position=self.current_pos)
self.assertEqual(status, 'optimal') self.assertEqual(status, 'optimal')
self.assertAlmostEqual(np.sum(w), 1.) self.assertAlmostEqual(np.sum(w), 1.)
self.assertTrue(np.all(w <= 0.01 + eplson)) self.assertTrue(np.all(w <= 0.01 + eplson))
......
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