Commit e97a8be4 authored by Dr.李's avatar Dr.李

FIX: update all the examples

parent 7223c542
......@@ -69,10 +69,10 @@ def mean_variance_builder(er: np.ndarray,
risk_exposure = risk_model['factor_loading']
if cov is None:
risk = cvxpy.sum_squares(cvxpy.multiply(cvxpy.sqrt(special_risk), w)) \
+ cvxpy.quad_form((w.T * risk_exposure).T, risk_cov)
+ cvxpy.quad_form((w.T @ risk_exposure).T, risk_cov)
else:
risk = cvxpy.quad_form(w, cov)
objective = cvxpy.Minimize(-w.T * er + 0.5 * lam * risk)
objective = cvxpy.Minimize(-w.T @ er + 0.5 * lam * risk)
prob = cvxpy.Problem(objective)
prob.solve(solver='ECOS', feastol=1e-9, abstol=1e-9, reltol=1e-9)
......
......@@ -60,25 +60,6 @@
"engine = SqlEngine(data_source)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[datetime.datetime(2020, 1, 2, 0, 0), datetime.datetime(2020, 1, 16, 0, 0), datetime.datetime(2020, 2, 7, 0, 0), datetime.datetime(2020, 2, 21, 0, 0)]\n",
"9\n"
]
}
],
"source": [
"print(ref_dates)\n",
"print(horizon)"
]
},
{
"cell_type": "code",
"execution_count": 4,
......@@ -265,77 +246,77 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:05:42,997 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 299\n",
"2020-11-22 01:05:46,864 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:46,867 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-22 01:05:46,892 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-22 01:05:46,899 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-22 01:05:46,903 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:46,906 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-22 01:05:46,933 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-22 01:05:46,944 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-22 01:05:46,951 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:46,954 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-22 01:05:46,983 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-22 01:05:46,992 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-22 01:05:46,999 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:47,002 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-22 01:05:47,029 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n",
"2020-11-22 01:05:49,109 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 300\n",
"2020-11-22 01:05:49,114 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:49,117 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-22 01:05:49,148 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-22 01:05:49,160 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-22 01:05:49,166 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:49,169 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-22 01:05:49,196 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-22 01:05:49,205 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-22 01:05:49,211 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:49,214 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-22 01:05:49,243 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-22 01:05:49,253 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-22 01:05:49,260 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:49,262 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-22 01:05:49,289 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n",
"2020-11-22 01:05:51,371 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 299\n",
"2020-11-22 01:05:51,376 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:51,378 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-22 01:05:51,406 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-22 01:05:51,417 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-22 01:05:51,421 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:51,423 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-22 01:05:51,453 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-22 01:05:51,464 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-22 01:05:51,470 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:51,472 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-22 01:05:51,500 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-22 01:05:51,509 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-22 01:05:51,514 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:51,517 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-22 01:05:51,547 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n",
"2020-11-22 01:05:53,957 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 300\n",
"2020-11-22 01:05:53,962 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:53,965 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-22 01:05:53,998 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-22 01:05:54,009 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-22 01:05:54,014 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:54,017 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-22 01:05:54,047 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-22 01:05:54,057 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-22 01:05:54,063 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:54,066 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-22 01:05:54,097 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-22 01:05:54,107 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-22 01:05:54,111 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-22 01:05:54,114 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-22 01:05:54,143 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n"
"2020-11-23 00:37:40,518 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 299\n",
"2020-11-23 00:37:44,315 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:44,317 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-23 00:37:44,338 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-23 00:37:44,346 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-23 00:37:44,350 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:44,352 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-23 00:37:44,376 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-23 00:37:44,387 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-23 00:37:44,392 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:44,395 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-23 00:37:44,424 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-23 00:37:44,432 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-23 00:37:44,439 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:44,442 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-23 00:37:44,471 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n",
"2020-11-23 00:37:46,613 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 300\n",
"2020-11-23 00:37:46,618 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:46,621 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-23 00:37:46,652 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-23 00:37:46,662 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-23 00:37:46,668 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:46,670 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-23 00:37:46,702 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-23 00:37:46,713 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-23 00:37:46,718 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:46,721 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-23 00:37:46,752 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-23 00:37:46,763 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-23 00:37:46,770 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:46,773 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-23 00:37:46,802 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n",
"2020-11-23 00:37:48,915 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 299\n",
"2020-11-23 00:37:48,920 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:48,922 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-23 00:37:48,952 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-23 00:37:48,964 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-23 00:37:48,970 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:48,972 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-23 00:37:49,001 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-23 00:37:49,009 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-23 00:37:49,015 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:49,018 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-23 00:37:49,048 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-23 00:37:49,059 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-23 00:37:49,065 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:49,068 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-23 00:37:49,099 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n",
"2020-11-23 00:37:51,347 - ALPHA_MIND - INFO - 2020-01-02 00:00:00: 300\n",
"2020-11-23 00:37:51,352 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:51,354 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 full re-balance\n",
"2020-11-23 00:37:51,387 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished\n",
"2020-11-23 00:37:51,398 - ALPHA_MIND - INFO - 2020-01-16 00:00:00: 300\n",
"2020-11-23 00:37:51,404 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:51,406 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 full re-balance\n",
"2020-11-23 00:37:51,437 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished\n",
"2020-11-23 00:37:51,446 - ALPHA_MIND - INFO - 2020-02-07 00:00:00: 300\n",
"2020-11-23 00:37:51,451 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:51,453 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 full re-balance\n",
"2020-11-23 00:37:51,483 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished\n",
"2020-11-23 00:37:51,494 - ALPHA_MIND - INFO - 2020-02-21 00:00:00: 300\n",
"2020-11-23 00:37:51,500 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:37:51,503 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 full re-balance\n",
"2020-11-23 00:37:51,535 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 17.4 s\n"
"Wall time: 13.3 s\n"
]
}
],
......
......@@ -134,17 +134,17 @@
" warm start: on, polish: on, time_limit: off\n",
"\n",
"iter objective pri res dua res rho time\n",
" 1 -7.8878e+03 4.61e+00 6.68e+04 1.00e-01 1.40e-03s\n",
" 125 -2.4830e+02 3.58e-07 2.76e-05 5.82e-01 4.57e-03s\n",
" 1 -7.8878e+03 4.61e+00 6.68e+04 1.00e-01 1.82e-03s\n",
" 125 -2.4830e+02 3.58e-07 2.76e-05 5.82e-01 5.80e-03s\n",
"\n",
"status: solved\n",
"solution polish: unsuccessful\n",
"number of iterations: 125\n",
"optimal objective: -248.2989\n",
"run time: 5.42e-03s\n",
"run time: 6.87e-03s\n",
"optimal rho estimate: 1.87e+00\n",
"\n",
"Wall time: 49 ms\n"
"Wall time: 38 ms\n"
]
},
{
......@@ -211,9 +211,9 @@
"12 -2.483e+02 -2.483e+02 +3e-07 5e-13 2e-15 1e-10 8e-10 0.9775 1e-04 1 1 1 | 0 0\n",
"\n",
"OPTIMAL (within feastol=5.3e-13, reltol=1.3e-09, abstol=3.2e-07).\n",
"Runtime: 0.015751 seconds.\n",
"Runtime: 0.014540 seconds.\n",
"\n",
"Wall time: 59 ms\n"
"Wall time: 49 ms\n"
]
},
{
......@@ -277,7 +277,7 @@
"12: -2.4829e+02 -2.4831e+02 1e-02 2e-16 4e-16\n",
"13: -2.4830e+02 -2.4830e+02 1e-04 2e-16 1e-15\n",
"Optimal solution found.\n",
"Wall time: 69 ms\n"
"Wall time: 74 ms\n"
]
}
],
......@@ -315,7 +315,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 26 ms\n"
"Wall time: 15 ms\n"
]
},
{
......@@ -465,9 +465,9 @@
"output_type": "stream",
"text": [
"Scale(n) cvxpy cvxopt ipopt\n",
"100 0.0320 0.0240 0.0060\n",
"200 0.0360 0.0420 0.0120\n",
"300 0.0440 0.0630 0.0180\n"
"100 0.0320 0.0270 0.0090\n",
"200 0.0370 0.0500 0.0160\n",
"300 0.0430 0.0630 0.0160\n"
]
}
],
......
......@@ -15,7 +15,7 @@
{
"data": {
"text/plain": [
"datetime.datetime(2020, 11, 22, 1, 6, 28, 118072)"
"datetime.datetime(2020, 11, 23, 0, 38, 28, 821914)"
]
},
"execution_count": 1,
......@@ -117,7 +117,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 5.93 s\n"
"Wall time: 6.09 s\n"
]
}
],
......@@ -135,14 +135,14 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:06:34,553 - ALPHA_MIND - INFO - 2020-01-02 full re-balance: 300\n",
"2020-11-22 01:06:35,020 - ALPHA_MIND - INFO - 2020-01-02 is finished\n",
"2020-11-22 01:06:35,023 - ALPHA_MIND - INFO - 2020-01-16 full re-balance: 300\n",
"2020-11-22 01:06:35,230 - ALPHA_MIND - INFO - 2020-01-16 is finished\n",
"2020-11-22 01:06:35,233 - ALPHA_MIND - INFO - 2020-02-07 full re-balance: 300\n",
"2020-11-22 01:06:35,428 - ALPHA_MIND - INFO - 2020-02-07 is finished\n",
"2020-11-22 01:06:35,432 - ALPHA_MIND - INFO - 2020-02-21 full re-balance: 300\n",
"2020-11-22 01:06:35,711 - ALPHA_MIND - INFO - 2020-02-21 is finished\n"
"2020-11-23 00:38:35,439 - ALPHA_MIND - INFO - 2020-01-02 full re-balance: 300\n",
"2020-11-23 00:38:35,874 - ALPHA_MIND - INFO - 2020-01-02 is finished\n",
"2020-11-23 00:38:35,877 - ALPHA_MIND - INFO - 2020-01-16 full re-balance: 300\n",
"2020-11-23 00:38:36,076 - ALPHA_MIND - INFO - 2020-01-16 is finished\n",
"2020-11-23 00:38:36,080 - ALPHA_MIND - INFO - 2020-02-07 full re-balance: 300\n",
"2020-11-23 00:38:36,276 - ALPHA_MIND - INFO - 2020-02-07 is finished\n",
"2020-11-23 00:38:36,280 - ALPHA_MIND - INFO - 2020-02-21 full re-balance: 300\n",
"2020-11-23 00:38:36,486 - ALPHA_MIND - INFO - 2020-02-21 is finished\n"
]
}
],
......
......@@ -11,7 +11,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -35,7 +35,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -57,16 +57,16 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"我们使用当期的`[ROE, EPS, ETOP]`因子,来尝试预测未来大概一个月以后的收益。\n",
"我们使用当期的`[\"EMA5D\", \"EMV6D\"]`因子,来尝试预测未来大概一个月以后的收益。\n",
"\n",
"* 训练的股票池为`zz800`;;\n",
"* 训练的股票池为`hs300`;;\n",
"* 因子都经过中性化以及标准化等预处理;\n",
"* 对于线性模型,我们以20个工作日为一个时间间隔,用过去8期的数据作为训练用特征。"
"* 对于线性模型,我们以10个工作日为一个时间间隔,用过去8期的数据作为训练用特征。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
......@@ -100,7 +100,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
......@@ -111,7 +111,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 6,
"metadata": {},
"outputs": [
{
......@@ -144,7 +144,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
......@@ -157,7 +157,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
......@@ -167,7 +167,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 9,
"metadata": {},
"outputs": [
{
......@@ -203,7 +203,7 @@
}
],
"source": [
"print(\"\\nConst. Testing IC: {0:.4f}\".format(const_composer.ic(ref_date=ref_date)[0]))\n",
"print(\"Const. Testing IC: {0:.4f}\".format(const_composer.ic(ref_date=ref_date)[0]))\n",
"print(\"Regression Testing IC: {0:.4f}\".format(regression_composer.ic(ref_date=ref_date)[0]))"
]
},
......@@ -227,7 +227,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 10,
"metadata": {},
"outputs": [
{
......@@ -324,7 +324,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 11,
"metadata": {},
"outputs": [
{
......@@ -373,7 +373,7 @@
"std 0.140552 0.166313"
]
},
"execution_count": 10,
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
......@@ -399,7 +399,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
......@@ -416,7 +416,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 13,
"metadata": {},
"outputs": [
{
......@@ -489,7 +489,7 @@
"16 2020-01-02 2010000012 -0.017889"
]
},
"execution_count": 12,
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
......@@ -500,21 +500,21 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:31:22,196 - ALPHA_MIND - INFO - 2020-01-02 full re-balance: 300\n",
"2020-11-22 01:31:22,210 - ALPHA_MIND - INFO - 2020-01-02 is finished\n",
"2020-11-22 01:31:22,220 - ALPHA_MIND - INFO - 2020-01-16 full re-balance: 300\n",
"2020-11-22 01:31:22,239 - ALPHA_MIND - INFO - 2020-01-16 is finished\n",
"2020-11-22 01:31:22,252 - ALPHA_MIND - INFO - 2020-02-07 full re-balance: 300\n",
"2020-11-22 01:31:22,269 - ALPHA_MIND - INFO - 2020-02-07 is finished\n",
"2020-11-22 01:31:22,280 - ALPHA_MIND - INFO - 2020-02-21 full re-balance: 300\n",
"2020-11-22 01:31:22,297 - ALPHA_MIND - INFO - 2020-02-21 is finished\n"
"2020-11-23 00:39:52,840 - ALPHA_MIND - INFO - 2020-01-02 full re-balance: 300\n",
"2020-11-23 00:39:52,869 - ALPHA_MIND - INFO - 2020-01-02 is finished\n",
"2020-11-23 00:39:52,878 - ALPHA_MIND - INFO - 2020-01-16 full re-balance: 300\n",
"2020-11-23 00:39:52,888 - ALPHA_MIND - INFO - 2020-01-16 is finished\n",
"2020-11-23 00:39:52,897 - ALPHA_MIND - INFO - 2020-02-07 full re-balance: 300\n",
"2020-11-23 00:39:52,909 - ALPHA_MIND - INFO - 2020-02-07 is finished\n",
"2020-11-23 00:39:52,917 - ALPHA_MIND - INFO - 2020-02-21 full re-balance: 300\n",
"2020-11-23 00:39:52,931 - ALPHA_MIND - INFO - 2020-02-21 is finished\n"
]
}
],
......@@ -575,7 +575,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 15,
"metadata": {},
"outputs": [
{
......@@ -584,7 +584,7 @@
"<AxesSubplot:title={'center':'Fixed freq rebalanced: 10b'}>"
]
},
"execution_count": 18,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
},
......
......@@ -131,19 +131,19 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:37:30,583 - ALPHA_MIND - INFO - alpha factor data loading finished ...\n",
"2020-11-22 01:37:30,745 - ALPHA_MIND - INFO - industry data loading finished ...\n",
"2020-11-22 01:37:30,878 - ALPHA_MIND - INFO - benchmark data loading finished ...\n",
"2020-11-22 01:37:31,240 - ALPHA_MIND - INFO - risk_model data loading finished ...\n",
"2020-11-22 01:37:31,909 - ALPHA_MIND - INFO - returns data loading finished ...\n",
"2020-11-22 01:37:32,006 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:32,013 - ALPHA_MIND - INFO - alpha models training finished ...\n",
"2020-11-22 01:37:32,018 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:32,037 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:30,181 - ALPHA_MIND - INFO - alpha factor data loading finished ...\n",
"2020-11-23 00:40:30,383 - ALPHA_MIND - INFO - industry data loading finished ...\n",
"2020-11-23 00:40:30,576 - ALPHA_MIND - INFO - benchmark data loading finished ...\n",
"2020-11-23 00:40:30,944 - ALPHA_MIND - INFO - risk_model data loading finished ...\n",
"2020-11-23 00:40:31,694 - ALPHA_MIND - INFO - returns data loading finished ...\n",
"2020-11-23 00:40:31,795 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:40:31,803 - ALPHA_MIND - INFO - alpha models training finished ...\n",
"2020-11-23 00:40:31,811 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:31,828 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\problems\\problem.py:1061: UserWarning: Solution may be inaccurate. Try another solver, adjusting the solver settings, or solve with verbose=True for more information.\n",
" \"Solution may be inaccurate. Try another solver, \"\n",
"2020-11-22 01:37:32,130 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:32,218 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n"
"2020-11-23 00:40:31,910 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:31,986 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n"
]
}
],
......
......@@ -38,11 +38,11 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:37:39,662 - ALPHA_MIND - INFO - alpha factor data loading finished ...\n",
"2020-11-22 01:37:39,820 - ALPHA_MIND - INFO - industry data loading finished ...\n",
"2020-11-22 01:37:39,959 - ALPHA_MIND - INFO - benchmark data loading finished ...\n",
"2020-11-22 01:37:40,318 - ALPHA_MIND - INFO - risk_model data loading finished ...\n",
"2020-11-22 01:37:41,003 - ALPHA_MIND - INFO - returns data loading finished ...\n"
"2020-11-23 00:40:47,602 - ALPHA_MIND - INFO - alpha factor data loading finished ...\n",
"2020-11-23 00:40:47,830 - ALPHA_MIND - INFO - industry data loading finished ...\n",
"2020-11-23 00:40:47,964 - ALPHA_MIND - INFO - benchmark data loading finished ...\n",
"2020-11-23 00:40:48,366 - ALPHA_MIND - INFO - risk_model data loading finished ...\n",
"2020-11-23 00:40:49,086 - ALPHA_MIND - INFO - returns data loading finished ...\n"
]
}
],
......@@ -169,40 +169,40 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:37:41,157 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:41,163 - ALPHA_MIND - INFO - alpha models training finished ...\n",
"2020-11-22 01:37:41,170 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,188 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,233 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,278 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,340 - ALPHA_MIND - INFO - weight_gap: 0.005 finished\n",
"2020-11-22 01:37:41,341 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:41,350 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,362 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,247 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:40:49,256 - ALPHA_MIND - INFO - alpha models training finished ...\n",
"2020-11-23 00:40:49,260 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,275 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,337 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,394 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,453 - ALPHA_MIND - INFO - weight_gap: 0.005 finished\n",
"2020-11-23 00:40:49,454 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:40:49,461 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,476 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\problems\\problem.py:1061: UserWarning: Solution may be inaccurate. Try another solver, adjusting the solver settings, or solve with verbose=True for more information.\n",
" \"Solution may be inaccurate. Try another solver, \"\n",
"2020-11-22 01:37:41,444 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,526 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,619 - ALPHA_MIND - INFO - weight_gap: 0.01 finished\n",
"2020-11-22 01:37:41,620 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:41,627 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,644 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,730 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,818 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,907 - ALPHA_MIND - INFO - weight_gap: 0.015 finished\n",
"2020-11-22 01:37:41,909 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:41,915 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:41,931 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,012 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,099 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,196 - ALPHA_MIND - INFO - weight_gap: 0.02 finished\n"
"2020-11-23 00:40:49,556 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,636 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,727 - ALPHA_MIND - INFO - weight_gap: 0.01 finished\n",
"2020-11-23 00:40:49,728 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:40:49,734 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,750 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,830 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,875 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,930 - ALPHA_MIND - INFO - weight_gap: 0.015 finished\n",
"2020-11-23 00:40:49,932 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:40:49,937 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:49,951 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:50,028 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:50,108 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:40:50,208 - ALPHA_MIND - INFO - weight_gap: 0.02 finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 1.14 s\n"
"Wall time: 1.06 s\n"
]
}
],
......@@ -220,44 +220,44 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-22 01:37:42,295 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:42,304 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,383 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,468 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,576 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,684 - ALPHA_MIND - INFO - target_vol: 0.0150 finished\n",
"2020-11-22 01:37:42,686 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:42,691 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,748 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,813 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,891 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:42,977 - ALPHA_MIND - INFO - target_vol: 0.0300 finished\n",
"2020-11-22 01:37:42,979 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:42,986 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,025 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,087 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,152 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,221 - ALPHA_MIND - INFO - target_vol: 0.0450 finished\n",
"2020-11-22 01:37:43,223 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-22 01:37:43,230 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,267 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,320 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,379 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-22 01:37:43,452 - ALPHA_MIND - INFO - target_vol: 0.0600 finished\n"
"2020-11-23 00:41:21,612 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:41:21,620 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:21,709 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:21,803 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:21,904 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,019 - ALPHA_MIND - INFO - target_vol: 0.0150 finished\n",
"2020-11-23 00:41:22,021 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:41:22,029 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,085 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,146 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,211 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,284 - ALPHA_MIND - INFO - target_vol: 0.0300 finished\n",
"2020-11-23 00:41:22,285 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:41:22,292 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,328 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,382 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,441 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,507 - ALPHA_MIND - INFO - target_vol: 0.0450 finished\n",
"2020-11-23 00:41:22,509 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:41:22,515 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,547 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,584 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,632 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:41:22,684 - ALPHA_MIND - INFO - target_vol: 0.0600 finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 1.23 s\n"
"Wall time: 1.11 s\n"
]
}
],
......@@ -265,7 +265,7 @@
"%%time\n",
"target_vols = [0.015, 0.030, 0.045, 0.060]\n",
"\n",
"with pd.ExcelWriter(f'zz800_cyb_{benchmark_code}_tv.xlsx', engine='xlsxwriter') as writer:\n",
"with pd.ExcelWriter(f'hs300_{benchmark_code}_tv.xlsx', engine='xlsxwriter') as writer:\n",
" for i, target_vol in enumerate(target_vols):\n",
" ret_df = create_scenario(0.01, target_vol=target_vol, method='tv')\n",
" res_df = create_report(ret_df, 25)\n",
......
......@@ -9,7 +9,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
......@@ -26,7 +26,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -60,7 +60,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -91,31 +91,28 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\data_preparing.py:412: FutureWarning: DataFrame.mean and DataFrame.median with numeric_only=None will include datetime64 and datetime64tz columns in a future version.\n",
" lambda x: x.fillna(x.median())).reset_index(\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\data_preparing.py:412: FutureWarning: DataFrame.mean and DataFrame.median with numeric_only=None will include datetime64 and datetime64tz columns in a future version.\n",
" lambda x: x.fillna(x.median())).reset_index(\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\data_preparing.py:412: FutureWarning: DataFrame.mean and DataFrame.median with numeric_only=None will include datetime64 and datetime64tz columns in a future version.\n",
" lambda x: x.fillna(x.median())).reset_index(\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\data_preparing.py:412: FutureWarning: DataFrame.mean and DataFrame.median with numeric_only=None will include datetime64 and datetime64tz columns in a future version.\n",
" lambda x: x.fillna(x.median())).reset_index(\n"
]
},
{
"ename": "IndexError",
"evalue": "index -1 is out of bounds for axis 0 with size 0",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<timed exec>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n",
"\u001b[1;32m<timed exec>\u001b[0m in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n",
"\u001b[1;32m<ipython-input-5-ec80423ad50f>\u001b[0m in \u001b[0;36mpredict_worker\u001b[1;34m(params)\u001b[0m\n\u001b[0;32m 20\u001b[0m data_source=data_source)\n\u001b[0;32m 21\u001b[0m \u001b[0mref_date\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mparams\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 22\u001b[1;33m \u001b[0mer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0m_\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpredict_by_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mref_date\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata_meta\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 23\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mer\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\composer.py\u001b[0m in \u001b[0;36mpredict_by_model\u001b[1;34m(ref_date, alpha_model, data_meta, x_values, codes)\u001b[0m\n\u001b[0;32m 165\u001b[0m codes: Iterable[int] = None):\n\u001b[0;32m 166\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mx_values\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 167\u001b[1;33m \u001b[0mpredict_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdata_meta\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfetch_predict_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mref_date\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha_model\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 168\u001b[0m \u001b[0mcodes\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mx_values\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpredict_data\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'predict'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'code'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpredict_data\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'predict'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'x'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 169\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\composer.py\u001b[0m in \u001b[0;36mfetch_predict_data\u001b[1;34m(self, ref_date, alpha_model)\u001b[0m\n\u001b[0;32m 140\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarm_start\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 141\u001b[0m \u001b[0mfillna\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 142\u001b[1;33m fit_target=alpha_model.fit_target)\n\u001b[0m\u001b[0;32m 143\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 144\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\model\\data_preparing.py\u001b[0m in \u001b[0;36mfetch_predict_phase\u001b[1;34m(engine, alpha_factors, ref_date, frequency, universe, batch, neutralized_risk, risk_model, pre_process, post_process, warm_start, fillna, fit_target)\u001b[0m\n\u001b[0;32m 444\u001b[0m \u001b[0mdates\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0munique\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdate_label\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 445\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 446\u001b[1;33m \u001b[1;32mif\u001b[0m \u001b[0mdates\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mdt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdatetime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstrptime\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mref_date\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'%Y-%m-%d'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 447\u001b[0m \u001b[0mend\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdates\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 448\u001b[0m \u001b[0mstart\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdates\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[0mbatch\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mbatch\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdates\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[0mdates\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mIndexError\u001b[0m: index -1 is out of bounds for axis 0 with size 0"
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 4.34 s\n"
]
}
],
......@@ -130,7 +127,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
......@@ -168,7 +165,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
......@@ -252,20 +249,28 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 7,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'predicts' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-9-b2513dd9cb9a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mret_df\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcreate_scenario\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mweight_gap\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n\u001b[0;32m 3\u001b[0m \u001b[0mtitle\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'Fixed freq rebalanced: {0} with benchmark {1}'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfreq\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m905\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m secondary_y='tc_cost')\n",
"\u001b[1;32m<ipython-input-8-aa06d4654124>\u001b[0m in \u001b[0;36mcreate_scenario\u001b[1;34m(weight_gap)\u001b[0m\n\u001b[0;32m 33\u001b[0m \u001b[0mubound\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mweight_gap\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mbenchmark_w\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 34\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 35\u001b[1;33m \u001b[0mer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpredicts\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mloc\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mcodes\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 36\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 37\u001b[0m target_pos, _ = er_portfolio_analysis(er,\n",
"\u001b[1;31mNameError\u001b[0m: name 'predicts' is not defined"
"data": {
"text/plain": [
"<AxesSubplot:title={'center':'Fixed freq rebalanced: 10b with benchmark 905'}>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAvkAAAFxCAYAAADpt7dQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAACUuUlEQVR4nOzdeVxU9f7H8dc57MuwKiCLG4rlUpqYZJYb2forr2XdskVbzFyxzb3smmXlLnZtMbOysntTu3VvWYZLSShqZGopKC4oigLKDjNzvr8/RkfJBVRgWD7Px6NHDud7znwGEN+c+X4/X00ppRBCCCGEEELUG7qjCxBCCCGEEEJULQn5QgghhBBC1DMS8oUQQgghhKhnJOQLIYQQQghRz0jIF0IIIYQQop6RkC+EEEIIIUQ9IyFfiCo2ZcoUWrVqVe3P8+GHH+Ls7HzRMRaLhccff5zAwEA0TWPt2rXVXldVWbt2LZqmkZGRcUXXqcznqTapqe+fC2nevDmvvvpqtT5HZb8mPXv25Mknn7zk62uaxieffHI5pVWpffv2oWkaP//8s6NLKcfR32NCiJohIV+IyzBo0CA0TTvnv88//5znn3+epKQkR5cIwJdffsmnn37K119/TWZmJt26dXN0SaKaxMXF0bVrVzw9PS8YoM1mMy+++CJNmjTBw8OD7t27s2XLlhquFB544AEOHTpkf/zJJ5+gaVqN1yEuzfvvv0+HDh3w9PSkadOmTJkyBcMwyo3JzMzk/vvvx8fHBx8fH/7+97+TlZVVbkzz5s3P+dnZvXv3mnwpQjQIdef2lhC1zE033cQXX3xR7mN+fn64u7vj7e3toKrKS01NJSws7KLhvqysDFdX1xqryWw24+LiUmPP11BYrVYeeughDh48yJw5c8475oUXXuDjjz9m8eLFtGzZkjfffJPY2Fj++OMPQkJCaqxWDw8PPDw8auz5hI1SCovFclnnvvfee4waNYqFCxdy0003sX37doYMGYLZbGbatGkAGIbBXXfdha7r/PDDDyilGDZsGP369WPDhg3lfpEbO3YscXFx9sc1+TNIiIZC7uQLcZlcXV0JCQkp95+7u3u5t8KVUtx555106dIFs9kM2P4hjI2N5eabb8ZqtQLwww8/cOONN+Lh4UFYWBiDBw8mOzvb/lyGYTB58mSCgoLw9vbmgQceIDc396L19ezZk8mTJ7N37140TaN58+b2jz/xxBNMnjyZJk2a0LRpUwDS0tK499578fPzw9/fn759+/L777+Xu+YXX3xBq1atcHd3p1u3bvznP/+pcDrCoEGDiI2NZf78+TRv3hw3NzeKi4s5evQogwYNonHjxphMJm688UbWr19/zvm//vor119/Pe7u7rRv356EhAT7MaUUTz31FJGRkXh4eNCyZUsmTJhAaWnpBevJzc3l4YcfpmnTpnh4eNCmTRtmzpzJ2Zt/n6753XffpVmzZvj4+HD33Xdz9OjRctdavXo1N910E56envj6+tKjRw/27NljP/7555/TsWNH3N3dad68Oc8++yyFhYX24yUlJTzzzDP4+vri7+/PM888c9HaL2b+/PmMHj2a9u3bn/d4Xl4eCxcu5PXXX+fuu++mffv2LF68GDc3NxYuXFhubHFxMU8++SQ+Pj40atSICRMmnHPH9mw33XQTEydOtD9++eWX0TSN1atX2z924403Mn78eKD8dJ21a9fyyCOPANjv6g4aNKjc9adOnUpISAgBAQE8+uijFBQUVPj5yM7O5t5778XLy4uwsDDmzp1b7nhBQQGjR48mLCwMT09POnXqxPLly+3HT0+1+eKLL7jrrrvw9PSkZcuWfPjhh+dcJy4ujoiICNzc3GjevDmvvfZauTGHDx++6DU0TWP+/Pk88MADeHl50bRpU/79739z8uRJBg4ciMlkomXLlnz55Zflzps4cSJXX301np6eREREMHToUE6ePGk/fvrzvGbNGjp16oSbm1u5r8lpOTk5dO/enV69epGXl3fez+eSJUt47LHHeOyxx2jZsiV33303Y8eOZc6cOfbv6dWrV7N161Y++eQTunbtSkxMDB9//DG//PIL69atK3c9b2/vcj87AwICzvu8QogroIQQl+yxxx5Tffr0Oe+xl19+WUVGRtofZ2VlqSZNmqjnnntOKaXUq6++qgICAtSBAweUUkr9+OOPysPDQ82bN0/t3r1bbdq0SfXs2VPdfPPNyjAMpZRSc+bMUZ6enurDDz9Uu3btUm+88Yby9fVVTk5OF6wxOztbPffcc6p58+YqMzNTZWVlKaWU6tGjh/L29lZPP/202rFjh9q2bZs6cuSICg4OVkOHDlXbtm1Tf/75pxoxYoQKCAiwn7d161al67oaN26c+vPPP9WXX36pmjdvrgD1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wGq1cs899/DTTz+xb98+fv75ZyZOnGgPoWPGjOGXX35h4sSJ7N69mxUrVjBz5szLer6BAwfSokUL7rzzTr7//nv27dvHxo0bef3118+ZgjR9+nT+97//8ccff/DMM89w7Ngxhg0bBkCbNm34/fff+eqrr9izZw9z584t1yHlfNq0acPatWtZs2YNu3fvZtKkSWzcuPGSX8PkyZP59ttviYuLY9u2bezatYsPP/yQXbt2ATBt2jTmzZvHtGnT2L59O7t27WLlypU8/fTTgO3djaFDhzJp0iT+85//sGvXLl588UX7+adt2rSJq666yv79ciFpaWmkpKRw4MABAFJSUkhJSbF3ovHx8WHo0KFMmDCBb775hh07dvD4449TXFxsr+m0lJQUpkyZwu7du/n000+ZO3duuSkW59O7d29+//13UlJS7O9e9O7dm08++QR3d3diYmIueG6LFi0A+M9//sOxY8cq1T2nIt988w3x8fGkpqYyf/58li1bZn8NvXv3JjY2lv79+7Ny5Ur27t3Lli1bmD9/Pu+9916ln6N3797cdNNNPPDAA3z11Vekp6ezYcMG3n///SuuvyJt2rTh2LFjLFq0iL179/LRRx/x9ttvX9I1XFxc+OKLL4iOjqZHjx7s3bv3gmPT0tJYsmQJu3fvZsuWLQwbNoxly5bx9ttv26frxMbGct111/Hwww+zadMmNm7cyKOPPkpMTAw9evQA4JdffmHGjBls3bqV/fv3s2rVKu666y6aNm3K3/72t8v/hAghzuXgNQFC1EmV7a6TnZ2twsPD7Z11TnvqqadUy5YtVV5enlJKqfXr16s+ffoob29v5enpqa666io1evRo+8JUq9Wqxo8frwIDA5Wnp6e699571axZsy574e0TTzxxzth9+/aphx56SDVq1Ei5urqqpk2bqoEDB6q9e/fax3z22WeqZcuWytXVVV1//fVq5cqVlVp4e77P1fHjx9XQoUNVaGiocnFxUaGhoapfv35q69atSqkzC2+/+uordd111ylXV1d19dVX2zu0KKVUWVmZGjJkiPL391cmk0k9+OCD9sXAp/11keeJEyfUgAEDlMlkUgEBAWrYsGFq0qRJqlmzZhet+XyLQ7/77jsVExOj3N3dlY+Pj+rZs6fas2eP/fiKFStUTEyM8vDwUCaTSV177bXqlVdesR8vKipSQ4YM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\n",
"text/plain": [
"<Figure size 864x432 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
......@@ -275,13 +280,6 @@
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
......
......@@ -11,7 +11,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
......@@ -30,7 +30,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -51,7 +51,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -77,7 +77,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
......@@ -86,44 +86,44 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-21 15:10:18,028 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:18,038 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-21 15:10:18,041 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 risk_exposure: 3.25829145513029e-31\n",
"2020-11-21 15:10:18,510 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:18,513 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-21 15:10:18,516 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 risk_exposure: 4.602789610027951e-31\n",
"2020-11-21 15:10:19,244 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:19,248 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-21 15:10:19,252 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 risk_exposure: 7.380374200927195e-31\n",
"2020-11-21 15:10:20,041 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:20,046 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-21 15:10:20,052 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 risk_exposure: 1.425987166389731e-31\n",
"2020-11-21 15:10:21,151 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:21,159 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-21 15:10:21,169 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 risk_exposure: 1.626600676017078e-31\n",
"2020-11-21 15:10:21,952 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:21,961 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-21 15:10:21,970 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 risk_exposure: 7.114752841729456e-31\n",
"2020-11-21 15:10:22,823 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:22,831 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-21 15:10:22,839 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 risk_exposure: 2.894999049336361e-31\n",
"2020-11-21 15:10:23,345 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-21 15:10:23,348 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-21 15:10:23,350 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 risk_exposure: 3.207077036087234e-31\n"
"2020-11-23 00:41:53,439 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:53,445 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-23 00:41:53,447 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 risk_exposure: 4.943553232055517e-31\n",
"2020-11-23 00:41:54,467 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:54,470 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-23 00:41:54,473 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 risk_exposure: 8.396812257213363e-31\n",
"2020-11-23 00:41:55,338 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:55,340 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-23 00:41:55,343 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 risk_exposure: 5.682726866635588e-31\n",
"2020-11-23 00:41:56,058 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:56,061 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished with 300 stocks for BETA\n",
"2020-11-23 00:41:56,063 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 risk_exposure: 9.795355575973521e-32\n",
"2020-11-23 00:41:57,012 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:57,014 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-23 00:41:57,016 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 risk_exposure: 1.484415398332342e-31\n",
"2020-11-23 00:41:57,794 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:57,796 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-23 00:41:57,799 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 risk_exposure: 4.379171870810272e-31\n",
"2020-11-23 00:41:58,810 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:41:58,813 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-23 00:41:58,815 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 risk_exposure: 2.2500853516126014e-31\n",
"2020-11-23 00:42:00,437 - ALPHA_MIND - WARNING - winsorize_normal normally should not be done after neutralize\n",
"2020-11-23 00:42:00,439 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 is finished with 300 stocks for SIZE\n",
"2020-11-23 00:42:00,442 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 risk_exposure: 1.4975497993984135e-31\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 6.91 s\n"
"Wall time: 8.23 s\n"
]
}
],
......@@ -134,7 +134,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
......@@ -147,7 +147,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 7,
"metadata": {},
"outputs": [
{
......@@ -198,7 +198,7 @@
"SIZE 0.941047"
]
},
"execution_count": 16,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
......
......@@ -47,7 +47,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -58,7 +58,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
......@@ -81,25 +81,11 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 5,
"metadata": {},
"outputs": [
{
"ename": "PortfolioBuilderException",
"evalue": "-13",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mPortfolioBuilderException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-10-ccd216424e89>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mstatus\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp_er\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp_weight\u001b[0m \u001b[1;33m=\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[0mtarget_vol_builder\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrisk_model\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlbound\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mubound\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcons_mat\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrisk_targets\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtarget_vol\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 12\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[0msec_cov\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrisk_exposure\u001b[0m \u001b[1;33m@\u001b[0m \u001b[0mrisk_cov\u001b[0m \u001b[1;33m@\u001b[0m \u001b[0mrisk_exposure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mT\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m10000.\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdiag\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mspecial_risk\u001b[0m \u001b[1;33m**\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m10000\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36mtarget_vol_builder\u001b[1;34m(er, risk_model, bm, lbound, ubound, risk_exposure, risk_target, vol_target, linear_solver)\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36m_create_result\u001b[1;34m(optimizer, bm)\u001b[0m\n",
"\u001b[1;31mPortfolioBuilderException\u001b[0m: -13"
]
}
],
"outputs": [],
"source": [
"er = factor['EMA5D'].values\n",
"er = factor['EMA5D'].fillna(factor[\"EMA5D\"].median()).values\n",
"bm = factor['weight'].values\n",
"lbound = np.zeros(len(er))\n",
"ubound = bm + 0.01\n",
......@@ -116,18 +102,16 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 6,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'p_weight' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-11-d3dba2152982>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# check the result\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mf\"total weight is {p_weight.sum(): .4f}\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mf\"portfolio activate weight forecasting vol is {np.sqrt((p_weight - bm) @ sec_cov @ (p_weight - bm)):.4f}\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mf\"portfolio er: {p_weight @ er:.4f} comparing with benchmark er: {bm @ er:.4f}\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mNameError\u001b[0m: name 'p_weight' is not defined"
"name": "stdout",
"output_type": "stream",
"text": [
"total weight is 1.0007\n",
"portfolio activate weight forecasting vol is 0.0250\n",
"portfolio er: 124.8851 comparing with benchmark er: 81.8985\n"
]
}
],
......@@ -148,7 +132,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
......@@ -156,26 +140,26 @@
"Back test parameter settings\n",
"\"\"\"\n",
"\n",
"start_date = '2016-01-01'\n",
"end_date = '2018-02-08'\n",
"start_date = '2020-01-01'\n",
"end_date = '2020-02-21'\n",
"\n",
"freq = '10b'\n",
"neutralized_risk = industry_styles\n",
"industry_name = 'sw_adj'\n",
"industry_name = 'sw'\n",
"industry_level = 1\n",
"risk_model = 'short'\n",
"batch = 0\n",
"horizon = map_freq(freq)\n",
"universe = Universe('zz800')\n",
"universe = Universe('hs300')\n",
"data_source = os.environ['DB_URI']\n",
"benchmark_code = 906\n",
"benchmark_code = 300\n",
"target_vol = 0.05\n",
"weights_bandwidth = 0.02"
]
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
......@@ -183,7 +167,7 @@
"Factor Model\n",
"\"\"\"\n",
"\n",
"alpha_factors = {'f01': CSRank(LAST('EPS'))}\n",
"alpha_factors = {'f01': CSRank(LAST('EMA5D'))}\n",
"weights = dict(f01=1.)\n",
"alpha_model = ConstLinearModel(features=alpha_factors, weights=weights)\n",
"\n",
......@@ -200,7 +184,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
......@@ -235,7 +219,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
......@@ -250,21 +234,24 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 11,
"metadata": {},
"outputs": [
{
"ename": "ValueError",
"evalue": "factors in <{'EPS'}> can't be find",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-16-9dbce5b29567>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[0mfreq\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mfreq\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m benchmark=benchmark_code)\n\u001b[1;32m---> 11\u001b[1;33m \u001b[0mstrategy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mprepare_backtest_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 12\u001b[0m \u001b[0mret_df\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpositions\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mstrategy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrunning_setting\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\strategy\\strategy.py\u001b[0m in \u001b[0;36mprepare_backtest_data\u001b[1;34m(self)\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\data\\engines\\sqlengine\\sqlengine_rl.py\u001b[0m in \u001b[0;36mfetch_factor_range\u001b[1;34m(self, universe, factors, start_date, end_date, dates, external_data, used_factor_tables)\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\data\\engines\\utilities.py\u001b[0m in \u001b[0;36m_map_factors\u001b[1;34m(factors, used_factor_tables)\u001b[0m\n",
"\u001b[1;31mValueError\u001b[0m: factors in <{'EPS'}> can't be find"
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-23 00:42:09,295 - ALPHA_MIND - INFO - alpha factor data loading finished ...\n",
"2020-11-23 00:42:09,475 - ALPHA_MIND - INFO - industry data loading finished ...\n",
"2020-11-23 00:42:09,613 - ALPHA_MIND - INFO - benchmark data loading finished ...\n",
"2020-11-23 00:42:10,057 - ALPHA_MIND - INFO - risk_model data loading finished ...\n",
"2020-11-23 00:42:10,929 - ALPHA_MIND - INFO - returns data loading finished ...\n",
"2020-11-23 00:42:11,025 - ALPHA_MIND - INFO - starting backting ...\n",
"2020-11-23 00:42:11,032 - ALPHA_MIND - INFO - alpha models training finished ...\n",
"2020-11-23 00:42:11,254 - ALPHA_MIND - INFO - 2020-01-02 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:42:11,302 - ALPHA_MIND - INFO - 2020-01-16 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:42:11,363 - ALPHA_MIND - INFO - 2020-02-07 00:00:00 re-balance: 300 codes\n",
"2020-11-23 00:42:11,434 - ALPHA_MIND - INFO - 2020-02-21 00:00:00 re-balance: 300 codes\n"
]
}
],
......@@ -285,19 +272,28 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 12,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'ret_df' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-17-abc77a7db1b9>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m ret_df[['excess_return', 'turn_over']].cumsum().plot(figsize=(14, 7),\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mtitle\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0;31m'\u001b[0m\u001b[0mFixed\u001b[0m \u001b[0mfreq\u001b[0m \u001b[0mrebalanced\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mtarget\u001b[0m \u001b[0mvol\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mat\u001b[0m \u001b[1;33m{\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;33m{\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m}\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mbenchmark\u001b[0m \u001b[1;33m{\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m}\u001b[0m\u001b[0;31m'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfreq\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbenchmark_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtarget_vol\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m secondary_y='turn_over')\n",
"\u001b[1;31mNameError\u001b[0m: name 'ret_df' is not defined"
"data": {
"text/plain": [
"<AxesSubplot:title={'center':'Fixed freq rebalanced with target vol at 0.05: 10b with benchmark 300'}>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1008x504 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
......
......@@ -44,7 +44,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -73,19 +73,14 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 3,
"metadata": {},
"outputs": [
{
"ename": "PortfolioBuilderException",
"evalue": "3",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mPortfolioBuilderException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-5-5d07b462ee32>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[0mrisk_target\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1.\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1.\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 15\u001b[1;33m \u001b[0mstatus\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mx1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlinear_builder\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlbound\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mubound\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrisk_constraints\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrisk_target\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 16\u001b[0m \u001b[0melasped_time1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtimeit\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtimeit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"linear_builder(er, lbound, ubound, risk_constraints, risk_target)\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnumber\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnumber\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mglobals\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mglobals\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m/\u001b[0m \u001b[0mnumber\u001b[0m \u001b[1;33m*\u001b[0m \u001b[1;36m1000\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\linearbuilder.py\u001b[0m in \u001b[0;36mlinear_builder\u001b[1;34m(er, lbound, ubound, risk_constraints, risk_target, turn_over_target, current_position, method)\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m'optimal'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfeval\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx_value\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 47\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 48\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPortfolioBuilderException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 49\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mmethod\u001b[0m \u001b[1;32min\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;34m\"simplex\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"interior\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mPortfolioBuilderException\u001b[0m: 3"
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-23 00:42:23,256 - ALPHA_MIND - INFO - hs300 is finished\n"
]
}
],
......@@ -96,7 +91,8 @@
"\n",
"for u_name, sample_data in zip(u_names, data_set):\n",
" factor_data = sample_data['factor']\n",
" er = factor_data[factor].values\n",
" er = factor_data[factor].fillna(factor_data[factor].median()).values\n",
" er = er / (np.std(er) + 1e-8)\n",
" n = len(er)\n",
" lbound = np.ones(n) * lb\n",
" ubound = np.ones(n) * ub\n",
......@@ -111,13 +107,13 @@
" b_eq = np.array([1.])\n",
" \n",
" w = cvxpy.Variable(n)\n",
" curr_risk_exposure = w * risk_constraints\n",
" curr_risk_exposure = w @ risk_constraints\n",
" \n",
" constraints = [w >= lbound,\n",
" w <= ubound,\n",
" curr_risk_exposure == risk_target[0]]\n",
" \n",
" objective = cvxpy.Minimize(-w.T * er)\n",
" objective = cvxpy.Minimize(-w.T @ er)\n",
" prob = cvxpy.Problem(objective, constraints)\n",
" \n",
" prob.solve(solver='ECOS')\n",
......@@ -133,28 +129,75 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>hs300</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>cvxpy</th>\n",
" <td>5.28</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind</th>\n",
" <td>3.81</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" hs300\n",
"cvxpy 5.28\n",
"alphamind 3.81"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 5,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'prob' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-6-3b5570823a9d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mNameError\u001b[0m: name 'prob' is not defined"
"data": {
"text/plain": [
"-3.705217838159465"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
......@@ -171,19 +214,14 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 6,
"metadata": {},
"outputs": [
{
"ename": "PortfolioBuilderException",
"evalue": "3",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mPortfolioBuilderException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-8-0fed6a1bf8d5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 27\u001b[0m \u001b[0mturn_over_target\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mturn_over_target\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 28\u001b[0m \u001b[0mcurrent_position\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcurrent_position\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 29\u001b[1;33m method='interior')\n\u001b[0m\u001b[0;32m 30\u001b[0m elasped_time1 = timeit.timeit(\"\"\"linear_builder(er,\n\u001b[0;32m 31\u001b[0m \u001b[0mlbound\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\linearbuilder.py\u001b[0m in \u001b[0;36mlinear_builder\u001b[1;34m(er, lbound, ubound, risk_constraints, risk_target, turn_over_target, current_position, method)\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m'optimal'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfeval\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx_value\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m:\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 91\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 92\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPortfolioBuilderException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 93\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlower\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'ecos'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 94\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mcvxpy\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mProblem\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mPortfolioBuilderException\u001b[0m: 3"
"name": "stderr",
"output_type": "stream",
"text": [
"2020-11-23 00:42:23,491 - ALPHA_MIND - INFO - hs300 is finished\n"
]
}
],
......@@ -196,7 +234,8 @@
"\n",
"for u_name, sample_data in zip(u_names, data_set):\n",
" factor_data = sample_data['factor']\n",
" er = factor_data[factor].values\n",
" er = factor_data[factor].fillna(factor_data[factor].median()).values\n",
" er = er / (np.std(er) + 1e-8)\n",
" n = len(er)\n",
" lbound = np.ones(n) * lb\n",
" ubound = np.ones(n) * ub\n",
......@@ -234,7 +273,7 @@
" curr_risk_exposure == risk_target[0],\n",
" pnorm(w - current_position, 1) <= turn_over_target]\n",
" \n",
" objective = cvxpy.Minimize(-w.T * er)\n",
" objective = cvxpy.Minimize(-w.T @ er)\n",
" prob = cvxpy.Problem(objective, constraints)\n",
" \n",
" prob.solve(solver='ECOS')\n",
......@@ -289,9 +328,67 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>hs300</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>cvxpy</th>\n",
" <td>7.44</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind (clp simplex)</th>\n",
" <td>9.30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind (clp interior)</th>\n",
" <td>35.81</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind (ecos)</th>\n",
" <td>20.04</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" hs300\n",
"cvxpy 7.44\n",
"alphamind (clp simplex) 9.30\n",
"alphamind (clp interior) 35.81\n",
"alphamind (ecos) 20.04"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
......@@ -306,13 +403,15 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\problems\\problem.py:1061: UserWarning: Solution may be inaccurate. Try another solver, adjusting the solver settings, or solve with verbose=True for more information.\n",
" \"Solution may be inaccurate. Try another solver, \"\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\expressions\\expression.py:550: UserWarning: \n",
"This use of ``*`` has resulted in matrix multiplication.\n",
"Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.\n",
......@@ -321,29 +420,7 @@
" Use ``multiply`` for elementwise multiplication.\n",
"\n",
" warnings.warn(__STAR_MATMUL_WARNING__, UserWarning)\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\expressions\\expression.py:550: UserWarning: \n",
"This use of ``*`` has resulted in matrix multiplication.\n",
"Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.\n",
" Use ``*`` for matrix-scalar and vector-scalar multiplication.\n",
" Use ``@`` for matrix-matrix and matrix-vector multiplication.\n",
" Use ``multiply`` for elementwise multiplication.\n",
"\n",
" warnings.warn(__STAR_MATMUL_WARNING__, UserWarning)\n"
]
},
{
"ename": "SolverError",
"evalue": "Solver 'ECOS' failed. Try another solver, or solve with verbose=True for more information.",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mSolverError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-9-07e9404e845e>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 27\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 28\u001b[1;33m lam=1)\n\u001b[0m\u001b[0;32m 29\u001b[0m elasped_time1 = timeit.timeit(\"\"\"mean_variance_builder(er,\n\u001b[0;32m 30\u001b[0m \u001b[0mrisk_model\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36mmean_variance_builder\u001b[1;34m(er, risk_model, bm, lbound, ubound, risk_exposure, risk_target, lam, linear_solver)\u001b[0m\n\u001b[0;32m 75\u001b[0m \u001b[0mobjective\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcvxpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mMinimize\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[0mw\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mT\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mer\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m0.5\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mlam\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mrisk\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 76\u001b[0m \u001b[0mprob\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcvxpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mProblem\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mobjective\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 77\u001b[1;33m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolver\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'ECOS'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfeastol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1e-9\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mabstol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1e-9\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mreltol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1e-9\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 78\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 79\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'optimal'\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0mprob\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'optimal_inaccurate'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\problems\\problem.py\u001b[0m in \u001b[0;36msolve\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 394\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 395\u001b[0m \u001b[0msolve_func\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mProblem\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_solve\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 396\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0msolve_func\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 397\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 398\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mclassmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\problems\\problem.py\u001b[0m in \u001b[0;36m_solve\u001b[1;34m(self, solver, warm_start, verbose, gp, qcp, requires_grad, enforce_dpp, **kwargs)\u001b[0m\n\u001b[0;32m 752\u001b[0m solution = solving_chain.solve_via_data(\n\u001b[0;32m 753\u001b[0m self, data, warm_start, verbose, kwargs)\n\u001b[1;32m--> 754\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0munpack_results\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msolving_chain\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minverse_data\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 755\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 756\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\problems\\problem.py\u001b[0m in \u001b[0;36munpack_results\u001b[1;34m(self, solution, chain, inverse_data)\u001b[0m\n\u001b[0;32m 1066\u001b[0m raise error.SolverError(\n\u001b[0;32m 1067\u001b[0m \u001b[1;34m\"Solver '%s' failed. \"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0mchain\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msolver\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1068\u001b[1;33m \u001b[1;34m\"Try another solver, or solve with verbose=True for more \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1069\u001b[0m \"information.\")\n\u001b[0;32m 1070\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0munpack\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mSolverError\u001b[0m: Solver 'ECOS' failed. Try another solver, or solve with verbose=True for more information."
"2020-11-23 00:42:23,778 - ALPHA_MIND - INFO - hs300 is finished\n"
]
}
],
......@@ -360,7 +437,8 @@
" risk_exposure = factor_data[all_styles].values\n",
" special_risk = factor_data.srisk.values\n",
" sec_cov = risk_exposure @ risk_cov @ risk_exposure.T / 10000 + np.diag(special_risk ** 2) / 10000\n",
" er = factor_data[factor].values\n",
" er = factor_data[factor].fillna(factor_data[factor].median()).values\n",
" er = er / (np.std(er) + 1e-8)\n",
" n = len(er)\n",
"\n",
" bm = np.zeros(n)\n",
......@@ -388,7 +466,7 @@
" \n",
" w = cvxpy.Variable(n)\n",
" risk = sum_squares(multiply(special_risk / 100., w)) + quad_form((w.T * risk_exposure).T, risk_cov / 10000.)\n",
" objective = cvxpy.Minimize(-w.T * er + 0.5 * risk)\n",
" objective = cvxpy.Minimize(-w.T @ er + 0.5 * risk)\n",
" prob = cvxpy.Problem(objective)\n",
" prob.solve(solver='ECOS')\n",
" elasped_time2 = timeit.timeit(\"prob.solve(solver='ECOS')\",\n",
......@@ -407,9 +485,65 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 9,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\ipykernel\\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
" and should_run_async(code)\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>hs300</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>cvxpy</th>\n",
" <td>29.21</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind</th>\n",
" <td>66.48</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" hs300\n",
"cvxpy 29.21\n",
"alphamind 66.48"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
......@@ -432,20 +566,16 @@
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\ipykernel\\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
" and should_run_async(code)\n"
]
},
{
"ename": "PortfolioBuilderException",
"evalue": "-13",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mPortfolioBuilderException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-10-8f6e73d51fb2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[0mubound\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 25\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 26\u001b[1;33m None)\n\u001b[0m\u001b[0;32m 27\u001b[0m elasped_time1 = timeit.timeit(\"\"\"mean_variance_builder(er,\n\u001b[0;32m 28\u001b[0m \u001b[0mrisk_model\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36mmean_variance_builder\u001b[1;34m(er, risk_model, bm, lbound, ubound, risk_exposure, risk_target, lam, linear_solver)\u001b[0m\n\u001b[0;32m 95\u001b[0m linear_solver=linear_solver)\n\u001b[0;32m 96\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 97\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_create_result\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 98\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 99\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36m_create_result\u001b[1;34m(optimizer, bm)\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m'optimal'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfeval\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx_value\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 47\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPortfolioBuilderException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 48\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mPortfolioBuilderException\u001b[0m: -13"
" and should_run_async(code)\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\expressions\\expression.py:550: UserWarning: \n",
"This use of ``*`` has resulted in matrix multiplication.\n",
"Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.\n",
" Use ``*`` for matrix-scalar and vector-scalar multiplication.\n",
" Use ``@`` for matrix-matrix and matrix-vector multiplication.\n",
" Use ``multiply`` for elementwise multiplication.\n",
"\n",
" warnings.warn(__STAR_MATMUL_WARNING__, UserWarning)\n",
"2020-11-23 00:42:23,972 - ALPHA_MIND - INFO - hs300 is finished\n"
]
}
],
......@@ -460,7 +590,8 @@
" risk_exposure = factor_data[all_styles].values\n",
" special_risk = factor_data.srisk.values\n",
" sec_cov = risk_exposure @ risk_cov @ risk_exposure.T / 10000 + np.diag(special_risk ** 2) / 10000\n",
" er = factor_data[factor].values\n",
" er = factor_data[factor].fillna(factor_data[factor].median()).values\n",
" er = er / (np.std(er) + 1e-8)\n",
" n = len(er)\n",
"\n",
" bm = np.zeros(n)\n",
......@@ -487,7 +618,7 @@
" \n",
" w = cvxpy.Variable(n)\n",
" risk = sum_squares(multiply(special_risk / 100., w)) + quad_form((w.T * risk_exposure).T, risk_cov / 10000.)\n",
" objective = cvxpy.Minimize(-w.T * er + 0.5 * risk)\n",
" objective = cvxpy.Minimize(-w.T @ er + 0.5 * risk)\n",
" constraints = [w >= lbound,\n",
" w <= ubound]\n",
" prob = cvxpy.Problem(objective, constraints)\n",
......@@ -546,11 +677,11 @@
" <tbody>\n",
" <tr>\n",
" <th>cvxpy</th>\n",
" <td>NaN</td>\n",
" <td>27.37</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind</th>\n",
" <td>NaN</td>\n",
" <td>19.60</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
......@@ -558,8 +689,8 @@
],
"text/plain": [
" hs300\n",
"cvxpy NaN\n",
"alphamind NaN"
"cvxpy 27.37\n",
"alphamind 19.60"
]
},
"execution_count": 11,
......@@ -589,20 +720,16 @@
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\ipykernel\\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
" and should_run_async(code)\n"
]
},
{
"ename": "PortfolioBuilderException",
"evalue": "-13",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mPortfolioBuilderException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-12-0c4eaa49b968>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 27\u001b[0m \u001b[0mubound\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 28\u001b[0m \u001b[0mrisk_constraints\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 29\u001b[1;33m risk_target)\n\u001b[0m\u001b[0;32m 30\u001b[0m elasped_time1 = timeit.timeit(\"\"\"mean_variance_builder(er,\n\u001b[0;32m 31\u001b[0m \u001b[0mrisk_model\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36mmean_variance_builder\u001b[1;34m(er, risk_model, bm, lbound, ubound, risk_exposure, risk_target, lam, linear_solver)\u001b[0m\n\u001b[0;32m 95\u001b[0m linear_solver=linear_solver)\n\u001b[0;32m 96\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 97\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_create_result\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 98\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 99\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36m_create_result\u001b[1;34m(optimizer, bm)\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m'optimal'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfeval\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx_value\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 47\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPortfolioBuilderException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 48\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mPortfolioBuilderException\u001b[0m: -13"
" and should_run_async(code)\n",
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\expressions\\expression.py:550: UserWarning: \n",
"This use of ``*`` has resulted in matrix multiplication.\n",
"Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.\n",
" Use ``*`` for matrix-scalar and vector-scalar multiplication.\n",
" Use ``@`` for matrix-matrix and matrix-vector multiplication.\n",
" Use ``multiply`` for elementwise multiplication.\n",
"\n",
" warnings.warn(__STAR_MATMUL_WARNING__, UserWarning)\n",
"2020-11-23 00:42:24,165 - ALPHA_MIND - INFO - hs300 is finished\n"
]
}
],
......@@ -617,7 +744,8 @@
" risk_exposure = factor_data[all_styles].values\n",
" special_risk = factor_data.srisk.values\n",
" sec_cov = risk_exposure @ risk_cov @ risk_exposure.T / 10000 + np.diag(special_risk ** 2) / 10000\n",
" er = factor_data[factor].values\n",
" er = factor_data[factor].fillna(factor_data[factor].median()).values\n",
" er = er / (np.std(er) + 1e-8)\n",
" n = len(er)\n",
" \n",
" bm = np.zeros(n)\n",
......@@ -647,7 +775,7 @@
" \n",
" w = cvxpy.Variable(n)\n",
" risk = sum_squares(multiply(special_risk / 100., w)) + quad_form((w.T * risk_exposure).T, risk_cov / 10000.)\n",
" objective = cvxpy.Minimize(-w.T * er + 0.5 * risk)\n",
" objective = cvxpy.Minimize(-w.T @ er + 0.5 * risk)\n",
" curr_risk_exposure = risk_constraints.T @ w\n",
" constraints = [w >= lbound,\n",
" w <= ubound,\n",
......@@ -660,7 +788,7 @@
" u1 = -x1 @ er + 0.5 * x1 @ sec_cov @ x1\n",
" x2 = np.array(w.value).flatten()\n",
" u2 = -x2 @ er + 0.5 * x2 @ sec_cov @ x2\n",
" \n",
"\n",
" np.testing.assert_array_almost_equal(u1, u2, 4)\n",
"\n",
" df.loc['alphamind', u_name] = elasped_time1\n",
......@@ -673,6 +801,14 @@
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\ipykernel\\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
" and should_run_async(code)\n"
]
},
{
"data": {
"text/html": [
......@@ -700,11 +836,11 @@
" <tbody>\n",
" <tr>\n",
" <th>cvxpy</th>\n",
" <td>NaN</td>\n",
" <td>24.13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind</th>\n",
" <td>NaN</td>\n",
" <td>29.01</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
......@@ -712,8 +848,8 @@
],
"text/plain": [
" hs300\n",
"cvxpy NaN\n",
"alphamind NaN"
"cvxpy 24.13\n",
"alphamind 29.01"
]
},
"execution_count": 13,
......@@ -735,7 +871,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 16,
"metadata": {},
"outputs": [
{
......@@ -743,20 +879,8 @@
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\ipykernel\\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
" and should_run_async(code)\n"
]
},
{
"ename": "PortfolioBuilderException",
"evalue": "-13",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mPortfolioBuilderException\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-14-d727a7f2ff85>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 32\u001b[0m \u001b[0mrisk_constraints\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 33\u001b[0m \u001b[0mrisk_target\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 34\u001b[1;33m vol_target=target_vol)\n\u001b[0m\u001b[0;32m 35\u001b[0m elasped_time1 = timeit.timeit(\"\"\"target_vol_builder(er,\n\u001b[0;32m 36\u001b[0m \u001b[0mrisk_model\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36mtarget_vol_builder\u001b[1;34m(er, risk_model, bm, lbound, ubound, risk_exposure, risk_target, vol_target, linear_solver)\u001b[0m\n\u001b[0;32m 123\u001b[0m linear_solver=linear_solver)\n\u001b[0;32m 124\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 125\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_create_result\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32mD:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\alpha_mind-0.2.3-py3.7-win-amd64.egg\\alphamind\\portfolio\\meanvariancebuilder.py\u001b[0m in \u001b[0;36m_create_result\u001b[1;34m(optimizer, bm)\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m'optimal'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfeval\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx_value\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mbm\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 47\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPortfolioBuilderException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 48\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mPortfolioBuilderException\u001b[0m: -13"
" and should_run_async(code)\n",
"2020-11-23 00:42:52,888 - ALPHA_MIND - INFO - hs300 is finished\n"
]
}
],
......@@ -773,7 +897,8 @@
" risk_exposure = factor_data[all_styles].values\n",
" special_risk = factor_data.srisk.values\n",
" sec_cov = risk_exposure @ risk_cov @ risk_exposure.T / 10000 + np.diag(special_risk ** 2) / 10000\n",
" er = factor_data[factor].values\n",
" er = factor_data[factor].fillna(factor_data[factor].median()).values\n",
" er = er / (np.std(er) + 1e-8)\n",
" n = len(er)\n",
" \n",
" if 'weight' in factor_data:\n",
......@@ -806,8 +931,8 @@
" number=number, globals=globals()) / number * 1000\n",
" \n",
" w = cvxpy.Variable(n)\n",
" risk = sum_squares(multiply(special_risk / 100., w)) + quad_form((w.T * risk_exposure).T, risk_cov / 10000.)\n",
" objective = cvxpy.Minimize(-w.T * er)\n",
" risk = sum_squares(multiply(special_risk / 100., w)) + quad_form((w.T @ risk_exposure).T, risk_cov / 10000.)\n",
" objective = cvxpy.Minimize(-w.T @ er)\n",
" curr_risk_exposure = risk_constraints.T @ w\n",
" constraints = [w >= lbound,\n",
" w <= ubound,\n",
......@@ -822,7 +947,7 @@
" x2 = np.array(w.value).flatten()\n",
" u2 = -x2 @ er\n",
" \n",
" np.testing.assert_array_almost_equal(u1, u2, 4)\n",
" np.testing.assert_array_almost_equal(u1, u2, 3)\n",
"\n",
" df.loc['alphamind', u_name] = elasped_time1\n",
" df.loc['cvxpy', u_name] = elasped_time2\n",
......@@ -831,7 +956,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 17,
"metadata": {},
"outputs": [
{
......@@ -861,11 +986,11 @@
" <tbody>\n",
" <tr>\n",
" <th>cvxpy</th>\n",
" <td>NaN</td>\n",
" <td>22.72</td>\n",
" </tr>\n",
" <tr>\n",
" <th>alphamind</th>\n",
" <td>NaN</td>\n",
" <td>44.56</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
......@@ -873,11 +998,11 @@
],
"text/plain": [
" hs300\n",
"cvxpy NaN\n",
"alphamind NaN"
"cvxpy 22.72\n",
"alphamind 44.56"
]
},
"execution_count": 15,
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
......
......@@ -14,7 +14,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -54,7 +54,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 3,
"metadata": {},
"outputs": [
{
......@@ -62,21 +62,21 @@
"output_type": "stream",
"text": [
"Scale(n) time(ms) feval min(x) max(x) sum(x) x(0) + x(1)\n",
"200 23.15 -0.82 -0.000000 0.010000 1.0000000.014999999999355636\n",
"400 29.00 -1.28 -0.000000 0.010000 1.0000000.014999999999977868\n",
"600 31.04 -1.54 -0.000000 0.010000 1.0000000.014999999999630973\n",
"800 37.00 -1.63 -0.000000 0.010000 1.0000000.014999999999937863\n",
"1000 42.99 -1.72 -0.000000 0.010000 1.0000000.014999999999985369\n",
"1200 83.97 -1.81 -0.000000 0.010000 1.0000000.014999999999661145\n",
"1400 121.77 -1.90 -0.000000 0.010000 1.0000000.014999999999617875\n",
"1600 125.93 -1.96 -0.000000 0.010000 1.0000000.01499999999998295\n",
"1800 75.05 -2.03 -0.000000 0.010000 1.0000000.014999999999785373\n",
"2000 45.95 -2.06 -0.000000 0.010000 1.0000000.014999999999994327\n",
"2200 68.05 -2.07 -0.000000 0.010000 1.0000000.014999999999979582\n",
"2400 144.36 -2.13 -0.000000 0.010000 1.0000000.014999999999836155\n",
"2600 140.00 -2.14 -0.000000 0.010000 1.0000000.01499999999985058\n",
"2800 145.48 -2.16 -0.000000 0.010000 1.0000000.014999999999853686\n",
"3000 125.97 -2.19 -0.000000 0.010000 1.0000000.014999999999981861\n"
"200 16.00 -0.82 -0.000000 0.010000 1.0000000.014999999999355636\n",
"400 14.00 -1.28 -0.000000 0.010000 1.0000000.014999999999977868\n",
"600 15.00 -1.54 -0.000000 0.010000 1.0000000.014999999999630973\n",
"800 16.00 -1.63 -0.000000 0.010000 1.0000000.014999999999937863\n",
"1000 20.00 -1.72 -0.000000 0.010000 1.0000000.014999999999985369\n",
"1200 24.00 -1.81 -0.000000 0.010000 1.0000000.014999999999661145\n",
"1400 27.00 -1.90 -0.000000 0.010000 1.0000000.014999999999617875\n",
"1600 36.00 -1.96 -0.000000 0.010000 1.0000000.01499999999998295\n",
"1800 35.03 -2.03 -0.000000 0.010000 1.0000000.014999999999785373\n",
"2000 43.00 -2.06 -0.000000 0.010000 1.0000000.014999999999994327\n",
"2200 36.97 -2.07 -0.000000 0.010000 1.0000000.014999999999979582\n",
"2400 45.00 -2.13 -0.000000 0.010000 1.0000000.014999999999836155\n",
"2600 49.00 -2.14 -0.000000 0.010000 1.0000000.01499999999985058\n",
"2800 59.00 -2.16 -0.000000 0.010000 1.0000000.014999999999853686\n",
"3000 61.00 -2.19 -0.000000 0.010000 1.0000000.014999999999981861\n"
]
}
],
......@@ -91,7 +91,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
......@@ -114,7 +114,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 5,
"metadata": {},
"outputs": [
{
......@@ -122,21 +122,21 @@
"output_type": "stream",
"text": [
"Scale(n) time(ms) feval min(x) max(x) sum(x) x(0) + x(1)\n",
"200 4.00 -0.82 0.000000 0.010000 1.0000000.015000000005429394\n",
"400 5.38 -1.28 0.000000 0.010000 1.0000000.015000000000751215\n",
"600 5.02 -1.54 0.000000 0.010000 1.0000000.01500000000851949\n",
"800 7.89 -1.63 0.000000 0.010000 1.0000000.015000000002481837\n",
"1000 7.97 -1.72 0.000000 0.010000 1.0000000.015000000001100414\n",
"1200 14.04 -1.81 0.000000 0.010000 1.0000000.01500000000548405\n",
"1400 13.85 -1.90 0.000000 0.010000 1.0000000.015000000001956426\n",
"1600 20.96 -1.96 0.000000 0.010000 1.0000000.015000000000082848\n",
"1800 26.95 -2.03 0.000000 0.010000 1.0000000.01500000000204834\n",
"2000 25.59 -2.06 0.000000 0.010000 1.0000000.0150000000008303\n",
"2200 27.25 -2.07 0.000000 0.010000 1.0000000.01500000000729576\n",
"2400 13.10 -2.13 0.000000 0.010000 1.0000000.015000000004022507\n",
"2600 19.00 -2.14 0.000000 0.010000 1.0000000.015000000001118521\n",
"2800 30.60 -2.16 0.000000 0.010000 1.0000000.01500000000064263\n",
"3000 25.00 -2.19 0.000000 0.010000 1.0000000.015000000003030482\n"
"200 2.00 -0.82 0.000000 0.010000 1.0000000.015000000005429394\n",
"400 3.00 -1.28 0.000000 0.010000 1.0000000.015000000000751215\n",
"600 3.00 -1.54 0.000000 0.010000 1.0000000.01500000000851949\n",
"800 5.00 -1.63 0.000000 0.010000 1.0000000.015000000002481837\n",
"1000 9.00 -1.72 0.000000 0.010000 1.0000000.015000000001100414\n",
"1200 7.00 -1.81 0.000000 0.010000 1.0000000.01500000000548405\n",
"1400 7.03 -1.90 0.000000 0.010000 1.0000000.015000000001956426\n",
"1600 7.97 -1.96 0.000000 0.010000 1.0000000.015000000000082848\n",
"1800 8.00 -2.03 0.000000 0.010000 1.0000000.01500000000204834\n",
"2000 10.03 -2.06 0.000000 0.010000 1.0000000.0150000000008303\n",
"2200 15.97 -2.07 0.000000 0.010000 1.0000000.01500000000729576\n",
"2400 16.03 -2.13 0.000000 0.010000 1.0000000.015000000004022507\n",
"2600 13.97 -2.14 0.000000 0.010000 1.0000000.015000000001118521\n",
"2800 17.02 -2.16 0.000000 0.010000 1.0000000.01500000000064263\n",
"3000 17.98 -2.19 0.000000 0.010000 1.0000000.015000000003030482\n"
]
}
],
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -51,73 +51,73 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.161516</td>\n",
" <td>0.400066</td>\n",
" <td>0.0</td>\n",
" <td>5.0</td>\n",
" <td>0.441676</td>\n",
" <td>0.559719</td>\n",
" <td>4.0</td>\n",
" <td>8.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.713214</td>\n",
" <td>0.742485</td>\n",
" <td>0.984315</td>\n",
" <td>0.765652</td>\n",
" <td>9.0</td>\n",
" <td>9.0</td>\n",
" <td>8.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.613470</td>\n",
" <td>0.492425</td>\n",
" <td>7.0</td>\n",
" <td>6.0</td>\n",
" <td>0.303978</td>\n",
" <td>0.050506</td>\n",
" <td>2.0</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.440124</td>\n",
" <td>0.701836</td>\n",
" <td>4.0</td>\n",
" <td>7.0</td>\n",
" <td>0.528663</td>\n",
" <td>0.153304</td>\n",
" <td>5.0</td>\n",
" <td>2.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.301544</td>\n",
" <td>0.180132</td>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" <td>0.533509</td>\n",
" <td>0.509512</td>\n",
" <td>6.0</td>\n",
" <td>7.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0.505832</td>\n",
" <td>0.069305</td>\n",
" <td>5.0</td>\n",
" <td>0.634676</td>\n",
" <td>0.075323</td>\n",
" <td>7.0</td>\n",
" <td>1.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>0.513519</td>\n",
" <td>0.354891</td>\n",
" <td>6.0</td>\n",
" <td>4.0</td>\n",
" <td>0.255377</td>\n",
" <td>0.221123</td>\n",
" <td>1.0</td>\n",
" <td>3.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>0.206737</td>\n",
" <td>0.061027</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>0.803129</td>\n",
" <td>0.423008</td>\n",
" <td>8.0</td>\n",
" <td>5.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>0.437573</td>\n",
" <td>0.916369</td>\n",
" <td>0.322453</td>\n",
" <td>0.449833</td>\n",
" <td>3.0</td>\n",
" <td>9.0</td>\n",
" <td>6.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>0.670278</td>\n",
" <td>0.299662</td>\n",
" <td>8.0</td>\n",
" <td>3.0</td>\n",
" <td>0.198229</td>\n",
" <td>0.229450</td>\n",
" <td>0.0</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
......@@ -125,16 +125,16 @@
],
"text/plain": [
" factor_1 factor_2 rank_1 rank_2\n",
"0 0.161516 0.400066 0.0 5.0\n",
"1 0.713214 0.742485 9.0 8.0\n",
"2 0.613470 0.492425 7.0 6.0\n",
"3 0.440124 0.701836 4.0 7.0\n",
"4 0.301544 0.180132 2.0 2.0\n",
"5 0.505832 0.069305 5.0 1.0\n",
"6 0.513519 0.354891 6.0 4.0\n",
"7 0.206737 0.061027 1.0 0.0\n",
"8 0.437573 0.916369 3.0 9.0\n",
"9 0.670278 0.299662 8.0 3.0"
"0 0.441676 0.559719 4.0 8.0\n",
"1 0.984315 0.765652 9.0 9.0\n",
"2 0.303978 0.050506 2.0 0.0\n",
"3 0.528663 0.153304 5.0 2.0\n",
"4 0.533509 0.509512 6.0 7.0\n",
"5 0.634676 0.075323 7.0 1.0\n",
"6 0.255377 0.221123 1.0 3.0\n",
"7 0.803129 0.423008 8.0 5.0\n",
"8 0.322453 0.449833 3.0 6.0\n",
"9 0.198229 0.229450 0.0 4.0"
]
},
"execution_count": 1,
......@@ -189,53 +189,53 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.990521</td>\n",
" <td>4</td>\n",
" <td>0.473528</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.366384</td>\n",
" <td>1</td>\n",
" <td>0.036662</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.098782</td>\n",
" <td>0</td>\n",
" <td>0.699256</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.644139</td>\n",
" <td>2</td>\n",
" <td>0.939615</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.790434</td>\n",
" <td>0.762472</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0.775871</td>\n",
" <td>0.054182</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>0.871524</td>\n",
" <td>2</td>\n",
" <td>0.906340</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>0.910101</td>\n",
" <td>3</td>\n",
" <td>0.141024</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>0.863434</td>\n",
" <td>1</td>\n",
" <td>0.387577</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>0.923118</td>\n",
" <td>4</td>\n",
" <td>0.868477</td>\n",
" <td>3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
......@@ -243,16 +243,16 @@
],
"text/plain": [
" factor_1 rank\n",
"0 0.990521 4\n",
"1 0.366384 1\n",
"2 0.098782 0\n",
"3 0.644139 2\n",
"4 0.790434 3\n",
"5 0.775871 0\n",
"6 0.871524 2\n",
"7 0.910101 3\n",
"8 0.863434 1\n",
"9 0.923118 4"
"0 0.473528 1\n",
"1 0.036662 0\n",
"2 0.699256 2\n",
"3 0.939615 4\n",
"4 0.762472 3\n",
"5 0.054182 0\n",
"6 0.906340 4\n",
"7 0.141024 1\n",
"8 0.387577 2\n",
"9 0.868477 3"
]
},
"execution_count": 2,
......@@ -314,63 +314,63 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.990521</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>0.473528</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.366384</td>\n",
" <td>1</td>\n",
" <td>0.036662</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.098782</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0.699256</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.644139</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>0.939615</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.790434</td>\n",
" <td>0.762472</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0.775871</td>\n",
" <td>0.054182</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>0.871524</td>\n",
" <td>2</td>\n",
" <td>3</td>\n",
" <td>0.906340</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>0.910101</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>0.141024</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>0.863434</td>\n",
" <td>1</td>\n",
" <td>0.387577</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>0.923118</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>0.868477</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
......@@ -378,16 +378,16 @@
],
"text/plain": [
" factor_1 rank quantile\n",
"0 0.990521 4 4\n",
"1 0.366384 1 0\n",
"2 0.098782 0 0\n",
"3 0.644139 2 1\n",
"4 0.790434 3 2\n",
"5 0.775871 0 1\n",
"6 0.871524 2 3\n",
"7 0.910101 3 3\n",
"8 0.863434 1 2\n",
"9 0.923118 4 4"
"0 0.473528 1 2\n",
"1 0.036662 0 0\n",
"2 0.699256 2 2\n",
"3 0.939615 4 4\n",
"4 0.762472 3 3\n",
"5 0.054182 0 0\n",
"6 0.906340 4 4\n",
"7 0.141024 1 1\n",
"8 0.387577 2 1\n",
"9 0.868477 3 3"
]
},
"execution_count": 3,
......
......@@ -31,24 +31,10 @@
"output_type": "stream",
"text": [
"Optimization status - optimal\n",
"Optimal expect return - 0.750529042208698\n",
"Optimial portfolio weights - [0.1 0.2 0.05 0.4 0.25]\n",
"Initial portfolio weights - [0.1 0.2 0. 0.4 0.3]\n",
"Turn over amount - 0.10000000000050759\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\site-packages\\cvxpy\\expressions\\expression.py:550: UserWarning: \n",
"This use of ``*`` has resulted in matrix multiplication.\n",
"Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.\n",
" Use ``*`` for matrix-scalar and vector-scalar multiplication.\n",
" Use ``@`` for matrix-matrix and matrix-vector multiplication.\n",
" Use ``multiply`` for elementwise multiplication.\n",
"\n",
" warnings.warn(__STAR_MATMUL_WARNING__, UserWarning)\n"
"Optimal expect return - -0.5259220412385935\n",
"Optimial portfolio weights - [0.11111111 0.38333333 0.22222222 0.11111111 0.17222222]\n",
"Initial portfolio weights - [0.11111111 0.33333333 0.22222222 0.11111111 0.22222222]\n",
"Turn over amount - 0.10000000000058906\n"
]
}
],
......@@ -195,16 +181,7 @@
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\ProgramData\\Anaconda3\\envs\\alpha-mind\\lib\\importlib\\_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n",
" return f(*args, **kwds)\n"
]
}
],
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -24,7 +24,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -39,7 +39,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -53,7 +53,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
......@@ -69,19 +69,19 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"neutralized_factors = neutralize(total_data[neutralized_styles].values.astype(float),\n",
" total_data[factors_names].values,\n",
" groups=total_data['trade_date'])\n",
" groups=total_data['trade_date'].values)\n",
"total_data[factors_names] = neutralized_factors"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
......@@ -94,9 +94,32 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"<AxesSubplot:>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1008x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"values.plot(kind='bar', figsize=(14, 8))"
]
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -15,4 +15,5 @@ scikit-learn
scipy
simpleutils
sqlalchemy
statsmodels
xgboost
\ No newline at end of file
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