|
|
|
@ -60,8 +60,8 @@ class MVO(object): |
|
|
|
|
retPort = ret@w # T-dimensional array |
|
|
|
|
stdPort = np.std(retPort) |
|
|
|
|
g1=manual_ret/stdPort |
|
|
|
|
g2=np.mean(retPort)*(-0.5)*stdPort**(-3)*(2*cov@w) |
|
|
|
|
return g1+g2 |
|
|
|
|
g2=np.mean(retPort)*stdPort**(-3)*cov@w |
|
|
|
|
return g1-g2 |
|
|
|
|
@staticmethod |
|
|
|
|
def sortino_ratio(w, ret): |
|
|
|
|
retPort = ret@w # T-dimensional array |
|
|
|
@ -74,8 +74,23 @@ class MVO(object): |
|
|
|
|
retPort = ret@w # T-dimensional arrayss |
|
|
|
|
stdPort = np.std(retPort) |
|
|
|
|
g1=manual_ret/stdPort |
|
|
|
|
g2=np.mean(retPort)*(-0.5)*stdPort**(-3)*(2*cov_sor@w) |
|
|
|
|
return g1+g2 |
|
|
|
|
g2=np.mean(retPort)*stdPort**(-3)*cov_sor@w |
|
|
|
|
return g1-g2 |
|
|
|
|
@staticmethod |
|
|
|
|
def sortino_ratio(w, ret): |
|
|
|
|
retPort = ret@w # T-dimensional array |
|
|
|
|
stdPort = np.std(np.maximum(-retPort, 0)) |
|
|
|
|
return np.mean(retPort)/stdPort |
|
|
|
|
@staticmethod |
|
|
|
|
def sortino_grad(w, ret, cov_sor): |
|
|
|
|
manual_ret = np.mean(ret, axis=0) |
|
|
|
|
# print(cov.shape, w.shape) |
|
|
|
|
retPort = ret@w # T-dimensional arrayss |
|
|
|
|
stdPort = np.std(retPort) |
|
|
|
|
g1=manual_ret/stdPort |
|
|
|
|
g2=np.mean(retPort)*stdPort**(-3)*cov_sor@w |
|
|
|
|
return g1-g2 |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def volatility(w, ret): |
|
|
|
|
retPort = ret@w # T-dimensional array |
|
|
|
@ -85,7 +100,7 @@ class MVO(object): |
|
|
|
|
def volatility_grad(w, ret, cov): |
|
|
|
|
retPort = ret@w # T-dimensional array |
|
|
|
|
stdPort = np.std(retPort) |
|
|
|
|
return cov@w/stdPort**(0.5) |
|
|
|
|
return cov@w/stdPort |
|
|
|
|
@classmethod |
|
|
|
|
def opt(cls, ret, role="max_sharpe"): |
|
|
|
|
n = ret.shape[1] |
|
|
|
@ -105,11 +120,12 @@ class MVO(object): |
|
|
|
|
else: |
|
|
|
|
return init |
|
|
|
|
bnds = [[0, 0.6] for i in range(n)] |
|
|
|
|
opts = {'maxiter': 10000, 'disp': False} |
|
|
|
|
opts = {'maxiter': 1000, 'disp': False} |
|
|
|
|
cons = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1}) |
|
|
|
|
result = minimize(loss, init, method="SLSQP",\ |
|
|
|
|
options=opts, bounds=bnds, tol = None, jac = grad, constraints=cons) |
|
|
|
|
sol = result['x'] |
|
|
|
|
print(sol) |
|
|
|
|
return np.round(sol, 2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|