Commit 390152e0 authored by Dr.李's avatar Dr.李

update optimizer

parent e0bfc963
...@@ -7,13 +7,14 @@ Created on 2017-7-20 ...@@ -7,13 +7,14 @@ Created on 2017-7-20
""" """
cimport numpy as cnp cimport numpy as cnp
from libcpp.string cimport string
from libcpp.vector cimport vector from libcpp.vector cimport vector
import numpy as np import numpy as np
cdef extern from "lpoptimizer.hpp" namespace "pfopt": cdef extern from "lpoptimizer.hpp" namespace "pfopt":
cdef cppclass LpOptimizer: cdef cppclass LpOptimizer:
LpOptimizer(int, int, double*, double*, double*, double*) except + LpOptimizer(int, int, double*, double*, double*, double*, string) except +
vector[double] xValue() vector[double] xValue()
double feval() double feval()
int status() int status()
...@@ -26,12 +27,15 @@ cdef class LPOptimizer: ...@@ -26,12 +27,15 @@ cdef class LPOptimizer:
cdef int m cdef int m
def __cinit__(self, def __cinit__(self,
cnp.ndarray[double, ndim=2] cons_matrix, cnp.ndarray[double, ndim=2] cons_matrix,
double[:] lbound, double[:] lbound,
double[:] ubound, double[:] ubound,
double[:] objective): double[:] objective,
str method='simplex'):
self.n = lbound.shape[0] self.n = lbound.shape[0]
self.m = cons_matrix.shape[0] self.m = cons_matrix.shape[0]
py_bytes = method.encode('ascii')
cdef char* c_str = py_bytes
cdef double[:] cons = cons_matrix.flatten(order='C'); cdef double[:] cons = cons_matrix.flatten(order='C');
self.cobj = new LpOptimizer(self.n, self.cobj = new LpOptimizer(self.n,
...@@ -39,7 +43,8 @@ cdef class LPOptimizer: ...@@ -39,7 +43,8 @@ cdef class LPOptimizer:
&cons[0], &cons[0],
&lbound[0], &lbound[0],
&ubound[0], &ubound[0],
&objective[0]) &objective[0],
c_str)
def __dealloc__(self): def __dealloc__(self):
del self.cobj del self.cobj
...@@ -151,9 +156,25 @@ cdef extern from "mvoptimizer.hpp" namespace "pfopt": ...@@ -151,9 +156,25 @@ cdef extern from "mvoptimizer.hpp" namespace "pfopt":
int status() int status()
cdef extern from "qpalglib.hpp" namespace "pfopt":
cdef cppclass QPAlglib:
QPAlglib(int,
double*,
double*,
double*,
double*,
double) except +
vector[double] xValue()
int status()
cdef class QPOptimizer: cdef class QPOptimizer:
cdef MVOptimizer* cobj cdef MVOptimizer* cobj
cdef QPAlglib* cobj2
cdef cnp.ndarray er
cdef cnp.ndarray cov
cdef double risk_aversion
cdef int n cdef int n
cdef int m cdef int m
...@@ -169,12 +190,15 @@ cdef class QPOptimizer: ...@@ -169,12 +190,15 @@ cdef class QPOptimizer:
self.n = lbound.shape[0] self.n = lbound.shape[0]
self.m = 0 self.m = 0
self.er = np.array(expected_return)
self.cov = np.array(cov_matrix)
self.risk_aversion = risk_aversion
cdef double[:] cov = cov_matrix.flatten(order='C') cdef double[:] cov = cov_matrix.flatten(order='C')
cdef double[:] cons cdef double[:] cons
if cons_matrix is not None: if cons_matrix is not None:
self.m = cons_matrix.shape[0] self.m = cons_matrix.shape[0]
cons = cons_matrix.flatten(order='C'); cons = cons_matrix.flatten(order='C')
self.cobj = new MVOptimizer(self.n, self.cobj = new MVOptimizer(self.n,
&expected_return[0], &expected_return[0],
...@@ -187,25 +211,39 @@ cdef class QPOptimizer: ...@@ -187,25 +211,39 @@ cdef class QPOptimizer:
&cubound[0], &cubound[0],
risk_aversion) risk_aversion)
else: else:
self.cobj = new MVOptimizer(self.n, self.cobj2 = new QPAlglib(self.n,
&expected_return[0], &expected_return[0],
&cov[0], &cov[0],
&lbound[0], &lbound[0],
&ubound[0], &ubound[0],
0, risk_aversion)
NULL,
NULL,
NULL,
risk_aversion)
def __dealloc__(self): def __dealloc__(self):
del self.cobj if self.cobj:
del self.cobj
else:
del self.cobj2
def feval(self): def feval(self):
return self.cobj.feval() if self.cobj:
return self.cobj.feval()
else:
x = np.array(self.cobj2.xValue())
return 0.5 * self.risk_aversion * x @ self.cov @ x - self.er @ x
def x_value(self): def x_value(self):
return np.array(self.cobj.xValue()) if self.cobj:
return np.array(self.cobj.xValue())
else:
return np.array(self.cobj2.xValue())
def status(self): def status(self):
return self.cobj.status() if self.cobj:
\ No newline at end of file return self.cobj.status()
else:
status = self.cobj2.status()
if 1 <= status <= 4:
return 0
else:
return status
Subproject commit 7e81e8ec55c9f43bb6256eeb78d744f4670dae1d Subproject commit 1ed77b10dab76d88b09a057670a3c01276bc82d0
...@@ -17,7 +17,8 @@ def linear_builder(er: np.ndarray, ...@@ -17,7 +17,8 @@ def linear_builder(er: np.ndarray,
risk_constraints: np.ndarray, risk_constraints: np.ndarray,
risk_target: Tuple[np.ndarray, np.ndarray], risk_target: Tuple[np.ndarray, np.ndarray],
turn_over_target: float = None, turn_over_target: float = None,
current_position: np.ndarray = None) -> Tuple[str, np.ndarray, np.ndarray]: current_position: np.ndarray = None,
method: str='simplex') -> Tuple[str, np.ndarray, np.ndarray]:
er = er.flatten() er = er.flatten()
n, m = risk_constraints.shape n, m = risk_constraints.shape
...@@ -36,7 +37,7 @@ def linear_builder(er: np.ndarray, ...@@ -36,7 +37,7 @@ def linear_builder(er: np.ndarray,
if not turn_over_target: if not turn_over_target:
cons_matrix = np.concatenate((risk_constraints.T, risk_lbound, risk_ubound), axis=1) cons_matrix = np.concatenate((risk_constraints.T, risk_lbound, risk_ubound), axis=1)
opt = LPOptimizer(cons_matrix, lbound, ubound, -er) opt = LPOptimizer(cons_matrix, lbound, ubound, -er, method)
status = opt.status() status = opt.status()
...@@ -77,7 +78,7 @@ def linear_builder(er: np.ndarray, ...@@ -77,7 +78,7 @@ def linear_builder(er: np.ndarray,
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, method)
status = opt.status() status = opt.status()
......
Subproject commit bf4367184164e593cd2856ef38f8dd4f8cc76999 Subproject commit a187ed6c8f3aa40b47d5be80667cbbe6a6fd563d
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