From 6068af240fbd421a3d85a61dd9b921515e26a2ae Mon Sep 17 00:00:00 2001 From: Juan Pablo Amoroso Date: Fri, 10 Jan 2020 13:54:35 -0300 Subject: [PATCH] Data cleanup v2. Removes ~%12 of the contracts --- backtester/demos/data_cleanup.ipynb | 553 ++++++++++++++++++++++++++-- 1 file changed, 524 insertions(+), 29 deletions(-) diff --git a/backtester/demos/data_cleanup.ipynb b/backtester/demos/data_cleanup.ipynb index a11f7c5..8bba1eb 100644 --- a/backtester/demos/data_cleanup.ipynb +++ b/backtester/demos/data_cleanup.ipynb @@ -6,9 +6,530 @@ "metadata": {}, "outputs": [], "source": [ - "import pandas as pd\n", "import os\n", - "from backtester.datahandler import HistoricalOptionsData" + "import sys\n", + "\n", + "import pandas as pd\n", + "\n", + "backtester_dir = os.path.realpath(os.path.join(os.getcwd(), '..', '..'))\n", + "sys.path.append(backtester_dir) # Add backtester base dir to $PYTHONPATH" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "data_dir = os.path.join(backtester_dir, 'data')\n", + "store_path = os.path.join(data_dir, 'options_data_full_v2.h5')\n", + "store = pd.HDFStore(store_path, complevel=9, complib='blosc', fletcher32=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we move the data from a h5 store with multiple keys (one per year) to another with a single key." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "old_data = os.path.join(data_dir, 'options_data_compressed_v2.h5')\n", + "sizes = {'optionroot': 20, 'optionalias': 20}\n", + "underlying_categories = pd.CategoricalDtype(categories=['SPX', 'SPXW', 'SPXPM'], ordered=False)\n", + "\n", + "keys = ('spx_{}'.format(year) for year in range(1990, 2019))\n", + "offset = 0\n", + "\n", + "for k in keys:\n", + " df = pd.read_hdf(old_data, key=k)\n", + " df['underlying'] = df['underlying'].astype(underlying_categories)\n", + " df.drop(columns='exchange', inplace=True)\n", + " \n", + " df.index += offset\n", + " offset += len(df)\n", + " store.append('/SPX', df, index=False, data_columns=['quotedate', 'expiration'], min_itemsize=sizes)\n", + " \n", + "os.path.getsize(store_path) / 1024**2" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "store.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data cleaning" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will remove contracts where `bid` _and_ `ask` columns go to 0 unexpectedly, that is, where the bid/ask price of the contract is greater than 0 for the previous and following days. \n", + "We will also remove contracts that have a missing `quotedate` before expiration." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
underlyingunderlying_lastoptionroottypeexpirationquotedatestrikelastbidaskvolumeopeninterestimpliedvoldeltagammathetavegaoptionalias
0SPX359.69SPX900120C00225000call1990-01-201990-01-02225.00.0135.5135.508200.00.00.00.00.0SPX900120C00225000
1SPX359.69SPX900120C00320000call1990-01-201990-01-02320.00.040.940.9010880.00.00.00.00.0SPX900120C00320000
2SPX359.69SPX900120C00325000call1990-01-201990-01-02325.00.035.935.9012520.00.00.00.00.0SPX900120C00325000
3SPX359.69SPX900120C00330000call1990-01-201990-01-02330.030.530.930.92587380.00.00.00.00.0SPX900120C00330000
4SPX359.69SPX900120C00335000call1990-01-201990-01-02335.00.026.026.005800.00.00.00.00.0SPX900120C00335000
\n", + "
" + ], + "text/plain": [ + " underlying underlying_last optionroot type expiration quotedate \\\n", + "0 SPX 359.69 SPX900120C00225000 call 1990-01-20 1990-01-02 \n", + "1 SPX 359.69 SPX900120C00320000 call 1990-01-20 1990-01-02 \n", + "2 SPX 359.69 SPX900120C00325000 call 1990-01-20 1990-01-02 \n", + "3 SPX 359.69 SPX900120C00330000 call 1990-01-20 1990-01-02 \n", + "4 SPX 359.69 SPX900120C00335000 call 1990-01-20 1990-01-02 \n", + "\n", + " strike last bid ask volume openinterest impliedvol delta gamma \\\n", + "0 225.0 0.0 135.5 135.5 0 820 0.0 0.0 0.0 \n", + "1 320.0 0.0 40.9 40.9 0 1088 0.0 0.0 0.0 \n", + "2 325.0 0.0 35.9 35.9 0 1252 0.0 0.0 0.0 \n", + "3 330.0 30.5 30.9 30.9 25 8738 0.0 0.0 0.0 \n", + "4 335.0 0.0 26.0 26.0 0 580 0.0 0.0 0.0 \n", + "\n", + " theta vega optionalias \n", + "0 0.0 0.0 SPX900120C00225000 \n", + "1 0.0 0.0 SPX900120C00320000 \n", + "2 0.0 0.0 SPX900120C00325000 \n", + "3 0.0 0.0 SPX900120C00330000 \n", + "4 0.0 0.0 SPX900120C00335000 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "full_data = os.path.join(data_dir, 'options_data_full_v2.h5')\n", + "df = pd.read_hdf(full_data, key='/SPX')\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "240554" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['optionroot'].nunique()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "16756680" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(df)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "to_clean = set()\n", + "threshold = 0.5\n", + "\n", + "dates = pd.Series(index=df['quotedate'].unique())\n", + "\n", + "for contract, group in df.groupby('optionroot'):\n", + " both_zero = group.eval('bid == ask == 0.0')\n", + " if both_zero.any():\n", + " ask_diff_previous = group['ask'].diff().abs()\n", + " ask_diff_next = group['ask'].diff(-1).abs()\n", + " \n", + " if ((ask_diff_previous > threshold) & (ask_diff_next > threshold) & both_zero).any():\n", + " to_clean.add(contract)\n", + " else:\n", + " start_date, end_date = group['quotedate'].min(), group['quotedate'].max()\n", + " if len(dates.loc[start_date:end_date]) != len(group):\n", + " to_clean.add(contract)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "29394" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(to_clean)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1221929379681901" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(to_clean) / df['optionroot'].nunique()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "to_clean_mask = df[df['optionroot'].isin(to_clean)]\n", + "clean_df = df.drop(to_clean_mask.index)\n", + "clean_df.reset_index(drop=True, inplace=True)\n", + "\n", + "min_sizes = {'optionroot': 20, 'optionalias': 20}\n", + "clean_file = os.path.join(data_dir, 'options_data_clean_v2.h5')\n", + "clean_df.to_hdf(clean_file,\n", + " mode='w',\n", + " key='/SPX',\n", + " format='table',\n", + " data_columns=['quotedate', 'expiration'],\n", + " complevel=9,\n", + " complib='blosc:lz4',\n", + " fletcher32=True,\n", + " min_itemsize=min_sizes)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 13909922 entries, 0 to 13909921\n", + "Data columns (total 18 columns):\n", + "underlying category\n", + "underlying_last float64\n", + "optionroot object\n", + "type category\n", + "expiration datetime64[ns]\n", + "quotedate datetime64[ns]\n", + "strike float64\n", + "last float64\n", + "bid float64\n", + "ask float64\n", + "volume int64\n", + "openinterest int64\n", + "impliedvol float64\n", + "delta float64\n", + "gamma float64\n", + "theta float64\n", + "vega float64\n", + "optionalias object\n", + "dtypes: category(2), datetime64[ns](2), float64(10), int64(2), object(2)\n", + "memory usage: 3.4 GB\n" + ] + } + ], + "source": [ + "clean_df.info(memory_usage='deep')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "568.1449775695801" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "os.path.getsize(clean_file) / 1024**2" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "unique_contracts_per_day = df.groupby('quotedate').apply(lambda x: x['optionroot'].nunique())\n", + "unique_contracts_per_day.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "unique_contracts_per_day_clean = clean_df.groupby('quotedate').apply(lambda x: x['optionroot'].nunique())\n", + "unique_contracts_per_day_clean.plot()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Previous data cleaning attempt" ] }, { @@ -47,15 +568,6 @@ " print(year)" ] }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": {}, - "outputs": [], - "source": [ - "store.close()" - ] - }, { "cell_type": "code", "execution_count": null, @@ -2595,23 +3107,6 @@ "source": [ "store.close()" ] - }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": {}, - "outputs": [], - "source": [ - "%cd -q /Users/jrchatruc/Documents/backtester_options/allspx\n", - "!ptrepack --complevel=9 --complib=blosc options_data_v2_pruned.h5 options_data_v2_pruned_compressed.h5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -2630,7 +3125,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.7.4" } }, "nbformat": 4,