Commit 8c5d6604 authored by Dr.李's avatar Dr.李

remove unnecessary files

parent 881d14a2
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import pandas as pd\n",
"from matplotlib import pyplot as plt\n",
"from alphamind.api import *\n",
"from PyFin.api import *\n",
"from PyFin.Math.Accumulators import MovingMaxDrawdown\n",
"plt.style.use('fivethirtyeight')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 0. Parameter Settings\n",
"---------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"engine = SqlEngine('postgres+psycopg2://postgres:A12345678!@10.63.6.220/alpha')\n",
"universe = Universe('custom', ['zz500'])\n",
"benchmark_code = 905\n",
"neutralize_risk = ['SIZE'] + industry_styles\n",
"constraint_risk = ['SIZE'] + industry_styles\n",
"start_date = '2015-01-01'\n",
"end_date = '2017-10-17'\n",
"industry_lower = 0.75\n",
"industry_upper = 1.25\n",
"\n",
"freq = '1d'\n",
"horizon = map_freq(freq)\n",
"dates = makeSchedule(start_date, end_date, tenor=freq, calendar='china.sse', dateGenerationRule=DateGeneration.Backward)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Current Production Strategy\n",
"-----------------------\n",
"\n",
"* **Factor Group #1**\n",
" * RVOL: 0.05\n",
" * EPS: 0.3\n",
" * DROEAfterNonRecurring: 0.35\n",
" * DivP: 0.075\n",
" * CFinc1: 0.15\n",
" * BDTO: 0.05\n",
" \n",
" \n",
"* **Factor Group #2**\n",
" * VAL: 0.034129344\n",
" * RVOL: 0.015881607\n",
" * ROEDiluted: 0.048765746\n",
" * GREV: 0.042747382\n",
" * EPS: -0.015900173\n",
" * CHV: 0.019044573\n",
" * CFinc1: -0.001792638\n",
" * BDTO: 0.014277867"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factor_group1 = ['RVOL', 'EPS', 'DROEAfterNonRecurring', 'DivP', 'CFinc1', 'BDTO']\n",
"factor_weight1 = [0.05, 0.3, 0.35, 0.075, 0.15, 0.05]\n",
"\n",
"factor_group2 = ['VAL', 'RVOL', 'ROEDiluted', 'GREV', 'EPS', 'CHV', 'CFinc1', 'BDTO']\n",
"factor_weight2 = [0.034129344, 0.015881607, 0.048765746, 0.042747382, -0.015900173, 0.019044573, -0.001792638, 0.014277867]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factors = list(set(factor_group1 + factor_group2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"all_data = engine.fetch_data_range(universe, factors, dates=dates, benchmark=905)\n",
"factor_all_data = all_data['factor']\n",
"factor_groups = factor_all_data.groupby('trade_date')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"turn_over_threshold = 0.70\n",
"executor = ThresholdExecutor(turn_over_threshold=turn_over_threshold)\n",
"execution_pipeline = ExecutionPipeline(executors=[executor])\n",
"leverags = []\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" total_data = data.dropna()\n",
" dx_return = None\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" if name == 'total' or name == 'SIZE':\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" else:\n",
" constraint.set_constraints(name, lower_bound=risk_target[i]*industry_lower, upper_bound=risk_target[i]*industry_upper)\n",
" \n",
" er1 = factor_processing(total_data[factor_group1].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight1\n",
" \n",
" er2 = factor_processing(total_data[factor_group2].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight2\n",
" \n",
" er = (er1 / er1.std() + er2 / er2.std())\n",
" \n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" target_pos['code'] = total_data['code'].values\n",
" \n",
" turn_over, executed_pos = execution_pipeline.execute(target_pos=target_pos)\n",
" \n",
" executed_codes = executed_pos.code.tolist()\n",
" dx_retuns = engine.fetch_dx_return(advanceDateByCalendar('china.sse', date, '1b').strftime('%Y-%m-%d'),\n",
" executed_codes,\n",
" horizon=horizon)\n",
" \n",
" result = pd.merge(executed_pos, total_data, on=['code'], how='inner')\n",
" result = pd.merge(result, dx_retuns, on=['code'])\n",
" leverage = result.weight_x.abs().sum()\n",
" \n",
" ret = (result.weight_x - result.weight_y).values @ result.dx.values\n",
" rets.append(ret)\n",
" leverags.append(executed_pos.weight.abs().sum())\n",
" turn_overs.append(turn_over)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df1 = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df1.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df1 = ret_df1.shift(1)\n",
"ret_df1.iloc[0] = 0.\n",
"ret_df1['tc_cost'] = ret_df1.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df1[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Threshold tc rebalanced: Monitored freq {0}, {1} tc'.format(freq,\n",
" turn_over_threshold),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_atfer_tc = ret_df1.returns - ret_df1.tc_cost\n",
"mmd = MovingMaxDrawdown(window=len(ret_atfer_tc))\n",
"\n",
"for ret in ret_atfer_tc:\n",
" mmd.push({'ret': ret})\n",
"\n",
"print(\"total return: \", ret_atfer_tc.mean() * 252 * 100)\n",
"print(\"sharp: \", ret_atfer_tc.mean() / ret_atfer_tc.std() * np.sqrt(252))\n",
"print(\"mmd: \", -mmd.result()[0]*100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Current Production Strategy with Target Turn Over\n",
"--------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"turn_over_target_base = 0.04\n",
"executor = NaiveExecutor()\n",
"execution_pipeline = ExecutionPipeline(executors=[executor])\n",
"leverags = []\n",
"previous_pos = pd.DataFrame()\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" total_data = data.dropna()\n",
" dx_return = None\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" if name == 'total' or name == 'SIZE':\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" else:\n",
" constraint.set_constraints(name, lower_bound=risk_target[i]*industry_lower, upper_bound=risk_target[i]*industry_upper)\n",
" \n",
" er1 = factor_processing(total_data[factor_group1].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight1\n",
" \n",
" er2 = factor_processing(total_data[factor_group2].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight2\n",
" \n",
" er = (er1 / er1.std() + er2 / er2.std())\n",
" \n",
" codes = total_data['code'].values\n",
" \n",
" if previous_pos.empty:\n",
" current_position = None\n",
" turn_over_target = None\n",
" else:\n",
" previous_pos.set_index('code', inplace=True)\n",
" remained_pos = previous_pos.loc[codes]\n",
" \n",
" remained_pos.fillna(0., inplace=True)\n",
" turn_over_target = turn_over_target_base\n",
" \n",
" current_position = remained_pos.weight.values\n",
" \n",
" try:\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w,\n",
" current_position=current_position,\n",
" turn_over_target=turn_over_target)\n",
" except ValueError:\n",
" print('{0} full rebalance'.format(date))\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" \n",
" target_pos['code'] = codes\n",
" \n",
" turn_over, executed_pos = execution_pipeline.execute(target_pos=target_pos)\n",
" \n",
" executed_codes = executed_pos.code.tolist()\n",
" dx_retuns = engine.fetch_dx_return(advanceDateByCalendar('china.sse', date, '1b').strftime('%Y-%m-%d'),\n",
" executed_codes,\n",
" horizon=horizon)\n",
" \n",
" result = pd.merge(executed_pos, total_data, on=['code'], how='inner')\n",
" result = pd.merge(result, dx_retuns, on=['code'])\n",
" \n",
" ret = (result.weight_x - result.weight_y ).values @ result.dx.values\n",
" rets.append(ret)\n",
" turn_overs.append(turn_over)\n",
" previous_pos = executed_pos"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df2 = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df2.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df2 = ret_df2.shift(1)\n",
"ret_df2.iloc[0] = 0.\n",
"ret_df2['tc_cost'] = ret_df2.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df2[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Target turn over rebalanced: Rebalance freq {0}, {1} turnover_target'.format(freq, turn_over_target_base),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_atfer_tc = ret_df2.returns - ret_df2.tc_cost\n",
"mmd = MovingMaxDrawdown(window=len(ret_atfer_tc))\n",
"\n",
"for ret in ret_atfer_tc:\n",
" mmd.push({'ret': ret})\n",
"\n",
"print(\"total return: \", ret_atfer_tc.mean() * 252 * 100)\n",
"print(\"sharp: \", ret_atfer_tc.mean() / ret_atfer_tc.std() * np.sqrt(252))\n",
"print(\"mmd: \", -mmd.result()[0]*100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Candidate Strategy\n",
"---------------------\n",
"\n",
"* **Factor Group #1**\n",
" * RVOL: 0.05\n",
" * EPS: 0.3\n",
" * DROEAfterNonRecurring: 0.35\n",
" * DivP: 0.075\n",
" * CFinc1: 0.15\n",
" * BDTO: 0.05\n",
" \n",
" \n",
"* **Factor Group #2**\n",
" * VAL: 0.034129344\n",
" * IVR: 0.015881607\n",
" * ROEDiluted: 0.048765746\n",
" * GREV: 0.042747382\n",
" * EPS: -0.015900173\n",
" * CHV: 0.019044573\n",
" * CFinc1: -0.001792638\n",
" * BDTO: 0.014277867\n",
"\n",
"\n",
"* **Factor Group #3**\n",
" * con_pe_rolling: -0.6\n",
" * con_pb_rolling: -0.6\n",
" * con_eps: 0.6\n",
" * con_target_price: 1.2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"factor_group1 = ['RVOL', 'EPS', 'DROEAfterNonRecurring', 'DivP', 'CFinc1', 'BDTO']\n",
"factor_weight1 = [0.05, 0.3, 0.35, 0.075, 0.15, 0.05]\n",
"group_weight1 = 1.\n",
"\n",
"factor_group2 = ['VAL', 'IVR', 'ROEDiluted', 'GREV', 'EPS', 'CHV', 'CFinc1', 'BDTO']\n",
"factor_weight2 = [0.034129344, 0.02, 0.048765746, 0.042747382, -0.015900173, 0.019044573, -0.001792638, 0.014277867]\n",
"group_weight2 = 1.\n",
"\n",
"factor_group3 = ['cs_pe', 'cs_pb', 'cs_eps']\n",
"factor_weight3 = [-0.6, -0.6, 0.6]\n",
"group_weight3 = 0.25"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factors = {'RVOL': LAST('RVOL'),\n",
" 'EPS': LAST('EPS'),\n",
" 'DROEAfterNonRecurring': LAST('DROEAfterNonRecurring'),\n",
" 'DivP': LAST('DivP'),\n",
" 'CFinc1': LAST('CFinc1'),\n",
" 'BDTO': LAST('BDTO'),\n",
" 'VAL': LAST('VAL'),\n",
" 'ROEDiluted': LAST('ROEDiluted'),\n",
" 'GREV': LAST('GREV'),\n",
" 'CHV': LAST('CHV'),\n",
" 'cs_pe': LAST('con_pe_rolling'),\n",
" 'cs_pb': LAST('con_pb_rolling'),\n",
" 'cs_eps': LAST('con_eps_rolling'),\n",
" 'IVR': LAST('IVR')}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"all_data = engine.fetch_data_range(universe, factors, dates=dates, benchmark=905)\n",
"factor_all_data = all_data['factor']\n",
"factor_groups = factor_all_data.groupby('trade_date')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"turn_over_threshold = 0.70\n",
"executor = ThresholdExecutor(turn_over_threshold=turn_over_threshold)\n",
"execution_pipeline = ExecutionPipeline(executors=[executor])\n",
"leverags = []\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" total_data = data.dropna()\n",
" dx_return = None\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" if name == 'total' or name == 'SIZE':\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" else:\n",
" constraint.set_constraints(name, lower_bound=risk_target[i]*industry_lower, upper_bound=risk_target[i]*industry_upper)\n",
" \n",
" er1 = factor_processing(total_data[factor_group1].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight1\n",
" \n",
" er2 = factor_processing(total_data[factor_group2].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight2\n",
" \n",
" er3 = factor_processing((total_data[factor_group3].values @ factor_weight3).reshape((-1,1)),\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]).flatten()\n",
" \n",
" er = (group_weight1* er1 / er1.std() + \n",
" group_weight2 * er2 / er2.std() + \n",
" group_weight3 * er3 / er3.std())\n",
" \n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" target_pos['code'] = total_data['code'].values\n",
" \n",
" turn_over, executed_pos = execution_pipeline.execute(target_pos=target_pos)\n",
" \n",
" executed_codes = executed_pos.code.tolist()\n",
" dx_retuns = engine.fetch_dx_return(advanceDateByCalendar('china.sse', date, '1b').strftime('%Y-%m-%d'),\n",
" executed_codes,\n",
" horizon=horizon)\n",
" \n",
" result = pd.merge(executed_pos, total_data, on=['code'], how='inner')\n",
" result = pd.merge(result, dx_retuns, on=['code'])\n",
" \n",
" ret = (result.weight_x - result.weight_y).values @ result.dx.values\n",
" rets.append(ret)\n",
" leverags.append(executed_pos.weight.abs().sum())\n",
" turn_overs.append(turn_over)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df3 = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df3.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df3 = ret_df3.shift(1)\n",
"ret_df3.iloc[0] = 0.\n",
"ret_df3['tc_cost'] = ret_df3.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df3[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Threshold tc rebalanced: Monitored freq {0}, {1} tc'.format(freq,\n",
" turn_over_threshold),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_atfer_tc = ret_df3.returns - ret_df3.tc_cost\n",
"\n",
"mmd = MovingMaxDrawdown(window=len(ret_atfer_tc))\n",
"\n",
"for ret in ret_atfer_tc:\n",
" mmd.push({'ret': ret})\n",
"\n",
"print(\"total return: \", ret_atfer_tc.mean() * 252 * 100)\n",
"print(\"sharp: \", ret_atfer_tc.mean() / ret_atfer_tc.std() * np.sqrt(252))\n",
"print(\"mmd: \", -mmd.result()[0]*100)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## 4. Candidate Strategy with Target Turn Over\n",
"-----------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"turn_over_target_base = 0.04\n",
"executor = NaiveExecutor()\n",
"execution_pipeline = ExecutionPipeline(executors=[executor])\n",
"leverags = []\n",
"previous_pos = pd.DataFrame()\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" total_data = data.dropna()\n",
" dx_return = None\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" if name == 'total' or name == 'SIZE':\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" else:\n",
" constraint.set_constraints(name, lower_bound=risk_target[i]*industry_lower, upper_bound=risk_target[i]*industry_upper)\n",
" \n",
" er1 = factor_processing(total_data[factor_group1].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight1\n",
" \n",
" er2 = factor_processing(total_data[factor_group2].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]) @ factor_weight2\n",
" \n",
" er3 = factor_processing((total_data[factor_group3].values @ factor_weight3).reshape((-1,1)),\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize]).flatten()\n",
" \n",
" er = (group_weight1* er1 / er1.std() + \n",
" group_weight2 * er2 / er2.std() + \n",
" group_weight3 * er3 / er3.std())\n",
" \n",
" codes = total_data['code'].values\n",
" \n",
" if previous_pos.empty:\n",
" current_position = None\n",
" turn_over_target = None\n",
" else:\n",
" previous_pos.set_index('code', inplace=True)\n",
" remained_pos = previous_pos.loc[codes]\n",
" \n",
" remained_pos.fillna(0., inplace=True)\n",
" turn_over_target = turn_over_target_base\n",
" \n",
" current_position = remained_pos.weight.values\n",
" \n",
" try:\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w,\n",
" current_position=current_position,\n",
" turn_over_target=turn_over_target)\n",
" except ValueError:\n",
" print('{0} full rebalance'.format(date))\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" \n",
" target_pos['code'] = codes\n",
" \n",
" turn_over, executed_pos = execution_pipeline.execute(target_pos=target_pos)\n",
" \n",
" executed_codes = executed_pos.code.tolist()\n",
" dx_retuns = engine.fetch_dx_return(advanceDateByCalendar('china.sse', date, '1b').strftime('%Y-%m-%d'),\n",
" executed_codes,\n",
" horizon=horizon)\n",
" \n",
" result = pd.merge(executed_pos, total_data, on=['code'], how='inner')\n",
" result = pd.merge(result, dx_retuns, on=['code'])\n",
" ret = (result.weight_x - result.weight_y).values @ result.dx.values\n",
" rets.append(ret)\n",
" turn_overs.append(turn_over)\n",
" previous_pos = executed_pos"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df4 = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df4.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df4 = ret_df4.shift(1)\n",
"ret_df4.iloc[0] = 0.\n",
"ret_df4['tc_cost'] = ret_df4.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df4[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Target turn over rebalanced: Rebalance freq {0}, {1} turnover_target'.format(freq, turn_over_target_base),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_atfer_tc = ret_df4.returns - ret_df4.tc_cost\n",
"mmd = MovingMaxDrawdown(window=len(ret_atfer_tc))\n",
"\n",
"for ret in ret_atfer_tc:\n",
" mmd.push({'ret': ret})\n",
"\n",
"print(\"total return: \", ret_atfer_tc.mean() * 252 * 100)\n",
"print(\"sharp: \", ret_atfer_tc.mean() / ret_atfer_tc.std() * np.sqrt(252))\n",
"print(\"mmd: \", -mmd.result()[0]*100)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import sqlalchemy\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"server = 'rm-bp1psdz5615icqc0yo.mysql.rds.aliyuncs.com'\n",
"user = 'sa'\n",
"pwd = 'We051253524522'\n",
"\n",
"engine = sqlalchemy.create_engine('mysql+pymysql://{0}:{1}@{2}/multifactor?charset=utf8'.format(user, pwd, server))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"index_components = pd.read_sql('select * from index_components', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"index_components.to_hdf('multifactor.hdf', 'index_components')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"index_data = pd.read_sql('select * from index_data', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"index_data.to_hdf('multifactor.hdf', 'index_data')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"prod_500 = pd.read_sql('select * from prod_500', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"prod_500.to_hdf('multifactor.hdf', 'prod_500')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_500 = pd.read_sql('select * from risk_factor_500', engine)\n",
"risk_factor_500['Market'] = 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_500.to_hdf('multifactor.hdf', 'risk_factor_500')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"trade_data = pd.read_sql('select * from trade_data', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"trade_data.to_hdf('multifactor.hdf', 'trade_data')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"prod_300 = pd.read_sql('select * from prod_300', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"prod_300.to_hdf('multifactor.hdf', 'prod_300')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_300 = pd.read_sql('select * from risk_factor_300', engine)\n",
"risk_factor_300['Market'] = 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"risk_factor_300.to_hdf('multifactor.hdf', 'risk_factor_300')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"factor_data = pd.read_sql('select * from factor_data', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factor_data.to_hdf('multifactor.hdf', 'factor_data')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"prod_500 = pd.read_hdf('multifactor.hdf', 'prod_500')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"prod_factor_cols = pd.Series(['CFinc1', 'BDTO', 'RVOL', 'CHV', 'VAL'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"prod_factor_cols.to_hdf('multifactor.hdf', 'prod_factor_cols')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_500 = pd.read_hdf('multifactor.hdf', 'risk_factor_500')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"del risk_factor_500['Bank']\n",
"del risk_factor_500['NonBankFinancial']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_cols = pd.Series(risk_factor_500.columns[2:].tolist())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_cols.to_hdf('multifactor.hdf', 'risk_factor_cols')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factor_data = pd.read_hdf('multifactor.hdf', 'factor_data')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"common_factor_cols = pd.Series(factor_data.columns[5:].tolist())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"common_factor_cols.to_hdf('multifactor.hdf', 'common_factor_cols')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"risk_factor_500.columns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"return_data_300 = pd.read_sql('select * from return_data_300', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"return_data_300.to_hdf('multifactor.hdf', 'return_data_300')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"return_data_500 = pd.read_sql('select * from return_data_500', engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"return_data_500.to_hdf('multifactor.hdf', 'return_data_500')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.3"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import pandas as pd\n",
"from alphamind.api import *\n",
"from PyFin.api import *\n",
"from matplotlib import pyplot as plt\n",
"plt.style.use('fivethirtyeight')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Parameter Setting\n",
"----------------------"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def _map_freq(freq):\n",
"\n",
" if freq == '1m':\n",
" horizon = 21\n",
" elif freq == '1w':\n",
" horizon = 4\n",
" elif freq == '2w':\n",
" horizon = 8\n",
" elif freq == '3w':\n",
" horizon = 12\n",
" elif freq == '1d':\n",
" horizon = 0\n",
" else:\n",
" raise ValueError(\"Unrecognized freq: {0}\".format(freq))\n",
" return horizon"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"factors = ['VAL', 'ROEDiluted', 'GREV', 'EPS', 'CHV', 'CFinc1', 'BDTO', 'IVR']\n",
"factor_weights = np.array([0.034129344,\n",
" 0.048765746,\n",
" 0.042747382,\n",
" -0.015900173,\n",
" 0.019044573,\n",
" -0.001792638,\n",
" 0.014277867,\n",
" 0.04])\n",
"\n",
"engine = SqlEngine(\"postgres+psycopg2://postgres:we083826@192.168.0.102/alpha\")\n",
"universe = Universe('custom', ['zz500'])\n",
"benchmark_code = 905\n",
"neutralize_risk = ['SIZE'] + industry_styles\n",
"constraint_risk = ['SIZE'] + industry_styles\n",
"start_date = '2017-01-01'\n",
"end_date = '2017-09-20'\n",
"\n",
"freq = '1w'\n",
"horizon = _map_freq(freq)\n",
"dates = makeSchedule(start_date, end_date, tenor=freq, calendar='china.sse', dateGenerationRule=DateGeneration.Backward)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"ename": "OperationalError",
"evalue": "(psycopg2.OperationalError) could not connect to server: Connection timed out (0x0000274C/10060)\n\tIs the server running on host \"192.168.0.102\" and accepting\n\tTCP/IP connections on port 5432?\n",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mEmpty\u001b[0m Traceback (most recent call last)",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_do_get\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1121\u001b[0m \u001b[0mwait\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0muse_overflow\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_overflow\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_max_overflow\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1122\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_pool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwait\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_timeout\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1123\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0msqla_queue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mEmpty\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\queue.py\u001b[0m in \u001b[0;36mget\u001b[1;34m(self, block, timeout)\u001b[0m\n\u001b[0;32m 144\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_empty\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--> 145\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mEmpty\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 146\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mEmpty\u001b[0m: ",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001b[1;31mOperationalError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\base.py\u001b[0m in \u001b[0;36m_wrap_pool_connect\u001b[1;34m(self, fn, connection)\u001b[0m\n\u001b[0;32m 2146\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 2147\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mfn\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 2148\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mdialect\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdbapi\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 386\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_use_threadlocal\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 387\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_ConnectionFairy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_checkout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 388\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_checkout\u001b[1;34m(cls, pool, threadconns, fairy)\u001b[0m\n\u001b[0;32m 765\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mfairy\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 766\u001b[1;33m \u001b[0mfairy\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_ConnectionRecord\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcheckout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpool\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 767\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36mcheckout\u001b[1;34m(cls, pool)\u001b[0m\n\u001b[0;32m 515\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcheckout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 516\u001b[1;33m \u001b[0mrec\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_do_get\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 517\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_do_get\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1137\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mutil\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msafe_reraise\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-> 1138\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_dec_overflow\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 1139\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\langhelpers.py\u001b[0m in \u001b[0;36m__exit__\u001b[1;34m(self, type_, value, traceback)\u001b[0m\n\u001b[0;32m 65\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarn_only\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 66\u001b[1;33m \u001b[0mcompat\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreraise\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexc_type\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_value\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_tb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 67\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\compat.py\u001b[0m in \u001b[0;36mreraise\u001b[1;34m(tp, value, tb, cause)\u001b[0m\n\u001b[0;32m 186\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 187\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 188\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_do_get\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1134\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1135\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_connection\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 1136\u001b[0m \u001b[1;32mexcept\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_create_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 332\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 333\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_ConnectionRecord\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 334\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, pool, connect)\u001b[0m\n\u001b[0;32m 460\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mconnect\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 461\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__connect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfirst_connect_check\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 462\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfinalize_callback\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdeque\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m__connect\u001b[1;34m(self, first_connect_check)\u001b[0m\n\u001b[0;32m 650\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstarttime\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 651\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_invoke_creator\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 652\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogger\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Created new connection %r\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\strategies.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(connection_record)\u001b[0m\n\u001b[0;32m 104\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 105\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mdialect\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mcargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mcparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 106\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\default.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(self, *cargs, **cparams)\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0mcargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mcparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 393\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdbapi\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mcargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mcparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 394\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\psycopg2\\__init__.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(dsn, connection_factory, cursor_factory, **kwargs)\u001b[0m\n\u001b[0;32m 129\u001b[0m \u001b[0mdsn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_ext\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmake_dsn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdsn\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[0m\n\u001b[1;32m--> 130\u001b[1;33m \u001b[0mconn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_connect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdsn\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnection_factory\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mconnection_factory\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwasync\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 131\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcursor_factory\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mOperationalError\u001b[0m: could not connect to server: Connection timed out (0x0000274C/10060)\n\tIs the server running on host \"192.168.0.102\" and accepting\n\tTCP/IP connections on port 5432?\n",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[1;31mOperationalError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-8-1b67018f9ed4>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mall_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mengine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfetch_data_range\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0muniverse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfactors\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdates\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mdates\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbenchmark\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m905\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mfactor_all_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mall_data\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'factor'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mfactor_groups\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfactor_all_data\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'trade_date'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\alpha_mind-0.1.0-py3.6-win-amd64.egg\\alphamind\\data\\engines\\sqlengine.py\u001b[0m in \u001b[0;36mfetch_data_range\u001b[1;34m(self, universe, factors, start_date, end_date, dates, benchmark, risk_model, industry, external_data)\u001b[0m\n\u001b[0;32m 554\u001b[0m \u001b[0mend_date\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 555\u001b[0m \u001b[0mdates\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 556\u001b[1;33m external_data=external_data)\n\u001b[0m\u001b[0;32m 557\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 558\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mbenchmark\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\alpha_mind-0.1.0-py3.6-win-amd64.egg\\alphamind\\data\\engines\\sqlengine.py\u001b[0m in \u001b[0;36mfetch_factor_range\u001b[1;34m(self, universe, factors, start_date, end_date, dates, external_data)\u001b[0m\n\u001b[0;32m 311\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0mselect_from\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbig_table\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 312\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 313\u001b[1;33m \u001b[0mdf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mread_sql\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mengine\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msort_values\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'trade_date'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'code'\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 314\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 315\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mexternal_data\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\pandas\\io\\sql.py\u001b[0m in \u001b[0;36mread_sql\u001b[1;34m(sql, con, index_col, coerce_float, params, parse_dates, columns, chunksize)\u001b[0m\n\u001b[0;32m 414\u001b[0m \u001b[0msql\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mindex_col\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mindex_col\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mparams\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[0;32m 415\u001b[0m \u001b[0mcoerce_float\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcoerce_float\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mparse_dates\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparse_dates\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 416\u001b[1;33m chunksize=chunksize)\n\u001b[0m\u001b[0;32m 417\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 418\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\pandas\\io\\sql.py\u001b[0m in \u001b[0;36mread_query\u001b[1;34m(self, sql, index_col, coerce_float, parse_dates, params, chunksize)\u001b[0m\n\u001b[0;32m 1085\u001b[0m \u001b[0margs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_convert_params\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msql\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[0;32m 1086\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1087\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexecute\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[0m\n\u001b[0m\u001b[0;32m 1088\u001b[0m \u001b[0mcolumns\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1089\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\pandas\\io\\sql.py\u001b[0m in \u001b[0;36mexecute\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 976\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mexecute\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[0;32m 977\u001b[0m \u001b[1;34m\"\"\"Simple passthrough to SQLAlchemy connectable\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 978\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnectable\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexecute\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[0m\n\u001b[0m\u001b[0;32m 979\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 980\u001b[0m def read_table(self, table_name, index_col=None, coerce_float=True,\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\base.py\u001b[0m in \u001b[0;36mexecute\u001b[1;34m(self, statement, *multiparams, **params)\u001b[0m\n\u001b[0;32m 2061\u001b[0m \"\"\"\n\u001b[0;32m 2062\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 2063\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcontextual_connect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mclose_with_result\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2064\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstatement\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0mmultiparams\u001b[0m\u001b[1;33m,\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[0;32m 2065\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\base.py\u001b[0m in \u001b[0;36mcontextual_connect\u001b[1;34m(self, close_with_result, **kwargs)\u001b[0m\n\u001b[0;32m 2110\u001b[0m return self._connection_cls(\n\u001b[0;32m 2111\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 2112\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_wrap_pool_connect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m,\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[0m\u001b[0;32m 2113\u001b[0m \u001b[0mclose_with_result\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mclose_with_result\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2114\u001b[0m **kwargs)\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\base.py\u001b[0m in \u001b[0;36m_wrap_pool_connect\u001b[1;34m(self, fn, connection)\u001b[0m\n\u001b[0;32m 2149\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mconnection\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2150\u001b[0m Connection._handle_dbapi_exception_noconnection(\n\u001b[1;32m-> 2151\u001b[1;33m e, dialect, self)\n\u001b[0m\u001b[0;32m 2152\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2153\u001b[0m \u001b[0mutil\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreraise\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexc_info\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;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\base.py\u001b[0m in \u001b[0;36m_handle_dbapi_exception_noconnection\u001b[1;34m(cls, e, dialect, engine)\u001b[0m\n\u001b[0;32m 1463\u001b[0m util.raise_from_cause(\n\u001b[0;32m 1464\u001b[0m \u001b[0msqlalchemy_exception\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1465\u001b[1;33m \u001b[0mexc_info\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1466\u001b[0m )\n\u001b[0;32m 1467\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\compat.py\u001b[0m in \u001b[0;36mraise_from_cause\u001b[1;34m(exception, exc_info)\u001b[0m\n\u001b[0;32m 201\u001b[0m \u001b[0mexc_type\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_value\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_tb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 202\u001b[0m \u001b[0mcause\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mexc_value\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mexc_value\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mexception\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 203\u001b[1;33m \u001b[0mreraise\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexception\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexception\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtb\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mexc_tb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcause\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcause\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 204\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 205\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mpy3k\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\compat.py\u001b[0m in \u001b[0;36mreraise\u001b[1;34m(tp, value, tb, cause)\u001b[0m\n\u001b[0;32m 184\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__cause__\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcause\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 185\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__traceback__\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mtb\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 186\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 187\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 188\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\base.py\u001b[0m in \u001b[0;36m_wrap_pool_connect\u001b[1;34m(self, fn, connection)\u001b[0m\n\u001b[0;32m 2145\u001b[0m \u001b[0mdialect\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdialect\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2146\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 2147\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mfn\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 2148\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mdialect\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdbapi\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2149\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mconnection\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 385\u001b[0m \"\"\"\n\u001b[0;32m 386\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_use_threadlocal\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 387\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_ConnectionFairy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_checkout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 388\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 389\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_checkout\u001b[1;34m(cls, pool, threadconns, fairy)\u001b[0m\n\u001b[0;32m 764\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_checkout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mthreadconns\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfairy\u001b[0m\u001b[1;33m=\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 765\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mfairy\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 766\u001b[1;33m \u001b[0mfairy\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_ConnectionRecord\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcheckout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpool\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 767\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 768\u001b[0m \u001b[0mfairy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_pool\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36mcheckout\u001b[1;34m(cls, pool)\u001b[0m\n\u001b[0;32m 514\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mclassmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 515\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcheckout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 516\u001b[1;33m \u001b[0mrec\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_do_get\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 517\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 518\u001b[0m \u001b[0mdbapi_connection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrec\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_do_get\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1136\u001b[0m \u001b[1;32mexcept\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1137\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mutil\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msafe_reraise\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-> 1138\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_dec_overflow\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 1139\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1140\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_do_get\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\langhelpers.py\u001b[0m in \u001b[0;36m__exit__\u001b[1;34m(self, type_, value, traceback)\u001b[0m\n\u001b[0;32m 64\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_exc_info\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m \u001b[1;31m# remove potential circular references\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 65\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarn_only\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 66\u001b[1;33m \u001b[0mcompat\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreraise\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexc_type\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_value\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_tb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 67\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 68\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mcompat\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpy3k\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_exc_info\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_exc_info\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[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\util\\compat.py\u001b[0m in \u001b[0;36mreraise\u001b[1;34m(tp, value, tb, cause)\u001b[0m\n\u001b[0;32m 185\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__traceback__\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mtb\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 186\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 187\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 188\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 189\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_do_get\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1133\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_inc_overflow\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 1134\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1135\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_connection\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 1136\u001b[0m \u001b[1;32mexcept\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1137\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mutil\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msafe_reraise\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;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m_create_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 331\u001b[0m \u001b[1;34m\"\"\"Called by subclasses to create a new ConnectionRecord.\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 332\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 333\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_ConnectionRecord\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 334\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 335\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_invalidate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexception\u001b[0m\u001b[1;33m=\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;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, pool, connect)\u001b[0m\n\u001b[0;32m 459\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__pool\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 460\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mconnect\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 461\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__connect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfirst_connect_check\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 462\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfinalize_callback\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdeque\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 463\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\pool.py\u001b[0m in \u001b[0;36m__connect\u001b[1;34m(self, first_connect_check)\u001b[0m\n\u001b[0;32m 649\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 650\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstarttime\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 651\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_invoke_creator\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 652\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogger\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Created new connection %r\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 653\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\strategies.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(connection_record)\u001b[0m\n\u001b[0;32m 103\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mconnection\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 104\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 105\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mdialect\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mcargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mcparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 106\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 107\u001b[0m \u001b[0mcreator\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpop_kwarg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'creator'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnect\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\sqlalchemy\\engine\\default.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(self, *cargs, **cparams)\u001b[0m\n\u001b[0;32m 391\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0mcargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mcparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 393\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdbapi\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mcargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mcparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 394\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 395\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcreate_connect_args\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0murl\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32mD:\\ProgramData\\IntelPython3_2018\\lib\\site-packages\\psycopg2\\__init__.py\u001b[0m in \u001b[0;36mconnect\u001b[1;34m(dsn, connection_factory, cursor_factory, **kwargs)\u001b[0m\n\u001b[0;32m 128\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 129\u001b[0m \u001b[0mdsn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_ext\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmake_dsn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdsn\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[0m\n\u001b[1;32m--> 130\u001b[1;33m \u001b[0mconn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_connect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdsn\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnection_factory\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mconnection_factory\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwasync\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 131\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcursor_factory\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 132\u001b[0m \u001b[0mconn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcursor_factory\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcursor_factory\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mOperationalError\u001b[0m: (psycopg2.OperationalError) could not connect to server: Connection timed out (0x0000274C/10060)\n\tIs the server running on host \"192.168.0.102\" and accepting\n\tTCP/IP connections on port 5432?\n"
]
}
],
"source": [
"all_data = engine.fetch_data_range(universe, factors, dates=dates, benchmark=905)\n",
"factor_all_data = all_data['factor']\n",
"factor_groups = factor_all_data.groupby('trade_date')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Naive Executor Strategy\n",
"---------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"executor = NaiveExecutor()\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" total_data = data.dropna()\n",
" dx_return = None\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" \n",
" er = factor_processing(total_data[factors].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[standardize]) @ factor_weights\n",
" \n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" target_pos['code'] = total_data['code'].values\n",
" \n",
" turn_over, executed_pos = executor.execute(target_pos=target_pos)\n",
" \n",
" executed_codes = executed_pos.code.tolist()\n",
" dx_retuns = engine.fetch_dx_return(date, executed_codes, horizon=horizon)\n",
" \n",
" result = pd.merge(executed_pos, total_data, on=['code'], how='inner')\n",
" result = pd.merge(result, dx_retuns, on=['code'])\n",
" \n",
" ret = (result.weight_x - result.weight_y).values @ result.dx.values\n",
" rets.append(ret)\n",
" turn_overs.append(turn_over)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"ret_df['tc_cost'] = ret_df.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6), title='Fixed frequency rebalanced: {0}'.format(freq), secondary_y='tc_cost')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Threshold Turn Over Strategy\n",
"------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"freq = '1d'\n",
"horizon = _map_freq(freq)\n",
"dates = makeSchedule(start_date, end_date, tenor=freq, calendar='china.sse', dateGenerationRule=DateGeneration.Backward)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"all_data = engine.fetch_data_range(universe, factors, dates=dates, benchmark=905)\n",
"factor_all_data = all_data['factor']\n",
"factor_groups = factor_all_data.groupby('trade_date')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"target_turn_over = 1.\n",
"executor = ThresholdExecutor(target_turn_over)\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" total_data = data.dropna()\n",
" dx_return = None\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" \n",
" er = factor_processing(total_data[factors].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[standardize]) @ factor_weights\n",
" \n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" target_pos['code'] = total_data['code'].values\n",
" \n",
" turn_over, executed_pos = executor.execute(target_pos=target_pos)\n",
" \n",
" executed_codes = executed_pos.code.tolist()\n",
" dx_retuns = engine.fetch_dx_return(date, executed_codes, horizon=horizon)\n",
" \n",
" result = pd.merge(executed_pos, total_data, on=['code'], how='inner')\n",
" result = pd.merge(result, dx_retuns, on=['code'])\n",
" \n",
" ret = (result.weight_x - result.weight_y).values @ result.dx.values\n",
" rets.append(ret)\n",
" turn_overs.append(turn_over)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"ret_df['tc_cost'] = ret_df.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Targeted turn over rebalanced: Monitored freq {0}, {1} target'.format(freq,\n",
" target_turn_over),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%pylab inline\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('ggplot')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"import numpy as np\n",
"import sqlalchemy\n",
"import pandas as pd\n",
"import alphamind.data.neutralize as ne\n",
"import alphamind.data.winsorize as ws\n",
"import alphamind.data.standardize as st\n",
"import alphamind.portfolio.rankbuilder as rb\n",
"import alphamind.portfolio.percentbuilder as pb\n",
"import alphamind.portfolio.linearbuilder as lb\n",
"import alphamind.analysis.riskanalysis as ra"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 4,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"risk_factor_table = 'risk_factor_500'\n",
"benchmark = 'zz500'\n",
"factor = 'NetCash' # 'DROEAfterNonRecurring'\n",
"index_compentns = '500Weight'\n",
"\n",
"conn = sqlalchemy.create_engine('mysql+pymysql://xx:xxxx@xxxx:xxxx/multifactor?charset=utf8')\n",
"factor_df = pd.read_sql('select factor_data.{0}, factor_data.申万一级行业, trade_data.Return as dailyReturn, {1}.*, 1 as Market '\n",
" 'from factor_data, trade_data, {1} '\n",
" 'where factor_data.Date = {1}.Date and factor_data.Code = {1}.Code '\n",
" 'and factor_data.Date = trade_data.Date and factor_data.Code = trade_data.Code;'.format(factor,\n",
" risk_factor_table),\n",
" conn)\n",
"\n",
"index_components_df = pd.read_sql('select Date, Code, {0} from index_components;'.format(index_compentns), conn)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"del factor_df['Bank']\n",
"del factor_df['NonBankFinancial']\n",
"factor_df.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"raw_df = pd.merge(factor_df, index_components_df, on=['Date', 'Code'], how='left')\n",
"raw_df.fillna(0, inplace=True)\n",
"raw_df[index_compentns] = raw_df[index_compentns] / 100."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 10,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"risk_facto_cols = raw_df.columns[5:-1]\n",
"risk_facto_cols"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"df = raw_df.copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"df['d1ret'] = df.dailyReturn.groupby(df.Code).shift(-1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"benchmark_data = pd.read_sql('select {0}, Date from index_data'.format(benchmark), conn)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"benchmark_data['ret'] = benchmark_data[benchmark] / benchmark_data[benchmark].shift(1) - 1.\n",
"benchmark_data['d1ret_b'] = benchmark_data['ret'] .shift(-1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"df = pd.merge(df, benchmark_data[['Date', 'd1ret_b']], on='Date', how='left')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"df.dropna(inplace=True)\n",
"df.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"# to transform industry codes to int variable\n",
"old_ind_values = df['申万一级行业'].copy()\n",
"\n",
"ind_list = df['申万一级行业'].unique()\n",
"ind_dict = {}\n",
"for i, ind in enumerate(ind_list):\n",
" ind_dict[ind] = i\n",
"\n",
"df['申万一级行业'].replace(ind_dict, inplace=True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": true,
"row": 0,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Factor Date Preprocessing (Winsorize -> Standardize -> neutralize)\n",
"-----------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"total_data = df.copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"total_data.loc[:, risk_facto_cols] = total_data[risk_facto_cols].groupby(total_data.Date).transform(lambda x: x / x.sum())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"y = total_data[factor].values\n",
"y.shape = -1, 1\n",
"groups = total_data.Date.values.astype(np.int)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 4,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"total_data['res'] = ne.neutralize(total_data[risk_facto_cols].values,\n",
" st.standardize(ws.winsorize_normal(y, groups=groups),\n",
" groups=groups),\n",
" groups)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 9,
"hidden": true,
"row": 0,
"width": 5
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data[[factor, 'res', 'Date', 'Code']].tail()"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 0,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Factor Performance (long_short)\n",
"------------------------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 5,
"height": 4,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"total_data['pos_long_short'] = total_data.res.groupby(groups).apply(lambda x: x / np.abs(x).sum())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 9,
"hidden": true,
"row": 4,
"width": 6
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data[['pos_long_short', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into = total_data[risk_facto_cols].multiply(total_data.pos_long_short, axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 6,
"height": 18,
"hidden": true,
"row": 4,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().max()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 18,
"hidden": true,
"row": 4,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"ret_series = (total_data.pos_long_short * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 4,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 16,
"hidden": false,
"row": 19,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum()[-60:].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 5,
"height": 5,
"hidden": true,
"row": 0,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data.pos_long_short.groupby(total_data.Date).apply(lambda x: x.sum()).head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 35,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Factor Performance (Long Only - Top 100 Equal Weighted)\n",
"------------------------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": true,
"row": 17,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"use_rank = 100\n",
"total_data['pos_100'] = rb.rank_build(total_data.res.values, use_rank, groups) / use_rank"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 9,
"hidden": true,
"row": 17,
"width": 6
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data[['pos_100', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into = total_data[risk_facto_cols].multiply(total_data.pos_100 - total_data[index_compentns], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 18,
"hidden": true,
"row": 17,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().max()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 18,
"hidden": true,
"row": 17,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"ret_series = ((total_data.pos_100 - total_data[index_compentns]) * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 39,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 16,
"hidden": false,
"row": 54,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum()[-30:].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 5,
"hidden": true,
"row": 17,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data.pos_100.groupby(total_data.Date).sum().head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 5,
"hidden": false,
"row": 70,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Factor Performance (Long Only - Top 100 Uniformly Distributed In Each Sector Equal Weighted)\n",
"-------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": true,
"row": 31,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"factor_data_values = total_data[['Date', 'res', '申万一级行业']]\n",
"\n",
"def get_percent_pos(x):\n",
" res_values = x.res.values\n",
" percent = 115. / len(res_values)\n",
" ind_values = x['申万一级行业'].values.astype(int)\n",
" final_choosed = pb.percent_build(res_values, percent, ind_values)\n",
" return pd.Series(final_choosed / final_choosed.sum())\n",
"\n",
"total_data['pos_100_uind'] = factor_data_values.groupby('Date').apply(get_percent_pos).values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into = total_data[risk_facto_cols].multiply(total_data.pos_100_uind - total_data[index_compentns], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 18,
"hidden": true,
"row": 31,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().max()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 18,
"hidden": true,
"row": 31,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 9,
"hidden": true,
"row": 39,
"width": 6
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data[['pos_100_uind', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"ret_series = ((total_data.pos_100_uind - total_data[index_compentns]) * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 75,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 90,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum()[-60:].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 5,
"hidden": true,
"row": 39,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data.pos_100_uind.groupby(total_data.Date).sum().head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 105,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Factor Performance (Long Only - Match Benchark Sectors)\n",
"-------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 12,
"hidden": true,
"row": 44,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"\n",
"lbound_exposure = -0.00001 * np.ones(len(risk_facto_cols))\n",
"ubound_exposure = 0.00001 * np.ones(len(risk_facto_cols))\n",
"lbound_exposure[-2] = -0.01\n",
"ubound_exposure[-2] = 0.01\n",
"\n",
"def get_benchmark_match_pos(x):\n",
" er = x.res.values\n",
" bm = x[index_compentns].values\n",
" lbound = 0.\n",
" ubound = 0.01 + bm\n",
" risk_exposure = x[risk_facto_cols].values\n",
" \n",
" status, value , ret = lb.linear_build(er,\n",
" lbound=lbound,\n",
" ubound=ubound,\n",
" risk_exposure=risk_exposure,\n",
" bm=bm,\n",
" risk_target=(lbound_exposure, ubound_exposure),\n",
" solver=None)\n",
" print(x.Date.unique()[0], ': ', status)\n",
" \n",
" if status != 'optimal':\n",
" return pd.Series(np.ones(len(er)) / len(er))\n",
" else:\n",
" return pd.Series(ret)\n",
"\n",
"res = total_data.groupby('Date').apply(get_benchmark_match_pos).values\n",
"total_data['pos_bmat'] = res"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into = total_data[risk_facto_cols].multiply(total_data.pos_bmat - total_data[index_compentns], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 18,
"hidden": true,
"row": 44,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().max()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 18,
"hidden": true,
"row": 44,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 9,
"hidden": true,
"row": 44,
"width": 6
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"total_data[['pos_bmat', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"ret_series = ((total_data.pos_bmat - total_data[index_compentns]) * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 109,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 16,
"hidden": false,
"row": 124,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum()[-40:].plot(figsize=(14,7))"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 140,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Postion Analysis and Comparison\n",
"----------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"pos_table = total_data[['Date', 'Code', '申万一级行业', 'pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat', index_compentns]].copy()\n",
"pos_table.loc[:, '申万一级行业'] = old_ind_values.values\n",
"\n",
"for name in ['pos_100', 'pos_100_uind', 'pos_bmat']:\n",
" pos_table.loc[:, name] = pos_table[name] - pos_table[index_compentns]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_pos_table = pos_table.groupby(['Date', '申万一级行业']).sum()\n",
"aggregated_pos_table.reset_index(level=1, inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 144,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_pos_table.loc[aggregated_pos_table['申万一级行业'] == '申万家用电器',['pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat']].plot(figsize=(16,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 6,
"hidden": false,
"row": 174,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_pos_table[['pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat']].corr()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 5,
"height": 9,
"hidden": true,
"row": 74,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"turn_over_table = {}\n",
"\n",
"for name in ['pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat']:\n",
" pos_series = pos_table[['Date', 'Code', name]]\n",
" pivot_position = pos_series.pivot_table(name, index='Date', columns='Code').fillna(0.)\n",
" turn_over_series = pivot_position.diff().abs().sum(axis=1)\n",
" turn_over_table[name] = turn_over_series.values\n",
" \n",
"turn_over_table = pd.DataFrame(turn_over_table, index=pos_table.Date.unique())\n",
"turn_over_table.tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 159,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"(turn_over_table.cumsum() * 0.0015).plot(figsize=(14, 7))"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 180,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Risk Exposure (Long Short)\n",
"---------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"net_weight = total_data.pos_long_short\n",
"next_bar_return_series = total_data.d1ret\n",
"risk_table = total_data[risk_facto_cols]\n",
"net_weight.index = total_data.Date\n",
"next_bar_return_series.index = total_data.Date\n",
"risk_table.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 4,
"hidden": true,
"row": 74,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 23,
"hidden": false,
"row": 184,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 8,
"hidden": true,
"row": 74,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 207,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 222,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Risk Exposure (Long Only - Top 100)\n",
"-------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"net_weight = total_data.pos_100 - total_data[index_compentns]\n",
"net_weight.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": true,
"row": 89,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 23,
"hidden": false,
"row": 226,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 8,
"hidden": true,
"row": 89,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 249,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 264,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Risk Exposure (Long Only - Top 100 Uniformly Distributed)\n",
"-------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"net_weight = total_data.pos_100_uind - total_data[index_compentns]\n",
"net_weight.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 4,
"hidden": true,
"row": 89,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 23,
"hidden": false,
"row": 268,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 8,
"hidden": true,
"row": 104,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 291,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 6,
"hidden": false,
"row": 306,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Risk Exposure (Long Only - Match Benchmark Sectors)\n",
"--------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"net_weight = total_data.pos_bmat - total_data[index_compentns]\n",
"net_weight.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 4,
"hidden": true,
"row": 112,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 23,
"hidden": false,
"row": 312,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 8,
"hidden": true,
"row": 108,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 15,
"hidden": false,
"row": 335,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 4,
"hidden": false,
"row": 350,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Risk Exposure for Historical Position\n",
"-----------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"total_data2 = df.copy()\n",
"unique_code = total_data2.Code.unique()\n",
"unique_date = total_data2.Date.unique()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"hist_data = pd.read_csv('portfolio.csv')\n",
"hist_data.Date = pd.to_datetime(hist_data.Date.astype('str'), format='%Y%m%d')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"def func(x):\n",
" x = x.set_index('Code')\n",
" return x.ix[unique_code]\n",
"\n",
"hist_data = hist_data.groupby('Date').apply(func)['Alpha_Trading']\n",
"hist_data = hist_data.reset_index()\n",
"hist_data['Alpha_Trading'] = hist_data['Alpha_Trading'].fillna(0.).values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"hist_data = pd.merge(total_data2, hist_data, on=['Date', 'Code'], how='left')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"hist_data = hist_data[hist_data.Date >= '2015-01-09'].reset_index(drop=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"hist_data['Alpha_Trading'] = hist_data['Alpha_Trading'].groupby(hist_data.Code).fillna(method='pad')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"hist_data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"net_weight = hist_data.Alpha_Trading - hist_data[index_compentns]\n",
"next_bar_return_series = hist_data.d1ret\n",
"risk_table = hist_data[risk_facto_cols]\n",
"\n",
"net_weight.index = hist_data.Date\n",
"risk_table.index = hist_data.Date\n",
"next_bar_return_series.index = hist_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"ret_series = (next_bar_return_series * net_weight).groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 9,
"hidden": true,
"row": 130,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 4,
"height": 9,
"hidden": true,
"row": 130,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"ret_series.cumsum()[-60:].plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 4,
"hidden": true,
"row": 130,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 23,
"hidden": false,
"row": 354,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 8,
"hidden": true,
"row": 130,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 0,
"height": 16,
"hidden": false,
"row": 377,
"width": 12
},
"report_default": {
"hidden": false
}
}
}
}
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"col": 8,
"height": 4,
"hidden": true,
"row": 130,
"width": 4
},
"report_default": {
"hidden": false
}
}
}
}
},
"source": [
"# Clean up\n",
"--------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"extensions": {
"jupyter_dashboards": {
"version": 1,
"views": {
"grid_default": {
"hidden": true
},
"report_default": {
"hidden": true
}
}
}
}
},
"outputs": [],
"source": []
}
],
"metadata": {
"extensions": {
"jupyter_dashboards": {
"activeView": "grid_default",
"version": 1,
"views": {
"grid_default": {
"cellMargin": 10,
"defaultCellHeight": 20,
"maxColumns": 12,
"name": "grid",
"type": "grid"
},
"report_default": {
"name": "report",
"type": "report"
}
}
}
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import pandas as pd\n",
"from matplotlib import pyplot as plt\n",
"import functools\n",
"from alphamind.api import *\n",
"from PyFin.api import *\n",
"\n",
"plt.style.use('ggplot')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Meta Data Parameters\n",
"----------------------"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"freq = '10b'\n",
"universe = Universe('custom', ['zz800'])\n",
"batch = 16\n",
"neutralized_risk = ['SIZE'] + industry_styles\n",
"risk_model = 'short'\n",
"pre_process = [winsorize_normal, standardize]\n",
"post_process = [winsorize_normal, standardize]\n",
"warm_start = 0\n",
"data_source = 'postgres+psycopg2://postgres:we083826@192.168.0.102/alpha'\n",
"dask_cluster = '192.168.0.102:8786'\n",
"\n",
"horizon = map_freq(freq)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Helper function to train / Precit a model\n",
"-------------------"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def train_daily_model(params):\n",
" ref_date, meta_model = params\n",
" data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model=risk_model,\n",
" pre_process=pre_process,\n",
" post_process=post_process,\n",
" warm_start=warm_start,\n",
" data_source=data_source)\n",
"\n",
" return train_model(ref_date=ref_date, alpha_model=meta_model, data_meta=data_meta)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def predict_daily_model(params):\n",
" ref_date, alpha_model = params\n",
" data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model=risk_model,\n",
" pre_process=pre_process,\n",
" post_process=post_process,\n",
" warm_start=warm_start,\n",
" data_source=data_source)\n",
" return predict_by_model(ref_date=ref_date, alpha_model=alpha_model, data_meta=data_meta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Strategy Settings\n",
"---------------------"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"start_date = '2010-02-01'\n",
"end_date = '2018-01-29'\n",
"industry_category = 'sw_adj'\n",
"industry_level = 1\n",
"industries = industry_list(industry_category, industry_level)\n",
"styles = ['SIZE']\n",
"benchmark = 905\n",
"turn_over_target_base = 0.30\n",
"executor = NaiveExecutor()\n",
"\n",
"ref_dates = makeSchedule(firstDate=start_date,\n",
" endDate=end_date,\n",
" tenor=freq,\n",
" calendar='china.sse',\n",
" dateGenerationRule=DateGeneration.Backward)\n",
"ref_dates = [ref_date.strftime('%Y-%m-%d') for ref_date in ref_dates]"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Features\n",
"\n",
"base1 = LAST('roe_q')\n",
"base2 = CSRes('ep_q', base1)\n",
"\n",
"features = {'f01': base1,\n",
" 'f02': base2,\n",
" 'f03': CSRes(CSRes('market_confidence_15d', base1), base2),\n",
" 'f04': CSRes(CSRes('val_q', base1), base2),\n",
" 'f05': CSRes(CSRes('ILLIQUIDITY', base1), base2),\n",
" 'f06': CSRes(CSRes('OperatingRevenueGrowRate', base1), base2),\n",
" 'f07': CSRes(CSRes('NetCFGrowth', base1), base2),\n",
" 'f08': CSRes(CSRes('con_pe_rolling_order', base1), base2),\n",
" 'f09': CSRes(CSRes('con_pb_rolling_order', base1), base2),\n",
" 'f10': CSRes(CSRes('DebtEquityRatio', base1), base2)}\n",
"\n",
"weights = {'f01': 1.0,\n",
" 'f02': 1.0,\n",
" 'f03': 0.25,\n",
" 'f04': 0.25,\n",
" 'f05': 0.25,\n",
" 'f06': 0.25,\n",
" 'f07': 0.25,\n",
" 'f08': -0.25,\n",
" 'f09': -0.25,\n",
" 'f10': -0.25}\n",
"\n",
"const_model = ConstLinearModel(features=features, weights=weights)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Model\n",
"\n",
"# meta_model = XGBTrainer(features=features,\n",
"# objective='reg:linear',\n",
"# booster='gbtree',\n",
"# tree_method='hist',\n",
"# n_estimators=2000,\n",
"# learning_rate=0.01,\n",
"# early_stopping_rounds=30,\n",
"# subsample=0.25,\n",
"# colsample_bytree=1.,\n",
"# n_jobs=1,\n",
"# eval_sample=0.3)\n",
"\n",
"meta_model = LassoRegression(alpha=0.01, features=features)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train / Predict Models with Dask Cluster\n",
"--------------------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Training Phase"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from dask.distributed import Client\n",
"client = Client(dask_cluster)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 2min 53s\n"
]
}
],
"source": [
"%%time\n",
"\n",
"tasks = client.map(train_daily_model, [(ref_date, meta_model) for ref_date in ref_dates])\n",
"models = client.gather(tasks) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predicting Phase"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 1min 19s\n"
]
}
],
"source": [
"%%time\n",
"\n",
"tasks = client.map(predict_daily_model, list(zip(ref_dates, models)))\n",
"predictions1 = client.gather(tasks)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 1min 23s\n"
]
}
],
"source": [
"%%time\n",
"\n",
"tasks = client.map(predict_daily_model, [(ref_date, const_model) for ref_date in ref_dates])\n",
"predictions2 = client.gather(tasks)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Portfolio Rebalance\n",
"-----------------------"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# constraints setting\n",
"total_risks = industries + styles + ['benchmark']\n",
"\n",
"b_type = []\n",
"l_val = []\n",
"u_val = []\n",
"\n",
"for j, name in enumerate(total_risks):\n",
" if name == 'benchmark':\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(0.8)\n",
" u_val.append(1.0)\n",
" elif name == 'SIZE':\n",
" b_type.append(BoundaryType.ABSOLUTE)\n",
" l_val.append(0.)\n",
" u_val.append(0.)\n",
" else:\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(1.0)\n",
" u_val.append(1.0)\n",
" \n",
"\n",
"bounds = create_box_bounds(total_risks, b_type, l_val, u_val)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-02-10 23:42:35,531 - ALPHA_MIND - INFO - 2010-02-04 is finished\n",
"2018-02-10 23:42:36,113 - ALPHA_MIND - INFO - 2010-02-25 is finished\n",
"2018-02-10 23:42:36,837 - ALPHA_MIND - INFO - 2010-03-11 is finished\n",
"2018-02-10 23:42:37,379 - ALPHA_MIND - INFO - 2010-03-25 is finished\n",
"2018-02-10 23:42:37,942 - ALPHA_MIND - INFO - 2010-04-09 is finished\n",
"2018-02-10 23:42:38,570 - ALPHA_MIND - INFO - 2010-04-23 is finished\n",
"2018-02-10 23:42:39,164 - ALPHA_MIND - INFO - 2010-05-10 is finished\n",
"2018-02-10 23:42:39,715 - ALPHA_MIND - INFO - 2010-05-24 is finished\n",
"2018-02-10 23:42:40,281 - ALPHA_MIND - INFO - 2010-06-07 is finished\n",
"2018-02-10 23:42:40,832 - ALPHA_MIND - INFO - 2010-06-24 is finished\n",
"2018-02-10 23:42:41,405 - ALPHA_MIND - INFO - 2010-07-08 is finished\n",
"2018-02-10 23:42:41,992 - ALPHA_MIND - INFO - 2010-07-22 is finished\n",
"2018-02-10 23:42:42,759 - ALPHA_MIND - INFO - 2010-08-05 is finished\n",
"2018-02-10 23:42:43,316 - ALPHA_MIND - INFO - 2010-08-19 is finished\n",
"2018-02-10 23:42:43,851 - ALPHA_MIND - INFO - 2010-09-02 is finished\n",
"2018-02-10 23:42:44,398 - ALPHA_MIND - INFO - 2010-09-16 is finished\n",
"2018-02-10 23:42:44,974 - ALPHA_MIND - INFO - 2010-10-12 is finished\n",
"2018-02-10 23:42:45,512 - ALPHA_MIND - INFO - 2010-10-26 is finished\n",
"2018-02-10 23:42:46,101 - ALPHA_MIND - INFO - 2010-11-09 is finished\n",
"2018-02-10 23:42:46,651 - ALPHA_MIND - INFO - 2010-11-23 is finished\n",
"2018-02-10 23:42:47,298 - ALPHA_MIND - INFO - 2010-12-07 is finished\n",
"2018-02-10 23:42:47,880 - ALPHA_MIND - INFO - 2010-12-21 is finished\n",
"2018-02-10 23:42:48,408 - ALPHA_MIND - INFO - 2011-01-05 is finished\n",
"2018-02-10 23:42:48,952 - ALPHA_MIND - INFO - 2011-01-19 is finished\n",
"2018-02-10 23:42:49,591 - ALPHA_MIND - INFO - 2011-02-09 is finished\n",
"2018-02-10 23:42:50,142 - ALPHA_MIND - INFO - 2011-02-23 is finished\n",
"2018-02-10 23:42:50,762 - ALPHA_MIND - INFO - 2011-03-09 is finished\n",
"2018-02-10 23:42:51,336 - ALPHA_MIND - INFO - 2011-03-23 is finished\n",
"2018-02-10 23:42:51,890 - ALPHA_MIND - INFO - 2011-04-08 is finished\n",
"2018-02-10 23:42:52,434 - ALPHA_MIND - INFO - 2011-04-22 is finished\n",
"2018-02-10 23:42:52,985 - ALPHA_MIND - INFO - 2011-05-09 is finished\n",
"2018-02-10 23:42:53,506 - ALPHA_MIND - INFO - 2011-05-23 is finished\n",
"2018-02-10 23:42:54,059 - ALPHA_MIND - INFO - 2011-06-07 is finished\n",
"2018-02-10 23:42:54,619 - ALPHA_MIND - INFO - 2011-06-21 is finished\n",
"2018-02-10 23:42:55,270 - ALPHA_MIND - INFO - 2011-07-05 is finished\n",
"2018-02-10 23:42:55,797 - ALPHA_MIND - INFO - 2011-07-19 is finished\n",
"2018-02-10 23:42:56,400 - ALPHA_MIND - INFO - 2011-08-02 is finished\n",
"2018-02-10 23:42:56,961 - ALPHA_MIND - INFO - 2011-08-16 is finished\n",
"2018-02-10 23:42:57,490 - ALPHA_MIND - INFO - 2011-08-30 is finished\n",
"2018-02-10 23:42:58,028 - ALPHA_MIND - INFO - 2011-09-14 is finished\n",
"2018-02-10 23:42:58,614 - ALPHA_MIND - INFO - 2011-09-28 is finished\n",
"2018-02-10 23:42:59,200 - ALPHA_MIND - INFO - 2011-10-19 is finished\n",
"2018-02-10 23:42:59,767 - ALPHA_MIND - INFO - 2011-11-02 is finished\n",
"2018-02-10 23:43:00,314 - ALPHA_MIND - INFO - 2011-11-16 is finished\n",
"2018-02-10 23:43:00,874 - ALPHA_MIND - INFO - 2011-11-30 is finished\n",
"2018-02-10 23:43:01,423 - ALPHA_MIND - INFO - 2011-12-14 is finished\n",
"2018-02-10 23:43:02,171 - ALPHA_MIND - INFO - 2011-12-28 is finished\n",
"2018-02-10 23:43:02,732 - ALPHA_MIND - INFO - 2012-01-13 is finished\n",
"2018-02-10 23:43:03,258 - ALPHA_MIND - INFO - 2012-02-03 is finished\n",
"2018-02-10 23:43:03,851 - ALPHA_MIND - INFO - 2012-02-17 is finished\n",
"2018-02-10 23:43:04,390 - ALPHA_MIND - INFO - 2012-03-02 is finished\n",
"2018-02-10 23:43:04,973 - ALPHA_MIND - INFO - 2012-03-16 is finished\n",
"2018-02-10 23:43:05,522 - ALPHA_MIND - INFO - 2012-03-30 is finished\n",
"2018-02-10 23:43:06,081 - ALPHA_MIND - INFO - 2012-04-18 is finished\n",
"2018-02-10 23:43:06,621 - ALPHA_MIND - INFO - 2012-05-04 is finished\n",
"2018-02-10 23:43:07,193 - ALPHA_MIND - INFO - 2012-05-18 is finished\n",
"2018-02-10 23:43:07,810 - ALPHA_MIND - INFO - 2012-06-01 is finished\n",
"2018-02-10 23:43:08,511 - ALPHA_MIND - INFO - 2012-06-15 is finished\n",
"2018-02-10 23:43:09,066 - ALPHA_MIND - INFO - 2012-07-02 is finished\n",
"2018-02-10 23:43:09,630 - ALPHA_MIND - INFO - 2012-07-16 is finished\n",
"2018-02-10 23:43:10,212 - ALPHA_MIND - INFO - 2012-07-30 is finished\n",
"2018-02-10 23:43:10,803 - ALPHA_MIND - INFO - 2012-08-13 is finished\n",
"2018-02-10 23:43:11,355 - ALPHA_MIND - INFO - 2012-08-27 is finished\n",
"2018-02-10 23:43:11,963 - ALPHA_MIND - INFO - 2012-09-10 is finished\n",
"2018-02-10 23:43:12,539 - ALPHA_MIND - INFO - 2012-09-24 is finished\n",
"2018-02-10 23:43:13,133 - ALPHA_MIND - INFO - 2012-10-15 is finished\n",
"2018-02-10 23:43:13,730 - ALPHA_MIND - INFO - 2012-10-29 is finished\n",
"2018-02-10 23:43:14,331 - ALPHA_MIND - INFO - 2012-11-12 is finished\n",
"2018-02-10 23:43:15,028 - ALPHA_MIND - INFO - 2012-11-26 is finished\n",
"2018-02-10 23:43:15,611 - ALPHA_MIND - INFO - 2012-12-10 is finished\n",
"2018-02-10 23:43:16,163 - ALPHA_MIND - INFO - 2012-12-24 is finished\n",
"2018-02-10 23:43:16,705 - ALPHA_MIND - INFO - 2013-01-10 is finished\n",
"2018-02-10 23:43:17,259 - ALPHA_MIND - INFO - 2013-01-24 is finished\n",
"2018-02-10 23:43:17,807 - ALPHA_MIND - INFO - 2013-02-07 is finished\n",
"2018-02-10 23:43:18,341 - ALPHA_MIND - INFO - 2013-02-28 is finished\n",
"2018-02-10 23:43:18,890 - ALPHA_MIND - INFO - 2013-03-14 is finished\n",
"2018-02-10 23:43:19,453 - ALPHA_MIND - INFO - 2013-03-28 is finished\n",
"2018-02-10 23:43:20,002 - ALPHA_MIND - INFO - 2013-04-15 is finished\n",
"2018-02-10 23:43:20,582 - ALPHA_MIND - INFO - 2013-05-02 is finished\n",
"2018-02-10 23:43:21,263 - ALPHA_MIND - INFO - 2013-05-16 is finished\n",
"2018-02-10 23:43:21,830 - ALPHA_MIND - INFO - 2013-05-30 is finished\n",
"2018-02-10 23:43:22,372 - ALPHA_MIND - INFO - 2013-06-18 is finished\n",
"2018-02-10 23:43:22,928 - ALPHA_MIND - INFO - 2013-07-02 is finished\n",
"2018-02-10 23:43:23,464 - ALPHA_MIND - INFO - 2013-07-16 is finished\n",
"2018-02-10 23:43:24,033 - ALPHA_MIND - INFO - 2013-07-30 is finished\n",
"2018-02-10 23:43:24,586 - ALPHA_MIND - INFO - 2013-08-13 is finished\n",
"2018-02-10 23:43:25,130 - ALPHA_MIND - INFO - 2013-08-27 is finished\n",
"2018-02-10 23:43:25,721 - ALPHA_MIND - INFO - 2013-09-10 is finished\n",
"2018-02-10 23:43:26,263 - ALPHA_MIND - INFO - 2013-09-26 is finished\n",
"2018-02-10 23:43:26,913 - ALPHA_MIND - INFO - 2013-10-17 is finished\n",
"2018-02-10 23:43:27,436 - ALPHA_MIND - INFO - 2013-10-31 is finished\n",
"2018-02-10 23:43:27,996 - ALPHA_MIND - INFO - 2013-11-14 is finished\n",
"2018-02-10 23:43:28,528 - ALPHA_MIND - INFO - 2013-11-28 is finished\n",
"2018-02-10 23:43:29,127 - ALPHA_MIND - INFO - 2013-12-12 is finished\n",
"2018-02-10 23:43:29,699 - ALPHA_MIND - INFO - 2013-12-26 is finished\n",
"2018-02-10 23:43:30,301 - ALPHA_MIND - INFO - 2014-01-10 is finished\n",
"2018-02-10 23:43:30,883 - ALPHA_MIND - INFO - 2014-01-24 is finished\n",
"2018-02-10 23:43:31,404 - ALPHA_MIND - INFO - 2014-02-14 is finished\n",
"2018-02-10 23:43:31,928 - ALPHA_MIND - INFO - 2014-02-28 is finished\n",
"2018-02-10 23:43:32,455 - ALPHA_MIND - INFO - 2014-03-14 is finished\n",
"2018-02-10 23:43:33,134 - ALPHA_MIND - INFO - 2014-03-28 is finished\n",
"2018-02-10 23:43:33,725 - ALPHA_MIND - INFO - 2014-04-14 is finished\n",
"2018-02-10 23:43:34,320 - ALPHA_MIND - INFO - 2014-04-28 is finished\n",
"2018-02-10 23:43:34,884 - ALPHA_MIND - INFO - 2014-05-14 is finished\n",
"2018-02-10 23:43:35,426 - ALPHA_MIND - INFO - 2014-05-28 is finished\n",
"2018-02-10 23:43:35,952 - ALPHA_MIND - INFO - 2014-06-12 is finished\n",
"2018-02-10 23:43:36,545 - ALPHA_MIND - INFO - 2014-06-26 is finished\n",
"2018-02-10 23:43:37,096 - ALPHA_MIND - INFO - 2014-07-10 is finished\n",
"2018-02-10 23:43:37,658 - ALPHA_MIND - INFO - 2014-07-24 is finished\n",
"2018-02-10 23:43:38,205 - ALPHA_MIND - INFO - 2014-08-07 is finished\n",
"2018-02-10 23:43:38,791 - ALPHA_MIND - INFO - 2014-08-21 is finished\n",
"2018-02-10 23:43:39,382 - ALPHA_MIND - INFO - 2014-09-04 is finished\n",
"2018-02-10 23:43:40,046 - ALPHA_MIND - INFO - 2014-09-19 is finished\n",
"2018-02-10 23:43:40,568 - ALPHA_MIND - INFO - 2014-10-10 is finished\n",
"2018-02-10 23:43:41,151 - ALPHA_MIND - INFO - 2014-10-24 is finished\n",
"2018-02-10 23:43:41,716 - ALPHA_MIND - INFO - 2014-11-07 is finished\n",
"2018-02-10 23:43:42,250 - ALPHA_MIND - INFO - 2014-11-21 is finished\n",
"2018-02-10 23:43:42,793 - ALPHA_MIND - INFO - 2014-12-05 is finished\n",
"2018-02-10 23:43:43,339 - ALPHA_MIND - INFO - 2014-12-19 is finished\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-02-10 23:43:43,898 - ALPHA_MIND - INFO - 2015-01-06 is finished\n",
"2018-02-10 23:43:44,480 - ALPHA_MIND - INFO - 2015-01-20 is finished\n",
"2018-02-10 23:43:45,048 - ALPHA_MIND - INFO - 2015-02-03 is finished\n",
"2018-02-10 23:43:45,608 - ALPHA_MIND - INFO - 2015-02-17 is finished\n",
"2018-02-10 23:43:46,174 - ALPHA_MIND - INFO - 2015-03-10 is finished\n",
"2018-02-10 23:43:46,811 - ALPHA_MIND - INFO - 2015-03-24 is finished\n",
"2018-02-10 23:43:47,470 - ALPHA_MIND - INFO - 2015-04-08 is finished\n",
"2018-02-10 23:43:48,034 - ALPHA_MIND - INFO - 2015-04-22 is finished\n",
"2018-02-10 23:43:48,659 - ALPHA_MIND - INFO - 2015-05-07 is finished\n",
"2018-02-10 23:43:49,244 - ALPHA_MIND - INFO - 2015-05-21 is finished\n",
"2018-02-10 23:43:49,790 - ALPHA_MIND - INFO - 2015-06-04 is finished\n",
"2018-02-10 23:43:50,415 - ALPHA_MIND - INFO - 2015-06-18 is finished\n",
"2018-02-10 23:43:50,953 - ALPHA_MIND - INFO - 2015-07-03 is finished\n",
"2018-02-10 23:43:51,484 - ALPHA_MIND - INFO - 2015-07-17 is finished\n",
"2018-02-10 23:43:52,043 - ALPHA_MIND - INFO - 2015-07-31 is finished\n",
"2018-02-10 23:43:52,669 - ALPHA_MIND - INFO - 2015-08-14 is finished\n",
"2018-02-10 23:43:53,258 - ALPHA_MIND - INFO - 2015-08-28 is finished\n",
"2018-02-10 23:43:53,836 - ALPHA_MIND - INFO - 2015-09-15 is finished\n",
"2018-02-10 23:43:54,387 - ALPHA_MIND - INFO - 2015-09-29 is finished\n",
"2018-02-10 23:43:54,915 - ALPHA_MIND - INFO - 2015-10-20 is finished\n",
"2018-02-10 23:43:55,470 - ALPHA_MIND - INFO - 2015-11-03 is finished\n",
"2018-02-10 23:43:56,051 - ALPHA_MIND - INFO - 2015-11-17 is finished\n",
"2018-02-10 23:43:56,657 - ALPHA_MIND - INFO - 2015-12-01 is finished\n",
"2018-02-10 23:43:57,249 - ALPHA_MIND - INFO - 2015-12-15 is finished\n",
"2018-02-10 23:43:57,798 - ALPHA_MIND - INFO - 2015-12-29 is finished\n",
"2018-02-10 23:43:58,347 - ALPHA_MIND - INFO - 2016-01-13 is finished\n",
"2018-02-10 23:43:58,992 - ALPHA_MIND - INFO - 2016-01-27 is finished\n",
"2018-02-10 23:43:59,551 - ALPHA_MIND - INFO - 2016-02-17 is finished\n",
"2018-02-10 23:44:00,133 - ALPHA_MIND - INFO - 2016-03-02 is finished\n",
"2018-02-10 23:44:00,669 - ALPHA_MIND - INFO - 2016-03-16 is finished\n",
"2018-02-10 23:44:01,243 - ALPHA_MIND - INFO - 2016-03-30 is finished\n",
"2018-02-10 23:44:01,797 - ALPHA_MIND - INFO - 2016-04-14 is finished\n",
"2018-02-10 23:44:02,443 - ALPHA_MIND - INFO - 2016-04-28 is finished\n",
"2018-02-10 23:44:03,068 - ALPHA_MIND - INFO - 2016-05-13 is finished\n",
"2018-02-10 23:44:03,659 - ALPHA_MIND - INFO - 2016-05-27 is finished\n",
"2018-02-10 23:44:04,193 - ALPHA_MIND - INFO - 2016-06-14 is finished\n",
"2018-02-10 23:44:04,946 - ALPHA_MIND - INFO - 2016-06-28 is finished\n",
"2018-02-10 23:44:05,534 - ALPHA_MIND - INFO - 2016-07-12 is finished\n",
"2018-02-10 23:44:06,089 - ALPHA_MIND - INFO - 2016-07-26 is finished\n",
"2018-02-10 23:44:06,670 - ALPHA_MIND - INFO - 2016-08-09 is finished\n",
"2018-02-10 23:44:07,274 - ALPHA_MIND - INFO - 2016-08-23 is finished\n",
"2018-02-10 23:44:07,842 - ALPHA_MIND - INFO - 2016-09-06 is finished\n",
"2018-02-10 23:44:08,433 - ALPHA_MIND - INFO - 2016-09-22 is finished\n",
"2018-02-10 23:44:09,010 - ALPHA_MIND - INFO - 2016-10-13 is finished\n",
"2018-02-10 23:44:09,560 - ALPHA_MIND - INFO - 2016-10-27 is finished\n",
"2018-02-10 23:44:10,126 - ALPHA_MIND - INFO - 2016-11-10 is finished\n",
"2018-02-10 23:44:10,857 - ALPHA_MIND - INFO - 2016-11-24 is finished\n",
"2018-02-10 23:44:11,418 - ALPHA_MIND - INFO - 2016-12-08 is finished\n",
"2018-02-10 23:44:12,011 - ALPHA_MIND - INFO - 2016-12-22 is finished\n",
"2018-02-10 23:44:12,565 - ALPHA_MIND - INFO - 2017-01-06 is finished\n",
"2018-02-10 23:44:13,128 - ALPHA_MIND - INFO - 2017-01-20 is finished\n",
"2018-02-10 23:44:13,672 - ALPHA_MIND - INFO - 2017-02-10 is finished\n",
"2018-02-10 23:44:14,246 - ALPHA_MIND - INFO - 2017-02-24 is finished\n",
"2018-02-10 23:44:14,861 - ALPHA_MIND - INFO - 2017-03-10 is finished\n",
"2018-02-10 23:44:15,430 - ALPHA_MIND - INFO - 2017-03-24 is finished\n",
"2018-02-10 23:44:16,045 - ALPHA_MIND - INFO - 2017-04-11 is finished\n",
"2018-02-10 23:44:16,628 - ALPHA_MIND - INFO - 2017-04-25 is finished\n",
"2018-02-10 23:44:17,205 - ALPHA_MIND - INFO - 2017-05-10 is finished\n",
"2018-02-10 23:44:17,900 - ALPHA_MIND - INFO - 2017-05-24 is finished\n",
"2018-02-10 23:44:18,498 - ALPHA_MIND - INFO - 2017-06-09 is finished\n",
"2018-02-10 23:44:19,082 - ALPHA_MIND - INFO - 2017-06-23 is finished\n",
"2018-02-10 23:44:19,660 - ALPHA_MIND - INFO - 2017-07-07 is finished\n",
"2018-02-10 23:44:20,248 - ALPHA_MIND - INFO - 2017-07-21 is finished\n",
"2018-02-10 23:44:20,851 - ALPHA_MIND - INFO - 2017-08-04 is finished\n",
"2018-02-10 23:44:21,429 - ALPHA_MIND - INFO - 2017-08-18 is finished\n",
"2018-02-10 23:44:22,036 - ALPHA_MIND - INFO - 2017-09-01 is finished\n",
"2018-02-10 23:44:22,579 - ALPHA_MIND - INFO - 2017-09-15 is finished\n",
"2018-02-10 23:44:23,167 - ALPHA_MIND - INFO - 2017-09-29 is finished\n",
"2018-02-10 23:44:23,898 - ALPHA_MIND - INFO - 2017-10-20 is finished\n",
"2018-02-10 23:44:24,486 - ALPHA_MIND - INFO - 2017-11-03 is finished\n",
"2018-02-10 23:44:25,044 - ALPHA_MIND - INFO - 2017-11-17 is finished\n",
"2018-02-10 23:44:25,599 - ALPHA_MIND - INFO - 2017-12-01 is finished\n",
"2018-02-10 23:44:26,200 - ALPHA_MIND - INFO - 2017-12-15 is finished\n",
"2018-02-10 23:44:26,762 - ALPHA_MIND - INFO - 2017-12-29 is finished\n",
"2018-02-10 23:44:27,331 - ALPHA_MIND - INFO - 2018-01-15 is finished\n",
"2018-02-10 23:44:27,840 - ALPHA_MIND - INFO - 2018-01-29 is finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 1min 52s\n"
]
}
],
"source": [
"%%time\n",
"\n",
"engine = SqlEngine(data_source)\n",
"\n",
"rets = []\n",
"turn_overs = []\n",
"previous_pos = pd.DataFrame()\n",
"\n",
"trade_dates = ref_dates\n",
"\n",
"for i, ref_date in enumerate(trade_dates):\n",
" er = 0.0 * predictions1[i].values.flatten().astype(float) + 1.0 * predictions2[i].values.flatten().astype(float)\n",
" codes = predictions2[i].index.values.astype(int).tolist()\n",
" industry_data = engine.fetch_industry_matrix(ref_date, codes, category=industry_category, level=industry_level)\n",
" industry_exp = industry_data[industries].values\n",
" industry_names = industry_data.industry_name.values\n",
" style_exp = engine.fetch_risk_model(ref_date, codes, risk_model=risk_model)[1][styles].values\n",
" benchmark_w = engine.fetch_benchmark(ref_date, benchmark, codes).weight.values\n",
" is_in_benchmark = (benchmark_w > 0.).astype(float)\n",
" \n",
" risk_exp = np.concatenate([industry_exp, style_exp, is_in_benchmark.reshape((-1, 1))], axis=1)\n",
" cons_mat = pd.DataFrame(risk_exp, columns=total_risks)\n",
" constraint = LinearConstraints(bounds=bounds,\n",
" cons_mat=cons_mat,\n",
" backbone=benchmark_w)\n",
" \n",
" lbound = np.maximum(0., benchmark_w - 0.01)\n",
" ubound = 0.01 + benchmark_w\n",
" \n",
" if previous_pos.empty:\n",
" current_position = None\n",
" turn_over_target = None\n",
" else:\n",
" previous_pos.set_index('code', inplace=True)\n",
" remained_pos = previous_pos.loc[codes]\n",
"\n",
" remained_pos.fillna(0., inplace=True)\n",
" turn_over_target = turn_over_target_base\n",
" current_position = remained_pos.weight.values\n",
" \n",
" try:\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry_names,\n",
" None,\n",
" constraint,\n",
" False,\n",
" benchmark_w,\n",
" method='risk_neutral',\n",
" turn_over_target=turn_over_target,\n",
" current_position=current_position,\n",
" lbound=lbound,\n",
" ubound=ubound)\n",
" except ValueError:\n",
" alpha_logger.info('{0} full re-balance'.format(ref_date))\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry_names,\n",
" None,\n",
" constraint,\n",
" False,\n",
" benchmark_w,\n",
" method='risk_neutral',\n",
" lbound=lbound,\n",
" ubound=ubound)\n",
" \n",
" target_pos['code'] = codes\n",
" \n",
" turn_over, executed_pos = executor.execute(target_pos=target_pos)\n",
" executed_codes = executed_pos.code.tolist()\n",
" \n",
" dx_returns = engine.fetch_dx_return(ref_date, executed_codes, horizon=horizon, offset=1)\n",
" result = pd.merge(executed_pos, dx_returns, on=['code'])\n",
" ret = result.weight.values @ (np.exp(result.dx.values) - 1.)\n",
" rets.append(np.log(1. + ret))\n",
" \n",
" executor.set_current(executed_pos)\n",
" turn_overs.append(turn_over)\n",
" previous_pos = executed_pos\n",
"\n",
" alpha_logger.info('{0} is finished'.format(ref_date))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x221baf91748>"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAuYAAAF2CAYAAAAiF12NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xd4VFX+x/H3nfTeK6EGCFIDBOlISxBQaaIuXcWygoB1\nkfJbXUVwFcECawFdF3VFYdE1EJSmdAiBUDUFQgkkhCSTXif3/P7IGh2TkBjKJOT7ep48T2buufec\nOxPlM2e+91xNKaUQQgghhBBCWJTB0gMQQgghhBBCSDAXQgghhBCiXpBgLoQQQgghRD0gwVwIIYQQ\nQoh6QIK5EEIIIYQQ9YAEcyGEEEIIIeoBCeZCCDMLFiygXbt2N6WvoKAglixZctU227Zto0OHDtjY\n2DB06NCbMq7G6nq995MmTeLOO++8DiO6Ofr168fjjz9ukb4TExPRNI39+/dbpH8hRP0iwVyIRmba\ntGlomlbp54svvgBg7ty57N6928Kj/NXjjz9Oz549SUpK4quvvrL0cIQA4OLFi0ycOJH27dtjZWVV\n7QeRS5cuce+99+Li4oKbmxsTJkwgPT39Jo9WCNFQSDAXohHq378/KSkpZj+jR48GwNnZGW9vbwuP\nsJyu65w+fZrw8HCCgoLw8PCosl1JSclNHlnDIq/P9VdUVISXlxfPPvssgwcPrrJNWVkZI0aMIDk5\nmW3btrF582ZOnTrFmDFjkHv7CSGqIsFciEbI1tYWf39/sx97e3vAvJxBKcWwYcPo3bs3JpMJKA/L\ngwYNYsCAAZSVlQGQm5vLk08+SWBgII6OjnTv3p1vvvnGrM8jR47Qq1cv7O3tCQkJYf369Vcd49at\nW7GyskIpxYQJE9A0jU8//ZStW7eiaRpRUVH07dsXe3t7PvroIwCio6MJDw/H2dkZX19f7r33Xi5c\nuGB23OXLlxMUFISjoyPDhw/nn//8J5qmkZqaCsCqVasqXotfnD17Fk3TzL5JiI+PZ8yYMbi7u+Ph\n4cGwYcM4efJkxfZfjrNr1y5CQ0NxdHTk9ttv58iRI2bHTkhIYNy4cXh6euLo6EiXLl2IiooiOzsb\nJycnvvzyS7P2p0+fxmAwVPutxrW+PgBr1qyhZcuW2NvbExERwdmzZ836HzNmDAEBATg6OtK5c2c+\n//zzKsfyi+joaIYNG4aPjw8uLi7cfvvtfP/992ZtgoKC+Nvf/saTTz6Jh4cHfn5+PP/88+i6XtFG\nKcXbb7/Nbbfdhp2dHX5+ftx///0V20tLS1m4cCEtWrTAwcGBjh07smrVKrN+kpKSiIiIwN7enubN\nm7Ny5cqrjr06wcHBvP322zz00EP4+flV2ea7777j6NGjfPbZZ9x+++307t2bTz75hN27d7Nnzx6z\ntmfOnGHQoEE4ODgQHBxc8Q2WEKJxkWAuhKiWpmmsWbOGs2fPsmDBAgBefvlljh07xueff14RnEeO\nHMnJkyf56quvOHHiBI888gjjx4/nxx9/BCA/P5/hw4fj4+PDwYMH+eijj1i8eDEZGRnV9j1gwACS\nk5MBeO+990hJSeHee++t2P7MM8/wwgsv8NNPP3H33Xdz/PhxBg4cSP/+/Tl06BBbt25FKUV4eHjF\njPH69et57rnneO6554iNjWXs2LE8//zzf/h1SUlJoV+/fjRp0oRdu3axb98+WrVqxcCBA83OqbS0\nlAULFrBixQpiYmJwdXXl/vvvr/hAc+nSJfr27Utubi6RkZEcP36cl156CYPBgJubGw888AAffvih\nWd+rVq2iXbt29OvX76pjrMvrA3DhwgU+/PBD1q1bx86dO8nMzGTcuHEVM7x5eXlERETw3Xffcfz4\ncR566CEmT57Mzp07qx1Lbm4uEydO5McffyQmJoYhQ4Zw9913k5iYaNZu2bJlNGvWjIMHD7Js2TLe\nfPNNPvvss4rtCxYsYP78+Tz55JMcP36cTZs20aVLl4rtDz74IN9++y2rVq3i1KlTLFiwgGeeeYZP\nPvkEKP9QOXr0aHJycti5cydff/0169ev59ixY2bjWLBgAdbW1ld9fWtjz549tGnThuDg4IrnunTp\nQkBAQKUPVs899xyPPPIIsbGx3HfffUycOJHY2NhrHoMQooFRQohGZerUqcrKyko5OTlV/LRq1api\n+/z581VISIjZPlu2bFFWVlbqxRdfVNbW1uqbb74x22Zvb69ycnLM9pk8ebIaN26cUkqpf/zjH8rF\nxUVlZWVVbD9y5IgC1OLFi6sda2lpqQLUv//9b7P+APX555+btZ04caKaOHGi2XMFBQXK1tZWffvt\nt0oppXr27KmmTJli1mb27NkKUCkpKUoppT788ENlZ2dn1iYpKUkBateuXRWvUd++fc3a6Lqumjdv\nrt55552K4wDq6NGjFW127dqlAJWYmKiUUmru3LkqICBA5efnV3n+Bw4cUJqmqdOnT1e8HgEBAerN\n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\nBgxo8prGtnSsvQ3t27cv2CWIiIiIyBkuPT39C5/fuHEjTz31FK7rMm7cOKZPn86iRYvIyMggJyeH\n+vp65s2bR2FhITExMcycOfPYZNHnnnuO119/HcdxuPHGGxk+fHiT9SiYi4iIiEiX1FQwb29qZRER\nERER6QAUzEVEREREOgAFcxERERGRDkDBXERERESkA1AwFxERERHpABTMRUREREQ6AAVzEREREZEO\nQMFcRERERKQDUDAXEREREekAOuTOnyIiIiIiXU2HGzG/9957g13CGUn3tW3ovrYN3dfWp3vaNnRf\n24bua9vQfe34OlwwFxERERHpihTMRUREREQ6AM/s2bNnB7uIz+rfv3+wSzgj6b62Dd3XtqH72vp0\nT9uG7mvb0H1tG7qvHZsmf4qIiIiIdABqZRERERER6QBCmjrg8OHDPPbYY5SWlmKMYcKECVx22WVU\nVlbyq1/9ikOHDpGSksKsWbOIiYlh7969/O53v6OwsJBrr72WK6644ti5Nm3axIIFC3Bdl/HjxzNt\n2rQTXnPlypU899xzAEyfPp1LLrmEuro6Hn30UQ4cOIDjOIwcOZKvf/3rJ3x9QUEBjz32GPX19Qwf\nPpybbroJY8yx51988UX++te/8sQTTxAXF3dKN6y1tOZ9/d3vfsfGjRuJj4/nkUceOek1T3b/f/vb\n37J9+3ZCQkLIyMjg1ltvJSTk8380Tnbc+vXrWbRoEcYYPB4PN954IwMHDmz9m9YMrXVfT3aeEznZ\nff39739PQUEB1lq6d+/OHXfcQURExOdef7I/r08//TTvvvsuISEhdOvWjdtvv53o6Oi2u3kn0Vr3\ntL6+nh//+Mc0Njbi9/sZPXo0V1999QmveaLvAQAPPvggpaWl+P1+Bg4cyC233ILjfH58oam/E2fa\n9wAA13W59957SUxMPOnKC6dzX7/o78SOHTv405/+RH19PR6Ph1tuuYUBAwa08h1rnta8r0f/zjqO\ng8fjYc6cOSe8ZlM/2+bPn8/rr7/O008/fcLXn+x7wJl6X6uqqvjDH/7A7t27McZw2223kZWV9blr\nnu59/fvf/86qVauorKw84TFr167l0Ucf5aGHHiIjI+M071DLtNZ93bdvH7/61a+OnffgwYNcffXV\nTJky5f+3d7ZBUVVhHP9vqxK4hbuLQiyaJusMZOYAplLGaEYy01TTOFkGLTVME5g042S+TZijDINo\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x221bacfe588>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=trade_dates)\n",
"\n",
"# index return\n",
"index_return = engine.fetch_dx_return_index_range(benchmark,\n",
" dates=trade_dates,\n",
" horizon=horizon,\n",
" offset=1).set_index('trade_date')\n",
"ret_df['index'] = index_return['dx']\n",
"\n",
"ret_df.loc[advanceDateByCalendar('china.sse', trade_dates[-1], freq)] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"ret_df['tc_cost'] = ret_df.turn_over * 0.002\n",
"ret_df['returns'] = ret_df['returns'] - ret_df['index']\n",
"\n",
"ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Fixed frequency rebalanced: {0}'.format(freq),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import xgboost as xgb\n",
"from sklearn.metrics import r2_score\n",
"from sklearn.model_selection import train_test_split\n",
"from alphamind.api import *\n",
"from PyFin.api import *\n",
"\n",
"engine = SqlEngine()"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"start_date = '2012-01-01'\n",
"end_date = '2018-01-05'\n",
"\n",
"features = ['roe_q',\n",
" 'ep_q',\n",
" 'DivP',\n",
" 'cfinc1_q',\n",
" 'EBIT',\n",
" 'EARNYILD',\n",
" 'EPIBS']\n",
"\n",
"freq = '5b'\n",
"batch = 32\n",
"universe = Universe('custom', ['zz500', 'hs300'])\n",
"benchmark = 905\n",
"neutralized_risk = ['SIZE'] + industry_styles\n",
"horizon = map_freq(freq)"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-01-10 14:56:47,595 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
"2018-01-10 14:56:54,781 - ALPHA_MIND - INFO - factor data loading finished\n",
"2018-01-10 14:57:03,949 - ALPHA_MIND - INFO - return data loading finished\n",
"2018-01-10 14:57:05,113 - ALPHA_MIND - INFO - industry data loading finished\n",
"2018-01-10 14:57:05,828 - ALPHA_MIND - INFO - benchmark data loading finished\n",
"2018-01-10 14:57:15,662 - ALPHA_MIND - INFO - risk data loading finished\n",
"2018-01-10 14:57:17,773 - ALPHA_MIND - INFO - data merging finished\n",
"2018-01-10 14:57:19,490 - ALPHA_MIND - INFO - Loading data is finished\n",
"2018-01-10 14:57:35,324 - ALPHA_MIND - INFO - Data processing is finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 47.7 s\n"
]
}
],
"source": [
"%%time\n",
"factor_data = fetch_data_package(engine,\n",
" features,\n",
" start_date,\n",
" end_date,\n",
" '5b',\n",
" universe,\n",
" benchmark,\n",
" batch=batch,\n",
" warm_start=batch,\n",
" neutralized_risk=neutralized_risk, \n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[winsorize_normal, standardize])"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"features = factor_data['x_names']\n",
"\n",
"train_x = factor_data['train']['x']\n",
"train_y = factor_data['train']['y']\n",
"train_risk = factor_data['train']['risk']\n",
"ref_dates = sorted(train_x.keys())\n",
"\n",
"predict_x = factor_data['predict']['x']\n",
"predict_y = factor_data['predict']['y']\n",
"predict_risk = factor_data['predict']['risk']\n",
"settlement = factor_data['settlement']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear Regression\n",
"------------------"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 1.26 s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" model = LinearRegression(fit_intercept=False, features=features)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0107609007052\n",
"-0.480548329833\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lasso Regression\n",
"---------"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 1.58 s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" model = LassoRegression(alpha=0.01, fit_intercept=False, features=features)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.00875291615929\n",
"-0.475440026\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear Regression with More Features\n",
"----------"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def cross_product(x, y):\n",
" n, m = x.shape\n",
" res = []\n",
" \n",
" for j in range(m):\n",
" res.append(x[:, [j]] * y)\n",
" \n",
" return np.concatenate(res, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2017-01-03 00:00:00\n"
]
},
{
"ename": "NameError",
"evalue": "name 'cross_product' 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<timed exec>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n",
"\u001b[1;31mNameError\u001b[0m: name 'cross_product' is not defined"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates[:1]):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" risk = train_risk[date][:, 1:]\n",
" new_x = cross_product(x, risk)\n",
" \n",
" model = LinearRegression(fit_intercept=False, features=features)\n",
" model.fit(new_x, y)\n",
" train_scores.append(model.score(new_x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" p_risk = predict_risk[date][:, 1:]\n",
" new_p_x = cross_product(p_x, p_risk)\n",
" predict_scores.append(model.score(new_p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0291928676769\n",
"-0.24146254373\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lasso Regression with More Features\n",
"----------------------"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2017-01-03 00:00:00\n",
"2017-04-27 00:00:00\n",
"2017-08-15 00:00:00\n",
"2017-12-05 00:00:00\n",
"Wall time: 4.78 s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" risk = train_risk[date][:, 1:]\n",
" new_x = cross_product(x, risk)\n",
" \n",
" model = LassoRegression(alpha=0.01, fit_intercept=False, features=features)\n",
" model.fit(new_x, y)\n",
" train_scores.append(model.score(new_x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" p_risk = predict_risk[date][:, 1:]\n",
" new_p_x = cross_product(p_x, p_risk)\n",
" predict_scores.append(model.score(new_p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.000355789142204\n",
"-0.200552889618\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Random Forest Regressor\n",
"---------------"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2017-01-03 00:00:00\n",
"2017-04-27 00:00:00\n",
"2017-08-15 00:00:00\n",
"2017-12-05 00:00:00\n",
"Wall time: 1min 18s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" model = RandomForestRegressor(n_estimators=500, max_features='sqrt', max_depth=3, n_jobs=-1)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0137863030105\n",
"-0.197952235791\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## XGBoost Regressor\n",
"------------"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2017-01-03 00:00:00\n",
"2017-04-27 00:00:00\n",
"2017-08-15 00:00:00\n",
"2017-12-05 00:00:00\n",
"Wall time: 1min 32s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" model = XGBRegressor(n_estimators=500,\n",
" learning_rate=0.02,\n",
" max_depth=3,\n",
" n_jobs=-1,\n",
" subsample=0.25,\n",
" colsample_bytree=0.5)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0575499865219\n",
"-0.209037365429\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## Native XGBoost Regressor\n",
"---------------"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 6min 57s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" x_train, x_eval, y_train, y_eval = train_test_split(x, y, test_size=0.33, random_state=42)\n",
" \n",
" dtrain = xgb.DMatrix(x_train, y_train)\n",
" deval = xgb.DMatrix(x_eval, y_eval)\n",
" param = {'silent': 1,\n",
" 'objective': 'reg:linear',\n",
" 'max_depth': 3,\n",
" 'eta': 0.005,\n",
" 'boost': 'gbtree',\n",
" 'tree_method': 'hist',\n",
" 'subsample': 0.1,\n",
" 'colsample_bytree': 0.25}\n",
" num_round = 2000\n",
" model = xgb.train(param, dtrain, num_round, evals=[(deval, 'eval')], early_stopping_rounds=50, verbose_eval=False)\n",
" \n",
" y_train_predict = model.predict(dtrain)\n",
" train_scores.append(r2_score(y_train, y_train_predict, multioutput='uniform_average'))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" dtest = xgb.DMatrix(p_x, p_y)\n",
" \n",
" y_test_predict = model.predict(dtest)\n",
" predict_scores.append(r2_score(p_y, y_test_predict, multioutput='uniform_average'))"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0158347715471\n",
"-0.477095380466\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import xgboost as xgb\n",
"import numpy as np\n",
"from alphamind.api import *\n",
"from PyFin.api import *\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"engine = SqlEngine()"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"start_date = '2012-01-01'\n",
"end_date = '2018-01-05'\n",
"\n",
"features = ['roe_q',\n",
" 'ep_q',\n",
" 'DivP',\n",
" 'cfinc1_q',\n",
" 'EBIT',\n",
" 'EARNYILD',\n",
" 'EPIBS']\n",
"\n",
"freq = '10b'\n",
"batch = 16\n",
"universe = Universe('custom', ['zz500', 'hs300'])\n",
"benchmark = 905\n",
"neutralized_risk = ['SIZE'] + industry_styles\n",
"horizon = map_freq(freq)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-01-11 15:12:44,105 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
"2018-01-11 15:12:53,578 - ALPHA_MIND - INFO - factor data loading finished\n",
"2018-01-11 15:13:03,880 - ALPHA_MIND - INFO - return data loading finished\n",
"2018-01-11 15:13:05,384 - ALPHA_MIND - INFO - industry data loading finished\n",
"2018-01-11 15:13:06,178 - ALPHA_MIND - INFO - benchmark data loading finished\n",
"2018-01-11 15:13:17,845 - ALPHA_MIND - INFO - risk data loading finished\n",
"2018-01-11 15:13:21,266 - ALPHA_MIND - INFO - data merging finished\n",
"2018-01-11 15:13:23,371 - ALPHA_MIND - INFO - Loading data is finished\n",
"2018-01-11 15:13:33,174 - ALPHA_MIND - INFO - Data processing is finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 49.1 s\n"
]
}
],
"source": [
"%%time\n",
"factor_data = fetch_data_package(engine,\n",
" features,\n",
" start_date,\n",
" end_date,\n",
" '5b',\n",
" universe,\n",
" benchmark,\n",
" batch=batch,\n",
" warm_start=batch,\n",
" neutralized_risk=neutralized_risk, \n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[winsorize_normal, standardize])"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"features = factor_data['x_names']\n",
"\n",
"train_x = factor_data['train']['x']\n",
"train_y = factor_data['train']['y']\n",
"train_risk = factor_data['train']['risk']\n",
"ref_dates = sorted(train_x.keys())\n",
"\n",
"predict_x = factor_data['predict']['x']\n",
"predict_y = factor_data['predict']['y']\n",
"predict_risk = factor_data['predict']['risk']\n",
"settlement = factor_data['settlement']"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"for key, val in train_y.items():\n",
" train_y[key] = np.where(val > 0., 1, 0)\n",
" \n",
"for key, val in predict_y.items():\n",
" predict_y[key] = np.where(val > 0., 1, 0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Logistic Regression\n",
"--------------"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 5.34 s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" model = LogisticRegression(fit_intercept=False, features=features)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.541013986745\n",
"0.51932344036\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Random Forest Classifier\n",
"-----------"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 15min 34s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" model = RandomForestClassifier(n_estimators=1000, max_features='sqrt', max_depth=3, n_jobs=-1)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.557563825608\n",
"0.553974775005\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## XGBoost Classifier\n",
"---------"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 13min 40s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" model = XGBClassifier(n_estimators=1000,\n",
" learning_rate=0.02,\n",
" max_depth=3,\n",
" n_jobs=-1,\n",
" subsample=0.25,\n",
" colsample_bytree=0.5)\n",
" model.fit(x, y)\n",
" train_scores.append(model.score(x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" predict_scores.append(model.score(p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.642946015759\n",
"0.537550683184\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Native XGBoost Classifier\n",
"---------------"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 1min 6s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" \n",
" x_train, x_eval, y_train, y_eval = train_test_split(x, y, test_size=0.33, random_state=42)\n",
" \n",
" dtrain = xgb.DMatrix(x_train, y_train)\n",
" deval = xgb.DMatrix(x_eval, y_eval)\n",
" param = {'silent': 1,\n",
" 'objective': 'binary:logistic',\n",
" 'max_depth': 3,\n",
" 'eta': 0.01,\n",
" 'boost': 'dart',\n",
" 'tree_method': 'hist',\n",
" 'subsample': 0.25,\n",
" 'colsample_bytree': 0.5}\n",
" num_round = 2000\n",
" model = xgb.train(param, dtrain, num_round, evals=[(deval, 'eval')], early_stopping_rounds=50, verbose_eval=False)\n",
" \n",
" y_train_predict = model.predict(dtrain)\n",
" label = dtrain.get_label()\n",
" train_score = np.sum((y_train_predict > 0.5) == label) / float(len(label))\n",
"\n",
" train_scores.append(train_score)\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" dtest = xgb.DMatrix(p_x, p_y)\n",
" \n",
" y_test_predict = model.predict(dtest)\n",
" p_label = dtest.get_label()\n",
" test_score = np.sum((y_test_predict > 0.5) == p_label) / float(len(p_label))\n",
" predict_scores.append(test_score)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.567225761699\n",
"0.550997907465\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Logistic Regression with More Features\n",
"-----------------"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def cross_product(x, y):\n",
" n, m = x.shape\n",
" res = []\n",
" \n",
" for j in range(m):\n",
" res.append(x[:, [j]] * y)\n",
" \n",
" return np.concatenate(res, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 36.1 s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" risk = train_risk[date][:, 1:]\n",
" new_x = cross_product(x, risk)\n",
" \n",
" model = LogisticRegression(fit_intercept=False, features=features)\n",
" model.fit(new_x, y)\n",
" train_scores.append(model.score(new_x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" p_risk = predict_risk[date][:, 1:]\n",
" new_p_x = cross_product(p_x, p_risk)\n",
" predict_scores.append(model.score(new_p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.568125478425\n",
"0.517523115163\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Random Forest Classifier with More Features\n",
"-----------"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 14min 40s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" risk = train_risk[date][:, 1:]\n",
" new_x = cross_product(x, risk)\n",
" \n",
" model = RandomForestClassifier(n_estimators=1000, max_features='sqrt', max_depth=3, n_jobs=-1)\n",
" model.fit(new_x, y)\n",
" train_scores.append(model.score(new_x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" p_risk = predict_risk[date][:, 1:]\n",
" new_p_x = cross_product(p_x, p_risk)\n",
" predict_scores.append(model.score(new_p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.549090142483\n",
"0.559944504146\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## XGBoost Classifier with More Features\n",
"---------"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 12min 25s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" risk = train_risk[date][:, 1:]\n",
" new_x = cross_product(x, risk)\n",
" \n",
" model = XGBClassifier(n_estimators=500,\n",
" learning_rate=0.02,\n",
" max_depth=3,\n",
" n_jobs=-1,\n",
" subsample=0.25,\n",
" colsample_bytree=0.1)\n",
" model.fit(new_x, y)\n",
" train_scores.append(model.score(new_x, y))\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" p_risk = predict_risk[date][:, 1:]\n",
" new_p_x = cross_product(p_x, p_risk)\n",
" predict_scores.append(model.score(new_p_x, p_y))"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.59375573895\n",
"0.55230987889\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Native XGBoost Classifier with More Features\n",
"---------------"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2012-02-15 00:00:00\n",
"2012-06-06 00:00:00\n",
"2012-09-20 00:00:00\n",
"2013-01-15 00:00:00\n",
"2013-05-14 00:00:00\n",
"2013-08-30 00:00:00\n",
"2013-12-24 00:00:00\n",
"2014-04-17 00:00:00\n",
"2014-08-05 00:00:00\n",
"2014-11-26 00:00:00\n",
"2015-03-20 00:00:00\n",
"2015-07-08 00:00:00\n",
"2015-10-30 00:00:00\n",
"2016-02-22 00:00:00\n",
"2016-06-08 00:00:00\n",
"2016-09-27 00:00:00\n",
"2017-01-18 00:00:00\n",
"2017-05-15 00:00:00\n",
"2017-08-30 00:00:00\n",
"2017-12-20 00:00:00\n",
"Wall time: 5min 23s\n"
]
}
],
"source": [
"%%time\n",
"train_dates = list(train_x.keys())\n",
"train_scores = []\n",
"predict_scores = []\n",
"\n",
"for i, date in enumerate(train_dates):\n",
" if i % 15 == 0:\n",
" print(date)\n",
" x = train_x[date]\n",
" y = train_y[date]\n",
" risk = train_risk[date][:, 1:]\n",
" new_x = cross_product(x, risk)\n",
" \n",
" x_train, x_eval, y_train, y_eval = train_test_split(new_x, y, test_size=0.33, random_state=42)\n",
" \n",
" dtrain = xgb.DMatrix(x_train, y_train)\n",
" deval = xgb.DMatrix(x_eval, y_eval)\n",
" param = {'silent': 1,\n",
" 'objective': 'binary:logistic',\n",
" 'max_depth': 3,\n",
" 'eta': 0.01,\n",
" 'booster': 'dart',\n",
" 'tree_method': 'hist',\n",
" 'subsample': 0.25,\n",
" 'colsample_bytree': 0.5}\n",
" num_round = 2000\n",
" model = xgb.train(param, dtrain, num_round, evals=[(deval, 'eval')], early_stopping_rounds=50, verbose_eval=False)\n",
" \n",
" y_train_predict = model.predict(dtrain)\n",
" label = dtrain.get_label()\n",
" train_score = np.sum((y_train_predict > 0.5) == label) / float(len(label))\n",
"\n",
" train_scores.append(train_score)\n",
" \n",
" p_x = predict_x[date]\n",
" p_y = predict_y[date]\n",
" p_risk = predict_risk[date][:, 1:]\n",
" new_p_x = cross_product(p_x, p_risk)\n",
" dtest = xgb.DMatrix(new_p_x, p_y)\n",
" \n",
" y_test_predict = model.predict(dtest)\n",
" p_label = dtest.get_label()\n",
" test_score = np.sum((y_test_predict > 0.5) == p_label) / float(len(p_label))\n",
" predict_scores.append(test_score)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.560057712549\n",
"0.552663472836\n"
]
}
],
"source": [
"print(np.mean(train_scores))\n",
"print(np.mean(predict_scores))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
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.
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%pylab inline\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('ggplot')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import sqlalchemy\n",
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factor_table = 'prod_500'\n",
"risk_table = 'risk_factor_500'\n",
"trade_table = 'trade_data'\n",
"index_components = '500Weight'\n",
"benchmark = 'zz500'\n",
"\n",
"prod_factors = ['VAL', 'BDTO', 'RVOL', 'CFinc1', 'CHV']\n",
"\n",
"factor_list = ','.join([factor_table + '.' + f for f in prod_factors])\n",
"\n",
"server = '10.63.6.176'\n",
"user = 'sa'\n",
"pwd = 'we083826'\n",
"\n",
"engine = sqlalchemy.create_engine('mysql+pymysql://{0}:{1}@{2}/multifactor?charset=utf8'.format(user, pwd, server))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sql_template1 = 'select {factor_list},{trade_table}.Return as dailyReturn, {risk_table}.* ' \\\n",
" 'from {factor_table}, trade_data, {risk_table} ' \\\n",
" 'where {factor_table}.Date = trade_data.Date and {factor_table}.Code = trade_data.Code ' \\\n",
" 'and {factor_table}.Date = {risk_table}.Date and {factor_table}.Code = {risk_table}.Code;'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"sql1 = sql_template1.format(factor_list=factor_list,\n",
" factor_table=factor_table,\n",
" risk_table=risk_table,\n",
" trade_table=trade_table)\n",
"\n",
"sql2 = 'select * from factor_data'\n",
"\n",
"# factor_df1 = pd.read_sql(sql1, engine)\n",
"# common_factor_df = pd.read_sql(sql2, engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"factor_df = pd.read_hdf('factor_data.hdf', 'all')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"index_components_df = pd.read_sql('select Date, Code, {0} from index_components;'.format(index_components), engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"del factor_df['Bank']\n",
"del factor_df['NonBankFinancial']\n",
"factor_df.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"raw_df = pd.merge(factor_df, index_components_df, on=['Date', 'Code'], how='left')\n",
"raw_df.fillna(0, inplace=True)\n",
"raw_df[index_components] = raw_df[index_components] / 100."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_cols = raw_df.columns[8:35]\n",
"ob_risk_factor_cols = risk_factor_cols.copy()\n",
"risk_factor_cols"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"common_factor = raw_df.columns[38:-1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df = raw_df.copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df['d1ret'] = df.dailyReturn.groupby(df.Code).shift(-2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"benchmark_data = pd.read_sql('select {0}, Date from index_data'.format(benchmark), engine)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"benchmark_data['ret'] = benchmark_data[benchmark] / benchmark_data[benchmark].shift(1) - 1.\n",
"benchmark_data['d1ret_b'] = benchmark_data['ret'] .shift(-1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df = pd.merge(df, benchmark_data[['Date', 'd1ret_b']], on='Date', how='left')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df.dropna(inplace=True)\n",
"df.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Calculate Market Risk\n",
"--------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"engine = sqlalchemy.create_engine('mysql+pymysql://sa:we083826@10.63.6.176/multifactor?charset=utf8')\n",
"\n",
"window = 250\n",
"return_data = pd.read_sql('select Date, Code, Price, `Return` from trade_data', engine)\n",
"return_pivot = return_data.pivot_table('Price', 'Date', 'Code')\n",
"return_pivot.fillna(method='pad', inplace=True)\n",
"return_pivot = return_pivot / return_pivot.shift(1) - 1.\n",
"index_data = benchmark_data.set_index('Date')\n",
"\n",
"full_df = pd.merge(return_pivot, index_data, left_index=True, right_index=True)\n",
"del full_df['zz500']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"corr_table = full_df.rolling(window=window).corr(full_df['ret'])\n",
"std_table = full_df.rolling(window=window).std()\n",
"\n",
"beta_table = std_table.copy()\n",
"for col in full_df.columns:\n",
" beta_table[col] = corr_table[col] * std_table[col] / std_table['ret']\n",
"beta_table = beta_table.stack().reset_index()\n",
"\n",
"beta_table.columns = ['Date', 'Code', 'market']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"beta_table.to_hdf('factor_data.hdf', 'beta')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df = pd.merge(df, beta_table, on=['Date', 'Code'], how='inner')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"analysis_factors = prod_factors + ['Size']\n",
"analysis_factors_weights = np.array([3., 1., 1., 0.5, 0.5, 3.])\n",
"\n",
"ob_risk_factor_cols = ob_risk_factor_cols.append(pd.Index(['market']))\n",
"risk_factor_cols = ob_risk_factor_cols.difference(analysis_factors)\n",
"risk_factor_cols = risk_factor_cols.unique()\n",
"ob_risk_factor_cols = ob_risk_factor_cols.unique()\n",
"risk_factor_cols"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ob_risk_factor_cols"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# to transform industry codes to int variable\n",
"old_ind_values = df['申万一级行业'].copy()\n",
"\n",
"ind_list = df['申万一级行业'].unique()\n",
"ind_dict = {}\n",
"for i, ind in enumerate(ind_list):\n",
" ind_dict[ind] = i\n",
"\n",
"df['申万一级行业'].replace(ind_dict, inplace=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Date Preprocessing (Winsorize -> Standardize -> neutralize)\n",
"---------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import alphamind.data.neutralize as ne\n",
"import alphamind.data.winsorize as ws\n",
"import alphamind.data.standardize as st"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data = df.copy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"y = total_data[common_factor].values\n",
"groups = total_data.Date.values.astype(np.int)\n",
"\n",
"total_data[common_factor] = st.standardize(ws.winsorize_normal"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"y = total_data[analysis_factors].values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"neutralized_values = ne.neutralize(total_data[risk_factor_cols].values,\n",
" st.standardize(ws.winsorize_normal(y, groups=groups),\n",
" groups=groups),\n",
" groups)\n",
"\n",
"total_data['res'] = neutralized_values @ analysis_factors_weights"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data.tail()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Performance (long_short)\n",
"------------------------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"total_data['pos_long_short'] = total_data.res.groupby(groups).apply(lambda x: x / np.abs(x).sum())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data[['pos_long_short', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into = total_data[ob_risk_factor_cols].multiply(total_data.pos_long_short, axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum()['Size'].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series = (total_data.pos_long_short * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series[-60:].cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data.pos_long_short.groupby(total_data.Date).apply(lambda x: x.sum()).head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Performance (Long Only - Top 100 Equal Weighted)\n",
"------------------------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import alphamind.portfolio.rankbuilder as rb"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"use_rank = 100\n",
"total_data['pos_100'] = rb.rank_build(total_data.res.values, use_rank, groups) / use_rank"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data[['pos_100', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into = total_data[ob_risk_factor_cols].multiply(total_data.pos_100 - total_data[index_components], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum()['Size'].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series = ((total_data.pos_100 - total_data[index_components]) * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series[-60:].cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data.pos_100.groupby(total_data.Date).sum().head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_pos_100 = ret_series.copy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Performance (Long Only - Top 100 Uniformly Distributed In Each Sector Equal Weighted)\n",
"-------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import alphamind.portfolio.percentbuilder as pb"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"factor_data_values = total_data[['Date', 'res', '申万一级行业']]\n",
"\n",
"def get_percent_pos(x):\n",
" res_values = x.res.values\n",
" percent = 115. / len(res_values)\n",
" ind_values = x['申万一级行业'].values.astype(int)\n",
" final_choosed = pb.percent_build(res_values, percent, ind_values)\n",
" return pd.Series(final_choosed / final_choosed.sum())\n",
"\n",
"total_data['pos_100_uind'] = factor_data_values.groupby('Date').apply(get_percent_pos).values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"(total_data['pos_100_uind'] > 0).groupby(total_data.Date).sum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into = total_data[ob_risk_factor_cols].multiply(total_data.pos_100_uind - total_data[index_components], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum()['Size'].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data[['pos_100_uind', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series = ((total_data.pos_100_uind - total_data[index_components]) * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series[-60:].cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data.pos_100_uind.groupby(total_data.Date).sum().head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_100_uind = ret_series.copy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Performance (Long Only - Match Benchark Sectors)\n",
"-------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import alphamind.portfolio.linearbuilder as lb"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"\n",
"lbound_exposure = -1e-3 * np.ones(len(risk_factor_cols))\n",
"ubound_exposure = 1e-3 * np.ones(len(risk_factor_cols))\n",
"\n",
"def get_benchmark_match_pos(x):\n",
" er = x.res.values\n",
" bm = x[index_components].values\n",
" lbound = 0.\n",
" ubound = 0.01 #+ bm\n",
" risk_exposure = x[risk_factor_cols].values\n",
" \n",
" status, value , ret = lb.linear_build(er,\n",
" lbound=lbound,\n",
" ubound=ubound,\n",
" risk_exposure=risk_exposure,\n",
" bm=bm,\n",
" risk_target=(lbound_exposure, ubound_exposure),\n",
" solver=None)\n",
" print(x.Date.unique()[0], ': ', status)\n",
" \n",
" if status != 'optimal':\n",
" return pd.Series(np.ones(len(er)) / len(er))\n",
" else:\n",
" return pd.Series(ret)\n",
"\n",
"res = total_data.groupby('Date').apply(get_benchmark_match_pos).values\n",
"total_data['pos_bmat'] = res"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"(total_data['pos_bmat'] > 1e-4).groupby(total_data.Date).sum().plot(ylim=(50, 250), figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into = total_data[ob_risk_factor_cols].multiply(total_data.pos_bmat - total_data[index_components], axis=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum()['Size'].plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"to_look_into.groupby(total_data.Date).sum().min()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data[['pos_bmat', 'res', 'dailyReturn', 'd1ret', 'd1ret_b', 'Code', 'Date']].tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series = ((total_data.pos_bmat - total_data[index_components]) * total_data.d1ret).groupby(total_data.Date).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series.cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_series[-60:].cumsum().plot(figsize=(14,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_bmat = ret_series.copy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Performance Analysis and Comparison\n",
"------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_mat = pd.DataFrame({'pos_100': ret_pos_100,\n",
" 'pos_100_uind': ret_100_uind,\n",
" 'pos_bmat': ret_bmat})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sharp_mat = ret_mat.rolling(window=250).mean() / ret_mat.rolling(window=250).std() * np.sqrt(250)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sharp_mat.plot(figsize=(14, 7))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Postion Analysis and Comparison\n",
"----------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"pos_table = total_data[['Date', 'Code', '申万一级行业', 'pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat', index_components]].copy()\n",
"pos_table.loc[:, '申万一级行业'] = old_ind_values.values\n",
"\n",
"for name in ['pos_100', 'pos_100_uind', 'pos_bmat']:\n",
" pos_table.loc[:, name] = pos_table[name] - pos_table[index_components]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_pos_table = pos_table.groupby(['Date', '申万一级行业']).sum()\n",
"aggregated_pos_table.reset_index(level=1, inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_pos_table.loc[aggregated_pos_table['申万一级行业'] == '申万化工',['pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat']].plot(figsize=(16,7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_pos_table[['pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat']].corr()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turn_over_table = {}\n",
"\n",
"for name in ['pos_long_short', 'pos_100', 'pos_100_uind', 'pos_bmat']:\n",
" pos_series = pos_table[['Date', 'Code', name]]\n",
" pivot_position = pos_series.pivot_table(name, index='Date', columns='Code').fillna(0.)\n",
" turn_over_series = pivot_position.diff().abs().sum(axis=1)\n",
" turn_over_table[name] = turn_over_series.values\n",
" \n",
"turn_over_table = pd.DataFrame(turn_over_table, index=pos_table.Date.unique())\n",
"turn_over_table.tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turn_over_table.plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"(turn_over_table * 0.0015).plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"(turn_over_table[-60:].cumsum() * 0.0015).plot(figsize=(14, 7))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Risk Exposure (Long Short)\n",
"---------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import alphamind.analysis.riskanalysis as ra"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"net_weight = total_data.pos_long_short\n",
"next_bar_return_series = total_data.d1ret\n",
"risk_table = total_data[ob_risk_factor_cols]\n",
"net_weight.index = total_data.Date\n",
"next_bar_return_series.index = total_data.Date\n",
"risk_table.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Risk Exposure (Long Only - Top 100)\n",
"-------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"net_weight = total_data.pos_100 - total_data[index_components]\n",
"net_weight.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Risk Exposure (Long Only - Top 100 Uniformly Distributed)\n",
"-------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"net_weight = total_data.pos_100_uind - total_data[index_components]\n",
"net_weight.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Risk Exposure (Long Only - Match Benchmark Sectors)\n",
"--------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"net_weight = total_data.pos_bmat - total_data[index_components]\n",
"net_weight.index = total_data.Date"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"explained_table, exposure_table = ra.risk_analysis(net_weight, next_bar_return_series, risk_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars = explained_table.groupby(level=0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"top_sources = aggregated_bars.sum().abs().sort_values(ascending=False).index[:10]\n",
"aggregated_bars.sum().sort_values(ascending=False).plot(kind='bar', figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].cumsum().plot(figsize=(14, 7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_bars[top_sources.difference(['idiosyncratic'])].plot(figsize=(14, 7))\n",
"plt.legend(loc='upper center', ncol=int(len(top_sources[1:]) // 3) + 1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
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.
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import pandas as pd\n",
"from PyFin.api import *\n",
"from alphamind.api import *\n",
"from matplotlib import pyplot as plt\n",
"plt.style.use('fivethirtyeight')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Parameter Setting\n",
"----------------------"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"#factors = ['RVOL', 'EPS', 'DROEAfterNonRecurring', 'DivP', 'CFinc1', 'BDTO']\n",
"#factor_weights = np.array([0.05, 0.3, 0.35, 0.075, 0.15, 0.05])\n",
"\n",
"factors = alpha_factors = {\n",
" 'eps': LAST('eps_q'),\n",
" 'roe': LAST('roe_q'),\n",
" 'bdto': LAST('BDTO'),\n",
" 'cfinc1': LAST('CFinc1'),\n",
" 'chv': LAST('CHV'),\n",
" 'rvol': LAST('RVOL'),\n",
" 'val': LAST('VAL'),\n",
" 'grev': LAST('GREV'),\n",
" 'droeafternonorecurring': LAST('DROEAfterNonRecurring')\n",
"}\n",
"\n",
"factor_weights = np.array([])\n",
"\n",
"engine = SqlEngine()\n",
"universe = Universe('custom', ['zz500'])\n",
"benchmark_code = 905\n",
"neutralize_risk = ['SIZE'] + industry_styles\n",
"constraint_risk = ['SIZE'] + industry_styles\n",
"freq = '1w'\n",
"\n",
"if freq == '1m':\n",
" horizon = 21\n",
"elif freq == '1w':\n",
" horizon = 4\n",
"elif freq == '2w':\n",
" horizon = 8\n",
"elif freq == '3w':\n",
" horizon = 12\n",
"elif freq == '1d':\n",
" horizon = 0\n",
"else:\n",
" raise ValueError(\"Unrecognized freq: {0}\".format(freq))\n",
" \n",
"dates = makeSchedule('2012-01-01', '2017-11-02', tenor=freq, calendar='china.sse', dateGenerationRule=DateGeneration.Backward)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"all_data = engine.fetch_data_range(universe, factors, dates=dates, benchmark=905)\n",
"factor_all_data = all_data['factor']\n",
"factor_groups = factor_all_data.groupby('trade_date')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Fixed Frequency Rebalance Strategy\n",
"-------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"previous_pos = pd.DataFrame()\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" returns = engine.fetch_dx_return(ref_date, codes, horizon=horizon)\n",
" total_data = pd.merge(data, returns, on=['code']).dropna()\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" dx_return = total_data.dx.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" \n",
" er = factor_processing(total_data[factors].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[standardize]) @ factor_weights\n",
" \n",
" pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" pos['code'] = total_data['code']\n",
" \n",
" ret = (pos.weight - benchmark_w) @ dx_return\n",
" rets.append(ret)\n",
" \n",
" if previous_pos.empty:\n",
" turn_over = 0.\n",
" else:\n",
" pos_merged = pd.merge(pos, previous_pos, on=['code'], how='outer')\n",
" pos_merged.fillna(0, inplace=True)\n",
" turn_over = np.abs(pos_merged.weight_x - pos_merged.weight_y).sum()\n",
" \n",
" turn_overs.append(turn_over)\n",
" \n",
" previous_pos = pos\n",
" previous_pos"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"ret_df['tc_cost'] = ret_df.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6), title='Fixed frequency rebalanced: {0}'.format(freq), secondary_y='tc_cost')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Targeted Turn Over Strategy\n",
"-------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"freq = '1d'\n",
"dates = makeSchedule('2012-01-01', '2017-09-19', tenor=freq, calendar='china.sse', dateGenerationRule=DateGeneration.Backward)\n",
"all_data = engine.fetch_data_range(universe, factors, dates=dates, benchmark=905)\n",
"factor_all_data = all_data['factor']\n",
"factor_groups = factor_all_data.groupby('trade_date')\n",
"\n",
"if freq == '1m':\n",
" horizon = 21\n",
"elif freq == '1w':\n",
" horizon = 4\n",
"elif freq == '2w':\n",
" horizon = 8\n",
"elif freq == '3w':\n",
" horizon = 12\n",
"elif freq == '1d':\n",
" horizon = 0\n",
"else:\n",
" raise ValueError(\"Unrecognized freq: {0}\".format(freq))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"target_turn_over = 0.5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"rets = []\n",
"turn_overs = []\n",
"previous_pos = pd.DataFrame()\n",
"\n",
"for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" codes = data.code.tolist()\n",
" ref_date = date.strftime('%Y-%m-%d')\n",
" returns = engine.fetch_dx_return(ref_date, codes, horizon=horizon)\n",
" total_data = pd.merge(data, returns, on=['code']).dropna()\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" industry = total_data.industry.values\n",
" dx_return = total_data.dx.values\n",
" benchmark_w = total_data.weight.values\n",
" \n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp, np.ones((len(risk_exp), 1))), axis=1).astype(float)\n",
" risk_names = constraint_risk + ['total']\n",
" risk_target = risk_exp_expand.T @ benchmark_w\n",
" lbound = np.zeros(len(total_data))\n",
" ubound = 0.01 + benchmark_w\n",
"\n",
" constraint = Constraints(risk_exp_expand, risk_names)\n",
" for i, name in enumerate(risk_names):\n",
" constraint.set_constraints(name, lower_bound=risk_target[i], upper_bound=risk_target[i])\n",
" \n",
" er = factor_processing(total_data[factors].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[standardize]) @ factor_weights\n",
" \n",
" pos, _ = er_portfolio_analysis(er,\n",
" industry,\n",
" dx_return,\n",
" constraint,\n",
" False,\n",
" benchmark_w)\n",
" pos['code'] = total_data['code'].astype(int).values\n",
" \n",
" if previous_pos.empty:\n",
" turn_over = 0.\n",
" else:\n",
" pos_merged = pd.merge(pos, previous_pos, on=['code'], how='left')\n",
" pos_merged.fillna(0, inplace=True)\n",
" turn_over = np.abs(pos_merged.weight_x - pos_merged.weight_y).sum()\n",
" \n",
" if turn_over < target_turn_over and not previous_pos.empty:\n",
" turn_over = 0.\n",
" previous_pos = pos_merged[['weight_y', 'code']]\n",
" previous_pos.rename(columns={'weight_y': 'weight'}, inplace=True)\n",
" pos = previous_pos.copy()\n",
" \n",
" turn_overs.append(turn_over)\n",
" \n",
" ret = (pos.weight - benchmark_w) @ dx_return\n",
" rets.append(ret)\n",
" \n",
" previous_pos = pos.copy()\n",
" print('{0} is finished'.format(date))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs}, index=dates)\n",
"ret_df.loc[advanceDateByCalendar('china.sse', dates[-1], freq)] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"ret_df['tc_cost'] = ret_df.turn_over * 0.002"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Targeted turn over rebalanced: Monitored freq {0}, {1} target'.format(freq,\n",
" target_turn_over),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%pylab inline\n",
"import pandas as pd\n",
"import sqlalchemy\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"factor_data = pd.read_hdf('multifactor.hdf', 'factor_data')\n",
"common_500 = pd.read_hdf('multifactor.hdf', 'common_500')\n",
"index_components = pd.read_hdf('multifactor.hdf', 'index_components')\n",
"index_data = pd.read_hdf('multifactor.hdf', 'index_data')\n",
"prod_500 = pd.read_hdf('multifactor.hdf', 'prod_500')\n",
"risk_factor_500 = pd.read_hdf('multifactor.hdf', 'risk_factor_500')\n",
"return_data_500 = pd.read_hdf('multifactor.hdf', 'return_data_500')\n",
"prod_factor_cols = pd.read_hdf('multifactor.hdf', 'prod_factor_cols')\n",
"risk_factor_cols = pd.read_hdf('multifactor.hdf', 'risk_factor_cols')\n",
"common_factor_cols = pd.read_hdf('multifactor.hdf', 'common_factor_cols')\n",
"common_500_factor_cols = pd.read_hdf('multifactor.hdf', 'common_500_factor_cols')"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# data merging\n",
"---------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"index_components_name = '500Weight'\n",
"benchmark = 'zz500'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"return_data_500['dret'] = return_data_500['D1LogReturn']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"index_data['ret'] = index_data[benchmark] / index_data[benchmark].shift(1) - 1.\n",
"index_data['dret_b'] = index_data['ret'] .shift(-2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"total_data = pd.merge(factor_data, prod_500[prod_factor_cols.append(pd.Series(['Date', 'Code']))], on=['Date', 'Code'])\n",
"total_data = pd.merge(total_data, common_500[common_500_factor_cols.append(pd.Series(['Date', 'Code']))], on=['Date', 'Code'])\n",
"total_data = pd.merge(total_data, index_data[['Date', 'dret_b']], on='Date', how='left')\n",
"total_data.dropna(inplace=True)\n",
"total_data = pd.merge(total_data, index_components[['Date', 'Code', index_components_name]], on=['Date', 'Code'], how='left')\n",
"total_data.fillna(0, inplace=True)\n",
"total_data = pd.merge(total_data, risk_factor_500, on=['Date', 'Code'])\n",
"total_data = pd.merge(total_data, return_data_500[['Date', 'Code', 'dret']], on=['Date', 'Code'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data = total_data[total_data[index_components_name] != 0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"len(total_data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# data processing\n",
"---------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from alphamind.data.standardize import standardize\n",
"from alphamind.data.neutralize import neutralize\n",
"from alphamind.data.winsorize import winsorize_normal"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_factors = common_factor_cols.append(prod_factor_cols)\n",
"total_factors = total_factors.append(common_500_factor_cols)\n",
"\n",
"#risk_factor_cols = risk_factor_cols[risk_factor_cols != 'Size']\n",
"\n",
"all_factors = total_data[total_factors]\n",
"risk_factors = total_data[risk_factor_cols]\n",
"groups = total_data.Date.values.astype(np.int)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"factor_processed = neutralize(risk_factors.values,\n",
" winsorize_normal(all_factors.values, groups=groups),\n",
" groups=groups)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"normed_factor = pd.DataFrame(factor_processed, columns=total_factors, index=total_data.Date)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Performance (Long top)\n",
"---------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from alphamind.portfolio.rankbuilder import rank_build"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%time\n",
"use_rank = 100\n",
"pos_data = rank_build(normed_factor.values, use_rank, groups)\n",
"pos_df = pd.DataFrame(pos_data, columns=normed_factor.columns, index=normed_factor.index) / use_rank"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_mat = (pos_df.values - total_data[[index_components_name]].values / 100.) * total_data[['dret']].values\n",
"ret_df = pd.DataFrame(ret_mat, columns=normed_factor.columns, index=normed_factor.index)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"top_factors = ret_df.groupby(level=0).sum()[-90:].sum().abs().sort_values(ascending=False)[:10].index"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[top_factors].groupby(level=0).sum()[-180:].cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[top_factors].groupby(level=0).sum()[-90:].cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[top_factors].groupby(level=0).sum()[-60:].cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[top_factors].groupby(level=0).sum().cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[prod_factor_cols].groupby(level=0).sum().cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[prod_factor_cols].groupby(level=0).sum()[-90:].cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"pos_corr = pos_df.corr()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"pos_corr = pos_corr.loc[total_factors, total_factors]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turn_over_table = {}\n",
"pos_df['Code'] = total_data.Code.values\n",
"pos_df.reset_index(inplace=True)\n",
"\n",
"for name in total_factors:\n",
" pos_series = pos_df[['Date', 'Code', name]]\n",
" pivot_position = pos_series.pivot_table(name, index='Date', columns='Code').fillna(0.)\n",
" turn_over_series = pivot_position.diff().abs().sum(axis=1)\n",
" turn_over_table[name] = turn_over_series.values\n",
" \n",
"turn_over_table = pd.DataFrame(turn_over_table, index=pos_df.Date.unique())\n",
"turn_over_table = turn_over_table[total_factors]\n",
"turn_over_table"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from pandas import ExcelWriter"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"writer = ExcelWriter('Summary_500_long_top_tmp.xlsx')\n",
"ret_series = ret_df.groupby(level=0).sum().dropna()\n",
"ret_series.to_excel(writer, 'ret_series')\n",
"pos_corr.to_excel(writer, 'pos_corr')\n",
"turn_over_table.to_excel(writer, 'turn_over')\n",
"writer.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Factor Performance (risk neutral)\n",
"---------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from alphamind.portfolio.linearbuilder import linear_build"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"total_data[total_factors] = normed_factor.values\n",
"total_data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"marke_netural_pos = {}\n",
"for i, name in enumerate(total_factors):\n",
"\n",
" lbound_exposure = -1e-2 * np.ones(len(risk_factor_cols))\n",
" ubound_exposure = 1e-2 * np.ones(len(risk_factor_cols))\n",
"\n",
" def get_benchmark_match_pos(x, name):\n",
" er = x[name].values\n",
" bm = x[index_components_name].values / 100.\n",
" lbound = 0.\n",
" ubound = 0.01 + bm\n",
" risk_exposure = x[risk_factor_cols].values\n",
"\n",
" status, value , ret = linear_build(er,\n",
" lbound=lbound,\n",
" ubound=ubound,\n",
" risk_exposure=risk_exposure,\n",
" bm=bm,\n",
" risk_target=(lbound_exposure, ubound_exposure),\n",
" solver='GLPK')\n",
"\n",
" if status != 'optimal':\n",
" return pd.Series(np.ones(len(er)) / len(er))\n",
" else:\n",
" return pd.Series(ret)\n",
" \n",
" look_into = risk_factor_cols.append(pd.Series([index_components_name, 'Date', name]))\n",
" res = total_data[look_into].groupby('Date').apply(get_benchmark_match_pos, name=name).values\n",
" marke_netural_pos[name] = res\n",
" print('{0}: Factor {1} is finished'.format(i, name))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"pos_df = pd.DataFrame(marke_netural_pos, index=total_data.Date)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_mat = (pos_df.values - total_data[[index_components_name]].values / 100.) * total_data[['dret']].values\n",
"ret_df = pd.DataFrame(ret_mat, columns=pos_df.columns, index=normed_factor.index)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[prod_factor_cols].groupby(level=0).sum().cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ret_df[prod_factor_cols].groupby(level=0).sum()[-90:].cumsum().plot(figsize=(16, 8))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"pos_corr = pos_df.corr()\n",
"pos_corr.loc[prod_factor_cols.tolist(), prod_factor_cols.tolist()]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turn_over_table = {}\n",
"pos_df['Code'] = total_data.Code.values\n",
"pos_df.reset_index(inplace=True)\n",
"\n",
"for name in total_factors:\n",
" pos_series = pos_df[['Date', 'Code', name]]\n",
" pivot_position = pos_series.pivot_table(name, index='Date', columns='Code').fillna(0.)\n",
" turn_over_series = pivot_position.diff().abs().sum(axis=1)\n",
" turn_over_table[name] = turn_over_series.values\n",
" \n",
"turn_over_table = pd.DataFrame(turn_over_table, index=pos_df.Date.unique())\n",
"turn_over_table = turn_over_table[total_factors]\n",
"turn_over_table"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"pos_corr = pos_corr.loc[total_factors, total_factors]\n",
"\n",
"writer = ExcelWriter('Summary_500_risk_neutral_tmp.xlsx')\n",
"ret_series = ret_df.groupby(level=0).sum().dropna()\n",
"ret_series.to_excel(writer, 'ret_series')\n",
"pos_corr.to_excel(writer, 'pos_corr')\n",
"turn_over_table.to_excel(writer, 'turn_over')\n",
"writer.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"turn_over_table"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Raw Product Factor \n",
"-----------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"risk_factor_values = total_data[risk_factor_cols].values\n",
"index_components_values = total_data[[index_components_name]].values / 100."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"for i, name in enumerate(total_factors):\n",
" pos_values = pos_df[[name]].values\n",
" risk_values = (pos_values - index_components_values) * risk_factor_values\n",
" risk_tables = pd.DataFrame(risk_values, columns=risk_factor_cols, index=total_data.Date)\n",
" aggregated_risk = risk_tables.groupby(level=0).sum()\n",
" print('{0}: Factor {1}, {2}, {3}'.format(i, name, aggregated_risk.min(),aggregated_risk.max()))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"aggregated_risk.max()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment