Commit 67abdf2c authored by Dr.李's avatar Dr.李

update 2 examples

parent 0725efec
{
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from cvxpy import *\n",
"from cvxopt import *\n",
"from alphamind.api import *\n",
"from alphamind.cython.optimizers import QPOptimizer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data Preparing\n",
"--------------------------"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"risk_penlty = 0.5\n",
"ref_date = '2018-02-08'\n",
"\n",
"engine = SqlEngine()\n",
"universe = Universe('custom', ['ashare_ex'])\n",
"codes = engine.fetch_codes(ref_date, universe)\n",
"\n",
"risk_cov, risk_exposure = engine.fetch_risk_model(ref_date, codes)\n",
"factor = engine.fetch_factor(ref_date, 'EPS', codes)\n",
"\n",
"total_data = pd.merge(factor, risk_exposure, on='code').dropna()\n",
"all_styles = risk_styles + industry_styles + macro_styles\n",
"\n",
"risk_exposure_values = total_data[all_styles].values.astype(float)\n",
"special_risk_values = total_data['s_srisk'].values.astype(float)\n",
"risk_cov_values = risk_cov[all_styles].values\n",
"\n",
"sec_cov_values_full = risk_exposure_values @ risk_cov_values @ risk_exposure_values.T / 10000 + np.diag(special_risk_values ** 2) / 10000\n",
"signal_full = total_data['EPS'].values"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"n = 200\n",
"\n",
"sec_cov_values = sec_cov_values_full[:n, :n]\n",
"signal = signal_full[:n]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optimizing Weights\n",
"-------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 360 ms, sys: 321 ms, total: 681 ms\n",
"Wall time: 48.3 ms\n"
]
}
],
"source": [
"%%time\n",
"w = Variable(n)\n",
"\n",
"lbound = 0.\n",
"ubound = 1. / n * 20\n",
"\n",
"objective = Minimize(risk_penlty * quad_form(w, sec_cov_values) - signal * w)\n",
"constraints = [w >= lbound,\n",
" w <= ubound,\n",
" sum_entries(w) == 1,]\n",
"\n",
"prob = Problem(objective, constraints)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"ECOS 2.0.4 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS\n",
"\n",
"It pcost dcost gap pres dres k/t mu step sigma IR | BT\n",
" 0 -3.236e-01 -9.496e+01 +2e+03 9e-01 1e-02 1e+00 5e+00 --- --- 1 1 - | - - \n",
" 1 -5.482e+00 -1.908e+01 +1e+03 2e-01 9e-04 4e-01 3e+00 0.6534 2e-01 1 2 2 | 0 0\n",
" 2 -2.485e+00 -3.161e+00 +1e+02 1e-02 3e-05 8e-02 3e-01 0.9700 8e-02 2 2 2 | 0 0\n",
" 3 -2.433e+00 -2.610e+00 +3e+01 3e-03 8e-06 2e-02 6e-02 0.7649 2e-02 2 2 2 | 0 0\n",
" 4 -2.416e+00 -2.454e+00 +5e+00 7e-04 2e-06 4e-03 1e-02 0.8454 6e-02 2 2 2 | 0 0\n",
" 5 -2.408e+00 -2.415e+00 +1e+00 1e-04 3e-07 6e-04 2e-03 0.8342 2e-02 2 2 2 | 0 0\n",
" 6 -2.403e+00 -2.406e+00 +4e-01 6e-05 1e-07 1e-04 1e-03 0.8410 3e-01 2 3 3 | 0 0\n",
" 7 -2.401e+00 -2.401e+00 +5e-02 7e-06 1e-08 1e-05 1e-04 0.8893 3e-03 2 2 2 | 0 0\n",
" 8 -2.400e+00 -2.400e+00 +7e-03 1e-06 2e-09 8e-07 2e-05 0.9647 1e-01 2 2 2 | 0 0\n",
" 9 -2.400e+00 -2.400e+00 +3e-04 4e-08 8e-11 3e-08 7e-07 0.9613 1e-04 2 2 2 | 0 0\n",
"10 -2.400e+00 -2.400e+00 +2e-05 3e-09 5e-12 2e-09 5e-08 0.9440 1e-02 2 2 2 | 0 0\n",
"11 -2.400e+00 -2.400e+00 +3e-07 4e-11 9e-14 3e-11 7e-10 0.9842 3e-04 2 2 2 | 0 0\n",
"12 -2.400e+00 -2.400e+00 +3e-09 5e-13 1e-15 4e-13 8e-12 0.9890 1e-04 3 1 1 | 0 0\n",
"\n",
"OPTIMAL (within feastol=5.2e-13, reltol=1.4e-09, abstol=3.3e-09).\n",
"Runtime: 0.259075 seconds.\n",
"\n",
"CPU times: user 339 ms, sys: 7.32 ms, total: 347 ms\n",
"Wall time: 340 ms\n"
]
},
{
"data": {
"text/plain": [
"-2.4003282365705503"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"prob.solve(verbose=True)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('optimal', -2.4003282365705503)"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prob.status, prob.value"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" pcost dcost gap pres dres k/t\n",
" 0: -3.8414e-01 -9.6498e+01 2e+03 1e+01 4e-01 1e+00\n",
" 1: -2.2054e-01 -2.8096e+01 2e+02 3e+00 1e-01 2e+00\n",
" 2: -7.3888e-01 -2.3177e+01 1e+02 3e+00 1e-01 2e+00\n",
" 3: -9.0974e-01 -1.6105e+01 9e+01 2e+00 7e-02 3e+00\n",
" 4: -2.5843e+00 -6.4237e+00 1e+01 5e-01 2e-02 1e+00\n",
" 5: -2.6397e+00 -2.9412e+00 1e+00 4e-02 2e-03 1e-01\n",
" 6: -2.5273e+00 -2.6901e+00 6e-01 2e-02 9e-04 5e-02\n",
" 7: -2.4427e+00 -2.5068e+00 2e-01 8e-03 3e-04 2e-02\n",
" 8: -2.4035e+00 -2.4090e+00 2e-02 7e-04 3e-05 1e-03\n",
" 9: -2.4004e+00 -2.4005e+00 4e-04 1e-05 5e-07 2e-05\n",
"10: -2.4003e+00 -2.4003e+00 6e-06 2e-07 9e-09 4e-07\n",
"11: -2.4003e+00 -2.4003e+00 1e-07 4e-09 2e-10 7e-09\n",
"Optimal solution found.\n",
"CPU times: user 1.47 s, sys: 1.61 s, total: 3.08 s\n",
"Wall time: 352 ms\n"
]
},
{
"data": {
"text/plain": [
"-2.4003282579305463"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"prob.solve(verbose=True, solver='CVXOPT')"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('optimal', -2.4003282579305463)"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prob.status, prob.value"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" pcost dcost gap pres dres\n",
" 0: -4.0275e+01 -8.9373e+01 8e+03 6e+01 5e-16\n",
" 1: -2.7029e+00 -8.3780e+01 2e+02 1e+00 1e-15\n",
" 2: -1.3699e+00 -2.0914e+01 2e+01 1e-15 2e-15\n",
" 3: -1.6193e+00 -6.3167e+00 5e+00 6e-16 2e-15\n",
" 4: -1.8992e+00 -4.2870e+00 2e+00 4e-16 1e-15\n",
" 5: -2.1306e+00 -3.2594e+00 1e+00 3e-16 8e-16\n",
" 6: -2.1625e+00 -2.9783e+00 8e-01 3e-16 6e-16\n",
" 7: -2.2529e+00 -2.6835e+00 4e-01 2e-16 6e-16\n",
" 8: -2.3100e+00 -2.5413e+00 2e-01 2e-16 4e-16\n",
" 9: -2.3407e+00 -2.4723e+00 1e-01 2e-16 4e-16\n",
"10: -2.3953e+00 -2.4100e+00 1e-02 3e-16 1e-15\n",
"11: -2.4002e+00 -2.4005e+00 2e-04 4e-16 9e-16\n",
"12: -2.4003e+00 -2.4003e+00 2e-06 2e-16 8e-16\n",
"13: -2.4003e+00 -2.4003e+00 2e-08 2e-16 1e-15\n",
"Optimal solution found.\n",
"CPU times: user 584 ms, sys: 636 ms, total: 1.22 s\n",
"Wall time: 83 ms\n"
]
}
],
"source": [
"%%time\n",
"P = matrix(sec_cov_values)\n",
"q = -matrix(signal)\n",
"\n",
"G = np.zeros((2*n, n))\n",
"h = np.zeros(2*n)\n",
"for i in range(n):\n",
" G[i, i] = 1.\n",
" h[i] = 1. / n * 20\n",
" G[i+n, i] = -1.\n",
" h[i+n] = 0.\n",
" \n",
"G = matrix(G)\n",
"h = matrix(h)\n",
" \n",
"A = np.ones((1, n))\n",
"b = np.ones(1)\n",
"\n",
"A = matrix(A)\n",
"b = matrix(b)\n",
"\n",
"sol = solvers.qp(P, q, G, h, A, b)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 70 ms, sys: 36.7 ms, total: 107 ms\n",
"Wall time: 107 ms\n"
]
}
],
"source": [
"%%time\n",
"lbound = np.zeros(n)\n",
"ubound = np.ones(n) * 20 / n\n",
"cons_matrix = np.ones((1, n))\n",
"clb = np.ones(1)\n",
"cub = np.ones(1)\n",
"qpopt = QPOptimizer(signal, sec_cov_values, lbound, ubound, cons_matrix, clb, cub, 1.)\n",
"qpopt.feval()\n",
"qpopt.status()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Performace Timing\n",
"-------------------------"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"import datetime as dt"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
"def time_function(py_callable, n):\n",
" start = dt.datetime.now()\n",
" py_callable(n)\n",
" return (dt.datetime.now() - start).total_seconds()"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"def cvxpy(n):\n",
" w = Variable(n)\n",
"\n",
" lbound = 0.\n",
" ubound = 0.01\n",
"\n",
" objective = Minimize(risk_penlty * quad_form(w, sec_cov_values) - signal * w)\n",
" constraints = [w >= lbound,\n",
" w <= ubound,\n",
" sum_entries(w) == 1,]\n",
"\n",
" prob = Problem(objective, constraints)\n",
" prob.solve(verbose=False, solver='CVXOPT', display=False)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"def cvxopt(n):\n",
" P = matrix(sec_cov_values)\n",
" q = -matrix(signal)\n",
"\n",
" G = np.zeros((2*n, n))\n",
" h = np.zeros(2*n)\n",
" for i in range(n):\n",
" G[i, i] = 1.\n",
" h[i] = 0.01\n",
" G[i+n, i] = -1.\n",
" h[i+n] = 0.\n",
"\n",
" G = matrix(G)\n",
" h = matrix(h)\n",
"\n",
" A = np.ones((1, n))\n",
" b = np.ones(1)\n",
"\n",
" A = matrix(A)\n",
" b = matrix(b)\n",
" \n",
" solvers.options['show_progress'] = False\n",
" sol = solvers.qp(P, q, G, h, A, b)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"def ipopt(n):\n",
" lbound = np.zeros(n)\n",
" ubound = np.ones(n) * 0.01\n",
" cons_matrix = np.ones((1, n))\n",
" clb = np.ones(1)\n",
" cub = np.ones(1)\n",
" qpopt = QPOptimizer(signal, sec_cov_values, lbound, ubound, cons_matrix, clb, cub, 1.)\n",
" qpopt.feval()"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Scale(n) cvxpy cvxopt ipopt\n",
"200 359.93 28.96 30.79\n",
"400 1104.61 436.92 86.73\n",
"600 2248.70 544.58 57.86\n",
"800 3371.36 1025.66 88.14\n",
"1000 6210.00 1657.73 104.53\n",
"1200 12045.02 2785.55 132.32\n",
"1400 18365.51 4679.09 154.84\n",
"1600 24513.72 5827.70 201.17\n",
"1800 33475.16 10443.92 309.69\n",
"2000 44205.53 12464.22 330.94\n",
"2200 59213.54 17986.24 439.36\n",
"2400 72602.25 20114.71 562.75\n",
"2600 93412.44 24947.24 573.60\n",
"2800 111345.23 31156.20 644.45\n",
"3000 127577.49 39207.67 804.31\n",
"3200 147128.87 47593.30 956.98\n"
]
}
],
"source": [
"n_steps = list(range(200, 3201, 200))\n",
"cvxpy_times = [None] * len(n_steps)\n",
"cvxopt_times = [None] * len(n_steps)\n",
"ipopt_times = [None] * len(n_steps)\n",
"print(\"{0:<8}{1:>12}{2:>12}{3:>12}\".format('Scale(n)', 'cvxpy', 'cvxopt', 'ipopt'))\n",
"\n",
"for i, n in enumerate(n_steps):\n",
" sec_cov_values = sec_cov_values_full[:n, :n]\n",
" signal = signal_full[:n]\n",
" cvxpy_times[i] = time_function(cvxpy, n) * 1000\n",
" cvxopt_times[i] = time_function(cvxopt, n) * 1000\n",
" ipopt_times[i] = time_function(ipopt, n) * 1000\n",
" \n",
" print(\"{0:<8}{1:>12.2f}{2:>12.2f}{3:>12.2f}\".format(n, cvxpy_times[i], cvxopt_times[i], ipopt_times[i]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import datetime as dt\n",
"import numpy as np\n",
"import cvxpy\n",
"from cvxopt import solvers\n",
"from alphamind.portfolio.linearbuilder import linear_builder"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"solvers.options['glpk'] = {'msg_lev': 'GLP_MSG_OFF'}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def time_function(py_callable, n):\n",
" start = dt.datetime.now()\n",
" result = py_callable(n)\n",
" elapsed = (dt.datetime.now() - start).total_seconds()\n",
" return elapsed, result\n",
"\n",
"def cvxpy_lp(n):\n",
" w = cvxpy.Variable(n)\n",
"\n",
" bndl = np.zeros(n)\n",
" bndu = 0.01 * np.ones(n)\n",
" risk_constraints1 = np.ones((n,1))\n",
" risk_constraints2 = np.zeros((n,1))\n",
" risk_constraints2[0][0] = 1.\n",
" risk_constraints2[1][0] = 1.\n",
" risk_constraints = np.concatenate((risk_constraints1, risk_constraints2), axis=1)\n",
"\n",
" curr_risk_exposure = risk_constraints.T @ w\n",
" risk_targets = np.array([1., 0.015])\n",
"\n",
" constraints = [w >= bndl,\n",
" w <= bndu,\n",
" curr_risk_exposure >= risk_targets,\n",
" curr_risk_exposure <= risk_targets]\n",
" \n",
" np.random.seed(1)\n",
" er = np.random.randn(n)\n",
"\n",
" objective = cvxpy.Minimize(-w.T * er)\n",
" prob = cvxpy.Problem(objective, constraints)\n",
" prob.solve(solver='GLPK')\n",
" return w, prob"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Scale(n) time(ms) feval min(x) max(x) sum(x) x(0) + x(1)\n",
"200 39.72 -0.82 0.000000 0.010000 1.000000 0.015\n",
"400 25.20 -1.28 0.000000 0.010000 1.000000 0.015\n",
"600 29.23 -1.54 0.000000 0.010000 1.000000 0.015\n",
"800 32.27 -1.63 0.000000 0.010000 1.000000 0.015\n",
"1000 15.13 -1.72 0.000000 0.010000 1.000000 0.015\n",
"1200 16.79 -1.81 0.000000 0.010000 1.000000 0.015\n",
"1400 18.62 -1.90 0.000000 0.010000 1.000000 0.015\n",
"1600 20.90 -1.96 0.000000 0.010000 1.000000 0.015\n",
"1800 24.02 -2.03 0.000000 0.010000 1.000000 0.015\n",
"2000 27.05 -2.06 0.000000 0.010000 1.000000 0.015\n",
"2200 28.04 -2.07 0.000000 0.010000 1.000000 0.015\n",
"2400 30.25 -2.13 0.000000 0.010000 1.000000 0.015\n",
"2600 31.96 -2.14 0.000000 0.010000 1.000000 0.015\n",
"2800 34.44 -2.16 0.000000 0.010000 1.000000 0.015\n",
"3000 36.86 -2.19 0.000000 0.010000 1.000000 0.015\n"
]
}
],
"source": [
"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)'))\n",
"\n",
"for n in range(200, 3200, 200):\n",
" elapsed, result = time_function(cvxpy_lp, n)\n",
" s = np.array(result[0].value).flatten()\n",
" 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]))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def clp_lp(n):\n",
" np.random.seed(1)\n",
" er = np.random.randn(n)\n",
"\n",
" bndl = np.zeros(n)\n",
" bndu = 0.01 * np.ones(n)\n",
" risk_constraints1 = np.ones((n,1))\n",
" risk_constraints2 = np.zeros((n,1))\n",
" risk_constraints2[0][0] = 1.\n",
" risk_constraints2[1][0] = 1.\n",
" risk_constraints = np.concatenate((risk_constraints1, risk_constraints2), axis=1)\n",
" risk_target = np.array([1., 0.015]), np.array([1., 0.015])\n",
" \n",
" result = linear_builder(er, bndl, bndu, risk_constraints, risk_target)\n",
" return result"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Scale(n) time(ms) feval min(x) max(x) sum(x) x(0) + x(1)\n",
"200 2.95 -0.82 0.000000 0.010000 1.000000 0.015\n",
"400 2.34 -1.28 0.000000 0.010000 1.000000 0.015\n",
"600 2.44 -1.54 0.000000 0.010000 1.000000 0.015\n",
"800 2.91 -1.63 0.000000 0.010000 1.000000 0.015\n",
"1000 7.58 -1.72 0.000000 0.010000 1.000000 0.015\n",
"1200 3.89 -1.81 0.000000 0.010000 1.000000 0.015\n",
"1400 4.22 -1.90 0.000000 0.010000 1.000000 0.015\n",
"1600 4.37 -1.96 0.000000 0.010000 1.000000 0.015\n",
"1800 4.81 -2.03 0.000000 0.010000 1.000000 0.015\n",
"2000 4.98 -2.06 0.000000 0.010000 1.000000 0.015\n",
"2200 5.31 -2.07 0.000000 0.010000 1.000000 0.015\n",
"2400 6.13 -2.13 0.000000 0.010000 1.000000 0.015\n",
"2600 6.12 -2.14 0.000000 0.010000 1.000000 0.015\n",
"2800 6.73 -2.16 0.000000 0.010000 1.000000 0.015\n",
"3000 7.39 -2.19 0.000000 0.010000 1.000000 0.015\n"
]
}
],
"source": [
"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)'))\n",
"\n",
"for n in range(200, 3200, 200):\n",
" elapsed, result = time_function(clp_lp, n)\n",
" s = result[2]\n",
" 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]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
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