Unverified Commit 9b36cc04 authored by lion-sing's avatar lion-sing Committed by GitHub

Merge pull request #5 from alpha-miner/master

sync from original repo
parents 4b49b7bb c461aee5
...@@ -27,6 +27,7 @@ from alphamind.data.winsorize import winsorize_normal ...@@ -27,6 +27,7 @@ from alphamind.data.winsorize import winsorize_normal
from alphamind.data.standardize import standardize from alphamind.data.standardize import standardize
from alphamind.data.standardize import projection from alphamind.data.standardize import projection
from alphamind.data.neutralize import neutralize from alphamind.data.neutralize import neutralize
from alphamind.data.rank import rank
from alphamind.data.engines.sqlengine import factor_tables from alphamind.data.engines.sqlengine import factor_tables
from alphamind.data.engines.utilities import industry_list from alphamind.data.engines.utilities import industry_list
...@@ -78,6 +79,7 @@ __all__ = [ ...@@ -78,6 +79,7 @@ __all__ = [
'standardize', 'standardize',
'projection', 'projection',
'neutralize', 'neutralize',
'rank',
'factor_tables', 'factor_tables',
'industry_list', 'industry_list',
'fetch_data_package', 'fetch_data_package',
......
...@@ -8,8 +8,10 @@ Created on 2017-4-25 ...@@ -8,8 +8,10 @@ Created on 2017-4-25
from alphamind.data.standardize import standardize from alphamind.data.standardize import standardize
from alphamind.data.winsorize import winsorize_normal as winsorize from alphamind.data.winsorize import winsorize_normal as winsorize
from alphamind.data.neutralize import neutralize from alphamind.data.neutralize import neutralize
from alphamind.data.rank import rank
__all__ = ['standardize', __all__ = ['standardize',
'winsorize', 'winsorize',
'neutralize'] 'neutralize',
'rank']
...@@ -120,9 +120,28 @@ class SqlEngine(object): ...@@ -120,9 +120,28 @@ class SqlEngine(object):
query = self.session.query(FactorMaster) query = self.session.query(FactorMaster)
return pd.read_sql(query.statement, query.session.bind) return pd.read_sql(query.statement, query.session.bind)
def fetch_factor_coverage(self) -> pd.DataFrame: def fetch_factor_coverage(self,
query = self.session.query(FactorLog) start_date: str,
return pd.read_sql(query.statement, query.session.bind) end_date: str,
universe: str=None,
source: str=None) -> pd.DataFrame:
conditions = []
conditions.append(FactorLog.trade_date.between(start_date, end_date))
if universe:
conditions.append(FactorLog.universe == universe)
if source:
conditions.append(FactorLog.source == source)
query = select([FactorLog]).where(
and_(
*conditions
)
)
return pd.read_sql(query, self.session.bind)
def fetch_risk_meta(self) -> pd.DataFrame: def fetch_risk_meta(self) -> pd.DataFrame:
query = self.session.query(RiskMaster) query = self.session.query(RiskMaster)
......
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\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",
"\n",
"plt.style.use('ggplot')"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"Back test parameter settings\n",
"\"\"\"\n",
"\n",
"start_date = '2010-01-01'\n",
"end_date = '2018-02-24'\n",
"\n",
"frequency = '10b'\n",
"industry_lower = 1.0\n",
"industry_upper = 1.0\n",
"method = 'risk_neutral'\n",
"neutralize_risk = ['SIZE'] + industry_styles\n",
"industry_name = 'sw_adj'\n",
"industry_level = 1\n",
"benchmark_total_lower = 0.8\n",
"benchmark_total_upper = 1.0\n",
"horizon = map_freq(frequency)\n",
"weight_gap = 0.01\n",
"benchmark_code = 905\n",
"universe_name = ['zz800']\n",
"universe = Universe('custom', universe_name)\n",
"ref_dates = makeSchedule(start_date, end_date, frequency, 'china.sse')\n",
"\n",
"executor = NaiveExecutor()\n",
"data_source = 'postgres+psycopg2://postgres:A12345678!@10.63.6.220/alpha'\n",
"engine = SqlEngine(data_source)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"Constraints settings\n",
"\"\"\"\n",
"\n",
"industry_names = industry_list(industry_name, industry_level)\n",
"constraint_risk = ['SIZE', 'SIZENL', 'BETA']\n",
"total_risk_names = constraint_risk + ['benchmark', 'total']\n",
"\n",
"b_type = []\n",
"l_val = []\n",
"u_val = []\n",
"\n",
"for name in total_risk_names:\n",
" if name == 'benchmark':\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(benchmark_total_lower)\n",
" u_val.append(benchmark_total_upper)\n",
" elif name in {'SIZE', 'SIZENL', 'BETA'}:\n",
" b_type.append(BoundaryType.ABSOLUTE)\n",
" l_val.append(0.0)\n",
" u_val.append(0.0)\n",
" else:\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(industry_lower)\n",
" u_val.append(industry_upper)\n",
"\n",
"bounds = create_box_bounds(total_risk_names, b_type, l_val, u_val)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def factor_analysis(engine, factor_name, universe, benchmark_code, positive):\n",
" \n",
" \"\"\"\n",
" Data phase\n",
" \"\"\"\n",
" index_return = engine.fetch_dx_return_index_range(benchmark_code, start_date, end_date, horizon=horizon,\n",
" offset=1).set_index('trade_date')\n",
"\n",
" codes_return = engine.fetch_dx_return_range(universe,\n",
" dates=ref_dates,\n",
" horizon=horizon,\n",
" offset=1)\n",
"\n",
" return_groups = codes_return.groupby('trade_date')\n",
" \n",
" \"\"\"\n",
" Model phase: we need 1 constant linear model and one linear regression model\n",
" \"\"\"\n",
" industry_total = engine.fetch_industry_matrix_range(universe, dates=ref_dates, category=industry_name, level=industry_level)\n",
" industry_groups = industry_total.groupby('trade_date')\n",
" \n",
" alpha_name = [str(factor_name) + '_' + ('pos' if positive else 'neg')]\n",
" simple_expression = CSRes(LAST(factor_name), 'roe_q') if positive else -CSRes(LAST(factor_name), 'roe_q')\n",
"\n",
" const_features = {alpha_name[0]: simple_expression}\n",
" const_weights = {alpha_name[0]: 1.}\n",
"\n",
" const_model = ConstLinearModel(features=alpha_name,\n",
" weights=const_weights)\n",
"\n",
" const_model_factor_data = engine.fetch_data_range(universe,\n",
" const_features,\n",
" dates=ref_dates,\n",
" benchmark=benchmark_code)['factor'].dropna()\n",
"\n",
" rets = []\n",
" turn_overs = []\n",
" leverags = []\n",
" ics = []\n",
" index_dates = []\n",
" factor_groups = const_model_factor_data.groupby('trade_date')\n",
"\n",
" for i, value in enumerate(factor_groups):\n",
" date = value[0]\n",
" data = value[1]\n",
" index_dates.append(date)\n",
" \n",
" industry_matrix = industry_groups.get_group(date)\n",
" total_data = data.fillna(data[alpha_name].median())\n",
" total_data = pd.merge(total_data, industry_matrix, on=['code'])\n",
" alpha_logger.info('{0}: {1}'.format(date, len(total_data)))\n",
" risk_exp = total_data[neutralize_risk].values.astype(float)\n",
" benchmark_w = total_data.weight.values\n",
" is_in_benchmark = (benchmark_w > 0.).astype(float).reshape(-1, 1)\n",
"\n",
" constraint_exp = total_data[constraint_risk].values\n",
" risk_exp_expand = np.concatenate((constraint_exp,\n",
" is_in_benchmark,\n",
" np.ones_like(is_in_benchmark)), axis=1).astype(float)\n",
" total_risk_exp = pd.DataFrame(risk_exp_expand, columns=total_risk_names)\n",
" constraints = LinearConstraints(bounds, total_risk_exp, benchmark_w)\n",
"\n",
" lbound = np.maximum(0., benchmark_w - weight_gap)\n",
" ubound = weight_gap + benchmark_w\n",
"\n",
" factor_values = factor_processing(total_data[alpha_name].values,\n",
" pre_process=[winsorize_normal, standardize],\n",
" risk_factors=risk_exp,\n",
" post_process=[winsorize_normal, standardize, rank])\n",
"\n",
" # const linear model\n",
" er = const_model.predict(pd.DataFrame(data={alpha_name[0]: factor_values.flatten()}))\n",
"\n",
" alpha_logger.info('{0} full re-balance'.format(date))\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" total_data.industry_name.values,\n",
" None,\n",
" constraints,\n",
" False,\n",
" benchmark_w,\n",
" method=method,\n",
" lbound=lbound,\n",
" ubound=ubound)\n",
"\n",
" target_pos['code'] = total_data['code'].values\n",
"\n",
" turn_over, executed_pos = executor.execute(target_pos=target_pos)\n",
" dx_returns = return_groups.get_group(date)\n",
"\n",
" result = pd.merge(executed_pos, total_data[['code', 'weight']], on=['code'], how='inner')\n",
" result = pd.merge(result, dx_returns, on=['code'])\n",
"\n",
" leverage = result.weight_x.abs().sum()\n",
"\n",
" excess_return = np.exp(result.dx.values) - 1. - index_return.loc[date, 'dx']\n",
" raw_weight = result.weight_x.values\n",
" activate_weight = raw_weight - result.weight_y.values\n",
" ret = raw_weight @ excess_return\n",
" risk_adjusted_ic = np.corrcoef(excess_return, activate_weight)[0, 1]\n",
" rets.append(np.log(1. + ret))\n",
" ics.append(risk_adjusted_ic)\n",
" executor.set_current(executed_pos)\n",
" turn_overs.append(turn_over)\n",
" leverags.append(leverage)\n",
"\n",
" alpha_logger.info('{0} is finished'.format(date))\n",
"\n",
" ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs, 'IC': ics, 'leverage': leverags}, index=index_dates)\n",
"\n",
" ret_df.loc[advanceDateByCalendar('china.sse', ref_dates[-1], frequency)] = 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",
"\n",
" return alpha_name[0], ret_df\n",
"\n",
"def worker_func_positive(factor_name):\n",
" from alphamind.api import SqlEngine\n",
" engine = SqlEngine(data_source)\n",
" return factor_analysis(engine, factor_name, universe, benchmark_code, positive=True)\n",
"\n",
"\n",
"def worker_func_negative(factor_name):\n",
" from alphamind.api import SqlEngine\n",
" engine = SqlEngine(data_source)\n",
" return factor_analysis(engine, factor_name, universe, benchmark_code, positive=False)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"df = engine.fetch_factor_coverage(start_date='2011-01-01',\n",
" end_date='2018-02-12',\n",
" universe=universe_name[0])\n",
"df = df[df.source != 'risk_exposure']\n",
"df = df.groupby('factor').mean()\n",
"df = df[df.coverage >= 0.95]"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 1h 25min 5s\n"
]
}
],
"source": [
"%%time\n",
"\n",
"from dask.distributed import Client\n",
"\n",
"client = Client('10.63.6.176:8786')\n",
"\n",
"tasks = client.map(worker_func_positive, df.index.tolist(), pure=False)\n",
"res1 = client.gather(tasks)\n",
"\n",
"tasks = client.map(worker_func_negative, df.index.tolist(), pure=False)\n",
"res2 = client.gather(tasks)\n",
"\n",
"factor_df = pd.DataFrame()\n",
"ic_df = pd.DataFrame()\n",
"\n",
"for f_name, res in res1:\n",
" factor_df[f_name] = res['returns']\n",
" ic_df[f_name] = res['IC']\n",
"\n",
"for f_name, res in res2:\n",
" factor_df[f_name] = res['returns']\n",
" ic_df[f_name] = res['IC']"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"factor_res = factor_df.agg(['mean', 'std']).T\n",
"factor_res['t.'] = factor_res['mean'] / factor_res['std'] * np.sqrt(len(factor_df))\n",
"\n",
"ic_res = ic_df.agg(['mean', 'std']).T\n",
"ic_res['t.'] = ic_res['mean'] / ic_res['std'] * np.sqrt(len(ic_df))"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"with pd.ExcelWriter(f'{universe_name[0]}_{benchmark_code}.xlsx', engine='xlsxwriter') as writer:\n",
" factor_df.to_excel(writer, sheet_name='ret')\n",
" factor_res.to_excel(writer, sheet_name='ic')\n",
" factor_df.to_excel(writer, sheet_name='ret_stat')\n",
" ic_res.to_excel(writer, sheet_name='ic_stat')"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"client.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"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",
"\n",
"plt.style.use('ggplot')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Back test parameter settings\n",
"start_date = '2010-01-01'\n",
"end_date = '2018-02-24'\n",
"\n",
"freq = '10b'\n",
"industry_lower = 1.\n",
"industry_upper = 1.\n",
"neutralized_risk = industry_styles\n",
"industry_name = 'sw_adj'\n",
"industry_level = 1\n",
"turn_over_target_base = 0.4\n",
"benchmark_total_lower = 0.8\n",
"benchmark_total_upper = 1.0\n",
"batch = 0\n",
"horizon = map_freq(freq)\n",
"weight_gap = 0.01\n",
"universe = Universe(\"custom\", ['zz800'])\n",
"data_source = 'postgres+psycopg2://postgres:A12345678!@10.63.6.220/alpha'\n",
"benchmark_code = 905\n",
"\n",
"executor = NaiveExecutor()\n",
"ref_dates = makeSchedule(start_date, end_date, freq, 'china.sse')\n",
"engine = SqlEngine(data_source)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"alpha_factors = {\n",
" 'f01': LAST('ep_q'),\n",
" 'f02': LAST('roe_q'),\n",
" 'f03': LAST('market_confidence_25d'),\n",
" 'f04': LAST('ILLIQUIDITY'),\n",
" 'f05': LAST('cfinc1_q'),\n",
" 'f06': LAST('CFO2EV'),\n",
" 'f07': LAST('IVR'),\n",
" 'f08': LAST('con_pe_rolling_order'),\n",
" 'f09': LAST('con_pb_rolling_order'),\n",
"}\n",
"\n",
"weights = dict(f01=1.,\n",
" f02=1.,\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",
"\n",
"alpha_model = ConstLinearModel(features=alpha_factors, weights=weights)\n",
"\n",
"def train_worker(ref_date):\n",
" data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model='short',\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[winsorize_normal, standardize],\n",
" warm_start=0,\n",
" data_source=data_source)\n",
" \n",
" return train_model(ref_date, alpha_model, data_meta)\n",
"\n",
"\n",
"def predict_worker(params):\n",
" data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model='short',\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[winsorize_normal, standardize],\n",
" warm_start=0,\n",
" data_source=data_source)\n",
" ref_date, model = params\n",
" er = predict_by_model(ref_date, model, data_meta)\n",
" return er"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# %%time\n",
"\n",
"# training / predict on dask executor\n",
"\n",
"from dask.distributed import Client\n",
"client = Client('10.63.6.13:8786')\n",
"\n",
"tasks = client.map(predict_worker, [(d.strftime('%Y-%m-%d'), alpha_model) for d in ref_dates], pure=False)\n",
"predicts = client.gather(tasks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# rebalance\n",
"\n",
"industry_names = industry_list(industry_name, industry_level)\n",
"constraint_risk = ['SIZE', 'SIZENL', 'BETA'] + industry_names\n",
"total_risk_names = constraint_risk + ['benchmark', 'total']\n",
"\n",
"b_type = []\n",
"l_val = []\n",
"u_val = []\n",
"\n",
"previous_pos = pd.DataFrame()\n",
"rets = []\n",
"turn_overs = []\n",
"leverags = []\n",
"\n",
"for name in total_risk_names:\n",
" if name == 'benchmark':\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(benchmark_total_lower)\n",
" u_val.append(benchmark_total_upper)\n",
" elif name in {'SIZE', 'SIZENL', 'BETA'}:\n",
" b_type.append(BoundaryType.ABSOLUTE)\n",
" l_val.append(0.0)\n",
" u_val.append(0.0)\n",
" else:\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(industry_lower)\n",
" u_val.append(industry_upper)\n",
"\n",
"bounds = create_box_bounds(total_risk_names, b_type, l_val, u_val)\n",
"\n",
"industry_total = engine.fetch_industry_matrix_range(universe, dates=ref_dates, category=industry_name, level=industry_level)\n",
"benchmark_total = engine.fetch_benchmark_range(dates=ref_dates, benchmark=benchmark_code)\n",
"risk_total = engine.fetch_risk_model_range(universe, dates=ref_dates)[1]\n",
"\n",
"for i, ref_date in enumerate(ref_dates):\n",
" ref_date = ref_date.strftime('%Y-%m-%d')\n",
" industry_matrix = industry_total[industry_total.trade_date == ref_date]\n",
" benchmark_w = benchmark_total[benchmark_total.trade_date == ref_date]\n",
" risk_matrix = risk_total[risk_total.trade_date == ref_date]\n",
" \n",
" res = pd.merge(industry_matrix, benchmark_w, on=['code'], how='left').fillna(0.)\n",
" res = pd.merge(res, risk_matrix, on=['code'])\n",
" res = res.dropna()\n",
" codes = res.code.values.tolist()\n",
" \n",
" benchmark_w = res.weight.values\n",
" is_in_benchmark = (benchmark_w > 0.).astype(float).reshape((-1, 1))\n",
" \n",
" total_risk_exp = np.concatenate([res[constraint_risk].values.astype(float),\n",
" is_in_benchmark,\n",
" np.ones_like(is_in_benchmark)],\n",
" axis=1)\n",
" total_risk_exp = pd.DataFrame(total_risk_exp, columns=total_risk_names)\n",
" constraints = LinearConstraints(bounds, total_risk_exp, benchmark_w)\n",
" \n",
" lbound = np.maximum(0., benchmark_w - weight_gap) # np.zeros(len(total_data))\n",
" ubound = weight_gap + 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",
" er = predicts[i].loc[codes].values\n",
" \n",
" try:\n",
" alpha_logger.info('{0} partial re-balance: {1}'.format(ref_date, len(er)))\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry_matrix.industry_name.values,\n",
" None,\n",
" constraints,\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: {1}'.format(ref_date, len(er)))\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry_matrix.industry_name.values,\n",
" None,\n",
" constraints,\n",
" False,\n",
" benchmark_w,\n",
" method='risk_neutral',\n",
" lbound=lbound,\n",
" ubound=ubound)\n",
" \n",
" target_pos['code'] = codes\n",
" turn_over, executed_pos = executor.execute(target_pos=target_pos)\n",
"\n",
" executed_codes = executed_pos.code.tolist()\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",
"\n",
" leverage = result.weight.abs().sum()\n",
"\n",
" ret = result.weight.values @ (np.exp(result.dx.values) - 1.)\n",
" rets.append(np.log(1. + ret))\n",
" executor.set_current(executed_pos)\n",
" turn_overs.append(turn_over)\n",
" leverags.append(leverage)\n",
"\n",
" previous_pos = executed_pos\n",
" alpha_logger.info('{0} is finished'.format(ref_date))"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x1b2d29094a8>"
]
},
"execution_count": 75,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1b2d1759ac8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs, 'leverage': leverags}, index=ref_dates)\n",
"\n",
"# index return\n",
"index_return = engine.fetch_dx_return_index_range(benchmark_code, start_date, end_date, horizon=horizon,\n",
" offset=1).set_index('trade_date')\n",
"ret_df['index'] = index_return['dx']\n",
"\n",
"ret_df.loc[advanceDateByCalendar('china.sse', ref_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'] * ret_df['leverage']\n",
"\n",
"ret_df[['returns', 'tc_cost']].cumsum().plot(figsize=(12, 6),\n",
" title='Fixed freq rebalanced: {0} with benchmark {1}'.format(freq, 905),\n",
" secondary_y='tc_cost')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%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.StatefulAccumulators import MovingAverage\n",
"from PyFin.Math.Accumulators.StatefulAccumulators import MovingSharp\n",
"from PyFin.Math.Accumulators.StatefulAccumulators import MovingMaxDrawdown\n",
"\n",
"plt.style.use('ggplot')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"Back test parameter settings\n",
"\"\"\"\n",
"\n",
"start_date = '2010-01-01'\n",
"end_date = '2018-02-24'\n",
"\n",
"freq = '10b'\n",
"industry_lower = 1.0\n",
"industry_upper = 1.0\n",
"neutralized_risk = industry_styles\n",
"industry_name = 'sw_adj'\n",
"industry_level = 1\n",
"turn_over_target_base = 0.4\n",
"benchmark_total_lower = 0.8\n",
"benchmark_total_upper = 1.0\n",
"batch = 0\n",
"horizon = map_freq(freq)\n",
"universe = Universe(\"custom\", ['zz800'])\n",
"data_source = 'postgres+psycopg2://postgres:A12345678!@10.63.6.220/alpha'\n",
"benchmark_code = 300\n",
"\n",
"executor = NaiveExecutor()\n",
"ref_dates = makeSchedule(start_date, end_date, freq, 'china.sse')\n",
"engine = SqlEngine(data_source)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"Factor Model\n",
"\"\"\"\n",
"\n",
"alpha_factors = {\n",
" 'f01': LAST('ep_q'),\n",
" 'f02': LAST('roe_q'),\n",
" 'f03': LAST('market_confidence_25d'),\n",
" 'f04': LAST('DivP'),\n",
" 'f05': LAST('BP'),\n",
" 'f06': LAST('val_q'),\n",
" 'f07': LAST('VOL60'),\n",
" 'f08': LAST('con_pe_rolling_order'),\n",
" 'f09': LAST('con_pb_rolling_order')\n",
"}\n",
"\n",
"weights = dict(f01=1.,\n",
" f02=1.,\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",
"\n",
"alpha_model = ConstLinearModel(features=alpha_factors, weights=weights)\n",
"\n",
"def predict_worker(params):\n",
" data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model='short',\n",
" pre_process=[winsorize_normal, standardize],\n",
" post_process=[winsorize_normal, standardize],\n",
" warm_start=0,\n",
" data_source=data_source)\n",
" ref_date, model = params\n",
" er = predict_by_model(ref_date, model, data_meta)\n",
" return er"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 0 ns\n"
]
}
],
"source": [
"%%time\n",
"\n",
"\"\"\"\n",
"Training Phase\n",
"\"\"\"\n",
"\n",
"pass"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 8.42 s\n"
]
}
],
"source": [
"%%time\n",
"\n",
"\"\"\"\n",
"Predicting Phase\n",
"\"\"\"\n",
"\n",
"from dask.distributed import Client\n",
"client = Client('10.63.6.13:8786')\n",
"\n",
"tasks = client.map(predict_worker, [(d.strftime('%Y-%m-%d'), alpha_model) for d in ref_dates], pure=False)\n",
"predicts = client.gather(tasks)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"Shared Data\n",
"\"\"\"\n",
"\n",
"industry_names = industry_list(industry_name, industry_level)\n",
"constraint_risk = ['SIZE', 'SIZENL', 'BETA'] + industry_names\n",
"total_risk_names = constraint_risk + ['benchmark', 'total']\n",
"\n",
"b_type = []\n",
"l_val = []\n",
"u_val = []\n",
"\n",
"for name in total_risk_names:\n",
" if name == 'benchmark':\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(benchmark_total_lower)\n",
" u_val.append(benchmark_total_upper)\n",
" elif name in {'SIZE', 'SIZENL', 'BETA'}:\n",
" b_type.append(BoundaryType.ABSOLUTE)\n",
" l_val.append(0.0)\n",
" u_val.append(0.0)\n",
" else:\n",
" b_type.append(BoundaryType.RELATIVE)\n",
" l_val.append(industry_lower)\n",
" u_val.append(industry_upper)\n",
" \n",
"bounds = create_box_bounds(total_risk_names, b_type, l_val, u_val)\n",
"industry_total = engine.fetch_industry_matrix_range(universe, dates=ref_dates, category=industry_name, level=industry_level)\n",
"benchmark_total = engine.fetch_benchmark_range(dates=ref_dates, benchmark=benchmark_code)\n",
"risk_total = engine.fetch_risk_model_range(universe, dates=ref_dates)[1]\n",
"index_return = engine.fetch_dx_return_index_range(benchmark_code, start_date, end_date, horizon=horizon, offset=1).set_index('trade_date')"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# rebalance\n",
"\n",
"def create_scenario(weight_gap):\n",
"\n",
" previous_pos = pd.DataFrame()\n",
" rets = []\n",
" turn_overs = []\n",
" leverags = []\n",
"\n",
" for i, ref_date in enumerate(ref_dates):\n",
" ref_date = ref_date.strftime('%Y-%m-%d')\n",
" industry_matrix = industry_total[industry_total.trade_date == ref_date]\n",
" benchmark_w = benchmark_total[benchmark_total.trade_date == ref_date]\n",
" risk_matrix = risk_total[risk_total.trade_date == ref_date]\n",
"\n",
" res = pd.merge(industry_matrix, benchmark_w, on=['code'], how='left').fillna(0.)\n",
" res = pd.merge(res, risk_matrix, on=['code'])\n",
" res = res.dropna()\n",
" codes = res.code.values.tolist()\n",
"\n",
" benchmark_w = res.weight.values\n",
" is_in_benchmark = (benchmark_w > 0.).astype(float).reshape((-1, 1))\n",
"\n",
" total_risk_exp = np.concatenate([res[constraint_risk].values.astype(float),\n",
" is_in_benchmark,\n",
" np.ones_like(is_in_benchmark)],\n",
" axis=1)\n",
" total_risk_exp = pd.DataFrame(total_risk_exp, columns=total_risk_names)\n",
" constraints = LinearConstraints(bounds, total_risk_exp, benchmark_w)\n",
"\n",
" lbound = np.maximum(0., benchmark_w - weight_gap) # np.zeros(len(total_data))\n",
" ubound = weight_gap + 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",
" er = predicts[i].loc[codes].values\n",
"\n",
" try:\n",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry_matrix.industry_name.values,\n",
" None,\n",
" constraints,\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",
" target_pos, _ = er_portfolio_analysis(er,\n",
" industry_matrix.industry_name.values,\n",
" None,\n",
" constraints,\n",
" False,\n",
" benchmark_w,\n",
" method='risk_neutral',\n",
" lbound=lbound,\n",
" ubound=ubound)\n",
"\n",
" target_pos['code'] = codes\n",
" turn_over, executed_pos = executor.execute(target_pos=target_pos)\n",
"\n",
" executed_codes = executed_pos.code.tolist()\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",
"\n",
" leverage = result.weight.abs().sum()\n",
"\n",
" ret = result.weight.values @ (np.exp(result.dx.values) - 1.)\n",
" rets.append(np.log(1. + ret))\n",
" executor.set_current(executed_pos)\n",
" turn_overs.append(turn_over)\n",
" leverags.append(leverage)\n",
"\n",
" previous_pos = executed_pos\n",
" \n",
" ret_df = pd.DataFrame({'returns': rets, 'turn_over': turn_overs, 'leverage': leverags}, index=ref_dates)\n",
"\n",
" # index return\n",
" \n",
" ret_df['index'] = index_return['dx']\n",
"\n",
" ret_df.loc[advanceDateByCalendar('china.sse', ref_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['ret_after_tc'] = ret_df['returns'] - ret_df['tc_cost'] - ret_df['index'] * ret_df['leverage']\n",
" return ret_df"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"def create_report(ret_df, windows):\n",
" sharp_calc = MovingSharp(windows)\n",
" drawdown_calc = MovingMaxDrawdown(windows)\n",
" max_drawdown_calc = MovingMaxDrawdown(len(ret_df))\n",
"\n",
" res_df = pd.DataFrame(columns=['daily_return', 'cum_ret', 'sharp', 'drawdown', 'max_drawn', 'leverage'])\n",
" total_returns = 0.\n",
"\n",
" for i, ret in enumerate(ret_df['ret_after_tc']):\n",
" date = ret_df.index[i]\n",
" total_returns += ret\n",
" sharp_calc.push({'ret': ret, 'riskFree': 0.})\n",
" drawdown_calc.push({'ret': ret})\n",
" max_drawdown_calc.push({'ret': ret})\n",
"\n",
" res_df.loc[date, 'daily_return'] = ret\n",
" res_df.loc[date, 'cum_ret'] = total_returns\n",
" res_df.loc[date, 'drawdown'] = drawdown_calc.result()[0]\n",
" res_df.loc[date, 'max_drawn'] = max_drawdown_calc.result()[0]\n",
" res_df.loc[date, 'leverage'] = ret_df.loc[date, 'leverage']\n",
"\n",
" if i < 5:\n",
" res_df.loc[date, 'sharp'] = 0.\n",
" else:\n",
" res_df.loc[date, 'sharp'] = sharp_calc.result() * np.sqrt(windows)\n",
" return res_df"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"d:\\ProgramData\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:39: FutureWarning: \n",
"Passing list-likes to .loc or [] with any missing label will raise\n",
"KeyError in the future, you can use .reindex() as an alternative.\n",
"\n",
"See the documentation here:\n",
"http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike\n",
"2018-02-27 15:42:15,597 - ALPHA_MIND - INFO - 0.005 finished\n",
"2018-02-27 15:43:09,157 - ALPHA_MIND - INFO - 0.01 finished\n",
"2018-02-27 15:44:02,819 - ALPHA_MIND - INFO - 0.015 finished\n",
"2018-02-27 15:44:56,827 - ALPHA_MIND - INFO - 0.02 finished\n"
]
}
],
"source": [
"weight_gaps = [0.005, 0.010, 0.015, 0.020]\n",
"\n",
"with pd.ExcelWriter(f'{universe.base_universe[0]}_{benchmark_code}_perf.xlsx', engine='xlsxwriter') as writer:\n",
" for i, weight_gap in enumerate(weight_gaps):\n",
" ret_df = create_scenario(weight_gap)\n",
" res_df = create_report(ret_df, 25)\n",
" res_df.to_excel(writer, sheet_name=f'{i}')\n",
" alpha_logger.info(f\"{weight_gap} finished\")"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>daily_return</th>\n",
" <th>cum_ret</th>\n",
" <th>sharp</th>\n",
" <th>drawdown</th>\n",
" <th>max_drawn</th>\n",
" <th>leverage</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2010-01-04</th>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-01-18</th>\n",
" <td>0.002456</td>\n",
" <td>0.002456</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.98210</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-02-01</th>\n",
" <td>-0.003691</td>\n",
" <td>-0.001234</td>\n",
" <td>0.000000</td>\n",
" <td>-0.003691</td>\n",
" <td>-0.003691</td>\n",
" <td>0.98080</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-02-22</th>\n",
" <td>-0.001398</td>\n",
" <td>-0.002632</td>\n",
" <td>0.000000</td>\n",
" <td>-0.005088</td>\n",
" <td>-0.005088</td>\n",
" <td>0.99880</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-03-08</th>\n",
" <td>0.001219</td>\n",
" <td>-0.001413</td>\n",
" <td>0.000000</td>\n",
" <td>-0.005088</td>\n",
" <td>-0.005088</td>\n",
" <td>1.00070</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-03-22</th>\n",
" <td>-0.003154</td>\n",
" <td>-0.004567</td>\n",
" <td>-1.564942</td>\n",
" <td>-0.007023</td>\n",
" <td>-0.007023</td>\n",
" <td>0.99990</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-04-06</th>\n",
" <td>0.005331</td>\n",
" <td>0.000764</td>\n",
" <td>0.170609</td>\n",
" <td>-0.007023</td>\n",
" <td>-0.007023</td>\n",
" <td>1.00030</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-04-20</th>\n",
" <td>-0.011791</td>\n",
" <td>-0.011027</td>\n",
" <td>-1.339591</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>1.00090</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-05-05</th>\n",
" <td>0.000307</td>\n",
" <td>-0.010720</td>\n",
" <td>-1.229194</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.99920</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-05-19</th>\n",
" <td>0.007962</td>\n",
" <td>-0.002758</td>\n",
" <td>-0.255024</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.99890</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-06-02</th>\n",
" <td>-0.007907</td>\n",
" <td>-0.010665</td>\n",
" <td>-0.862161</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.99980</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-06-21</th>\n",
" <td>0.007624</td>\n",
" <td>-0.003041</td>\n",
" <td>-0.214491</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.99990</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-07-05</th>\n",
" <td>0.008193</td>\n",
" <td>0.005152</td>\n",
" <td>0.323698</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.99960</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-07-19</th>\n",
" <td>0.001580</td>\n",
" <td>0.006732</td>\n",
" <td>0.408208</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.97430</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-08-02</th>\n",
" <td>0.005666</td>\n",
" <td>0.012399</td>\n",
" <td>0.708708</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>0.97470</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-08-16</th>\n",
" <td>-0.013279</td>\n",
" <td>-0.000880</td>\n",
" <td>-0.041376</td>\n",
" <td>-0.013484</td>\n",
" <td>-0.013484</td>\n",
" <td>1.00010</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-08-30</th>\n",
" <td>-0.002519</td>\n",
" <td>-0.003399</td>\n",
" <td>-0.154688</td>\n",
" <td>-0.015798</td>\n",
" <td>-0.015798</td>\n",
" <td>0.99900</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-09-13</th>\n",
" <td>-0.012298</td>\n",
" <td>-0.015698</td>\n",
" <td>-0.633037</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99960</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-09-30</th>\n",
" <td>0.003504</td>\n",
" <td>-0.012194</td>\n",
" <td>-0.474059</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99970</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-10-21</th>\n",
" <td>0.032270</td>\n",
" <td>0.020077</td>\n",
" <td>0.508137</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99950</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-11-04</th>\n",
" <td>-0.001903</td>\n",
" <td>0.018173</td>\n",
" <td>0.448466</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99990</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-11-18</th>\n",
" <td>0.004564</td>\n",
" <td>0.022737</td>\n",
" <td>0.546899</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99980</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-02</th>\n",
" <td>0.005751</td>\n",
" <td>0.028489</td>\n",
" <td>0.667092</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99970</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-16</th>\n",
" <td>-0.001650</td>\n",
" <td>0.026839</td>\n",
" <td>0.614522</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99950</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-30</th>\n",
" <td>0.007329</td>\n",
" <td>0.034168</td>\n",
" <td>0.759830</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99960</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-01-14</th>\n",
" <td>0.013885</td>\n",
" <td>0.048052</td>\n",
" <td>1.030272</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99960</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-01-28</th>\n",
" <td>0.010359</td>\n",
" <td>0.058411</td>\n",
" <td>1.180538</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.95740</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-02-18</th>\n",
" <td>0.001031</td>\n",
" <td>0.059442</td>\n",
" <td>1.290546</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.95720</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-04</th>\n",
" <td>0.001280</td>\n",
" <td>0.060722</td>\n",
" <td>1.351831</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99890</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-18</th>\n",
" <td>0.018729</td>\n",
" <td>0.079451</td>\n",
" <td>1.632026</td>\n",
" <td>-0.028096</td>\n",
" <td>-0.028096</td>\n",
" <td>0.99900</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2016-12-19</th>\n",
" <td>0.001795</td>\n",
" <td>0.619046</td>\n",
" <td>1.928640</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99999</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-03</th>\n",
" <td>0.006513</td>\n",
" <td>0.625559</td>\n",
" <td>1.833167</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99999</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-17</th>\n",
" <td>0.006098</td>\n",
" <td>0.631657</td>\n",
" <td>1.732021</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-02-07</th>\n",
" <td>0.003424</td>\n",
" <td>0.635081</td>\n",
" <td>2.190087</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-02-21</th>\n",
" <td>0.010451</td>\n",
" <td>0.645533</td>\n",
" <td>2.439619</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99996</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-03-07</th>\n",
" <td>-0.001086</td>\n",
" <td>0.644447</td>\n",
" <td>2.149152</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99798</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-03-21</th>\n",
" <td>0.016426</td>\n",
" <td>0.660873</td>\n",
" <td>2.235613</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-04-06</th>\n",
" <td>-0.001144</td>\n",
" <td>0.659729</td>\n",
" <td>2.356093</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-04-20</th>\n",
" <td>0.007881</td>\n",
" <td>0.667610</td>\n",
" <td>2.448745</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-05-05</th>\n",
" <td>-0.008892</td>\n",
" <td>0.658717</td>\n",
" <td>2.227092</td>\n",
" <td>-0.013104</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-05-19</th>\n",
" <td>-0.002924</td>\n",
" <td>0.655793</td>\n",
" <td>2.487909</td>\n",
" <td>-0.012972</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99990</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-06</th>\n",
" <td>0.003434</td>\n",
" <td>0.659228</td>\n",
" <td>2.593745</td>\n",
" <td>-0.012802</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99990</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-20</th>\n",
" <td>0.011297</td>\n",
" <td>0.670525</td>\n",
" <td>2.860042</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-07-04</th>\n",
" <td>0.009526</td>\n",
" <td>0.680050</td>\n",
" <td>3.041796</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-07-18</th>\n",
" <td>0.016175</td>\n",
" <td>0.696225</td>\n",
" <td>3.055025</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99999</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-08-01</th>\n",
" <td>0.002968</td>\n",
" <td>0.699193</td>\n",
" <td>2.857844</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99999</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-08-15</th>\n",
" <td>-0.007531</td>\n",
" <td>0.691662</td>\n",
" <td>2.289452</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-08-29</th>\n",
" <td>0.001026</td>\n",
" <td>0.692688</td>\n",
" <td>2.742168</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-09-12</th>\n",
" <td>0.000855</td>\n",
" <td>0.693543</td>\n",
" <td>2.830931</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-09-26</th>\n",
" <td>-0.000392</td>\n",
" <td>0.693151</td>\n",
" <td>2.633798</td>\n",
" <td>-0.011817</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99997</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-10-17</th>\n",
" <td>-0.006175</td>\n",
" <td>0.686976</td>\n",
" <td>2.390601</td>\n",
" <td>-0.012217</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99997</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-10-31</th>\n",
" <td>-0.004647</td>\n",
" <td>0.682329</td>\n",
" <td>2.037490</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00002</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-11-14</th>\n",
" <td>0.005732</td>\n",
" <td>0.688061</td>\n",
" <td>2.259706</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00011</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-11-28</th>\n",
" <td>0.014009</td>\n",
" <td>0.702070</td>\n",
" <td>2.700705</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00011</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-12</th>\n",
" <td>0.000715</td>\n",
" <td>0.702786</td>\n",
" <td>2.437891</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99994</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-26</th>\n",
" <td>0.003241</td>\n",
" <td>0.706027</td>\n",
" <td>2.481936</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99996</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-01-10</th>\n",
" <td>0.009375</td>\n",
" <td>0.715401</td>\n",
" <td>2.536598</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>1.00008</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-01-24</th>\n",
" <td>0.001758</td>\n",
" <td>0.717159</td>\n",
" <td>2.417740</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99998</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-02-07</th>\n",
" <td>0.003852</td>\n",
" <td>0.721011</td>\n",
" <td>2.429653</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99993</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-02-28</th>\n",
" <td>0.000391</td>\n",
" <td>0.721402</td>\n",
" <td>2.185579</td>\n",
" <td>-0.016864</td>\n",
" <td>-0.035754</td>\n",
" <td>0.99994</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>199 rows × 6 columns</p>\n",
"</div>"
],
"text/plain": [
" daily_return cum_ret sharp drawdown max_drawn leverage\n",
"2010-01-04 0.000000 0.000000 0.000000 0.000000 0.000000 0.00000\n",
"2010-01-18 0.002456 0.002456 0.000000 0.000000 0.000000 0.98210\n",
"2010-02-01 -0.003691 -0.001234 0.000000 -0.003691 -0.003691 0.98080\n",
"2010-02-22 -0.001398 -0.002632 0.000000 -0.005088 -0.005088 0.99880\n",
"2010-03-08 0.001219 -0.001413 0.000000 -0.005088 -0.005088 1.00070\n",
"2010-03-22 -0.003154 -0.004567 -1.564942 -0.007023 -0.007023 0.99990\n",
"2010-04-06 0.005331 0.000764 0.170609 -0.007023 -0.007023 1.00030\n",
"2010-04-20 -0.011791 -0.011027 -1.339591 -0.013484 -0.013484 1.00090\n",
"2010-05-05 0.000307 -0.010720 -1.229194 -0.013484 -0.013484 0.99920\n",
"2010-05-19 0.007962 -0.002758 -0.255024 -0.013484 -0.013484 0.99890\n",
"2010-06-02 -0.007907 -0.010665 -0.862161 -0.013484 -0.013484 0.99980\n",
"2010-06-21 0.007624 -0.003041 -0.214491 -0.013484 -0.013484 0.99990\n",
"2010-07-05 0.008193 0.005152 0.323698 -0.013484 -0.013484 0.99960\n",
"2010-07-19 0.001580 0.006732 0.408208 -0.013484 -0.013484 0.97430\n",
"2010-08-02 0.005666 0.012399 0.708708 -0.013484 -0.013484 0.97470\n",
"2010-08-16 -0.013279 -0.000880 -0.041376 -0.013484 -0.013484 1.00010\n",
"2010-08-30 -0.002519 -0.003399 -0.154688 -0.015798 -0.015798 0.99900\n",
"2010-09-13 -0.012298 -0.015698 -0.633037 -0.028096 -0.028096 0.99960\n",
"2010-09-30 0.003504 -0.012194 -0.474059 -0.028096 -0.028096 0.99970\n",
"2010-10-21 0.032270 0.020077 0.508137 -0.028096 -0.028096 0.99950\n",
"2010-11-04 -0.001903 0.018173 0.448466 -0.028096 -0.028096 0.99990\n",
"2010-11-18 0.004564 0.022737 0.546899 -0.028096 -0.028096 0.99980\n",
"2010-12-02 0.005751 0.028489 0.667092 -0.028096 -0.028096 0.99970\n",
"2010-12-16 -0.001650 0.026839 0.614522 -0.028096 -0.028096 0.99950\n",
"2010-12-30 0.007329 0.034168 0.759830 -0.028096 -0.028096 0.99960\n",
"2011-01-14 0.013885 0.048052 1.030272 -0.028096 -0.028096 0.99960\n",
"2011-01-28 0.010359 0.058411 1.180538 -0.028096 -0.028096 0.95740\n",
"2011-02-18 0.001031 0.059442 1.290546 -0.028096 -0.028096 0.95720\n",
"2011-03-04 0.001280 0.060722 1.351831 -0.028096 -0.028096 0.99890\n",
"2011-03-18 0.018729 0.079451 1.632026 -0.028096 -0.028096 0.99900\n",
"... ... ... ... ... ... ...\n",
"2016-12-19 0.001795 0.619046 1.928640 -0.013104 -0.035754 0.99999\n",
"2017-01-03 0.006513 0.625559 1.833167 -0.013104 -0.035754 0.99999\n",
"2017-01-17 0.006098 0.631657 1.732021 -0.013104 -0.035754 1.00003\n",
"2017-02-07 0.003424 0.635081 2.190087 -0.013104 -0.035754 1.00003\n",
"2017-02-21 0.010451 0.645533 2.439619 -0.013104 -0.035754 0.99996\n",
"2017-03-07 -0.001086 0.644447 2.149152 -0.013104 -0.035754 0.99798\n",
"2017-03-21 0.016426 0.660873 2.235613 -0.013104 -0.035754 1.00003\n",
"2017-04-06 -0.001144 0.659729 2.356093 -0.013104 -0.035754 1.00003\n",
"2017-04-20 0.007881 0.667610 2.448745 -0.013104 -0.035754 1.00004\n",
"2017-05-05 -0.008892 0.658717 2.227092 -0.013104 -0.035754 1.00004\n",
"2017-05-19 -0.002924 0.655793 2.487909 -0.012972 -0.035754 0.99990\n",
"2017-06-06 0.003434 0.659228 2.593745 -0.012802 -0.035754 0.99990\n",
"2017-06-20 0.011297 0.670525 2.860042 -0.011817 -0.035754 1.00004\n",
"2017-07-04 0.009526 0.680050 3.041796 -0.011817 -0.035754 1.00004\n",
"2017-07-18 0.016175 0.696225 3.055025 -0.011817 -0.035754 0.99999\n",
"2017-08-01 0.002968 0.699193 2.857844 -0.011817 -0.035754 0.99999\n",
"2017-08-15 -0.007531 0.691662 2.289452 -0.011817 -0.035754 1.00004\n",
"2017-08-29 0.001026 0.692688 2.742168 -0.011817 -0.035754 1.00004\n",
"2017-09-12 0.000855 0.693543 2.830931 -0.011817 -0.035754 1.00004\n",
"2017-09-26 -0.000392 0.693151 2.633798 -0.011817 -0.035754 0.99997\n",
"2017-10-17 -0.006175 0.686976 2.390601 -0.012217 -0.035754 0.99997\n",
"2017-10-31 -0.004647 0.682329 2.037490 -0.016864 -0.035754 1.00002\n",
"2017-11-14 0.005732 0.688061 2.259706 -0.016864 -0.035754 1.00011\n",
"2017-11-28 0.014009 0.702070 2.700705 -0.016864 -0.035754 1.00011\n",
"2017-12-12 0.000715 0.702786 2.437891 -0.016864 -0.035754 0.99994\n",
"2017-12-26 0.003241 0.706027 2.481936 -0.016864 -0.035754 0.99996\n",
"2018-01-10 0.009375 0.715401 2.536598 -0.016864 -0.035754 1.00008\n",
"2018-01-24 0.001758 0.717159 2.417740 -0.016864 -0.035754 0.99998\n",
"2018-02-07 0.003852 0.721011 2.429653 -0.016864 -0.035754 0.99993\n",
"2018-02-28 0.000391 0.721402 2.185579 -0.016864 -0.035754 0.99994\n",
"\n",
"[199 rows x 6 columns]"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res_df"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>leverage</th>\n",
" <th>returns</th>\n",
" <th>turn_over</th>\n",
" <th>index</th>\n",
" <th>tc_cost</th>\n",
" <th>ret_after_tc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2010-01-04</th>\n",
" <td>0.00000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-01-18</th>\n",
" <td>1.00000</td>\n",
" <td>0.053401</td>\n",
" <td>1.824820</td>\n",
" <td>0.058077</td>\n",
" <td>0.003650</td>\n",
" <td>-0.008325</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-02-01</th>\n",
" <td>1.00000</td>\n",
" <td>-0.119192</td>\n",
" <td>0.294016</td>\n",
" <td>-0.115825</td>\n",
" <td>0.000588</td>\n",
" <td>-0.003955</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-02-22</th>\n",
" <td>0.99839</td>\n",
" <td>0.030674</td>\n",
" <td>0.416928</td>\n",
" <td>0.035925</td>\n",
" <td>0.000834</td>\n",
" <td>-0.006026</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-03-08</th>\n",
" <td>0.99537</td>\n",
" <td>0.055301</td>\n",
" <td>0.400000</td>\n",
" <td>0.044084</td>\n",
" <td>0.000800</td>\n",
" <td>0.010621</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-03-22</th>\n",
" <td>0.99846</td>\n",
" <td>-0.005239</td>\n",
" <td>0.400000</td>\n",
" <td>-0.000303</td>\n",
" <td>0.000800</td>\n",
" <td>-0.005736</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-04-06</th>\n",
" <td>0.99846</td>\n",
" <td>0.041815</td>\n",
" <td>0.400000</td>\n",
" <td>0.043072</td>\n",
" <td>0.000800</td>\n",
" <td>-0.001990</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-04-20</th>\n",
" <td>0.99837</td>\n",
" <td>0.007571</td>\n",
" <td>0.400000</td>\n",
" <td>0.006209</td>\n",
" <td>0.000800</td>\n",
" <td>0.000573</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-05-05</th>\n",
" <td>0.99837</td>\n",
" <td>-0.086619</td>\n",
" <td>0.400000</td>\n",
" <td>-0.101913</td>\n",
" <td>0.000800</td>\n",
" <td>0.014328</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-05-19</th>\n",
" <td>0.99857</td>\n",
" <td>-0.120487</td>\n",
" <td>0.400000</td>\n",
" <td>-0.124804</td>\n",
" <td>0.000800</td>\n",
" <td>0.003338</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-06-02</th>\n",
" <td>0.99857</td>\n",
" <td>0.038966</td>\n",
" <td>0.400000</td>\n",
" <td>0.038406</td>\n",
" <td>0.000800</td>\n",
" <td>-0.000185</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-06-21</th>\n",
" <td>0.99856</td>\n",
" <td>0.027008</td>\n",
" <td>0.400000</td>\n",
" <td>0.016080</td>\n",
" <td>0.000800</td>\n",
" <td>0.010152</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-07-05</th>\n",
" <td>0.99856</td>\n",
" <td>-0.101685</td>\n",
" <td>0.400000</td>\n",
" <td>-0.116871</td>\n",
" <td>0.000800</td>\n",
" <td>0.014218</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-07-19</th>\n",
" <td>0.99864</td>\n",
" <td>0.090080</td>\n",
" <td>0.357899</td>\n",
" <td>0.075146</td>\n",
" <td>0.000716</td>\n",
" <td>0.014320</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-08-02</th>\n",
" <td>0.99864</td>\n",
" <td>0.065057</td>\n",
" <td>0.400000</td>\n",
" <td>0.059507</td>\n",
" <td>0.000800</td>\n",
" <td>0.004831</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-08-16</th>\n",
" <td>0.99857</td>\n",
" <td>0.060243</td>\n",
" <td>0.442552</td>\n",
" <td>0.061077</td>\n",
" <td>0.000885</td>\n",
" <td>-0.001633</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-08-30</th>\n",
" <td>0.99857</td>\n",
" <td>0.020421</td>\n",
" <td>0.400000</td>\n",
" <td>0.029092</td>\n",
" <td>0.000800</td>\n",
" <td>-0.009430</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-09-13</th>\n",
" <td>0.99857</td>\n",
" <td>0.038996</td>\n",
" <td>0.400000</td>\n",
" <td>0.046005</td>\n",
" <td>0.000800</td>\n",
" <td>-0.007743</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-09-30</th>\n",
" <td>0.99870</td>\n",
" <td>0.017004</td>\n",
" <td>0.400000</td>\n",
" <td>-0.007814</td>\n",
" <td>0.000800</td>\n",
" <td>0.024007</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-10-21</th>\n",
" <td>0.99882</td>\n",
" <td>0.060105</td>\n",
" <td>0.400000</td>\n",
" <td>0.022792</td>\n",
" <td>0.000800</td>\n",
" <td>0.036541</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-11-04</th>\n",
" <td>0.99882</td>\n",
" <td>0.091060</td>\n",
" <td>0.400000</td>\n",
" <td>0.085199</td>\n",
" <td>0.000800</td>\n",
" <td>0.005161</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-11-18</th>\n",
" <td>0.99871</td>\n",
" <td>-0.033025</td>\n",
" <td>0.400000</td>\n",
" <td>-0.044425</td>\n",
" <td>0.000800</td>\n",
" <td>0.010543</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-02</th>\n",
" <td>0.99871</td>\n",
" <td>0.011059</td>\n",
" <td>0.400000</td>\n",
" <td>0.003812</td>\n",
" <td>0.000800</td>\n",
" <td>0.006452</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-16</th>\n",
" <td>0.99889</td>\n",
" <td>0.037539</td>\n",
" <td>0.342705</td>\n",
" <td>0.024784</td>\n",
" <td>0.000685</td>\n",
" <td>0.012097</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-30</th>\n",
" <td>0.99889</td>\n",
" <td>-0.051308</td>\n",
" <td>0.400000</td>\n",
" <td>-0.057394</td>\n",
" <td>0.000800</td>\n",
" <td>0.005223</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-01-14</th>\n",
" <td>0.99889</td>\n",
" <td>-0.067475</td>\n",
" <td>0.320836</td>\n",
" <td>-0.088210</td>\n",
" <td>0.000642</td>\n",
" <td>0.019996</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-01-28</th>\n",
" <td>0.99886</td>\n",
" <td>0.032970</td>\n",
" <td>0.400000</td>\n",
" <td>0.019919</td>\n",
" <td>0.000800</td>\n",
" <td>0.012274</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-02-18</th>\n",
" <td>0.99886</td>\n",
" <td>0.096319</td>\n",
" <td>0.400000</td>\n",
" <td>0.089584</td>\n",
" <td>0.000800</td>\n",
" <td>0.006037</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-04</th>\n",
" <td>0.99669</td>\n",
" <td>0.027365</td>\n",
" <td>0.445334</td>\n",
" <td>0.018727</td>\n",
" <td>0.000891</td>\n",
" <td>0.007809</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-18</th>\n",
" <td>0.99883</td>\n",
" <td>-0.007476</td>\n",
" <td>0.400000</td>\n",
" <td>-0.010187</td>\n",
" <td>0.000800</td>\n",
" <td>0.001899</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2016-12-19</th>\n",
" <td>0.99999</td>\n",
" <td>-0.033943</td>\n",
" <td>0.400000</td>\n",
" <td>-0.029751</td>\n",
" <td>0.000800</td>\n",
" <td>-0.004993</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-03</th>\n",
" <td>0.99999</td>\n",
" <td>0.017296</td>\n",
" <td>0.400000</td>\n",
" <td>0.014796</td>\n",
" <td>0.000800</td>\n",
" <td>0.001700</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-17</th>\n",
" <td>1.00015</td>\n",
" <td>-0.052533</td>\n",
" <td>0.495767</td>\n",
" <td>-0.052350</td>\n",
" <td>0.000992</td>\n",
" <td>-0.001166</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-02-07</th>\n",
" <td>1.00015</td>\n",
" <td>0.043140</td>\n",
" <td>0.400000</td>\n",
" <td>0.036071</td>\n",
" <td>0.000800</td>\n",
" <td>0.006263</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-02-21</th>\n",
" <td>0.99995</td>\n",
" <td>0.037631</td>\n",
" <td>0.298597</td>\n",
" <td>0.028620</td>\n",
" <td>0.000597</td>\n",
" <td>0.008415</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-03-07</th>\n",
" <td>0.99995</td>\n",
" <td>0.008797</td>\n",
" <td>0.392917</td>\n",
" <td>0.003521</td>\n",
" <td>0.000786</td>\n",
" <td>0.004491</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-03-21</th>\n",
" <td>0.99992</td>\n",
" <td>0.013840</td>\n",
" <td>0.400000</td>\n",
" <td>0.000433</td>\n",
" <td>0.000800</td>\n",
" <td>0.012607</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-04-06</th>\n",
" <td>0.99992</td>\n",
" <td>0.018937</td>\n",
" <td>0.400000</td>\n",
" <td>0.012087</td>\n",
" <td>0.000800</td>\n",
" <td>0.006052</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-04-20</th>\n",
" <td>1.00001</td>\n",
" <td>-0.025861</td>\n",
" <td>0.400000</td>\n",
" <td>-0.043176</td>\n",
" <td>0.000800</td>\n",
" <td>0.016516</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-05-05</th>\n",
" <td>1.00001</td>\n",
" <td>-0.064204</td>\n",
" <td>0.400000</td>\n",
" <td>-0.052973</td>\n",
" <td>0.000800</td>\n",
" <td>-0.012030</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-05-19</th>\n",
" <td>1.00002</td>\n",
" <td>-0.017313</td>\n",
" <td>0.400000</td>\n",
" <td>-0.014611</td>\n",
" <td>0.000800</td>\n",
" <td>-0.003502</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-06</th>\n",
" <td>1.00002</td>\n",
" <td>0.021499</td>\n",
" <td>0.400000</td>\n",
" <td>0.011175</td>\n",
" <td>0.000800</td>\n",
" <td>0.009524</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-20</th>\n",
" <td>1.00001</td>\n",
" <td>0.026088</td>\n",
" <td>0.400000</td>\n",
" <td>0.020476</td>\n",
" <td>0.000800</td>\n",
" <td>0.004812</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-07-04</th>\n",
" <td>1.00001</td>\n",
" <td>0.036755</td>\n",
" <td>0.400000</td>\n",
" <td>0.018864</td>\n",
" <td>0.000800</td>\n",
" <td>0.017091</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-07-18</th>\n",
" <td>1.00009</td>\n",
" <td>-0.002142</td>\n",
" <td>0.497130</td>\n",
" <td>-0.021973</td>\n",
" <td>0.000994</td>\n",
" <td>0.018838</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-08-01</th>\n",
" <td>1.00009</td>\n",
" <td>0.044924</td>\n",
" <td>0.400000</td>\n",
" <td>0.031278</td>\n",
" <td>0.000800</td>\n",
" <td>0.012844</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-08-15</th>\n",
" <td>1.00001</td>\n",
" <td>0.015946</td>\n",
" <td>0.400000</td>\n",
" <td>0.010663</td>\n",
" <td>0.000800</td>\n",
" <td>0.004483</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-08-29</th>\n",
" <td>1.00001</td>\n",
" <td>0.023096</td>\n",
" <td>0.400000</td>\n",
" <td>0.021099</td>\n",
" <td>0.000800</td>\n",
" <td>0.001197</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-09-12</th>\n",
" <td>1.00001</td>\n",
" <td>0.042608</td>\n",
" <td>0.400000</td>\n",
" <td>0.035183</td>\n",
" <td>0.000800</td>\n",
" <td>0.006625</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-09-26</th>\n",
" <td>1.00006</td>\n",
" <td>-0.014834</td>\n",
" <td>0.400000</td>\n",
" <td>-0.015251</td>\n",
" <td>0.000800</td>\n",
" <td>-0.000382</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-10-17</th>\n",
" <td>1.00006</td>\n",
" <td>-0.002885</td>\n",
" <td>0.400000</td>\n",
" <td>-0.002997</td>\n",
" <td>0.000800</td>\n",
" <td>-0.000688</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-10-31</th>\n",
" <td>1.00001</td>\n",
" <td>0.003111</td>\n",
" <td>0.372023</td>\n",
" <td>-0.001593</td>\n",
" <td>0.000744</td>\n",
" <td>0.003961</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-11-14</th>\n",
" <td>1.00002</td>\n",
" <td>-0.002265</td>\n",
" <td>0.400000</td>\n",
" <td>-0.002333</td>\n",
" <td>0.000800</td>\n",
" <td>-0.000731</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-11-28</th>\n",
" <td>1.00002</td>\n",
" <td>-0.026042</td>\n",
" <td>0.400000</td>\n",
" <td>-0.034113</td>\n",
" <td>0.000800</td>\n",
" <td>0.007272</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-12</th>\n",
" <td>0.99995</td>\n",
" <td>-0.004642</td>\n",
" <td>0.400000</td>\n",
" <td>-0.006497</td>\n",
" <td>0.000800</td>\n",
" <td>0.001054</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-26</th>\n",
" <td>0.99995</td>\n",
" <td>-0.014361</td>\n",
" <td>0.515549</td>\n",
" <td>-0.016749</td>\n",
" <td>0.001031</td>\n",
" <td>0.001356</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-01-10</th>\n",
" <td>0.99999</td>\n",
" <td>0.070323</td>\n",
" <td>0.400000</td>\n",
" <td>0.040133</td>\n",
" <td>0.000800</td>\n",
" <td>0.029391</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-01-24</th>\n",
" <td>1.00011</td>\n",
" <td>0.004529</td>\n",
" <td>0.400000</td>\n",
" <td>-0.006750</td>\n",
" <td>0.000800</td>\n",
" <td>0.010480</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-02-07</th>\n",
" <td>1.00004</td>\n",
" <td>-0.080637</td>\n",
" <td>0.400000</td>\n",
" <td>-0.101533</td>\n",
" <td>0.000800</td>\n",
" <td>0.020100</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018-02-28</th>\n",
" <td>0.99994</td>\n",
" <td>0.031790</td>\n",
" <td>0.400000</td>\n",
" <td>0.044632</td>\n",
" <td>0.000800</td>\n",
" <td>-0.013639</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>199 rows × 6 columns</p>\n",
"</div>"
],
"text/plain": [
" leverage returns turn_over index tc_cost ret_after_tc\n",
"2010-01-04 0.00000 0.000000 0.000000 0.000000 0.000000 0.000000\n",
"2010-01-18 1.00000 0.053401 1.824820 0.058077 0.003650 -0.008325\n",
"2010-02-01 1.00000 -0.119192 0.294016 -0.115825 0.000588 -0.003955\n",
"2010-02-22 0.99839 0.030674 0.416928 0.035925 0.000834 -0.006026\n",
"2010-03-08 0.99537 0.055301 0.400000 0.044084 0.000800 0.010621\n",
"2010-03-22 0.99846 -0.005239 0.400000 -0.000303 0.000800 -0.005736\n",
"2010-04-06 0.99846 0.041815 0.400000 0.043072 0.000800 -0.001990\n",
"2010-04-20 0.99837 0.007571 0.400000 0.006209 0.000800 0.000573\n",
"2010-05-05 0.99837 -0.086619 0.400000 -0.101913 0.000800 0.014328\n",
"2010-05-19 0.99857 -0.120487 0.400000 -0.124804 0.000800 0.003338\n",
"2010-06-02 0.99857 0.038966 0.400000 0.038406 0.000800 -0.000185\n",
"2010-06-21 0.99856 0.027008 0.400000 0.016080 0.000800 0.010152\n",
"2010-07-05 0.99856 -0.101685 0.400000 -0.116871 0.000800 0.014218\n",
"2010-07-19 0.99864 0.090080 0.357899 0.075146 0.000716 0.014320\n",
"2010-08-02 0.99864 0.065057 0.400000 0.059507 0.000800 0.004831\n",
"2010-08-16 0.99857 0.060243 0.442552 0.061077 0.000885 -0.001633\n",
"2010-08-30 0.99857 0.020421 0.400000 0.029092 0.000800 -0.009430\n",
"2010-09-13 0.99857 0.038996 0.400000 0.046005 0.000800 -0.007743\n",
"2010-09-30 0.99870 0.017004 0.400000 -0.007814 0.000800 0.024007\n",
"2010-10-21 0.99882 0.060105 0.400000 0.022792 0.000800 0.036541\n",
"2010-11-04 0.99882 0.091060 0.400000 0.085199 0.000800 0.005161\n",
"2010-11-18 0.99871 -0.033025 0.400000 -0.044425 0.000800 0.010543\n",
"2010-12-02 0.99871 0.011059 0.400000 0.003812 0.000800 0.006452\n",
"2010-12-16 0.99889 0.037539 0.342705 0.024784 0.000685 0.012097\n",
"2010-12-30 0.99889 -0.051308 0.400000 -0.057394 0.000800 0.005223\n",
"2011-01-14 0.99889 -0.067475 0.320836 -0.088210 0.000642 0.019996\n",
"2011-01-28 0.99886 0.032970 0.400000 0.019919 0.000800 0.012274\n",
"2011-02-18 0.99886 0.096319 0.400000 0.089584 0.000800 0.006037\n",
"2011-03-04 0.99669 0.027365 0.445334 0.018727 0.000891 0.007809\n",
"2011-03-18 0.99883 -0.007476 0.400000 -0.010187 0.000800 0.001899\n",
"... ... ... ... ... ... ...\n",
"2016-12-19 0.99999 -0.033943 0.400000 -0.029751 0.000800 -0.004993\n",
"2017-01-03 0.99999 0.017296 0.400000 0.014796 0.000800 0.001700\n",
"2017-01-17 1.00015 -0.052533 0.495767 -0.052350 0.000992 -0.001166\n",
"2017-02-07 1.00015 0.043140 0.400000 0.036071 0.000800 0.006263\n",
"2017-02-21 0.99995 0.037631 0.298597 0.028620 0.000597 0.008415\n",
"2017-03-07 0.99995 0.008797 0.392917 0.003521 0.000786 0.004491\n",
"2017-03-21 0.99992 0.013840 0.400000 0.000433 0.000800 0.012607\n",
"2017-04-06 0.99992 0.018937 0.400000 0.012087 0.000800 0.006052\n",
"2017-04-20 1.00001 -0.025861 0.400000 -0.043176 0.000800 0.016516\n",
"2017-05-05 1.00001 -0.064204 0.400000 -0.052973 0.000800 -0.012030\n",
"2017-05-19 1.00002 -0.017313 0.400000 -0.014611 0.000800 -0.003502\n",
"2017-06-06 1.00002 0.021499 0.400000 0.011175 0.000800 0.009524\n",
"2017-06-20 1.00001 0.026088 0.400000 0.020476 0.000800 0.004812\n",
"2017-07-04 1.00001 0.036755 0.400000 0.018864 0.000800 0.017091\n",
"2017-07-18 1.00009 -0.002142 0.497130 -0.021973 0.000994 0.018838\n",
"2017-08-01 1.00009 0.044924 0.400000 0.031278 0.000800 0.012844\n",
"2017-08-15 1.00001 0.015946 0.400000 0.010663 0.000800 0.004483\n",
"2017-08-29 1.00001 0.023096 0.400000 0.021099 0.000800 0.001197\n",
"2017-09-12 1.00001 0.042608 0.400000 0.035183 0.000800 0.006625\n",
"2017-09-26 1.00006 -0.014834 0.400000 -0.015251 0.000800 -0.000382\n",
"2017-10-17 1.00006 -0.002885 0.400000 -0.002997 0.000800 -0.000688\n",
"2017-10-31 1.00001 0.003111 0.372023 -0.001593 0.000744 0.003961\n",
"2017-11-14 1.00002 -0.002265 0.400000 -0.002333 0.000800 -0.000731\n",
"2017-11-28 1.00002 -0.026042 0.400000 -0.034113 0.000800 0.007272\n",
"2017-12-12 0.99995 -0.004642 0.400000 -0.006497 0.000800 0.001054\n",
"2017-12-26 0.99995 -0.014361 0.515549 -0.016749 0.001031 0.001356\n",
"2018-01-10 0.99999 0.070323 0.400000 0.040133 0.000800 0.029391\n",
"2018-01-24 1.00011 0.004529 0.400000 -0.006750 0.000800 0.010480\n",
"2018-02-07 1.00004 -0.080637 0.400000 -0.101533 0.000800 0.020100\n",
"2018-02-28 0.99994 0.031790 0.400000 0.044632 0.000800 -0.013639\n",
"\n",
"[199 rows x 6 columns]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ret_df"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'zz800'"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"universe.base_universe[0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
This source diff could not be displayed because it is too large. You can view the blob instead.
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