{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Case2-3: CustomBusinessDayで満期日を列挙し、満期日までの日数を営業日で計算してみる \n", "Compute the last trading day by CustomBusinessDay class" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:04.873267", "start_time": "2016-09-17T13:52:03.864196" }, "collapsed": false }, "outputs": [], "source": [ "from itertools import chain\n", "from datetime import datetime\n", "from datetime import date\n", "from pandas.tseries.offsets import CustomBusinessDay\n", "import pandas as pd\n", "import yaml\n", "import requests" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 番外編(Appendix)\n", "QuantLibに日本の祝日があるが、情報が古い \n", "Japanese holiday in QuantLib is too old" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:05.073197", "start_time": "2016-09-17T13:52:04.876192" }, "collapsed": false }, "source": [ "```\n", "import QuantLib as ql\n", "calender = ql.Japan()\n", "calender.isHoliday(ql.Date(11, 8, 2016))\n", "```\n", "```\n", "False\n", "# No \"Mountain day\"\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Windowsの場合はビルド済のwheelからインストールするのが簡単 \n", "* For windows, Easy to install QuantLib from pre-built wheel \n", "http://www.lfd.uci.edu/~gohlke/pythonlibs/#quantlib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## holiday_jpから祝日のyamlファイルを取得 \n", "Get hoilday yaml file from hoilday_jp\n", "> * Initial datasets\n", "> \n", "> [komagata/holiday_jp](https://github.com/komagata/holiday_jp)\n", "> \n", "> * komagata/holiday_jp Copyright\n", "> \n", "> Copyright (c) 2009 Masaki Komagata. See [LICENSE](https://github.com/komagata/holiday_jp/blob/master/LICENSE) for details.\n", "> \n", "> * \"Datasets\" idea\n", "> \n", "> [Project Woothee](https://woothee.github.io/)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.183219", "start_time": "2016-09-17T13:52:05.076195" }, "collapsed": false }, "outputs": [], "source": [ "# https://github.com/k1LoW/holiday_jp\n", "try:\n", " holiday_jp_yaml = yaml.load(requests.get('https://raw.githubusercontent.com/k1LoW/holiday_jp/master/holidays.yml').text)\n", "except Exception:\n", " with open('data/holidays.yml', 'rb') as f:\n", " holiday_jp_yaml = yaml.load(f)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.194193", "start_time": "2016-09-17T13:52:07.186192" }, "collapsed": false }, "outputs": [], "source": [ "holiday_jp = list(holiday_jp_yaml.keys())" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.222196", "start_time": "2016-09-17T13:52:07.199196" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[datetime.date(1970, 1, 1),\n", " datetime.date(1970, 1, 15),\n", " datetime.date(1970, 2, 11),\n", " datetime.date(1970, 3, 21),\n", " datetime.date(1970, 4, 29)]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sorted(holiday_jp)[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 取引所は三が日と大晦日が休場のため休みを追加する \n", "Add \"The First Three Days of the New Year\" and \"new years eve\" as holidays" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.247196", "start_time": "2016-09-17T13:52:07.227196" }, "collapsed": false }, "outputs": [], "source": [ "holiday_newyear = chain.from_iterable(\n", " [[date(y, 1, 2), date(y, 1, 3), date(y, 12, 31)]\n", " for y in range(sorted(holiday_jp)[0].year, sorted(holiday_jp)[-1].year + 1)])" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.265214", "start_time": "2016-09-17T13:52:07.251196" }, "collapsed": true }, "outputs": [], "source": [ "holiday_jpx = chain(holiday_jp, holiday_newyear)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CustomBusinessDayのインスタンスを作成 \n", "create CustomBusinessDay instance" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.354194", "start_time": "2016-09-17T13:52:07.268196" }, "collapsed": false }, "outputs": [], "source": [ "bday_jpx = CustomBusinessDay(holidays=holiday_jpx)" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2016-09-02T11:09:46.572072", "start_time": "2016-09-02T11:09:46.568069" } }, "source": [ "## Case2-1と同様にdate_rangeを作成\n", "Create \"date_range\" same as case2-1 \n", "\n", "\n", "freq='WOM-2FRI'を指定することで毎月の第二金曜日を指定できる \n", "to specify \"The 2nd Friday of every month\" by freq='WOM-2FRI'" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.391196", "start_time": "2016-09-17T13:52:07.357198" }, "collapsed": true }, "outputs": [], "source": [ "sq_date = pd.date_range(datetime(2017, 1, 1), datetime(2017, 12, 31), freq='WOM-2FRI')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.414195", "start_time": "2016-09-17T13:52:07.396195" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2017-01-13', '2017-02-10', '2017-03-10', '2017-04-14',\n", " '2017-05-12', '2017-06-09', '2017-07-14', '2017-08-11',\n", " '2017-09-08', '2017-10-13', '2017-11-10', '2017-12-08'],\n", " dtype='datetime64[ns]', freq='WOM-2FRI')" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_date" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CustomBusinessDayで作成したインスタンスを利用して第二金曜日が祝日だった場合は一営業日前倒しする \n", "If the 2nd Friday is holiday, Set the day before as the last trading day" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.432195", "start_time": "2016-09-17T13:52:07.418196" }, "collapsed": true }, "outputs": [], "source": [ "def shift_bday(dt):\n", " if dt.date() in bday_jpx.holidays:\n", " return (dt - bday_jpx)\n", " else:\n", " return dt" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.782209", "start_time": "2016-09-17T13:52:07.436193" }, "collapsed": false }, "outputs": [], "source": [ "sq_date = sq_date.map(shift_bday)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.798193", "start_time": "2016-09-17T13:52:07.784196" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([Timestamp('2017-01-13 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-02-10 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-03-10 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-04-14 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-05-12 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-06-09 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-07-14 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-08-10 00:00:00'),\n", " Timestamp('2017-09-08 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-10-13 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-11-10 00:00:00', offset='WOM-2FRI'),\n", " Timestamp('2017-12-08 00:00:00', offset='WOM-2FRI')], dtype=object)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq_date" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "8月11日が祝日なので、一日前倒しされる \n", "11th of Aug is holiday, so Set the day before as the last trading day" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2017年5月1日から5月満期日までの営業日\n", "Business day from 1 May ,2017 to contract expires" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.823194", "start_time": "2016-09-17T13:52:07.802197" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2017-05-01', '2017-05-02', '2017-05-08', '2017-05-09',\n", " '2017-05-10', '2017-05-11', '2017-05-12'],\n", " dtype='datetime64[ns]', freq='C')" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.date_range(datetime(2017, 5, 1), sq_date[4], freq=bday_jpx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 営業日をカウントすれば営業日数を得られる \n", "Count the number of business day" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.857196", "start_time": "2016-09-17T13:52:07.831195" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(pd.date_range(datetime(2017, 5, 1), sq_date[4], freq=bday_jpx))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 番外編(Appendix)\n", "pandas 0.18.1からCustomBusinessHourが使えるように \n", "Possible to use \"CustomBusinessHour\" from pandas 0.18.1 \n", "\n", "http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#custom-business-hour" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.873197", "start_time": "2016-09-17T13:52:07.861197" }, "collapsed": false }, "outputs": [], "source": [ "from pandas.tseries.offsets import CustomBusinessHour" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### JPX(東証)の取引時間を設定 \n", "Set JPX trading hours" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.912195", "start_time": "2016-09-17T13:52:07.876195" }, "collapsed": false }, "outputs": [], "source": [ "bhour_jpx = CustomBusinessHour(start='9:00', end='15:00', holidays=bday_jpx.holidays)" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2016-09-11T16:16:36.328481", "start_time": "2016-09-11T16:16:36.313477" }, "collapsed": true }, "source": [ "### 営業時間で計算ができる \n", "adding or subtracting business hours" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "ExecuteTime": { "end_time": "2016-09-17T13:52:07.937192", "start_time": "2016-09-17T13:52:07.921197" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Timestamp('2016-09-23 09:00:00')" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "datetime(2016, 9, 21, 13) + bhour_jpx * 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "hide_input": false, "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.5.1" }, "nav_menu": {}, "toc": { "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 6, "toc_cell": false, "toc_section_display": "block", "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 1 }