In [1]:
import datetime as dt
import numpy as np
import cvxpy
from alphamind.portfolio.linearbuilder import linear_builder

In [10]:
def time_function(py_callable, n):
    start = dt.datetime.now()
    result = py_callable(n)
    elapsed = (dt.datetime.now() - start).total_seconds()
    return elapsed, result

def cvxpy_lp(n):
    w = cvxpy.Variable(n)

    bndl = np.zeros(n)
    bndu = 0.01 * np.ones(n)
    risk_constraints1 = np.ones((n,1))
    risk_constraints2 = np.zeros((n,1))
    risk_constraints2[0][0] = 1.
    risk_constraints2[1][0] = 1.
    risk_constraints = np.concatenate((risk_constraints1, risk_constraints2), axis=1)

    curr_risk_exposure = risk_constraints.T @ w
    risk_targets = np.array([1., 0.015])

    constraints = [w >= bndl,
                   w <= bndu,
                   curr_risk_exposure >= risk_targets,
                   curr_risk_exposure <= risk_targets]
    
    np.random.seed(1)
    er = np.random.randn(n)

    objective = cvxpy.Minimize(-w.T * er)
    prob = cvxpy.Problem(objective, constraints)
    prob.solve(solver='ECOS')
    return w, prob

In [11]:
print("{0:<8}{1:>12}{2:>12}{3:>12}{4:>12}{5:>12}{6:>15}".format('Scale(n)', 'time(ms)', 'feval', 'min(x)', 'max(x)', 'sum(x)', 'x(0) + x(1)'))

for n in range(200, 3200, 200):
    elapsed, result = time_function(cvxpy_lp, n)
    s = np.array(result[0].value).flatten()
    print("{0:<8}{1:>12.2f}{2:>12.2f}{3:>12f}{4:>12f}{5:>12f}{6:>15}".format(n, elapsed*1000, result[1].value, s.min(), s.max(), s.sum(), s[0] + s[1]))


Scale(n)    time(ms)       feval      min(x)      max(x)      sum(x)    x(0) + x(1)
200             8.98       -0.82   -0.000000    0.010000    1.0000000.014999999999355636
400            10.97       -1.28   -0.000000    0.010000    1.0000000.014999999999977868
600            12.01       -1.54   -0.000000    0.010000    1.0000000.014999999999630973
800            11.93       -1.63   -0.000000    0.010000    1.0000000.014999999999937863
1000           12.00       -1.72   -0.000000    0.010000    1.0000000.014999999999985369
1200           13.97       -1.81   -0.000000    0.010000    1.0000000.014999999999661145
1400           15.92       -1.90   -0.000000    0.010000    1.0000000.014999999999617875
1600           18.97       -1.96   -0.000000    0.010000    1.0000000.01499999999998295
1800           19.99       -2.03   -0.000000    0.010000    1.0000000.014999999999785373
2000           22.93       -2.06   -0.000000    0.010000    1.0000000.014999999999994327
2200           21.92       -2.07   -0.000000    0.010000    1.0000000.014999999999979582
2400           25.90       -2.13   -0.000000    0.010000    1.0000000.014999999999836155
2600           29.93       -2.14   -0.000000    0.010000    1.0000000.01499999999985058
2800           28.87       -2.16   -0.000000    0.010000    1.0000000.014999999999853686
3000           32.96       -2.19   -0.000000    0.010000    1.0000000.014999999999981861

In [4]:
def clp_lp(n):
    np.random.seed(1)
    er = np.random.randn(n)

    bndl = np.zeros(n)
    bndu = 0.01 * np.ones(n)
    risk_constraints1 = np.ones((n,1))
    risk_constraints2 = np.zeros((n,1))
    risk_constraints2[0][0] = 1.
    risk_constraints2[1][0] = 1.
    risk_constraints = np.concatenate((risk_constraints1, risk_constraints2), axis=1)
    risk_target = np.array([1., 0.015]), np.array([1., 0.015])
    
    result = linear_builder(er, bndl, bndu, risk_constraints, risk_target)
    return result

In [5]:
print("{0:<8}{1:>12}{2:>12}{3:>12}{4:>12}{5:>12}{6:>15}".format('Scale(n)', 'time(ms)', 'feval', 'min(x)', 'max(x)', 'sum(x)', 'x(0) + x(1)'))

for n in range(200, 3200, 200):
    elapsed, result = time_function(clp_lp, n)
    s = result[2]
    print("{0:<8}{1:>12.2f}{2:>12.2f}{3:>12f}{4:>12f}{5:>12f}{6:>15}".format(n, elapsed*1000, result[1], s.min(), s.max(), s.sum(), s[0] + s[1]))


Scale(n)    time(ms)       feval      min(x)      max(x)      sum(x)    x(0) + x(1)
200             2.00       -0.82    0.000000    0.010000    1.0000000.015000000005429394
400             4.00       -1.28    0.000000    0.010000    1.0000000.015000000000751215
600             4.02       -1.54    0.000000    0.010000    1.0000000.01500000000851949
800             3.99       -1.63    0.000000    0.010000    1.0000000.015000000002481837
1000            7.94       -1.72    0.000000    0.010000    1.0000000.015000000001100414
1200            5.03       -1.81    0.000000    0.010000    1.0000000.01500000000548405
1400            8.94       -1.90    0.000000    0.010000    1.0000000.015000000001956426
1600            8.02       -1.96    0.000000    0.010000    1.0000000.015000000000082848
1800            9.98       -2.03    0.000000    0.010000    1.0000000.01500000000204834
2000            9.97       -2.06    0.000000    0.010000    1.0000000.0150000000008303
2200           14.91       -2.07    0.000000    0.010000    1.0000000.01500000000729576
2400           12.97       -2.13    0.000000    0.010000    1.0000000.015000000004022507
2600           15.96       -2.14    0.000000    0.010000    1.0000000.015000000001118521
2800           19.92       -2.16    0.000000    0.010000    1.0000000.01500000000064263
3000           21.93       -2.19    0.000000    0.010000    1.0000000.015000000003030482

In [ ]: