├── .gitignore ├── Case1-1_2.xlsm ├── Case1-3.ipynb ├── Case1-4.ipynb ├── Case1-5.ipynb ├── Case1-6_7 ├── Case1_6.py ├── Case1_6.xlsm ├── Case1_7.py └── Case1_7.xlsm ├── Case2-1_2.ipynb ├── Case2-3.ipynb ├── Case3-1.ipynb ├── Case3-2.ipynb ├── README.md └── data ├── 2016.xls ├── AAPL.mpack ├── FB.mpack ├── GOOG.mpack ├── MSFT.mpack ├── NA04Q.xls ├── NA21M.xls ├── NE11M.xls ├── NE51M.xls ├── NVDA.mpack ├── RatesXML.xml ├── ^DJI.mpack ├── ^GSPC.mpack ├── ^IXIC.mpack ├── etfreit.zip ├── holidays.yml ├── indices_I101_1d_2016.csv ├── indices_I102_1d_2016.csv ├── indices_I103_1d_2016.csv └── indices_I133_1d_2016.csv /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | QUBELEY.xlsm 3 | -------------------------------------------------------------------------------- /Case1-1_2.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/Case1-1_2.xlsm -------------------------------------------------------------------------------- /Case1-3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Case1-3: モンテカルロ・シミュレーションをPythonで実装\n", 8 | "Implement Monte-Carlo Simulation in Python" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "metadata": { 15 | "ExecuteTime": { 16 | "end_time": "2016-09-17T13:46:45.425234", 17 | "start_time": "2016-09-17T13:46:44.040168" 18 | }, 19 | "collapsed": false, 20 | "hide_input": false 21 | }, 22 | "outputs": [], 23 | "source": [ 24 | "%matplotlib inline\n", 25 | "import numpy as np\n", 26 | "import pandas as pd\n", 27 | "import seaborn" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": { 34 | "ExecuteTime": { 35 | "end_time": "2016-09-17T13:46:45.431169", 36 | "start_time": "2016-09-17T13:46:45.427205" 37 | }, 38 | "collapsed": true 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "s, t, r, sigma = 1000, 30 / 365.0, 0.001, 0.2\n", 43 | "path_of_monte_carlo = 50000" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "## 次の確率微分方程式にしたがう確率過程 Stを求める([幾何ブラウン運動](https://ja.wikipedia.org/wiki/幾何ブラウン運動 \"Wikipedia\")) \n", 51 | "it satisfies the following stochastic differential equation \n", 52 | "$$dS_t = \\mu S_t\\,dt + \\sigma S_t\\,dB_t$$" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": { 59 | "ExecuteTime": { 60 | "end_time": "2016-09-17T13:46:45.458169", 61 | "start_time": "2016-09-17T13:46:45.438170" 62 | }, 63 | "code_folding": [], 64 | "collapsed": true 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "def future_stock_price(s, r, sigma, t):\n", 69 | " return s*np.exp(np.random.normal((r - 0.5 * np.power(sigma, 2)) * t, sigma * np.sqrt(t)))" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "## 上記の関数を50000回実行\n", 77 | "run 50000 times" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": { 84 | "ExecuteTime": { 85 | "end_time": "2016-09-17T13:46:45.960171", 86 | "start_time": "2016-09-17T13:46:45.462169" 87 | }, 88 | "collapsed": false 89 | }, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | "CPU times: user 580 ms, sys: 0 ns, total: 580 ms\n", 96 | "Wall time: 578 ms\n" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "%time stock_price_results = [future_stock_price(s, r, sigma, t) for _ in range(path_of_monte_carlo)]" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "## ヒストグラムを表示\n", 109 | "plot histgram" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 5, 115 | "metadata": { 116 | "ExecuteTime": { 117 | "end_time": "2016-09-17T13:46:46.642172", 118 | "start_time": "2016-09-17T13:46:45.963174" 119 | }, 120 | "collapsed": false 121 | }, 122 | "outputs": [ 123 | { 124 | "name": "stdout", 125 | "output_type": "stream", 126 | "text": [ 127 | "CPU times: user 250 ms, sys: 0 ns, total: 250 ms\n", 128 | "Wall time: 260 ms\n" 129 | ] 130 | }, 131 | { 132 | "data": { 133 | "text/plain": [ 134 | "" 135 | ] 136 | }, 137 | "execution_count": 5, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | }, 141 | { 142 | "data": { 143 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAr4AAAHcCAYAAAAwU6m5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3X90VPWdx//XkDQkSKLJJPxwgQMaD0ODNJMY2kSFNFT4\nnnZ32aOn7ga1FU6J24q2hkqkIMVTmjjTyJfaBiyCB6s5i3WNWMue/Vpx0W6DFUna0tgZ3SJLStDC\nkGzCMGGamfv9g+Wuk4QfgZnMTe7zcY4H+dzPTN6T9yR55fK5n+swDMMQAAAAMMqNSXYBAAAAwHAg\n+AIAAMAWCL4AAACwBYIvAAAAbIHgCwAAAFsg+AIAAMAWCL4AAACwBYIvAAAAbIHgCwAAAFsg+AIA\nAMAWhhx89+3bp/vuu08333yzXC6X9uzZE3P8f/7nf7RmzRrdeuutKiws1N/93d/p5ZdfjpkTiUTk\n8XhUVlamwsJCVVVV6ejRozFzgsGgVq9erZKSEhUXF2vlypXq6uq6jJcIAAAAXEbwDYVCKigo0Jo1\na+RwOAYcX7dunQ4cOKCNGzfq5z//uf7+7/9eq1ev1m9+8xtzTn19vZqamlRbW6vGxkaFQiFVVVUp\nGo2ac1avXq133nlHmzdv1rZt2+T3+7Vy5crLfJkAAACwuyEH34qKCj344IMqLy+XYRgDjv/2t7/V\nHXfcoZKSEk2bNk3Lly/XhAkTdPDgQUlSOBzWzp07tWLFCpWXl6ugoEBer1eHDh3S3r17JUnHjh3T\na6+9pjVr1qikpERut1vr16/Xr3/9a/n9/it7xQAAALCluK/xLSoq0p49e3TixAlJ0uuvv67u7m7d\ncsstkiSfz6fe3l6Vlpaaj5k8ebKmT5+u1tZWSVJra6scDkfMnOLiYqWnp5tzAAAAgKFIjfcT1tbW\n6uGHH9Ytt9yi1NRUpaWlqb6+Xi6XS5LMQOx0OmMe53Q6zWOBQEDp6enKyMgwjzscDmVnZ5tzAAAA\ngKGIe/DdsmWLDh06pKeffloTJkzQm2++qVWrVmnHjh2aM2dOvD/cBRmGMeg6ZAAAANhPXIPvyZMn\n9fTTT2vr1q269dZbJUkzZ87U/v379eyzz+qJJ55Qbm6upLNndbOzs83HBgIBud1uSVJubq56e3sV\nCoXMs76GYaizs9N8/KVwOBzq7g4pEolefDKGVUrKGGVlZdAfC6I31kVvrI3+WBe9sa5zvRkucQ2+\n4XB40AvexowZY+7Y4HK5lJ6erubmZuXn50uSOjo6dPjwYRUVFUmSCgsLZRiGmpubtWDBAknSgQMH\ndObMGTMcX6pIJKq+Pt7kVkV/rIveWBe9sTb6Y130BkMOvsFgUO3t7QqFQpKk9vZ2+Xw+5eTkaNKk\nSXK5XPJ6vUpLS9PEiRO1d+9e/epXv1J9fb0kKS0tTZWVlWpoaNCUKVOUl5cnr9er/Px8zZs3T9LZ\ni90WLVqkuro6jR8/XqmpqVq/fr3Kyso0c+bMOL58AAAA2IXDGOwU7QX86le/0vLlywesnV26dKlW\nrVqljz76SPX19frNb36jU6dOacqUKbrnnnt05513mnP7+vr0xBNP6JVXXlEoFNLcuXP13e9+V9de\ne6055/Tp09qwYYN++ctfKhqNqry8XOvWrdPVV189pBfY2RnktzsLSk0do+zsq+iPBdEb66I31kZ/\nrIveWNe53gyXIQffkYY3uTXxTci66I110Rtroz/WRW+sa7iDb9z38QUAAACsiOALAAAAWyD4AgAA\nwBYIvgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYI\nvgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAA\nALAFgi8AAABsgeALAAAAWyD4AgAAwBZSk10AAGCgcDistraDMWMpKWN0662fS1JFADDyEXwBwILa\n2g5q1cYmZTqnmWM9gSN6OitD+fmfTmJlADByEXwBIEEGO2srSQUFNyotLe2ij890TtM1k25IRGkA\nYEsEXwBIkPOdtfVWS2538ZCfLxrp03vvvafu7pAikag5fqlBGgDsjuALAAkUz7O2wa5j+n//pUOZ\nzuPm2JUEaQCwG4IvACTZYEsi/H7foHNZ/gAAl4/gCwBJNtiSiI8P7dfE60qSWBUAjD4EXwCwgP5n\ncnsC7UmsBgBGJ4IvAAyjaKRvwDKG8y1rAADEF8EXAIZRsOuYtu/uUObbp8yxeC9ruNJt1ABgtCL4\nAsAwS/SyhnhvowYAowXBFwBGIXZ/AICBCL4AMIKxZhgALt2Qg+++ffu0Y8cO/eEPf1AgEFBDQ4MW\nLFgQM+eDDz7QE088of3798swDM2aNUubNm1SXl6eJCkSiai+vl6vvPKKTp8+rblz5+q73/2u/uZv\n/sZ8jmAwqA0bNuj1119XNBpVeXm5Hn30UV1zzTVX+JIBYPQYjjXDADBaDDn4hkIhFRQUaPHixVq5\ncuWA4x9++KGWLFmiBQsW6Mknn9RVV12lQ4cOKSUlxZxTX1+vpqYmeTwe5eXl6fHHH1dVVZVeffVV\njRkzRpK0evVqtbW1afPmzUpNTdWjjz6qlStXavv27VfwcgEgMYZyE4p4Yys0ALg0Qw6+FRUVqqio\n0OnTp2UYxoDjTzzxhG666SY9/vjj5lhhYaH5/+FwWDt37lR1dbXKy8slSV6vVxUVFdq7d68qKip0\n7Ngxvfbaa9q8ebNKSs6etVi/fr3uvvtu+f1+zZw5c6hlA0BCcRMKALC+MfF8sr/+9a966623VFBQ\noHvvvVdlZWX6x3/8R+3Zs8ec4/P51Nvbq9LSUnNs8uTJmj59ulpbWyVJra2tcjgcMXOKi4uVnp5u\nzgEAqzl35vXcf+OunpTskgAAnxDXi9v+8pe/KBwOa/v27Vq5cqUeeeQRvf7667r//vv13HPPqaSk\nRCdOnJAkOZ3OmMc6nU7zWCAQUHp6ujIyMszjDodD2dnZ5pxLlZIS12yPODnXF/pjPfTm8oyEz1dK\nyhilplq/zpGKrx3rojfWNdw9iWvwjUajkqSFCxfq7rvvliS5XC7t379fjY2N5rKF4ZSVlXHxSUga\n+mNd9GZoRsLnKysrQ9nZVyW7jFFvJLwX7IreIK7BNzc3Vw6HQzNmzIgZv/7669XW1mbOkc6e1c3O\nzjbnBAIBud1uc05vb69CoZB51tcwDHV2dpqPv1Td3SFFItHLfk1IjJSUMcrKyqA/FkRvLk93dyjZ\nJVxUd3dInZ3BZJcxavG1Y130xrrO9Wa4xDX4ZmRkaNasWTp8+HDM+Icffqhrr71W0tkzwOnp6Wpu\nblZ+fr4kqaOjQ4cPH1ZRUZGksxfDGYah5uZmc6u0AwcO6MyZM2Y4vlSRSFR9fbzJrYr+WBe9GZqR\n8MOUng4PPs/WRW8w5OAbDAbV3t6uUOjs2Y329nb5fD7l5ORowoQJ+trXvqaamhoVFRXppptu0uuv\nv67f/OY3+ulPfypJSktLU2VlpRoaGjRlyhTl5eXJ6/UqPz9f8+bNk3T2YrdFixaprq5O48ePV2pq\nqtavX6+ysjJ2dAAAAMBlGXLwbWlp0fLly+VwOORwOOTxeCRJS5cu1apVq/TFL35RwWBQTz/9tGpr\nazVjxgz96Ec/0k033WQ+R3V1tQzD0Nq1axUKhTR37lx5PJ6YvX7r6uq0YcMGrVixwryBxbp16+Lw\nkgEAAGBHQw6+t956q3y+C2/K/uUvf1lf/vKXz/9BU1NVU1Ojmpqa884ZN26camtrVVtbO9QSAQAA\ngAHY1wMAAAC2QPAFAACALRB8AQAAYAsEXwAAANgCwRcAAAC2QPAFAACALRB8AQAAYAsEXwAAANgC\nwRcAAAC2QPAFAACALRB8AQAAYAsEXwAAANhCarILAAAkXjTSJ7/fFzNWUHCj0tLSklQRAAw/gi8A\n2ECw65i27+5Q5tunJEk9gSPyVktud3GSKwOA4UPwBQCbyHRO0zWTbkh2GQCQNKzxBQAAgC0QfAEA\nAGALBF8AAADYAsEXAAAAtkDwBQAAgC2wqwMAXIZwOKy2toPm3/vvkQsAsB6CLwBchra2g1q1sUmZ\nzmmSpI8P7dfE60qSXBUA4EIIvgBwmT65L25PoD3J1QAALoY1vgAAALAFgi8AAABsgaUOAHAR/S9k\nk7iYDQBGIoIvAFxE/wvZJC5mA4CRiOALAJfgkxeySVzMBgAjEWt8AQAAYAsEXwAAANgCwRcAAAC2\nQPAFAACALXBxGwBA0uDbtklSQcGNSktLS0JFABBfBF8AgKTBt23rCRyRt1pyu4uTWBkAxAfBFwBs\nKBrpG3ATDr/fN2DbNgAYTQi+AGBDwa5j2r67Q5lvnzLHuCkHgNGO4AsANsVNOQDYzZB3ddi3b5/u\nu+8+3XzzzXK5XNqzZ895565bt04ul0tPPfVUzHgkEpHH41FZWZkKCwtVVVWlo0ePxswJBoNavXq1\nSkpKVFxcrJUrV6qrq2uo5QIAAACSLiP4hkIhFRQUaM2aNXI4HOed98tf/lK///3vNXHixAHH6uvr\n1dTUpNraWjU2NioUCqmqqkrRaNScs3r1ar3zzjvavHmztm3bJr/fr5UrVw61XAAAAEDSZQTfiooK\nPfjggyovL5dhGIPO+eijj7RhwwY98cQTSklJiTkWDoe1c+dOrVixQuXl5SooKJDX69WhQ4e0d+9e\nSdKxY8f02muvac2aNSopKZHb7db69ev161//Wn6/f+ivEgAAALYX9xtYGIahhx9+WMuXL9f1118/\n4LjP51Nvb69KS0vNscmTJ2v69OlqbW2VJLW2tsrhcMTMKS4uVnp6ujkHAAAAGIq4X9y2ZcsWjR07\nVnffffegx0+cOCFJcjqdMeNOp9M8FggElJ6eroyMDPO4w+FQdna2OedSpaRwczorOtcX+mM99GYg\nO38uopE+ffCBf8DnYPZsbmrRH1871kVvrGu4exLX4Pv73/9ejY2N2rVrVzyf9opkZWVcfBKShv5Y\nF735P3b+XAS7junpVzuU2dxjjvUEjujp72WopIStzwZj5/eL1dEbxDX4vvvuu+rs7FR5ebk5FolE\n9OSTT+r555/Xf/7nfyo3N1fS2bO62dnZ5rxAICC32y1Jys3NVW9vr0KhkHnW1zAMdXZ2mo+/VN3d\nIUUi0YtPxLBKSRmjrKwM+mNB9Gag7u5QsktIqsFuatHdHVJnZzBJFVkTXzvWRW+s61xvhktcg+8d\nd9yhefPmxYwtW7ZMixYt0pIlSyRJLpdL6enpam5uVn5+viSpo6NDhw8fVlFRkSSpsLBQhmGoublZ\nCxYskCQdOHBAZ86cMcPxpYpEourr401uVfTHuujN/+EH5UC8P86Pz4110RsMOfgGg0G1t7crFDp7\nBqS9vV0+n085OTmaMGGCrr766tgPkJoqp9OpGTNmSJLS0tJUWVmphoYGTZkyRXl5efJ6vcrPzzdD\n8+TJk7Vo0SLV1dVp/PjxSk1N1fr161VWVqaZM2de6WsGAACADQ05+La0tGj58uVyOBxyOBzyeDyS\npKVLl2rVqlUD5g+21291dbUMw9DatWsVCoU0d+5ceTyemK3P6urqtGHDBq1YsULRaFTl5eVat27d\nUMsFgCEJh8NqazsYM+b3+5JUDQAgnoYcfG+99Vb5fJf+Q2CwO7ulpqaqpqZGNTU1533cuHHjVFtb\nq9ra2qGWCACXra3toFZtbFKmc5o59vGh/Zp4HRdyAcBIF/ftzABgpOt/MVdPoD2J1QAA4oUN7QAA\nAGALBF8AAADYAsEXAAAAtkDwBQAAgC0QfAEAAGALBF8AAADYAsEXAAAAtkDwBQAAgC0QfAEAAGAL\nBF8AAADYAsEXAAAAtkDwBQAAgC0QfAEAAGALBF8AAADYQmqyCwCA4RAOh9XWdnDAeEHBjUpLS0tC\nRQCA4UbwBWALbW0HtWpjkzKd08yxnsAReaslt7s4iZWNPNFIn/x+34BxfokAYHUEXwC2kemcpmsm\n3ZDsMka8YNcxbd/docy3T5lj/BIBYCQg+AIAhoxfIgCMRARfALY12D/ZD/ZP+ACA0YHgC8C2Bvsn\n+48P7dfE60qSWBUAIFEIvgBsrf8/2fcE2pNYDQAgkdjHFwAAALZA8AUAAIAtEHwBAABgCwRfAAAA\n2ALBFwAAALZA8AUAAIAtEHwBAABgCwRfAAAA2ALBFwAAALZA8AUAAIAtEHwBAABgCwRfAAAA2ALB\nFwAAALZA8AUAAIAtDDn47tu3T/fdd59uvvlmuVwu7dmzxzwWjUb14x//WLfffrvcbrduueUWPfTQ\nQ2pvb495jkgkIo/Ho7KyMhUWFqqqqkpHjx6NmRMMBrV69WqVlJSouLhYK1euVFdX12W+TAAAANjd\nkINvKBRSQUGB1qxZI4fDEXOst7dXr7/+um6//XY9/fTT+t73vqf/+q//0te+9jX19fWZ8+rr69XU\n1KTa2lo1NjYqFAqpqqpK0WjUnLN69Wq988472rx5s7Zt2ya/36+VK1dewUsFACRKNNInv9+n1tYD\nMf+Fw+FklwYAptShPqCiokIVFRU6ffq0DMOIOTZu3Djt2rUrZszpdOrOO+/UBx98oFmzZikcDmvn\nzp2qrq5WeXm5JMnr9aqiokJ79+5VRUWFjh07ptdee02bN29WSUmJJGn9+vW6++675ff7NXPmzMt8\nuQCARAh2HdP23R3KfPuUOdYTOCJvteR2FyexMgD4P0MOvkMVDoflcDiUk5MjSfL5fOrt7VVpaak5\nZ/LkyZo+fbpaW1tVUVGh1tZWORyOmDnFxcVKT09Xa2srwRfABYXDYbW1HYwZ8/t9SarGPjKd03TN\npBuSXQYAnFdCg284HJbX69XChQs1ceJESdKJEycknT0T/ElOp9M8FggElJ6eroyMDPO4w+FQdna2\nOedSpaRw/Z4VnesL/bGe0dCb3/++Tas2NinTOc0c+/jQfk28riSJVdlTSsoYpaaO3PfSUIyGr53R\nit5Y13D3JGHBt6+vT9/61rcUiUT0/e9/P1Ef5qKysjIuPglJQ3+sayT3JisrY8DZx55A+wUegUTJ\nyspQdvZVyS5jWI3kr53Rjt4gIcE3HA7rwQcf1PHjx/Xss89q/Pjx5rHc3FxJZ8/qZmdnm+OBQEBu\nt9uc09vbq1AoZJ71NQxDnZ2d5uMvVXd3SJFI9OITMaxSUsYoKyuD/ljQaOhNd3co2SXgf3V3h9TZ\nGUx2GcNiNHztjFb0xrrO9Wa4xD34njlzRt/4xjfU3d09IPRKksvlUnp6upqbm5Wfny9J6ujo0OHD\nh1VUVCRJKiwslGEYam5u1oIFCyRJBw4c0JkzZ8xwfKkikaj6+niTWxX9sa6R3Bt+sFnHSH4fXS47\nvuaRgt5gyME3GAyqvb1dodDZMyrt7e3y+XzKyclRdna2li9friNHjqi+vl5//vOfzcdNmTJF48eP\nV1pamiorK9XQ0KApU6YoLy9PXq9X+fn5mjdvnqSzF7stWrRIdXV1Gj9+vFJTU7V+/XqVlZVxYRsA\nAAAuy5CDb0tLi5YvXy6HwyGHwyGPxyNJWrp0qb761a/qnXfekcPh0D333BPzuB//+Mfm2dvq6moZ\nhqG1a9cqFApp7ty58ng8SklJMefX1dVpw4YNWrFihaLRqMrLy7Vu3borea0AAACwsSEH31tvvVU+\n3/m3BbrQMfODpqaqpqZGNTU1550zbtw41dbWqra2dqglAgAAAAOwrwcAAABsgeALAAAAWyD4AgAA\nwBYIvgAAALAFgi8AAABsgeALAAAAW0jILYsBAIhG+uT3D9zisqDgRqWlpSWhIgB2R/AFACREsOuY\ntu/uUObbp8yxnsAReaslt7s4iZUBsCuCLwAgYTKd03TNpBuSXQYASGKNLwAAAGyC4AsAAABbIPgC\nAADAFljjC2BEC4fDams7GDM22E4CAAAQfAGMaG1tB7VqY5MyndPMsY8P7dfE60qSWBUAwIoIvgBG\nvP47B/QE2pNYDQDAqljjCwAAAFsg+AIAAMAWCL4AAACwBYIvAAAAbIHgCwAAAFtgVwcAwLCJRvoG\n3We5oOBGpaWlJaEiAHZC8AUADJtg1zFt392hzLdPmWM9gSPyVktud3ESKwNgBwRfAMCw6r/vMgAM\nF9b4AgAAwBYIvgAAALAFgi8AAABsgTW+AICkGmynB3Z5AJAIBF8AQFL13+mBXR4AJArBFwCQdOz0\nAGA4sMYXAAAAtkDwBQAAgC0QfAEAAGALBF8AAADYAsEXAAAAtkDwBQAAgC0QfAEAAGALQw6++/bt\n03333aebb75ZLpdLe/bsGTBn69atKi8v15w5c7RkyRL5fLF35IlEIvJ4PCorK1NhYaGqqqp09OjR\nmDnBYFCrV69WSUmJiouLtXLlSnV1dQ21XAAAAEDSZQTfUCikgoICrVmzRg6HY8DxxsZGNTQ06KGH\nHtKLL76oCRMmaNmyZerp6THn1NfXq6mpSbW1tWpsbFQoFFJVVZWi0ag5Z/Xq1XrnnXe0efNmbdu2\nTX6/XytXrrzMlwkAAAC7G3Lwraio0IMPPqjy8nIZhjHg+I4dO1RZWanFixdr5syZ8ng86u3t1a5d\nuyRJ4XBYO3fu1IoVK1ReXq6CggJ5vV4dOnRIe/fulSQdO3ZMr732mtasWaOSkhK53W6tX79ev/71\nr+X3+6/sFQMAAMCW4rrG9+TJk2pvb1dpaak5NnbsWBUVFam1tVWS5PP51NvbGzNn8uTJmj59ujmn\ntbVVDocjZk5xcbHS09PNOQAAAMBQpMbzyY4fPy6HwyGn0xkz7nQ61dHRIUk6ceKEOdZ/zrljgUBA\n6enpysjIMI87HA5lZ2ebcy5VSgrX71nRub7QH+sZab0ZKXViaFJSxig1dWT1dqR97dgJvbGu4e5J\nXIOvpEGXP0gadD3wcMjKyrj4JCQN/bEuK/YmHA7rd7/7XczYn//8YZKqQSJlZWUoO/uqZJdxWaz4\ntYOz6A3iGnzz8vIknT1j+0mBQEC5ubmSZP4ZCASUnZ0dM8ftdptzent7FQqFzLO+hmGos7PTfPyl\n6u4OKRKJXnwihlVKyhhlZWXQHwuycm9aWg5o5Q/+VZnOaebYx4f2a+J1JUmsConQ3R1SZ2cw2WUM\niZW/duyO3ljXud4Ml7gG35ycHE2dOlXNzc2aP3++JKm3t1ctLS2qrq6WJLlcLqWnp6u5uVn5+fmS\npI6ODh0+fFhFRUWSpMLCQhmGoebmZi1YsECSdODAAZ05c8YMx5cqEomqr483uVXRH+uyYm8ikagy\nndN0zaQbzLGeQHsSK0KiWPH9d6lGcu2jHb3BkINvMBhUe3u7QqGQJKm9vV0+n085OTmaMGGC7r33\nXnm9Xs2aNUsul0tbtmxRRkaGFi9eLElKS0tTZWWlGhoaNGXKFOXl5cnr9So/P1/z5s2TdPZit0WL\nFqmurk7jx49Xamqq1q9fr7KyMs2cOTOOLx8AAAB2MeTg29LSouXLl8vhcMjhcMjj8UiSli5dqlWr\nVumuu+5SMBjUpk2b1NnZqdmzZ+uZZ55RZmam+RzV1dUyDENr165VKBTS3Llz5fF4lJKSYs6pq6vT\nhg0btGLFCkWjUZWXl2vdunVxeMkAAACwoyEH31tvvXXAndj6q6qqUlVV1fk/aGqqampqVFNTc945\n48aNU21trWpra4daIgAAADAA+3oAAADAFgi+AAAAsIW47+MLAMCViEb65PcPXFJXUHCj0tLSklAR\ngNGC4AsAsJRg1zFt392hzLdPmWM9gSPyVktud3ESKwMw0hF8AQCW03+/ZgCIB9b4AgAAwBYIvgAA\nALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAAALAFtjMDYEnhcFhtbQdjxga7qQEAAJeK4AvAktra\nDmrVxiZlOqeZYx8f2q+J15UksSoAwEhG8AVgWf1vYtATaE9iNQCAkY41vgAAALAFgi8AAABsgeAL\nAAAAWyD4AgAAwBYIvgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAAALAFgi8AAABsgeALAAAA\nWyD4AgAAwBYIvgAAALAFgi8AAABsITXZBQAAcDHRSJ/8ft+A8YKCG5WWlpaEigCMRARfAIDlBbuO\nafvuDmW+fcoc6wkckbdacruLk1gZgJGE4AsAGBEyndN0zaQbkl0GgBGMNb4AAACwBYIvAAAAbIHg\nCwAAAFsg+AIAAMAWCL4AAACwBYIvAAAAbCEhwTccDsvj8ejzn/+8PvOZz2jRokXatm1bzJytW7eq\nvLxcc+bM0ZIlS+TzxW5MHolE5PF4VFZWpsLCQlVVVeno0aOJKBcAAAA2kJDgu2nTJr3yyit67LHH\n9Itf/EL33XefNm3apKamJklSY2OjGhoa9NBDD+nFF1/UhAkTtGzZMvX09JjPUV9fr6amJtXW1qqx\nsVGhUEhVVVWKRqOJKBkAAACjXEKC729/+1stXLhQ8+bN09SpU3X77bfrxhtv1MGDByVJO3bsUGVl\npRYvXqyZM2fK4/Got7dXu3btknT2jPHOnTu1YsUKlZeXq6CgQF6vV4cOHdLevXsTUTIAAABGuYQE\nX7fbrX379qm9vV2S1NLSog8++EDl5eU6efKk2tvbVVpaas4fO3asioqK1NraKkny+Xzq7e2NmTN5\n8mRNnz7dnAMAAAAMRUJuWVxdXa3Tp0/rtttuU2rq2Q+xZs0azZ8/X36/Xw6HQ06nM+YxTqdTHR0d\nkqQTJ06YY/3nnDt2qVJSuH7Pis71hf5Yj1V6k+yPj5EhJWWMUlOt8V6xytcOBqI31jXcPUlI8H3h\nhRf0xhtv6Mknn9SMGTPU2tqquro65eXlaerUqTIMY9DHORyOuNeSlZUR9+dE/NAf60p2b5L98TEy\nZGVlKDv7qmSXEYP3rnXRGyQk+D7xxBN6+OGHtXDhQknSDTfcoPfee0/btm3T5s2bJUmBQCDmMYFA\nQLm5uZJk/hkIBJSdnR0zx+12D6mW7u6QIhEuiLOalJQxysrKoD8WZJXedHeHkvaxMXJ0d4fU2RlM\ndhmSrPNBqnSZAAAfEUlEQVS1g4HojXWd681wiXvwjUQiCofDA8YdDoei0ahycnI0depUNTc3a/78\n+ZKk3t5etbS0qLq6WpLkcrmUnp6u5uZm5efnS5I6Ojp0+PBhFRUVDbGeqPr6eJNbFf2xruHuTTgc\nVlvbQfPvfr/vArOBs6z4PcSKNeEseoO4B9+UlBTNmzdPTz31lCZNmqQZM2aopaVFL7/8su6//35J\n0r333iuv16tZs2bJ5XJpy5YtysjI0OLFiyVJaWlpqqysVENDg6ZMmaK8vDx5vV7l5+dr3rx58S4Z\ngAW0tR3Uqo1NynROkyR9fGi/Jl5XkuSqYGXRSN+gvyAVFNyotLS0JFQEwOoSstShrq5OGzdu1GOP\nPabOzk5NnDhR3/jGN/S1r31NknTXXXcpGAxq06ZN6uzs1OzZs/XMM88oMzPTfI7q6moZhqG1a9cq\nFApp7ty58ng8SklJSUTJACwg0zlN10y6QZLUE2hPcjWwumDXMW3f3aHMt0+ZYz2BI/JWS253cRIr\nA2BVCQm+WVlZWr9+/QXnVFVVqaqq6rzHU1NTVVNTo5qamjhXBwAYLT75yxIAXAz7egAAAMAWCL4A\nAACwBYIvAAAAbIHgCwAAAFsg+AIAAMAWCL4AAACwhYRsZwYAF9L/Lm0Sd2oDACQewRfAsOt/lzaJ\nO7UBABKP4AsgKfrfeIA7tQEAEo01vgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAAALAFgi8A\nAABsgeALAAAAWyD4AgAAwBYIvgAAALAFgi8AAABsgeALAAAAW0hNdgEAAMRLNNInv983YLyg4Eal\npaUloSIAVkLwBQCMGsGuY9q+u0OZb58yx3oCR+Stltzu4iRWBsAKCL4AgFEl0zlN10y6IdllALAg\n1vgCAADAFjjjCyChwuGw2toOxowNtgYTAIBEI/gCSKi2toNatbFJmc5p5tjHh/Zr4nUlSawKAGBH\nBF8ACdd/zWVPoD2J1QAA7Io1vgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBYIvgAAALAFgi8AAABs\nge3MAACjWjTSN+hNUwoKblRaWloSKgKQLARfAMCoFuw6pu27O5T59ilzrCdwRN5qye0uTmJlAIYb\nwRcAMOr1v4kKAHtK2Brfjz76SCtXrtRnP/tZud1u3XHHHfL7/ebxrVu3qry8XHPmzNGSJUvk88X+\nM1QkEpHH41FZWZkKCwtVVVWlo0ePJqpcAAAAjHIJCb6dnZ2qrKxUT0+PvF6vnn32WS1btkxjx46V\nJDU2NqqhoUEPPfSQXnzxRU2YMEHLli1TT0+P+Rz19fVqampSbW2tGhsbFQqFVFVVpWg0moiSAQAA\nMMolZKnDU089pauvvlpbt241x+bMmWP+/44dO1RZWanFixdLkjwej0pLS7Vr1y7dc889CofD2rlz\np6qrq1VeXi5J8nq9qqio0N69e1VRUZGIsgEAADCKJeSM7549e3TTTTdpxYoVKi0t1e23364XX3xR\nknTy5Em1t7ertLTUnD927FgVFRWptbVVkuTz+dTb2xszZ/LkyZo+fbo5BwAAABiKhJzx7ejo0M9+\n9jMtX75cK1as0IEDB/TYY4/pU5/6lGbNmiVJcjqdMY9xOp3q6OiQJJ04ceK8c84du1QpKWxVbEXn\n+kJ/rCfevaHHsKqUlDFKTY3f+5Pva9ZFb6xruHsS9+BrGIai0ajmzJmjBx54QJLkcrnU1tamxsZG\nbdiw4byPdTgc8S5HWVkZcX9OxA/9sa549YYew6qysjKUnX1VQp4X1kRvEPfg63A45HQ6NWPGjJjx\n66+/Xm+99Zby8vIkSYFAIOZ4IBBQbm6uJJl/BgIBZWdnx8xxu91Dqqe7O6RIhAvirCYlZYyysjLo\njwXFuzfd3aE4VAXEX3d3SJ2dwbg9H9/XrIveWNe53gyXhCx1KCoq0uHDh2PGDh06pGuvvVY5OTma\nOnWqmpubNX/+fElSb2+vWlpaVF1dLensGeL09HQ1NzcrPz9f0tnlE4cPH1ZRUdGQaolEourr401u\nVfTHuuLVG37IwKoS9f2H72vWRW+QkOC7dOlSfeUrX9FTTz2lhQsX6sCBA3r11Vf1ve99T5J07733\nyuv1atasWXK5XNqyZYsyMjLMXR7S0tJUWVmphoYGTZkyRXl5efJ6vcrPz9e8efMSUTIAAABGuYSd\n8f3hD3+oTZs2acuWLZoyZYoeffRRM9jeddddCgaD2rRpkzo7OzV79mw988wzyszMNJ+jurpahmFo\n7dq1CoVCmjt3rjwej1JSUhJRMgAAAEa5hN2yeMGCBVqwYMF5j1dVVamqquq8x1NTU1VTU6OamppE\nlAcAAACbSVjwBWA/4XBYbW0HY8b8ft95ZgMAMLwIvgDipq3toFZtbFKmc5o59vGh/Zp4XUkSqwIG\nikb6Bv2lrKDgRqWlpSWhIgDDgeALIK4yndN0zaQbzL/3BNqTWA0wuGDXMW3f3aHMt0+ZYz2BI/JW\nS253cRIrA5BIBF8AgC31/yUNwOjHvfsAAABgCwRfAAAA2ALBFwAAALZA8AUAAIAtEHwBAABgCwRf\nAAAA2ALBFwAAALZA8AUAAIAtEHwBAABgCwRfAAAA2ALBFwAAALZA8AUAAIAtEHwBAABgCwRfAAAA\n2ALBFwAAALaQmuwCAIxM4XBYbW0HY8b8fl+SqgEA4OIIvgAuS1vbQa3a2KRM5zRz7OND+zXxupIk\nVgUAwPkRfAFctkznNF0z6Qbz7z2B9iRWAwDAhRF8AQCQFI30Dbpcp6DgRqWlpSWhIgDxRvAFAEBS\nsOuYtu/uUObbp8yxnsAReaslt7s4iZUBiBeCLwAA/6v/8p3BDHZhZ0HBjUpNTU9kaQDigOALAMAQ\n9L+w89xZ4ZISLuwErI7gCwDAEF3KmWEA1sMNLAAAAGALnPEFAOA8BtvpgRu1ACMXwRcAgPMYbKcH\nbtQCjFwEXwAXxe2JYWfcqAUYPQi+AC6K2xMDAEYDgi+AS8JZLwDASMeuDgAAALAFgi8AAABsgeAL\nAAAAWyD4AgAAwBYSHnx/8pOfyOVy6dFHH40Z37p1q8rLyzVnzhwtWbJEPl/s1kiRSEQej0dlZWUq\nLCxUVVWVjh49muhyAQAAMEolNPj+/ve/189+9jO5XK6Y8cbGRjU0NOihhx7Siy++qAkTJmjZsmXq\n6ekx59TX16upqUm1tbVqbGxUKBRSVVWVotFoIksGAADAKJWw4Hvq1Ck9/PDD2rBhgzIzM2OO7dix\nQ5WVlVq8eLFmzpwpj8ej3t5e7dq1S9LZzfJ37typFStWqLy8XAUFBfJ6vTp06JD27t2bqJIBAAAw\niiUs+D722GOqqKhQaWlpzPjJkyfV3t4eMz527FgVFRWptbVVkuTz+dTb2xszZ/LkyZo+fbo5BwAA\nABiKhNzA4uc//7n8fr9qa2sHHDt+/LgcDoecTmfMuNPpVEdHhyTpxIkT5lj/OeeOXaqUFK7fs6Jz\nfaE/1jNYb+gTcGEpKWP4vmZh9Ma6hrsncQ++R48eVV1dnXbs2KFPfepTg84xDGPQcYfDEe9ylJWV\nEffnRPzQH+v6ZG/oE3BhWVkZ5tcJXy/WRW8Q9+D7hz/8QV1dXbrjjjvMgBuJRPTuu+/q5Zdf1muv\nvSZJCgQCMY8LBALKzc2VJPPPQCCg7OzsmDlut3tI9XR3hxSJcEGc1aSkjFFWVgb9saDBetPdHUpy\nVYC1dXeH1N0d4vuaRfEzx7rO9Wa4xD343nLLLXr11Vdjxh555BFde+21+uY3v6nJkydr6tSpam5u\n1vz58yVJvb29amlpUXV1tSTJ5XIpPT1dzc3Nys/PlyR1dHTo8OHDKioqGlI9kUhUfX28ya2K/ljX\nJ3vDDwrgwiKRqPl1wvc166I3iHvwveqqq8ywek5GRoauvvpqXX/99ZKke++9V16vV7NmzZLL5dKW\nLVuUkZGhxYsXS5LS0tJUWVmphoYGTZkyRXl5efJ6vcrPz9e8efPiXTIAAABsICEXt/XXf+3uXXfd\npWAwqE2bNqmzs1OzZ8/WM888E7PtWXV1tQzD0Nq1axUKhTR37lx5PB6lpKQMR8kAAAAYZYYl+P70\npz8dMFZVVaWqqqrzPiY1NVU1NTWqqalJZGkAAACwCfb1AAAAgC0QfAEAAGALBF8AAADYwrCs8QUw\ncoTDYe3f/17Mfpd+vy/JVQEAcOUIvgBi/OEPB7XyB/+qTOc0c+zjQ/s18bqSJFYFAMCVI/gCGCDT\nOU3XTLrB/HtPoD2J1QAAEB+s8QUAAIAtEHwBAABgCwRfAAAA2ALBFwAAALZA8AUAAIAtsKsDAABX\nIBrpk9/vU0rKGGVlZZh7YBcU3Ki0tLRklwfgEwi+gI2Fw2G1tR2MGfvgA3+SqgFGpmDXMW3f3aHM\nt0+ZYz2BI/JWS253cRIrA9AfwRewsba2g1q1sYmbVQBXqP/e1wCsieAL2Bw3qwAA2AXBFwCAODu3\n7rc/1v0CyUXwBQAgzlj3C1gTwRcAgARg3S9gPQRfwEb67+Iw2D/FAgAwWhF8ARvpv4sDOzgAAOyE\n4AvYzCf/+ZUdHAAAdsItiwEAAGALBF8AAADYAsEXAAAAtkDwBQAAgC1wcRsAAMOAu7kByUfwBQBg\nGHA3NyD5CL4AAAwT7uYGJBdrfAEAAGALBF8AAADYAsEXAAAAtsAaX2CUCofDams7GDM22BXlAADY\nBcEXGKXa2g5q1cYmZTqnmWMfH9qvideVJLEqAACSh+ALjGL9ryDvCbQnsRoAAJKLNb4AAACwBYIv\nAAAAbCHuwfe5555TZWWlSkpK9LnPfU5VVVXy+WIvqNm6davKy8s1Z84cLVmyZMDxSCQij8ejsrIy\nFRYWqqqqSkePHo13qQAAALCRuAffX/ziF6qoqNCPfvQjbdy4UcFgUEuXLtXJkyclSY2NjWpoaNBD\nDz2kF198URMmTNCyZcvU09NjPkd9fb2amppUW1urxsZGhUIhVVVVKRqNxrtcAAAA2ETcL2574YUX\nYv7ucrlUVlamlpYWfeELX9COHTtUWVmpxYsXS5I8Ho9KS0u1a9cu3XPPPQqHw9q5c6eqq6tVXl4u\nSfJ6vaqoqNDevXtVUVER75IBAABgAwlf43vmzBlJUk5Ojk6ePKn29naVlpaax8eOHauioiK1trZK\nknw+n3p7e2PmTJ48WdOnTzfnAAAwGkQjffL7fWptPRDzXzgcTnZpwKiU8O3MNmzYoDlz5qioqEh+\nv18Oh0NOpzNmjtPpVEdHhyTpxIkT5lj/OeeODUVKCtfvWdG5vtCfxOFzC1hfsOuYtu/uUObbp8yx\nnsARPfHwGBUVFSexstGFnznWNdw9SWjwfeyxx+T3+9XY2GiOGYYx6FyHw5GQGrKyMhLyvIgP+pM4\nfG6BkaH/ftvS2a/f7OyrklTR6MX3RSQs+K5bt07Nzc16/vnnNXHiRElSXl6eJCkQCMTMDQQCys3N\nlSTzz0AgoOzs7Jg5brd7yHV0d4cUiXBRnNWkpIxRVlYG/Umg7u5QsksAcJm6u0Pq7Awmu4xRg585\n1nWuN8Ml7sHXMAx95zvf0bvvvqvnn39ekyZNMo/l5ORo6tSpam5u1vz58yVJvb29amlpUXV1taSz\nF8Olp6erublZ+fn5kqSOjg4dPnxYRUVFQ64nEomqr483uVXRn/gIh8NqazsYM+b3+84zG4CVRSN9\neu+99wYEtIKCG5WWlpakqkYHfuYg7sH329/+tt58803V19erq6tLXV1dkqQJEyYoJydH9957r7xe\nr2bNmiWXy6UtW7YoIyPD3OUhLS1NlZWVamho0JQpU5SXlyev16v8/HzNmzcv3uUCo0Jb20Gt2tik\nTOc0c+zjQ/s18bqSJFYF4HKcb92vt1pyu1n3C1yJuAfff//3f1c0GtXXv/71mPHVq1frK1/5iu66\n6y4Fg0Ft2rRJnZ2dmj17tp555hllZmaac6urq2UYhtauXatQKKS5c+fK4/EoJSUl3uUCo0b/dYI9\ngfYkVgPgSgy27hfAlYt78G1ra7vonKqqKlVVVZ33eGpqqmpqalRTUxPP0gAAAGBjCd/ODAAAXJlz\n+/32x7pfYGgIvgAAWBzrfoH4IPgCADACsO4XuHLcwgQAAAC2QPAFAACALRB8AQAAYAsEXwAAANgC\nF7cBIwy3JwYgscUZcDkIvoCFnS/kbt/9HrcnBmyOLc6AoSP4AhbW1nZQqzY2DRpyuT0xALY4A4aG\n4AtYXP8fbIRcAAAuDxe3AQAAwBY44wsAwCjBBW/AhRF8AQAYJbjgDbgwgi8AAKMIF7wB58caXwAA\nANgCZ3yBJBhsf96//vWvkqRPfepT5hg3pgBwpQZb98uaX9gVwRdIgvPtzzvu6oncmAJAXPVf98ua\nX9gZwRdIksH25810TmXPXgBxx7pf4CzW+AIAAMAWOOMLAICNDLbmd7BrDCTWAmP0IfgCAGAjg+31\nO9g1BqwFxmhE8AUAwGYu5RoDYDRijS8AAABsgTO+QIINtmcv+/MCADD8CL5Agp1vz1725wUAYHgR\nfIFhMNh6OgAAMLwIvkAcsawBwGjBtmcYjQi+QByxrAHAaMG2ZxiNCL7AFeh/htfv97GsAcCowbZn\nGG0IvsAV6H+Gl7O7AOxmsCUREssfYE0EX+AKffKMCGd3AdjNYEsi/uf4h1r+dz7NnOmKmUsYRrIR\nfAEAwBUZbEnE9t3vxYRh1gLDCgi+AAAg7vqHYcAKCL7AJWKrMgAARjaCL3CJ2KoMAC4fF8HBCiwf\nfF966SX95Cc/0bFjx5Sfn6+amhp97nOfS3ZZGKEGO2s72Ibsg42xVRkAXL5LuQjuUr8fSwRmXB5L\nB9+9e/fq0UcfVU1NjcrKyvTCCy/on//5n/Xqq69q6tSpyS4PI9D5ztr235D9fGOc3QWAy3exi+Au\n9fvxYLtGXCggp6amJ+T1YOSxdPDdsWOHKioq9NWvflWStHbtWr311ltqbGzUI488kuTqkCyDnbWV\nBv72f741uZeyIfv5xgAA8dV/S8hL/X7cf9eICwXkT3/608rKylB3d0iRSJSzxTZm6eD7u9/9Tt/+\n9rdjxkpLS9Xa2pqkimAFg521Hey3f7/fd/YbI2dtAWDUudSTGP0D8qWeLWaJxehk2eB76tQphUIh\n5ebmxow7nU4dP378kp8nJWVMvEvDJ0Sj0UEvVggGgxoz5vyf+zFjHBo/Pl2nTvUqGjWG9DE/+MA/\nYKy354Q2/fT/07is//ul6OQxv/KmzRkwtydwJObvp//nI0lGXMbi+VzDMWaVOkZabdRr39qod+TV\nNu7qiTFj5/t5kX5VtsZlTbjg2Onuv6j63v9HLtcsjRRFRdbeN3m4c5plg++FOByOS56blZWRwEog\nSWVlw3sGdcGCebr//mH9kAAAYBSw7OnQ8ePHKyMjQydOnIgZDwQCA84CAwAAABdj2eArSZ/5zGe0\nb9++mLF9+/apqKgoSRUBAABgpLJ08F26dKneeOMN7dixQ++//76+973v6S9/+YuWLFmS7NIAAAAw\nwjgMwxjalUXDrKmpSU899ZQ++ugjXX/99XrkkUf02c9+NtllAQAAYISxfPAFAAAA4sHSSx0AAACA\neCH4AgAAwBYIvgAAALAFgi8AAABsgeALAAAAWyD4AgAAwBZGVPBduHChXC7XgP/WrVtnztm6davK\ny8s1Z84cLVmyRD6fL+Y5IpGIPB6PysrKVFhYqKqqKh09enS4X8qoFA6H5fF49PnPf16f+cxntGjR\nIm3bti1mDv1JjmAwqO9///tmb+666y61tbXFzKE3w2Pfvn267777dPPNN8vlcmnPnj0D5sSjF8Fg\nUKtXr1ZJSYmKi4u1cuVKdXV1JfS1jXQX682//du/aenSpZo7d65cLteAvkj0JpEu1J9oNKof//jH\nuv322+V2u3XLLbfooYceUnt7e8xz0J/EuNjXzpYtW/SlL31Jbrdbc+fO1Ve+8hW9++67MXOGrTfG\nCPKnP/3J+OMf/2j+98tf/tJwuVzGr371K8MwDOP555835syZY+zatcvw+XzGN7/5TaO0tNTo7u42\nn+Pxxx835s6da/zHf/yH8Yc//MG4++67jS9+8YtGJBJJ1ssaNTwej1FaWmq8+eabxpEjR4yXXnrJ\nKCgoMF566SXDMOhPMn3zm980brvtNqO5udn405/+ZDz++ONGSUmJceLECcMw6M1w2rNnj/HDH/7Q\n2L17t+FyuYzXX3895ni8evHAAw8YFRUVxjvvvGO0tLQYX/rSl4xly5YN2+sciS7Wm5deesnYsmWL\n8fzzzxsul8v44x//OOA56E3iXKg/wWDQWLx4sfHcc88Z+/fvN9544w3jb//2b42FCxcaf/3rX815\n9CcxLva109jYaOzevdv47W9/a+zbt8944IEHjMLCQuOjjz4y5wxXb0ZU8O1v48aNxuc//3nz71/4\nwheMuro68++9vb2G2+02fvrTnxqGYRhnzpwxCgsLzb8bhmF0dHQYLpfL2LNnz/AVPkpVVlYa3/3u\nd2PG/umf/slYv369YRj0J1l6e3uNT3/608arr74aM37bbbcZP/rRjwzDoDfJEAwGjZkzZw74ARGP\nXnR0dBgzZ86M6c3+/fuNmTNnGj6fL5Eva1Q4X2/Oef/99wcNvvRmeFysP+f87ne/M2bOnGm89957\nhmHQn+Fwqb3p6emJ+TwPZ29G1FKHT4pGo9q1a5duv/12SdLJkyfV3t6u0tJSc87YsWNVVFSk1tZW\nSZLP51Nvb2/MnMmTJ2v69OnmHFw+t9utffv2mf+01NLSog8++EDl5eX0J4n6+voUiUSUnp4eM56e\nnq6WlhZ6YyHx6kVra6scDkfMnOLiYqWnp9OvBKI31hIOh+VwOJSTkyOJ/ljF6dOn1djYqHHjxmn2\n7NmShrc3qXF6HcNu7969OnHihO644w5J0vHjx+VwOOR0OmPmOZ1OdXR0SJJOnDhhjvWfc+4YLl91\ndbVOnz6t2267TampZ99aa9as0fz58+X3++lPklx11VUqLCzUtm3bdOONNyo3N1cvv/yy3n//fRmG\noePHj0sa/PNOb4ZXvL6PBQIBpaenKyMjwzzucDiUnZ1NvxKI3lhHOByW1+vVwoULNXHiREn0J9ne\neOMNPfDAA4pEIsrNzdX27ds1YcIEScPbmxEbfP/1X/9VpaWlmjx5sjlmGMagcx0Ox3CVZWsvvPCC\n3njjDT355JOaMWOGWltbVVdXp7y8PE2dOpX+JNEPfvADfec739H8+fOVmpqq2bNnq7y8XMeOHbvg\n4+jN8OPrBLgyfX19+ta3vqVIJKLvf//7yS4H/+tzn/ucXnnlFXV2durFF19UdXW1XnjhBTP8DpcR\nudTh+PHjeuutt3TnnXeaY3l5eZLO/kbwSYFAQLm5uZJk/nmhObh8TzzxhL7+9a9r4cKFuuGGG3Tn\nnXdq8eLF2rZtG/1JsqlTp+q5555Ta2ur3nzzTe3cuVM9PT2aMmUKvbGQePUiNzdXvb29CoVC5nHD\nMNTZ2Um/EojeJF84HNaKFSv08ccf69lnn9X48ePNY/QnucaNG6f8/HyVlJTI6/UqJSVFP/vZzyQN\nb29GZPB96aWXlJWVpYqKCnMsJydHU6dOVXNzsznW29urlpYWFRUVSZJcLpfS09Nj5nR0dOjw4cPm\nHFyeSCSicDg8YNzhcCgajdIfi8jIyJDT6dT777+vlpYWfeELX6A3FhKvXhQWFsowjJg5Bw4c0Jkz\nZ+R2u4fp1dgPvUmuM2fO6Otf/7oCgcCA0CvRHyuJRCLq6+szc8Nw9mZELnVoamrSP/zDP5jrSM+5\n99575fV6NWvWLLlcLm3ZskUZGRlavHixJCktLU2VlZVqaGgwz3R5vV7l5+dr3rx5yXgpo0ZKSorm\nzZunp556SpMmTdKMGTPU0tKil19+Wffff78k+pNMe/fuVWdnp6ZPn64PP/xQmzZtUlFRkfm5pzfD\nJxgMqr293Txr0d7eLp/Pp5ycHE2YMCEuvZg8ebIWLVqkuro6jR8/XqmpqVq/fr3Kyso0c+bMpL12\nq7tYb7q6uvTRRx/pv//7v2UYhg4dOiRJmjhxorKzs+lNgl2oP9nZ2Vq+fLmOHDmi+vp6/fnPfzYf\nN2XKFI0fP57+JNCFejN+/Hh5PB7NmzdPeXl56uzs1L/8y78oEAjoi1/8oqRh/r52yfs/WMS+ffsM\nl8tl/P/t3D1qKlEYBmCyGm38QWwEQW1mES5ArLWyshJ0CdMLrsLGHbgAS8FSQQsR/NIJJibhwo0h\nOc8DU52PwwxvMW8xczabzcP1PM+j1WpFuVyObrf77oiLy+US0+k0Go1GVKvV6PV6sd1un3Hrf97h\ncIjxeBztdjsqlUpkWRZ5nsf1er3NyOdnLJfLyLIsSqVSNJvNmEwmcTwe72Zk8xyr1SoKhUIUi8W7\nazab3Wb+Rxan0ylGo1HU6/Wo1WoxGAxiv98/5Rl/q6+yWSwWD9fn8/ltD9l8n8/y2e12D9fenikr\nn+/xWTbn8zmGw2F0Op3bO6jf78d6vb7b41nZvER88CcFAAD8Ib/yG18AAPhXii8AAElQfAEASILi\nCwBAEhRfAACSoPgCAJAExRcAgCQovgAAJEHxBQAgCYovAABJUHwBAEjCK5AJujesuW2QAAAAAElF\nTkSuQmCC\n", 144 | "text/plain": [ 145 | "" 146 | ] 147 | }, 148 | "metadata": {}, 149 | "output_type": "display_data" 150 | } 151 | ], 152 | "source": [ 153 | "%time pd.Series(stock_price_results).hist(bins=100)" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "metadata": { 160 | "collapsed": true 161 | }, 162 | "outputs": [], 163 | "source": [] 164 | } 165 | ], 166 | "metadata": { 167 | "hide_input": false, 168 | "kernelspec": { 169 | "display_name": "Python 3", 170 | "language": "python", 171 | "name": "python3" 172 | }, 173 | "language_info": { 174 | "codemirror_mode": { 175 | "name": "ipython", 176 | "version": 3 177 | }, 178 | "file_extension": ".py", 179 | "mimetype": "text/x-python", 180 | "name": "python", 181 | "nbconvert_exporter": "python", 182 | "pygments_lexer": "ipython3", 183 | "version": "3.5.1" 184 | }, 185 | "nav_menu": {}, 186 | "toc": { 187 | "navigate_menu": true, 188 | "number_sections": true, 189 | "sideBar": true, 190 | "threshold": 6, 191 | "toc_cell": false, 192 | "toc_section_display": "block", 193 | "toc_window_display": true 194 | } 195 | }, 196 | "nbformat": 4, 197 | "nbformat_minor": 0 198 | } 199 | -------------------------------------------------------------------------------- /Case1-6_7/Case1_6.py: -------------------------------------------------------------------------------- 1 | import xlwings as xw 2 | import os 3 | from datetime import datetime 4 | import pandas as pd 5 | from pandas_datareader import data 6 | 7 | script_dir = os.path.abspath(os.path.dirname(__file__)) 8 | data_dir = os.path.join(script_dir, 'data') 9 | wb = xw.Book.caller() 10 | sheet = wb.sheets['Case1-6_7'] 11 | 12 | 13 | def stock_price(): 14 | code = sheet.range('A1').value 15 | try: 16 | df = data.DataReader(code, 'yahoo', 17 | datetime(2006, 1, 1), 18 | datetime(2015, 12, 31)) 19 | except: 20 | file_path = os.path.join(data_dir, code + '.mpack') 21 | df = pd.read_msgpack(file_path) 22 | sheet.range('A11').value = df 23 | 24 | 25 | def clear_data(): 26 | rng1 = sheet.range('A11').expand('table') 27 | rng1.clear() 28 | -------------------------------------------------------------------------------- /Case1-6_7/Case1_6.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/Case1-6_7/Case1_6.xlsm -------------------------------------------------------------------------------- /Case1-6_7/Case1_7.py: -------------------------------------------------------------------------------- 1 | import xlwings as xw 2 | import numpy as np 3 | import pandas as pd 4 | 5 | 6 | @xw.func 7 | def atr(close_prev, high, low): 8 | d1 = high - low 9 | d2 = abs(high - close_prev) 10 | d3 = abs(close_prev - low) 11 | return max(d1, d2, d3) 12 | 13 | 14 | @xw.func 15 | @xw.arg('x', np.array) 16 | def ptp(x): 17 | return np.ptp(x) 18 | 19 | 20 | @xw.func 21 | @xw.arg('x', pd.DataFrame, index=False, header=False) 22 | @xw.ret(index=False, header=False) 23 | def describe(x): 24 | return x.describe().values 25 | -------------------------------------------------------------------------------- /Case1-6_7/Case1_7.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/Case1-6_7/Case1_7.xlsm -------------------------------------------------------------------------------- /Case2-3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Case2-3: CustomBusinessDayで満期日を列挙し、満期日までの日数を営業日で計算してみる \n", 8 | "Compute the last trading day by CustomBusinessDay class" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "metadata": { 15 | "ExecuteTime": { 16 | "end_time": "2016-09-17T13:52:04.873267", 17 | "start_time": "2016-09-17T13:52:03.864196" 18 | }, 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "from itertools import chain\n", 24 | "from datetime import datetime\n", 25 | "from datetime import date\n", 26 | "from pandas.tseries.offsets import CustomBusinessDay\n", 27 | "import pandas as pd\n", 28 | "import yaml\n", 29 | "import requests" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "### 番外編(Appendix)\n", 37 | "QuantLibに日本の祝日があるが、情報が古い \n", 38 | "Japanese holiday in QuantLib is too old" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "ExecuteTime": { 45 | "end_time": "2016-09-17T13:52:05.073197", 46 | "start_time": "2016-09-17T13:52:04.876192" 47 | }, 48 | "collapsed": false 49 | }, 50 | "source": [ 51 | "```\n", 52 | "import QuantLib as ql\n", 53 | "calender = ql.Japan()\n", 54 | "calender.isHoliday(ql.Date(11, 8, 2016))\n", 55 | "```\n", 56 | "```\n", 57 | "False\n", 58 | "# No \"Mountain day\"\n", 59 | "```" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "* Windowsの場合はビルド済のwheelからインストールするのが簡単 \n", 67 | "* For windows, Easy to install QuantLib from pre-built wheel \n", 68 | "http://www.lfd.uci.edu/~gohlke/pythonlibs/#quantlib" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "## holiday_jpから祝日のyamlファイルを取得 \n", 76 | "Get hoilday yaml file from hoilday_jp\n", 77 | "> * Initial datasets\n", 78 | "> \n", 79 | "> [komagata/holiday_jp](https://github.com/komagata/holiday_jp)\n", 80 | "> \n", 81 | "> * komagata/holiday_jp Copyright\n", 82 | "> \n", 83 | "> Copyright (c) 2009 Masaki Komagata. See [LICENSE](https://github.com/komagata/holiday_jp/blob/master/LICENSE) for details.\n", 84 | "> \n", 85 | "> * \"Datasets\" idea\n", 86 | "> \n", 87 | "> [Project Woothee](https://woothee.github.io/)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 2, 93 | "metadata": { 94 | "ExecuteTime": { 95 | "end_time": "2016-09-17T13:52:07.183219", 96 | "start_time": "2016-09-17T13:52:05.076195" 97 | }, 98 | "collapsed": false 99 | }, 100 | "outputs": [], 101 | "source": [ 102 | "# https://github.com/k1LoW/holiday_jp\n", 103 | "try:\n", 104 | " holiday_jp_yaml = yaml.load(requests.get('https://raw.githubusercontent.com/k1LoW/holiday_jp/master/holidays.yml').text)\n", 105 | "except Exception:\n", 106 | " with open('data/holidays.yml', 'rb') as f:\n", 107 | " holiday_jp_yaml = yaml.load(f)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 3, 113 | "metadata": { 114 | "ExecuteTime": { 115 | "end_time": "2016-09-17T13:52:07.194193", 116 | "start_time": "2016-09-17T13:52:07.186192" 117 | }, 118 | "collapsed": false 119 | }, 120 | "outputs": [], 121 | "source": [ 122 | "holiday_jp = list(holiday_jp_yaml.keys())" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 4, 128 | "metadata": { 129 | "ExecuteTime": { 130 | "end_time": "2016-09-17T13:52:07.222196", 131 | "start_time": "2016-09-17T13:52:07.199196" 132 | }, 133 | "collapsed": false 134 | }, 135 | "outputs": [ 136 | { 137 | "data": { 138 | "text/plain": [ 139 | "[datetime.date(1970, 1, 1),\n", 140 | " datetime.date(1970, 1, 15),\n", 141 | " datetime.date(1970, 2, 11),\n", 142 | " datetime.date(1970, 3, 21),\n", 143 | " datetime.date(1970, 4, 29)]" 144 | ] 145 | }, 146 | "execution_count": 4, 147 | "metadata": {}, 148 | "output_type": "execute_result" 149 | } 150 | ], 151 | "source": [ 152 | "sorted(holiday_jp)[:5]" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "## 取引所は三が日と大晦日が休場のため休みを追加する \n", 160 | "Add \"The First Three Days of the New Year\" and \"new years eve\" as holidays" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 5, 166 | "metadata": { 167 | "ExecuteTime": { 168 | "end_time": "2016-09-17T13:52:07.247196", 169 | "start_time": "2016-09-17T13:52:07.227196" 170 | }, 171 | "collapsed": false 172 | }, 173 | "outputs": [], 174 | "source": [ 175 | "holiday_newyear = chain.from_iterable(\n", 176 | " [[date(y, 1, 2), date(y, 1, 3), date(y, 12, 31)]\n", 177 | " for y in range(sorted(holiday_jp)[0].year, sorted(holiday_jp)[-1].year + 1)])" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 6, 183 | "metadata": { 184 | "ExecuteTime": { 185 | "end_time": "2016-09-17T13:52:07.265214", 186 | "start_time": "2016-09-17T13:52:07.251196" 187 | }, 188 | "collapsed": true 189 | }, 190 | "outputs": [], 191 | "source": [ 192 | "holiday_jpx = chain(holiday_jp, holiday_newyear)" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "metadata": {}, 198 | "source": [ 199 | "## CustomBusinessDayのインスタンスを作成 \n", 200 | "create CustomBusinessDay instance" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 7, 206 | "metadata": { 207 | "ExecuteTime": { 208 | "end_time": "2016-09-17T13:52:07.354194", 209 | "start_time": "2016-09-17T13:52:07.268196" 210 | }, 211 | "collapsed": false 212 | }, 213 | "outputs": [], 214 | "source": [ 215 | "bday_jpx = CustomBusinessDay(holidays=holiday_jpx)" 216 | ] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": { 221 | "ExecuteTime": { 222 | "end_time": "2016-09-02T11:09:46.572072", 223 | "start_time": "2016-09-02T11:09:46.568069" 224 | } 225 | }, 226 | "source": [ 227 | "## Case2-1と同様にdate_rangeを作成\n", 228 | "Create \"date_range\" same as case2-1 \n", 229 | "\n", 230 | "\n", 231 | "freq='WOM-2FRI'を指定することで毎月の第二金曜日を指定できる \n", 232 | "to specify \"The 2nd Friday of every month\" by freq='WOM-2FRI'" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 8, 238 | "metadata": { 239 | "ExecuteTime": { 240 | "end_time": "2016-09-17T13:52:07.391196", 241 | "start_time": "2016-09-17T13:52:07.357198" 242 | }, 243 | "collapsed": true 244 | }, 245 | "outputs": [], 246 | "source": [ 247 | "sq_date = pd.date_range(datetime(2017, 1, 1), datetime(2017, 12, 31), freq='WOM-2FRI')" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 9, 253 | "metadata": { 254 | "ExecuteTime": { 255 | "end_time": "2016-09-17T13:52:07.414195", 256 | "start_time": "2016-09-17T13:52:07.396195" 257 | }, 258 | "collapsed": false 259 | }, 260 | "outputs": [ 261 | { 262 | "data": { 263 | "text/plain": [ 264 | "DatetimeIndex(['2017-01-13', '2017-02-10', '2017-03-10', '2017-04-14',\n", 265 | " '2017-05-12', '2017-06-09', '2017-07-14', '2017-08-11',\n", 266 | " '2017-09-08', '2017-10-13', '2017-11-10', '2017-12-08'],\n", 267 | " dtype='datetime64[ns]', freq='WOM-2FRI')" 268 | ] 269 | }, 270 | "execution_count": 9, 271 | "metadata": {}, 272 | "output_type": "execute_result" 273 | } 274 | ], 275 | "source": [ 276 | "sq_date" 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": {}, 282 | "source": [ 283 | "## CustomBusinessDayで作成したインスタンスを利用して第二金曜日が祝日だった場合は一営業日前倒しする \n", 284 | "If the 2nd Friday is holiday, Set the day before as the last trading day" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 10, 290 | "metadata": { 291 | "ExecuteTime": { 292 | "end_time": "2016-09-17T13:52:07.432195", 293 | "start_time": "2016-09-17T13:52:07.418196" 294 | }, 295 | "collapsed": true 296 | }, 297 | "outputs": [], 298 | "source": [ 299 | "def shift_bday(dt):\n", 300 | " if dt.date() in bday_jpx.holidays:\n", 301 | " return (dt - bday_jpx)\n", 302 | " else:\n", 303 | " return dt" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 11, 309 | "metadata": { 310 | "ExecuteTime": { 311 | "end_time": "2016-09-17T13:52:07.782209", 312 | "start_time": "2016-09-17T13:52:07.436193" 313 | }, 314 | "collapsed": false 315 | }, 316 | "outputs": [], 317 | "source": [ 318 | "sq_date = sq_date.map(shift_bday)" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": 12, 324 | "metadata": { 325 | "ExecuteTime": { 326 | "end_time": "2016-09-17T13:52:07.798193", 327 | "start_time": "2016-09-17T13:52:07.784196" 328 | }, 329 | "collapsed": false 330 | }, 331 | "outputs": [ 332 | { 333 | "data": { 334 | "text/plain": [ 335 | "array([Timestamp('2017-01-13 00:00:00', offset='WOM-2FRI'),\n", 336 | " Timestamp('2017-02-10 00:00:00', offset='WOM-2FRI'),\n", 337 | " Timestamp('2017-03-10 00:00:00', offset='WOM-2FRI'),\n", 338 | " Timestamp('2017-04-14 00:00:00', offset='WOM-2FRI'),\n", 339 | " Timestamp('2017-05-12 00:00:00', offset='WOM-2FRI'),\n", 340 | " Timestamp('2017-06-09 00:00:00', offset='WOM-2FRI'),\n", 341 | " Timestamp('2017-07-14 00:00:00', offset='WOM-2FRI'),\n", 342 | " Timestamp('2017-08-10 00:00:00'),\n", 343 | " Timestamp('2017-09-08 00:00:00', offset='WOM-2FRI'),\n", 344 | " Timestamp('2017-10-13 00:00:00', offset='WOM-2FRI'),\n", 345 | " Timestamp('2017-11-10 00:00:00', offset='WOM-2FRI'),\n", 346 | " Timestamp('2017-12-08 00:00:00', offset='WOM-2FRI')], dtype=object)" 347 | ] 348 | }, 349 | "execution_count": 12, 350 | "metadata": {}, 351 | "output_type": "execute_result" 352 | } 353 | ], 354 | "source": [ 355 | "sq_date" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "8月11日が祝日なので、一日前倒しされる \n", 363 | "11th of Aug is holiday, so Set the day before as the last trading day" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": {}, 369 | "source": [ 370 | "## 2017年5月1日から5月満期日までの営業日\n", 371 | "Business day from 1 May ,2017 to contract expires" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 13, 377 | "metadata": { 378 | "ExecuteTime": { 379 | "end_time": "2016-09-17T13:52:07.823194", 380 | "start_time": "2016-09-17T13:52:07.802197" 381 | }, 382 | "collapsed": false 383 | }, 384 | "outputs": [ 385 | { 386 | "data": { 387 | "text/plain": [ 388 | "DatetimeIndex(['2017-05-01', '2017-05-02', '2017-05-08', '2017-05-09',\n", 389 | " '2017-05-10', '2017-05-11', '2017-05-12'],\n", 390 | " dtype='datetime64[ns]', freq='C')" 391 | ] 392 | }, 393 | "execution_count": 13, 394 | "metadata": {}, 395 | "output_type": "execute_result" 396 | } 397 | ], 398 | "source": [ 399 | "pd.date_range(datetime(2017, 5, 1), sq_date[4], freq=bday_jpx)" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "metadata": {}, 405 | "source": [ 406 | "## 営業日をカウントすれば営業日数を得られる \n", 407 | "Count the number of business day" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "execution_count": 14, 413 | "metadata": { 414 | "ExecuteTime": { 415 | "end_time": "2016-09-17T13:52:07.857196", 416 | "start_time": "2016-09-17T13:52:07.831195" 417 | }, 418 | "collapsed": false 419 | }, 420 | "outputs": [ 421 | { 422 | "data": { 423 | "text/plain": [ 424 | "7" 425 | ] 426 | }, 427 | "execution_count": 14, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "len(pd.date_range(datetime(2017, 5, 1), sq_date[4], freq=bday_jpx))" 434 | ] 435 | }, 436 | { 437 | "cell_type": "markdown", 438 | "metadata": {}, 439 | "source": [ 440 | "## 番外編(Appendix)\n", 441 | "pandas 0.18.1からCustomBusinessHourが使えるように \n", 442 | "Possible to use \"CustomBusinessHour\" from pandas 0.18.1 \n", 443 | "\n", 444 | "http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#custom-business-hour" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": 15, 450 | "metadata": { 451 | "ExecuteTime": { 452 | "end_time": "2016-09-17T13:52:07.873197", 453 | "start_time": "2016-09-17T13:52:07.861197" 454 | }, 455 | "collapsed": false 456 | }, 457 | "outputs": [], 458 | "source": [ 459 | "from pandas.tseries.offsets import CustomBusinessHour" 460 | ] 461 | }, 462 | { 463 | "cell_type": "markdown", 464 | "metadata": {}, 465 | "source": [ 466 | "### JPX(東証)の取引時間を設定 \n", 467 | "Set JPX trading hours" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 16, 473 | "metadata": { 474 | "ExecuteTime": { 475 | "end_time": "2016-09-17T13:52:07.912195", 476 | "start_time": "2016-09-17T13:52:07.876195" 477 | }, 478 | "collapsed": false 479 | }, 480 | "outputs": [], 481 | "source": [ 482 | "bhour_jpx = CustomBusinessHour(start='9:00', end='15:00', holidays=bday_jpx.holidays)" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": { 488 | "ExecuteTime": { 489 | "end_time": "2016-09-11T16:16:36.328481", 490 | "start_time": "2016-09-11T16:16:36.313477" 491 | }, 492 | "collapsed": true 493 | }, 494 | "source": [ 495 | "### 営業時間で計算ができる \n", 496 | "adding or subtracting business hours" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": 17, 502 | "metadata": { 503 | "ExecuteTime": { 504 | "end_time": "2016-09-17T13:52:07.937192", 505 | "start_time": "2016-09-17T13:52:07.921197" 506 | }, 507 | "collapsed": false 508 | }, 509 | "outputs": [ 510 | { 511 | "data": { 512 | "text/plain": [ 513 | "Timestamp('2016-09-23 09:00:00')" 514 | ] 515 | }, 516 | "execution_count": 17, 517 | "metadata": {}, 518 | "output_type": "execute_result" 519 | } 520 | ], 521 | "source": [ 522 | "datetime(2016, 9, 21, 13) + bhour_jpx * 2" 523 | ] 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": null, 528 | "metadata": { 529 | "collapsed": true 530 | }, 531 | "outputs": [], 532 | "source": [] 533 | } 534 | ], 535 | "metadata": { 536 | "hide_input": false, 537 | "kernelspec": { 538 | "display_name": "Python 3", 539 | "language": "python", 540 | "name": "python3" 541 | }, 542 | "language_info": { 543 | "codemirror_mode": { 544 | "name": "ipython", 545 | "version": 3 546 | }, 547 | "file_extension": ".py", 548 | "mimetype": "text/x-python", 549 | "name": "python", 550 | "nbconvert_exporter": "python", 551 | "pygments_lexer": "ipython3", 552 | "version": "3.5.1" 553 | }, 554 | "nav_menu": {}, 555 | "toc": { 556 | "navigate_menu": true, 557 | "number_sections": true, 558 | "sideBar": true, 559 | "threshold": 6, 560 | "toc_cell": false, 561 | "toc_section_display": "block", 562 | "toc_window_display": true 563 | } 564 | }, 565 | "nbformat": 4, 566 | "nbformat_minor": 1 567 | } 568 | -------------------------------------------------------------------------------- /Case3-1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Case3-1: マジックコマンドを自作してみる \n", 8 | "Create own magic command" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "metadata": { 15 | "ExecuteTime": { 16 | "end_time": "2016-09-17T13:53:08.333228", 17 | "start_time": "2016-09-17T13:53:07.515201" 18 | }, 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "import functools\n", 24 | "from IPython.core.magic import register_line_magic, register_cell_magic\n", 25 | "from IPython.display import IFrame\n", 26 | "import pandas as pd\n", 27 | "import yaml\n", 28 | "import ast\n", 29 | "from io import StringIO" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "ExecuteTime": { 36 | "end_time": "2016-09-02T17:54:45.409012", 37 | "start_time": "2016-09-02T17:54:45.405011" 38 | } 39 | }, 40 | "source": [ 41 | "## line magic" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "metadata": { 48 | "ExecuteTime": { 49 | "end_time": "2016-09-17T13:53:08.345200", 50 | "start_time": "2016-09-17T13:53:08.335197" 51 | }, 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "@register_line_magic\n", 57 | "def ms(code):\n", 58 | " url = \"https://www.morningstar.co.jp/StockInfo/info/snap/{0}\".format(code)\n", 59 | " print(url)\n", 60 | " return IFrame(url, \"100%\", 600)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "ExecuteTime": { 68 | "end_time": "2016-09-17T13:53:08.394202", 69 | "start_time": "2016-09-17T13:53:08.351200" 70 | }, 71 | "collapsed": false, 72 | "scrolled": true 73 | }, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "https://www.morningstar.co.jp/StockInfo/info/snap/7974\n" 80 | ] 81 | }, 82 | { 83 | "data": { 84 | "text/html": [ 85 | "\n", 86 | " \n", 93 | " " 94 | ], 95 | "text/plain": [ 96 | "" 97 | ] 98 | }, 99 | "execution_count": 3, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "%ms 7974" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "## cell magic" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 4, 118 | "metadata": { 119 | "ExecuteTime": { 120 | "end_time": "2016-09-17T13:53:08.409202", 121 | "start_time": "2016-09-17T13:53:08.398201" 122 | }, 123 | "collapsed": true 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "@register_cell_magic\n", 128 | "def csv(line, cell):\n", 129 | " sio = StringIO(cell)\n", 130 | " if line:\n", 131 | " options = dict(ast.literal_eval(line))\n", 132 | " return pd.read_csv(sio, **options)\n", 133 | " else:\n", 134 | " return pd.read_csv(sio)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 5, 140 | "metadata": { 141 | "ExecuteTime": { 142 | "end_time": "2016-09-17T13:53:08.431202", 143 | "start_time": "2016-09-17T13:53:08.412199" 144 | }, 145 | "collapsed": false 146 | }, 147 | "outputs": [], 148 | "source": [ 149 | "@register_cell_magic\n", 150 | "def yml(line, cell):\n", 151 | " sio = StringIO(cell)\n", 152 | " return pd.DataFrame(yaml.load(sio))" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 6, 158 | "metadata": { 159 | "ExecuteTime": { 160 | "end_time": "2016-09-17T13:53:08.449200", 161 | "start_time": "2016-09-17T13:53:08.434198" 162 | }, 163 | "collapsed": false 164 | }, 165 | "outputs": [], 166 | "source": [ 167 | "@register_cell_magic\n", 168 | "def json(line, cell):\n", 169 | " sio = StringIO(cell)\n", 170 | " return pd.read_json(sio)" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "### csv形式のデータをDataFrameに変換 \n", 178 | "convert csv data into DataFrame" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": { 184 | "ExecuteTime": { 185 | "end_time": "2016-09-05T17:21:25.187404", 186 | "start_time": "2016-09-05T17:21:25.181382" 187 | } 188 | }, 189 | "source": [ 190 | "pandas.read_html()では読み込めないがコピペすることでDataFrameとして取り込める \n", 191 | "cannot read data by pdandas.read_html(), but can fetch data as DataFrame by copy&paste" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 7, 197 | "metadata": { 198 | "ExecuteTime": { 199 | "end_time": "2016-09-17T13:53:08.501202", 200 | "start_time": "2016-09-17T13:53:08.454200" 201 | }, 202 | "collapsed": false 203 | }, 204 | "outputs": [ 205 | { 206 | "data": { 207 | "text/html": [ 208 | "
\n", 209 | "\n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | "
012
0始値26,910(09/13 09:00)
1高値27,080(09/13 09:05)
2安値25,590(09/13 14:52)
3出来高(株)6,017,700(09/13 15:00)
4前日終値26,690(09/12)
5年初来高値32,700(2016/7/19)
6年初来安値13,360(2016/6/28)
7発行済株式数(千株)141,669
\n", 269 | "
" 270 | ], 271 | "text/plain": [ 272 | " 0 1 2\n", 273 | "0 始値 26,910 (09/13 09:00)\n", 274 | "1 高値 27,080 (09/13 09:05)\n", 275 | "2 安値 25,590 (09/13 14:52)\n", 276 | "3 出来高(株) 6,017,700 (09/13 15:00)\n", 277 | "4 前日終値 26,690 (09/12)\n", 278 | "5 年初来高値 32,700 (2016/7/19)\n", 279 | "6 年初来安値 13,360 (2016/6/28)\n", 280 | "7 発行済株式数(千株) 141,669 " 281 | ] 282 | }, 283 | "execution_count": 7, 284 | "metadata": {}, 285 | "output_type": "execute_result" 286 | } 287 | ], 288 | "source": [ 289 | "%%csv {'sep': '\\t', 'header': None}\n", 290 | "始値\t26,910\t(09/13 09:00)\n", 291 | "高値\t27,080\t(09/13 09:05)\n", 292 | "安値\t25,590\t(09/13 14:52)\n", 293 | "出来高(株)\t6,017,700\t(09/13 15:00)\n", 294 | "前日終値\t26,690\t(09/12)\n", 295 | "年初来高値\t32,700\t(2016/7/19)\n", 296 | "年初来安値\t13,360\t(2016/6/28)\n", 297 | "発行済株式数(千株)\t141,669\t " 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": {}, 303 | "source": [ 304 | "\\_ に直前の結果が格納されている \n", 305 | "store the previous output in \\_" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 8, 311 | "metadata": { 312 | "ExecuteTime": { 313 | "end_time": "2016-09-17T13:53:08.511198", 314 | "start_time": "2016-09-17T13:53:08.506202" 315 | }, 316 | "collapsed": true 317 | }, 318 | "outputs": [], 319 | "source": [ 320 | "df = _" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 9, 326 | "metadata": { 327 | "ExecuteTime": { 328 | "end_time": "2016-09-17T13:53:08.546197", 329 | "start_time": "2016-09-17T13:53:08.515200" 330 | }, 331 | "collapsed": false 332 | }, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/html": [ 337 | "
\n", 338 | "\n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | "
012
0始値26,910(09/13 09:00)
1高値27,080(09/13 09:05)
2安値25,590(09/13 14:52)
3出来高(株)6,017,700(09/13 15:00)
4前日終値26,690(09/12)
\n", 380 | "
" 381 | ], 382 | "text/plain": [ 383 | " 0 1 2\n", 384 | "0 始値 26,910 (09/13 09:00)\n", 385 | "1 高値 27,080 (09/13 09:05)\n", 386 | "2 安値 25,590 (09/13 14:52)\n", 387 | "3 出来高(株) 6,017,700 (09/13 15:00)\n", 388 | "4 前日終値 26,690 (09/12)" 389 | ] 390 | }, 391 | "execution_count": 9, 392 | "metadata": {}, 393 | "output_type": "execute_result" 394 | } 395 | ], 396 | "source": [ 397 | "df.head()" 398 | ] 399 | }, 400 | { 401 | "cell_type": "markdown", 402 | "metadata": { 403 | "ExecuteTime": { 404 | "end_time": "2016-09-09T10:05:05.488199", 405 | "start_time": "2016-09-09T10:05:05.484195" 406 | }, 407 | "collapsed": true 408 | }, 409 | "source": [ 410 | "### json形式のデータをDataFrameに変換 \n", 411 | "Covert json type data into DataFrame" 412 | ] 413 | }, 414 | { 415 | "cell_type": "markdown", 416 | "metadata": {}, 417 | "source": [ 418 | "> * json data \n", 419 | "> https://www.google.com/finance/info?q=NASDAQ%3aGOOG" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": 10, 425 | "metadata": { 426 | "ExecuteTime": { 427 | "end_time": "2016-09-17T13:53:08.643198", 428 | "start_time": "2016-09-17T13:53:08.552201" 429 | }, 430 | "collapsed": false, 431 | "scrolled": true 432 | }, 433 | "outputs": [ 434 | { 435 | "data": { 436 | "text/html": [ 437 | "
\n", 438 | "\n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | "
cc_fixccolcpcp_fixdiveecec_fixeccol...ll_curl_fixltlt_dtslttpcls_fixstyld
000chb00NASDAQ0.840.84chg...767.05767.05767.05Aug 31, 4:00PM EDT2016-08-31T16:00:02Z4:00PM EDT767.051GOOG
\n", 492 | "

1 rows × 27 columns

\n", 493 | "
" 494 | ], 495 | "text/plain": [ 496 | " c c_fix ccol cp cp_fix div e ec ec_fix eccol ... l \\\n", 497 | "0 0 0 chb 0 0 NASDAQ 0.84 0.84 chg ... 767.05 \n", 498 | "\n", 499 | " l_cur l_fix lt lt_dts ltt \\\n", 500 | "0 767.05 767.05 Aug 31, 4:00PM EDT 2016-08-31T16:00:02Z 4:00PM EDT \n", 501 | "\n", 502 | " pcls_fix s t yld \n", 503 | "0 767.05 1 GOOG \n", 504 | "\n", 505 | "[1 rows x 27 columns]" 506 | ] 507 | }, 508 | "execution_count": 10, 509 | "metadata": {}, 510 | "output_type": "execute_result" 511 | } 512 | ], 513 | "source": [ 514 | "%%json\n", 515 | "[ { \"id\": \"304466804484872\" ,\"t\" : \"GOOG\" ,\"e\" : \"NASDAQ\" ,\"l\" : \"767.05\" ,\"l_fix\" : \"767.05\" ,\"l_cur\" : \"767.05\" ,\"s\": \"1\" ,\"ltt\":\"4:00PM EDT\" ,\"lt\" : \"Aug 31, 4:00PM EDT\" ,\"lt_dts\" : \"2016-08-31T16:00:02Z\" ,\"c\" : \"0.00\" ,\"c_fix\" : \"0.00\" ,\"cp\" : \"0.00\" ,\"cp_fix\" : \"0.00\" ,\"ccol\" : \"chb\" ,\"pcls_fix\" : \"767.05\" ,\"el\": \"767.89\" ,\"el_fix\": \"767.89\" ,\"el_cur\": \"767.89\" ,\"elt\" : \"Sep 1, 9:24AM EDT\" ,\"ec\" : \"+0.84\" ,\"ec_fix\" : \"0.84\" ,\"ecp\" : \"0.11\" ,\"ecp_fix\" : \"0.11\" ,\"eccol\" : \"chg\" ,\"div\" : \"\" ,\"yld\" : \"\" } ]" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": 11, 521 | "metadata": { 522 | "ExecuteTime": { 523 | "end_time": "2016-09-17T13:53:08.679198", 524 | "start_time": "2016-09-17T13:53:08.650198" 525 | }, 526 | "collapsed": false 527 | }, 528 | "outputs": [ 529 | { 530 | "data": { 531 | "text/html": [ 532 | "
\n", 533 | "\n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | " \n", 555 | " \n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | " \n", 560 | " \n", 561 | " \n", 562 | " \n", 563 | " \n", 564 | " \n", 565 | " \n", 566 | " \n", 567 | " \n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | " \n", 639 | " \n", 640 | " \n", 641 | " \n", 642 | " \n", 643 | " \n", 644 | " \n", 645 | " \n", 646 | " \n", 647 | " \n", 648 | " \n", 649 | " \n", 650 | "
0
c0
c_fix0
ccolchb
cp0
cp_fix0
div
eNASDAQ
ec0.84
ec_fix0.84
eccolchg
ecp0.11
ecp_fix0.11
el767.89
el_cur767.89
el_fix767.89
eltSep 1, 9:24AM EDT
id304466804484872
l767.05
l_cur767.05
l_fix767.05
ltAug 31, 4:00PM EDT
lt_dts2016-08-31T16:00:02Z
ltt4:00PM EDT
pcls_fix767.05
s1
tGOOG
yld
\n", 651 | "
" 652 | ], 653 | "text/plain": [ 654 | " 0\n", 655 | "c 0\n", 656 | "c_fix 0\n", 657 | "ccol chb\n", 658 | "cp 0\n", 659 | "cp_fix 0\n", 660 | "div \n", 661 | "e NASDAQ\n", 662 | "ec 0.84\n", 663 | "ec_fix 0.84\n", 664 | "eccol chg\n", 665 | "ecp 0.11\n", 666 | "ecp_fix 0.11\n", 667 | "el 767.89\n", 668 | "el_cur 767.89\n", 669 | "el_fix 767.89\n", 670 | "elt Sep 1, 9:24AM EDT\n", 671 | "id 304466804484872\n", 672 | "l 767.05\n", 673 | "l_cur 767.05\n", 674 | "l_fix 767.05\n", 675 | "lt Aug 31, 4:00PM EDT\n", 676 | "lt_dts 2016-08-31T16:00:02Z\n", 677 | "ltt 4:00PM EDT\n", 678 | "pcls_fix 767.05\n", 679 | "s 1\n", 680 | "t GOOG\n", 681 | "yld " 682 | ] 683 | }, 684 | "execution_count": 11, 685 | "metadata": {}, 686 | "output_type": "execute_result" 687 | } 688 | ], 689 | "source": [ 690 | "_.T" 691 | ] 692 | }, 693 | { 694 | "cell_type": "markdown", 695 | "metadata": {}, 696 | "source": [ 697 | "### yaml形式のデータをDataFrameに変換 \n", 698 | "convert yaml type data into DataFrame" 699 | ] 700 | }, 701 | { 702 | "cell_type": "markdown", 703 | "metadata": {}, 704 | "source": [ 705 | "yaml data at [Case2-3](Case2-3.ipynb)" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "execution_count": 12, 711 | "metadata": { 712 | "ExecuteTime": { 713 | "end_time": "2016-09-17T13:53:08.720197", 714 | "start_time": "2016-09-17T13:53:08.684203" 715 | }, 716 | "collapsed": false 717 | }, 718 | "outputs": [ 719 | { 720 | "data": { 721 | "text/html": [ 722 | "
\n", 723 | "\n", 724 | " \n", 725 | " \n", 726 | " \n", 727 | " \n", 728 | " \n", 729 | " \n", 730 | " \n", 731 | " \n", 732 | " \n", 733 | " \n", 734 | " \n", 735 | " \n", 736 | " \n", 737 | " \n", 738 | " \n", 739 | " \n", 740 | " \n", 741 | " \n", 742 | " \n", 743 | " \n", 744 | " \n", 745 | " \n", 746 | " \n", 747 | " \n", 748 | " \n", 749 | " \n", 750 | " \n", 751 | " \n", 752 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | " \n", 762 | " \n", 763 | " \n", 764 | "
1970-01-011970-01-151970-02-11
date1970-01-011970-01-151970-02-11
name元日成人の日建国記念の日
name_enNew Year's DayComing of Age DayNational Foundation Day
week
week_enThursdayThursdayWednesday
\n", 765 | "
" 766 | ], 767 | "text/plain": [ 768 | " 1970-01-01 1970-01-15 1970-02-11\n", 769 | "date 1970-01-01 1970-01-15 1970-02-11\n", 770 | "name 元日 成人の日 建国記念の日\n", 771 | "name_en New Year's Day Coming of Age Day National Foundation Day\n", 772 | "week 木 木 水\n", 773 | "week_en Thursday Thursday Wednesday" 774 | ] 775 | }, 776 | "execution_count": 12, 777 | "metadata": {}, 778 | "output_type": "execute_result" 779 | } 780 | ], 781 | "source": [ 782 | "%%yml\n", 783 | "1970-01-01:\n", 784 | " date: 1970-01-01\n", 785 | " week: 木\n", 786 | " week_en: Thursday\n", 787 | " name: 元日\n", 788 | " name_en: \"New Year's Day\"\n", 789 | "\n", 790 | "1970-01-15:\n", 791 | " date: 1970-01-15\n", 792 | " week: 木\n", 793 | " week_en: Thursday\n", 794 | " name: 成人の日\n", 795 | " name_en: \"Coming of Age Day\"\n", 796 | "\n", 797 | "1970-02-11:\n", 798 | " date: 1970-02-11\n", 799 | " week: 水\n", 800 | " week_en: Wednesday\n", 801 | " name: 建国記念の日\n", 802 | " name_en: \"National Foundation Day\"" 803 | ] 804 | }, 805 | { 806 | "cell_type": "code", 807 | "execution_count": 13, 808 | "metadata": { 809 | "ExecuteTime": { 810 | "end_time": "2016-09-17T13:53:08.767201", 811 | "start_time": "2016-09-17T13:53:08.724202" 812 | }, 813 | "collapsed": false 814 | }, 815 | "outputs": [ 816 | { 817 | "data": { 818 | "text/html": [ 819 | "
\n", 820 | "\n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | "
datenamename_enweekweek_en
1970-01-011970-01-01元日New Year's DayThursday
1970-01-151970-01-15成人の日Coming of Age DayThursday
1970-02-111970-02-11建国記念の日National Foundation DayWednesday
\n", 858 | "
" 859 | ], 860 | "text/plain": [ 861 | " date name name_en week week_en\n", 862 | "1970-01-01 1970-01-01 元日 New Year's Day 木 Thursday\n", 863 | "1970-01-15 1970-01-15 成人の日 Coming of Age Day 木 Thursday\n", 864 | "1970-02-11 1970-02-11 建国記念の日 National Foundation Day 水 Wednesday" 865 | ] 866 | }, 867 | "execution_count": 13, 868 | "metadata": {}, 869 | "output_type": "execute_result" 870 | } 871 | ], 872 | "source": [ 873 | "_.T" 874 | ] 875 | }, 876 | { 877 | "cell_type": "code", 878 | "execution_count": null, 879 | "metadata": { 880 | "collapsed": true 881 | }, 882 | "outputs": [], 883 | "source": [] 884 | } 885 | ], 886 | "metadata": { 887 | "hide_input": false, 888 | "kernelspec": { 889 | "display_name": "Python 3", 890 | "language": "python", 891 | "name": "python3" 892 | }, 893 | "language_info": { 894 | "codemirror_mode": { 895 | "name": "ipython", 896 | "version": 3 897 | }, 898 | "file_extension": ".py", 899 | "mimetype": "text/x-python", 900 | "name": "python", 901 | "nbconvert_exporter": "python", 902 | "pygments_lexer": "ipython3", 903 | "version": "3.5.1" 904 | }, 905 | "nav_menu": {}, 906 | "toc": { 907 | "navigate_menu": true, 908 | "number_sections": true, 909 | "sideBar": true, 910 | "threshold": 6, 911 | "toc_cell": false, 912 | "toc_section_display": "block", 913 | "toc_window_display": true 914 | } 915 | }, 916 | "nbformat": 4, 917 | "nbformat_minor": 1 918 | } 919 | -------------------------------------------------------------------------------- /Case3-2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Case3-2: ipywidgetsを使ってみる \n", 8 | "Use ipywidgets" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "metadata": { 15 | "ExecuteTime": { 16 | "end_time": "2016-09-19T12:52:41.041667", 17 | "start_time": "2016-09-19T12:52:33.732604" 18 | }, 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "%matplotlib inline\n", 24 | "import seaborn as sns\n", 25 | "import datetime\n", 26 | "import pandas as pd\n", 27 | "from pandas_datareader import data\n", 28 | "from ipywidgets import interact\n", 29 | "import matplotlib.pyplot as plt" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## 株価(S&P指数)を取得 \n", 37 | "get stock price (S&P 500)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 2, 43 | "metadata": { 44 | "ExecuteTime": { 45 | "end_time": "2016-09-19T12:52:41.901677", 46 | "start_time": "2016-09-19T12:52:41.044607" 47 | }, 48 | "collapsed": false 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "try:\n", 53 | " gspc = data.DataReader(\"^GSPC\", 'yahoo', datetime.datetime(2006, 1, 1), datetime.datetime(2015, 12, 31))\n", 54 | "except Exception:\n", 55 | " gspc = pd.read_msgpack('data/^GSPC.mpack')" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "> * ipywidgets \n", 63 | "> https://ipywidgets.readthedocs.io/en/latest/\n", 64 | "> * Computational tools \n", 65 | "> http://pandas.pydata.org/pandas-docs/stable/computation.html \n", 66 | "> pandasではmoving windowを扱うメソッドが用意されているので、移動平均や自作の関数を移動xxとして実装できる \n", 67 | "> pandas has method which handle moving windows, so can implement moving average and own function as moving xx" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "## 株価に移動平均とボリンジャーバンドを加えて視覚化 \n", 75 | "Create interactive visualization of moving average and Bollinger-Bands" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 3, 81 | "metadata": { 82 | "ExecuteTime": { 83 | "end_time": "2016-09-19T12:52:42.608638", 84 | "start_time": "2016-09-19T12:52:41.904637" 85 | }, 86 | "collapsed": false 87 | }, 88 | "outputs": [ 89 | { 90 | "data": { 91 | "image/png": "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\ndygOTfJ0fYWFhcyYMYOvvvqK8ePH2x6XnqzLSZ7a15k5kkJtR8eOHaOwsJD/+7//o6Wlhb/97W+c\nPHnS3mE5nMrKSv7jP/6DPXv2MGPGDMLDw+0dkkOSPLVv165dhIaG8tprr5GTk8Mnn3xCVVWV9GRd\nQfLUvs7MkeqVV1555ab/reIqFosFhUJBXl4e3333HWFhYQQHB7N69Wo2bdpEc3MzJpOJTz/9FE9P\nTyIjI+0dssP4/vvvKS8vJy0tjT179pCZmYmrqyt+fn6X7UPv7CRPl7N+5/bv38+FCxfw9/fHy8uL\njIwM9u3bR7du3Thy5AhHjhzBz8+PHj162Dtku5A8tc/eOZJC3Umsd1mLFy/m3LlzREdH4+3tTffu\n3SkqKmLBggXccccdFBcXc/78eQYNGmT7cDij7Oxsvv76a/r06YNSqeSLL75g165dBAUF4eXlRXZ2\nNhUVFfTv39/eodqV5On6FAoFTU1NvPTSS7i7uxMXF4e/vz+VlZVERETwxBNPMHToUPbs2UNQUBAR\nERH2DtkuJE/ts3eOfvAWouLHO3z4MDk5OSQkJHDw4EFCQkIYPnw4/fr1o6GhAY1GQ2xsLPv27QNw\n2iIN8Nlnn1FRUcHdd9+Nn58fgwcPpqamhunTp2OxWNi2bRsnT56kubkZtVpt73DtRvLUtvXr11NW\nVkZRURGHDh3i7rvv5r/+679QKBSYTCY8PT3RaDRcuHDB3qHaleSpffbMkbSob6FVq1aRlZWF2Wwm\nNDQUs9lMSkoKPj4+5Ofn4+3tjb+/P6WlpcycOZPa2lpWr17N+PHjiY6Otnf4ncpsNttuTDIzM9m5\ncydRUVF89913DB06lPj4ePr27YvFYsHFxYX9+/cDcMcdd9gz7E4nebq++vp63njjDUpKSjAajQQG\nBmKxWBg9ejQ1NTWUlZURHh6Oj48P27dvJz09nVOnTnHkyBEmTpzoNJM5JU/tc7QcSaG+ycxmM0aj\nkSVLllBQUEBqairvvvsuLi4uDBo0iKCgIPz8/MjJycFgMBAbG4u/vz8eHh7U1tYybdo0pzplrL6+\nnoULF5KTk4Ner6dnz55otVqCg4NJTU1l+/bthIaGEhgYyL/+9S9mz57NqVOn2L9/P6NHjyYsLMze\nl9ApJE9tKysrY+7cufTo0YPg4GAWLVrEfffdR3R0NP7+/igUCnJzc1EqlURHR9t+eFUqFXPmzCEg\n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\n+ACz2WxrLbm4uDhVkYYflydnKtLQ8Rxduvd9WlpalyjS0IUnk23dupWFCxdisVgwmUwsXbqU0NBQ\nmpqaqKqq4te//jUBAQE0NDSwZ88eYmNjWb9+PWq1mgEDBjjVF6GhoQGVSmXbtKWwsJC//OUvnDlz\nhiFDhuDn52dbeuXm5kZERAReXl6X5ci6Rror+7F5cgYmk4lDhw6hVCpthfaf//wn6enpDBs2jBUr\nVuDm5oanpyeffPIJI0aMYO3ateTn5zNq1CinmfEueWqf5OhqXbJQ19TU8OGHH/Lkk08yceJEEhMT\n8fX1JTMzk5CQED766CNSU1Px8fHhH//4BxcuXODhhx9m5MiRDBkyxKmKdG5uLmvWrEGn0xEYGMi+\nffuYP38+KSkp5Ofnc+rUKVJSUkhISOCjjz7i888/5z//8z+dYlbppSRP1/f5558zf/58KioqWLly\nJWq1mqioKL7++msSEhJISEhg8+bNtjPbS0pK+PjjjzGZTMydO9fWKurqJE/tkxxdW5cs1Fu2bKG4\nuJjHH38co9GISqUiJiaGLVu2EBcXR3R0NFu3bmXLli0cO3aM+++/n/DwcNvYhrM5ePAgJpOJ3r17\ns2vXLgIDA5k2bRrx8fF88803KBQKhg8fbjvFKSkpCRcXF6e6oQHJ05X0ej3Tp0+npKSEF154gUcf\nfZTQ0FBOnDjB4cOH8fT0ZPny5RQUFPDnP/+Z8vJyXFxcGD9+PMOGDWPEiBFO8Z2TPLVPctS2LjlG\nHR0djUajoa6uDldXV9tswOTkZLZt28akSZN47rnnGD16NO+//77TLI2B1n25p0+fzu7duzEYDPj7\n+5OamsrJkyfJyckhJCSE8+fP09zcjJ+fH42NjbZztwMCAnjiiSfw8PDossXHSvLUPovFgp+fH/fd\nd59tC9QhQ4aQnJxMbW0tZrOZAQMGkJiYyPvvv89nn31ma/E4Q0+DleSpfZKjtnXJFrXRaLRtPxgZ\nGWmbuLNr1y5SUlKIiorCw8OjSx8TeD1NTU2sX7+e1atXU1hYSHV1NaNGjSI3N5empia8vLw4d+4c\n27dvJzs7m1OnTjFhwoTLjs9zBpKn9mk0GrRaLZ999hkJCQl4enqiVCoxGo3s3LmTtLQ0EhMTOXLk\nCFqtlgULFjhVfqwkT+2THLWtSxZqLy8vysvL2bZtG42NjRiNRhYvXkxZWRnjxo1zmgk+16LRaAgM\nDMRoNHLXXXexa9cuvvzyS06dOkVDQwMxMTE89NBDNDY24unpycsvv+xUXwgryVP7rLtA5efnc+LE\nCYYMGQK0bryxYcMG7rnnHsLCwhg0aBADBw60c7T2I3lqn+SobV2yUCsUCvr06YOHhwcnT57k888/\nZ/jw4cyaNcupi7SVj48P+fn5AMydO5fIyEiOHz/O1q1bqa2tZfTo0QwYMICEhAQ7R2pfkqf2qdVq\nPDw82LNnD/Hx8RgMBl555RWCgoK4//77UalUXbr7v6MkT+2THF2fU2x4cuWaV9G6e9aHH37I1KlT\nbYXmxIkTGI1Gpy48V5I8ta+5uZnVq1ezfPlyevbsyYQJE5xuF7+OkDy1T3J0bU5RqMXVmpub+eij\njzh69Khtf2VxNclTx1jP+33sscdQq9X2DsdhSZ7aJzm6mhRqJ3b69GmOHz/O6NGjnbZLqSMkT0II\ne5JCLYQQQjgwGbgVQgghHJgUaiGEEMKBSaEWQgghHJgUaiGEEMKBSaEWQgghHFjXP0RYCCdXVFTE\nAw88QFxcHBaLhaamJnr16sVLL71E9+7dr/u+X/ziF6xYsaITIxVCXIu0qIVwAgEBAWzcuJFPPvmE\nzz77jPDwcGbOnNnme/bv399J0Qkh2iItaiGc0K9//WvuuusuvvvuO1atWkVeXh56vZ6oqCjefvtt\nlixZAsDPf/5z1q1bR1ZWFm+//TYmk4nQ0FBeffVVvL297XwVQjgHaVEL4YRcXV0JDw9nx44dqNVq\n1q5dyxdffEFDQwNZWVm8+OKLAKxbt47Kykr+93//l+XLl/Pxxx9z55132gq5EOLWkxa1EE5KoVAQ\nHx9PaGgoq1evpqCggLNnz2IwGGzPQ+vBJCUlJfziF7/AYrFgNpvp1q2bPUMXwqlIoRbCCRmNRlth\nfvPNN5k6dSqPPPIIVVVVV73WZDKRnJzM0qVLgdaDSqzFXAhx60nXtxBO4NIt/S0WC2+//TaJiYkU\nFhby4IMP8vDDD+Pr68uBAwcwmUwAqFQqzGYzAwYMICcnh9OnTwPwzjvvsHjxYntchhBOSVrUQjiB\niooKHn74YVvXdXx8POnp6ZSWlvLcc8+xbds21Go1iYmJnDt3DoCf/OQnjBs3jg0bNvD666/zm9/8\nBrPZTGBgoIxRC9GJ5PQsIYQQwoFJ17cQQgjhwKRQCyGEEA5MCrUQQgjhwKRQCyGEEA5MCrUQQgjh\nwKRQCyGEEA5MCrUQQgjhwKRQCyGEEA7s/wEF9aWLQ7jBaAAAAABJRU5ErkJggg==\n", 92 | "text/plain": [ 93 | "" 94 | ] 95 | }, 96 | "metadata": {}, 97 | "output_type": "display_data" 98 | } 99 | ], 100 | "source": [ 101 | "@interact(days=(30, len(gspc), 10), n=(2, 200, 1), rolling_mean=False, bollinger_bands=False)\n", 102 | "def plot_rolling_mean(days=60, n=20, rolling_mean=False, bollinger_bands=False):\n", 103 | " gspc['Adj Close'].iloc[-days:].plot()\n", 104 | " if rolling_mean:\n", 105 | " gspc['Adj Close'].rolling(n).mean().iloc[-days:].plot()\n", 106 | " if bollinger_bands:\n", 107 | " sigma_1 = gspc['Adj Close'].rolling(n).apply(lambda x: x.mean() - x.std()).iloc[-days:]\n", 108 | " sigma_2 = gspc['Adj Close'].rolling(n).apply(lambda x: x.mean() - x.std() * 2).iloc[-days:]\n", 109 | " sigma1 = gspc['Adj Close'].rolling(n).apply(lambda x: x.mean() + x.std()).iloc[-days:]\n", 110 | " sigma2 = gspc['Adj Close'].rolling(n).apply(lambda x: x.mean() + x.std() * 2).iloc[-days:]\n", 111 | " plt.fill_between(sigma1.index, sigma_1, sigma1, alpha=0.3, color='b')\n", 112 | " plt.fill_between(sigma1.index, sigma_2, sigma2, alpha=0.3, color='r')" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "collapsed": true 120 | }, 121 | "outputs": [], 122 | "source": [] 123 | } 124 | ], 125 | "metadata": { 126 | "hide_input": false, 127 | "kernelspec": { 128 | "display_name": "Python 3", 129 | "language": "python", 130 | "name": "python3" 131 | }, 132 | "language_info": { 133 | "codemirror_mode": { 134 | "name": "ipython", 135 | "version": 3 136 | }, 137 | "file_extension": ".py", 138 | "mimetype": "text/x-python", 139 | "name": "python", 140 | "nbconvert_exporter": "python", 141 | "pygments_lexer": "ipython3", 142 | "version": "3.5.1" 143 | }, 144 | "nav_menu": { 145 | "height": "12px", 146 | "width": "160px" 147 | }, 148 | "toc": { 149 | "navigate_menu": true, 150 | "number_sections": true, 151 | "sideBar": true, 152 | "threshold": 6, 153 | "toc_cell": false, 154 | "toc_section_display": "block", 155 | "toc_window_display": true 156 | }, 157 | "widgets": { 158 | "state": { 159 | "a8f241b51df4493b9e6a8753781c19a6": { 160 | "views": [ 161 | { 162 | "cell_index": 6 163 | } 164 | ] 165 | } 166 | }, 167 | "version": "1.2.0" 168 | } 169 | }, 170 | "nbformat": 4, 171 | "nbformat_minor": 1 172 | } 173 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyconjp2016 2 | Start hacking finance data with Python 3 | 4 | [PyCon JP 2016 Talk#024](https://pycon.jp/2016/ja/schedule/presentation/24/) driller@patraqushe 5 | 6 | * Slide 7 | en: http://www.slideshare.net/drillan/pycon-jp-2016-talk054-en 8 | ja: http://www.slideshare.net/drillan/pycon-jp-2016-talk024-ja 9 | 10 | * [Docker image](https://hub.docker.com/r/driller/docker-pyconjp2016/) 11 | This image doesn't include packages related to Excel. 12 | 13 | ### Usage Example 14 | 15 | * Linux or docker-machine(Docker Toolbox) 16 | ``` 17 | git clone https://github.com/drillan/pyconjp2016.git 18 | docker run -d --name pycon -p 8888:8888 -v $PWD/pyconjp2016:/notebooks driller/docker-pyconjp2016 19 | ``` 20 | 21 | * Docker for Windows 22 | ``` 23 | git clone https://github.com/drillan/pyconjp2016.git 24 | docker run -d --name pycon -p 8888:8888 -v %CD%/pyconjp2016:/notebooks driller/docker-pyconjp2016 25 | ``` 26 | 27 | --- 28 | # Sample code and files 29 | 30 | * Some code is redundant due to: 31 | * Python 2/3 support 32 | * Offline mode 33 | * No license limitations 34 | 35 | --- 36 | ## Case1-1: Implement Monte-Carlo Simulation in Excel Function 37 | 38 | 1. Input formula into a Cell to generate random number with geometric Brownian motion(it satisfies the following stochastic differential equation) 39 | 40 | ![$$dS_t = \mu S_t\,dt + \sigma S_t\,dB_t$$](https://wikimedia.org/api/rest_v1/media/math/render/svg/22a084f84c78d0ae6983fd7283004f412f42757b) 41 | 42 | 2. Copy above formula count of sample paths 43 | 44 | 3. Classify the result into bin 45 | 46 | 4. Count the number of each bins then visualize 47 | 48 | --- 49 | ## Case1-2: Implement Monte-Carlo Simulation in VBA 50 | 51 | * Very long code(especially histogram) 52 | 53 | * When changing the layout of an Excel sheet, you have to change all the addresses of related cells(can handle by "name manager" partially) 54 | 55 | * Very slow 56 | 57 | --- 58 | ## [Case1-3](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case1-3.ipynb): Implement Monte-Carlo Simulation in Python 59 | 60 | * Very short code(especially histogram) 61 | 62 | * No need to consider data storage 63 | 64 | * Faster than VBA 65 | 66 | --- 67 | ## [Case-1-4](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case1-4.ipynb): Correlation between Economic indicator and exchange rate and stock price 68 | 69 | * Open Economic indicator & Stock price Excel file @ vdata.Nikkei.com through pandas 70 | * Economic indicator 71 | * Real Gross Domestic Product 72 | * Diffusion Index 73 | * Currency Pair : USD/JPY 74 | * Stock: Nikkei Index 75 | 76 | * Visualize by seaborn 77 | 78 | --- 79 | ## [Case1-5](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case1-5.ipynb): Relationship ETF/J-REIT purchases and stock prices 80 | 81 | * Open Excel files from BOJ site using pandas 82 | 83 | * Load TSE REIT index and stock index price data from k-db site 84 | * Stock Indices 85 | * TOPIX 86 | * JPX400 87 | * Nikkei225 88 | 89 | * Visualize relationship using seaborn 90 | 91 | --- 92 | ## [Case1-6](Case1-6_7): Download stock prices and store into Excel cells 93 | 94 | * xlwings features 95 | * Calling Python from Excel 96 | * Put pandas DataFrame data into Excel cells 97 | * Uses syntax close to VBA 98 | 99 | * Get stock prices using pandas_datareader 100 | 101 | --- 102 | ## [Case1-7](Case1-6_7): Create User Defined Function by Python, and use it as Excel function 103 | 104 | * Windows only 105 | * Install add-in 106 | * Call function written in Python like an Excel function 107 | * Fetch Excel Range(multiple cells) as array data(pandas or Numpy) in UDF function 108 | * Input multiple return values into Excel Range(multiple cells) 109 | 110 | --- 111 | ## [Case2-1](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case2-1_2.ipynb): Use DatetimeIndex 112 | 113 | * pandas.date_range is very useful to create continuous data 114 | * Advantage of DatetimeIndex : 115 | * Specify various types when selecting a location 116 | * datetime.date, datetime.datetime, datetime.time, str, int and so on… 117 | * Able to parse most known formats(similar to parsing by dateutil.parser) 118 | * Allows slicing into year, month, etc 119 | * Handles missing values 120 | 121 | --- 122 | ## [Case2-2](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case2-1_2.ipynb): Create OHLC data and covert time range 123 | 124 | * Not that easy to create OHLC 125 | * Convert time-series data into frequencies using the .resample() method 126 | * .resample() performs resampling operations during frequency conversion 127 | * Daily, Weekly, 30minute, 1hour, Quarter, etc 128 | * There are tips to convert between different OHLC data representations 129 | 130 | --- 131 | ## [Case2-3](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case2-3.ipynb): Compute the last trading day by CustomBusinessDay class 132 | 133 | * Import holiday data from YAML file 134 | * Select the 2nd friday of evey month using pandas.date_range(feq='WOM-2FRI') 135 | * Skip holidays using the CustomBusinessDay class 136 | 137 | --- 138 | ## [Case3-1](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case3-1.ipynb): Create own magic command 139 | 140 | * Search stock price using "line magic", and output it to IPython.display.Iframe 141 | * Paste data in various formats into notebook cells using "cell magic" , and convert it into a pandas DataFrame 142 | * Save frequently used commands to a file and re-use them using %load_ext 143 | 144 | --- 145 | ## [Case3-2](http://nbviewer.jupyter.org/github/drillan/pyconjp2016/blob/master/Case3-2.ipynb): ipywidgets is the easiest way to create a UI 146 | 147 | * Easy to implement a UI using the ipywidgets.interact decorator 148 | * Automatically creates UI controls for function arguments 149 | * bool: check box 150 | * Int: slider 151 | * Creates interactive visualization of moving averages and Bollinger-Bands 152 | 153 | 154 | -------------------------------------------------------------------------------- /data/2016.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/2016.xls -------------------------------------------------------------------------------- /data/AAPL.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/AAPL.mpack -------------------------------------------------------------------------------- /data/FB.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/FB.mpack -------------------------------------------------------------------------------- /data/GOOG.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/GOOG.mpack -------------------------------------------------------------------------------- /data/MSFT.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/MSFT.mpack -------------------------------------------------------------------------------- /data/NA04Q.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/NA04Q.xls -------------------------------------------------------------------------------- /data/NA21M.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/NA21M.xls -------------------------------------------------------------------------------- /data/NE11M.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/NE11M.xls -------------------------------------------------------------------------------- /data/NE51M.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/NE51M.xls -------------------------------------------------------------------------------- /data/NVDA.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/NVDA.mpack -------------------------------------------------------------------------------- /data/RatesXML.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.11459 5 | 1.11483 6 | 1.11674 7 | 1.11263 8 | 0 9 | 05:03:23 10 | 11 | 12 | 103.519 13 | 103.543 14 | 103.661 15 | 103.048 16 | 0 17 | 05:03:21 18 | 19 | 20 | 1.32481 21 | 1.32508 22 | 1.32677 23 | 1.3127 24 | 0 25 | 05:03:23 26 | 27 | 28 | 0.98626 29 | 0.98653 30 | 0.98861 31 | 0.98274 32 | -1 33 | 05:03:24 34 | 35 | 36 | 1.09941 37 | 1.09966 38 | 1.10023 39 | 1.09638 40 | 0 41 | 05:03:24 42 | 43 | 44 | 0.75349 45 | 0.75372 46 | 0.7549 47 | 0.75113 48 | 1 49 | 05:03:23 50 | 51 | 52 | 1.31103 53 | 1.31129 54 | 1.31311 55 | 1.30924 56 | 0 57 | 05:03:23 58 | 59 | 60 | 0.7268 61 | 0.72706 62 | 0.72783 63 | 0.72341 64 | -1 65 | 05:03:23 66 | 67 | 68 | 115.391 69 | 115.42 70 | 115.475 71 | 115.011 72 | -1 73 | 05:03:22 74 | 75 | 76 | 137.147 77 | 137.19 78 | 137.361 79 | 135.384 80 | 0 81 | 05:03:23 82 | 83 | 84 | 0.84121 85 | 0.84144 86 | 0.84999 87 | 0.84021 88 | 0 89 | 05:03:23 90 | 91 | 92 | 104.942 93 | 104.974 94 | 105.183 95 | 104.737 96 | -1 97 | 05:03:23 98 | 99 | 100 | 1.30672 101 | 1.30707 102 | 1.30836 103 | 1.29105 104 | 0 105 | 05:03:24 106 | 107 | 108 | 1.47902 109 | 1.47933 110 | 1.48515 111 | 1.47683 112 | -1 113 | 05:03:23 114 | 115 | 116 | 1.46136 117 | 1.4617 118 | 1.46377 119 | 1.45987 120 | -1 121 | 05:03:23 122 | 123 | 124 | 0.98791 125 | 0.98823 126 | 0.98886 127 | 0.9844 128 | 0 129 | 05:03:23 130 | 131 | 132 | 78.007 133 | 78.033 134 | 78.105 135 | 77.477 136 | 1 137 | 05:03:23 138 | 139 | 140 | 78.946 141 | 78.977 142 | 79.036 143 | 78.592 144 | -1 145 | 05:03:22 146 | 147 | 148 | 75.241 149 | 75.28 150 | 75.363 151 | 74.687 152 | 0 153 | 05:03:21 154 | 155 | 156 | 1.75794 157 | 1.75835 158 | 1.75937 159 | 1.74092 160 | 0 161 | 05:03:23 162 | 163 | 164 | 1.03651 165 | 1.03683 166 | 1.04027 167 | 1.03622 168 | -1 169 | 05:03:23 170 | 171 | 172 | 0.74319 173 | 0.7435 174 | 0.74407 175 | 0.73862 176 | 0 177 | 05:03:24 178 | 179 | 180 | 1.53325 181 | 1.5336 182 | 1.54318 183 | 1.53155 184 | -1 185 | 05:03:22 186 | 187 | 188 | 7.7563 189 | 7.757 190 | 7.75841 191 | 7.756 192 | 0 193 | 04:59:34 194 | 195 | 196 | 18.77 197 | 18.773291 198 | 18.8141 199 | 18.759199 200 | 0 201 | 05:03:21 202 | 203 | 204 | 1.82234 205 | 1.82284 206 | 1.82408 207 | 1.80649 208 | 0 209 | 05:03:23 210 | 211 | 212 | 8.57165 213 | 8.57357 214 | 8.61666 215 | 8.5475 216 | 0 217 | 05:03:24 218 | 219 | 220 | 9.55481 221 | 9.55742 222 | 9.592 223 | 9.5353 224 | -1 225 | 05:03:23 226 | 227 | 228 | 9.31597 229 | 9.32035 230 | 9.3536 231 | 9.272 232 | -1 233 | 05:03:21 234 | 235 | 236 | 8.35818 237 | 8.36045 238 | 8.4021 239 | 8.3054 240 | 0 241 | 05:03:22 242 | 243 | 244 | 14.6126 245 | 14.61591 246 | 14.7518 247 | 14.611 248 | 1 249 | 05:03:18 250 | 251 | 252 | 1.73694 253 | 1.73737 254 | 1.73896 255 | 1.72046 256 | 0 257 | 05:03:23 258 | 259 | 260 | 2.95597 261 | 2.95691 262 | 2.96064 263 | 2.95405 264 | -1 265 | 05:03:23 266 | 267 | 268 | 3.2975 269 | 3.29938 270 | 3.30765 271 | 3.2923 272 | -1 273 | 05:03:23 274 | 275 | 276 | 0.71671 277 | 0.71741 278 | 0.71791 279 | 0.71105 280 | 0 281 | 05:03:24 282 | 283 | 284 | 0.75197 285 | 0.75267 286 | 0.75339 287 | 0.74928 288 | 0 289 | 05:03:24 290 | 291 | 292 | 0.95293 293 | 0.95332 294 | 0.95396 295 | 0.94857 296 | 0 297 | 05:03:22 298 | 299 | 300 | 18456.0 301 | 18458.0 302 | 18469.0 303 | 18391.0 304 | -1 305 | 05:03:01 306 | 307 | 308 | 2176.32 309 | 2176.82 310 | 2178.65 311 | 2169.07 312 | -1 313 | 05:02:52 314 | 315 | 316 | 4788.7 317 | 4789.7 318 | 4794.6 319 | 4770.1 320 | -1 321 | 05:02:02 322 | 323 | 324 | 6801.3 325 | 6802.3 326 | 6827.8 327 | 6784.5 328 | 1 329 | 05:03:23 330 | 331 | 332 | 10663.05 333 | 10663.95 334 | 10680.65 335 | 10587.05 336 | -1 337 | 05:03:22 338 | 339 | 340 | 8839.0 341 | 8847.0 342 | 8855.0 343 | 8718.0 344 | -1 345 | 05:03:23 346 | 347 | 348 | 4485.0 349 | 4486.0 350 | 4492.5 351 | 4436.5 352 | -1 353 | 05:03:21 354 | 355 | 356 | 23210.0 357 | 23220.0 358 | 23220.0 359 | 22825.0 360 | 1 361 | 04:28:49 362 | 363 | 364 | 16998.5 365 | 17008.5 366 | 17033.5 367 | 16841.0 368 | 1 369 | 05:02:54 370 | 371 | 372 | 5424.0 373 | 5425.0 374 | 5432.0 375 | 5401.0 376 | 0 377 | 05:01:08 378 | 379 | 380 | 44.77 381 | 44.82 382 | 45.096 383 | 44.634 384 | -1 385 | 05:02:56 386 | 387 | 388 | 46.91 389 | 46.96 390 | 47.265 391 | 46.76 392 | -1 393 | 05:03:18 394 | 395 | 396 | 1305.55 397 | 1305.97 398 | 1311.93 399 | 1304.25 400 | 0 401 | 05:03:21 402 | 403 | 404 | 18.642 405 | 18.685 406 | 18.818 407 | 18.57 408 | -1 409 | 05:03:18 410 | 411 | 412 | 11986.4 413 | 11988.7 414 | 12015.8 415 | 11980.7 416 | 1 417 | 05:03:23 418 | 419 | 420 | 3.77512 421 | 3.77907 422 | 3.79421 423 | 3.7645 424 | -1 425 | 05:01:06 426 | 427 | 428 | 34.956 429 | 35.023 430 | 35.06 431 | 34.772 432 | 0 433 | 05:03:23 434 | 435 | 436 | 6.68773 437 | 6.69007 438 | 6.6958 439 | 6.68526 440 | -1 441 | 05:03:19 442 | 443 | 444 | 2.8575 445 | 2.8675 446 | 2.886 447 | 2.8565 448 | -1 449 | 05:03:15 450 | 451 | 452 | 2.08675 453 | 2.08875 454 | 2.09825 455 | 2.07725 456 | -1 457 | 05:03:22 458 | 459 | 460 | 3050.0 461 | 3051.0 462 | 3056.5 463 | 3021.5 464 | 1 465 | 05:03:18 466 | 467 | 468 | 167.08 469 | 167.11 470 | 167.32 471 | 166.94 472 | 1 473 | 05:03:16 474 | 475 | 476 | -------------------------------------------------------------------------------- /data/^DJI.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/^DJI.mpack -------------------------------------------------------------------------------- /data/^GSPC.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/^GSPC.mpack -------------------------------------------------------------------------------- /data/^IXIC.mpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/^IXIC.mpack -------------------------------------------------------------------------------- /data/etfreit.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/etfreit.zip -------------------------------------------------------------------------------- /data/indices_I101_1d_2016.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/indices_I101_1d_2016.csv -------------------------------------------------------------------------------- /data/indices_I102_1d_2016.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/indices_I102_1d_2016.csv -------------------------------------------------------------------------------- /data/indices_I103_1d_2016.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/indices_I103_1d_2016.csv -------------------------------------------------------------------------------- /data/indices_I133_1d_2016.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drillan/pyconjp2016/5bdb505d5b673d2dc49ea139cc311c0b687931e4/data/indices_I133_1d_2016.csv --------------------------------------------------------------------------------