├── 1) Monte Carlo valuation of European call option in py2.ipynb ├── 2) mcs_vector_numpy in py27.ipynb ├── 3) Data Visualisation.ipynb ├── 4) Financial Time Series in Py27.ipynb ├── 5) Input-Output Operations (I-O) in py27.ipynb ├── 6) Mathematical Tools.ipynb ├── 7) Excel Spreadsheet Interaction in Py27.ipynb ├── 8) Object Orientation and Graphical User Interfaces in Py27.ipynb ├── 9) Web Integeration.ipynb ├── A) Data Types and Structure in Py27.ipynb ├── C) Dates and Times.ipynb ├── README.md ├── cash_flow_series_GUI.PNG ├── cash_flow_series_GUI.py ├── es.txt ├── es50.txt ├── extended_short_rate_GUI.PNG ├── extended_short_rate_GUI.py ├── short rate GUI.PNG ├── short_rate_GUI.py ├── stock.csv ├── tradechat ├── static │ └── style.css ├── table.sql ├── templates │ ├── layout.html │ ├── login.html │ ├── register.html │ └── show_entries.html ├── tradechat.db └── tradechat.py └── vs.txt /1) Monte Carlo valuation of European call option in py2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Monte Carlo valuation of European call option\n", 8 | "in Black-Scholes-Merton model" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 6, 14 | "metadata": {}, 15 | "outputs": [ 16 | { 17 | "name": "stdout", 18 | "output_type": "stream", 19 | "text": [ 20 | "Value of the European Call Option 7.996\n" 21 | ] 22 | } 23 | ], 24 | "source": [ 25 | "\n", 26 | "import numpy as np\n", 27 | "\n", 28 | "# Parameter Values\n", 29 | "S0 = 100. # initial index level\n", 30 | "K = 105. # strike price\n", 31 | "T = 1.0 # time-to-maturity\n", 32 | "r = 0.05 # riskless short rate\n", 33 | "sigma = 0.2 # volatility\n", 34 | "\n", 35 | "I = 100000 # number of simulations\n", 36 | "\n", 37 | "# Valuation Algorithm\n", 38 | "z = np.random.standard_normal(I) # pseudorandom numbers\n", 39 | "ST = S0 * np.exp((r - 0.5 * sigma ** 2) * T + sigma * np.sqrt(T) * z)\n", 40 | " # index values at maturity\n", 41 | "hT = np.maximum(ST - K, 0) # inner values at maturity\n", 42 | "C0 = np.exp(-r * T) * np.sum(hT) / I # Monte Carlo estimator\n", 43 | "\n", 44 | "# Result Output\n", 45 | "print \"Value of the European Call Option %5.3f\" % C0" 46 | ] 47 | } 48 | ], 49 | "metadata": { 50 | "kernelspec": { 51 | "display_name": "Python [conda env:py27]", 52 | "language": "python", 53 | "name": "conda-env-py27-py" 54 | }, 55 | "language_info": { 56 | "codemirror_mode": { 57 | "name": "ipython", 58 | "version": 2 59 | }, 60 | "file_extension": ".py", 61 | "mimetype": "text/x-python", 62 | "name": "python", 63 | "nbconvert_exporter": "python", 64 | "pygments_lexer": "ipython2", 65 | "version": "2.7.15" 66 | } 67 | }, 68 | "nbformat": 4, 69 | "nbformat_minor": 2 70 | } 71 | -------------------------------------------------------------------------------- /2) mcs_vector_numpy in py27.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Monte Carlo valuation of European call option with NumPy" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 37, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "European Option Value 8.037\n", 20 | "Duration in Seconds 2.519\n" 21 | ] 22 | } 23 | ], 24 | "source": [ 25 | "# mcs_vector_numpy.py\n", 26 | "import math\n", 27 | "import numpy as np\n", 28 | "from time import time\n", 29 | "\n", 30 | "np.random.seed(20000)\n", 31 | "t0 = time()\n", 32 | "\n", 33 | "# Parameters\n", 34 | "S0 = 100.; K = 105.; T = 1.0; r = 0.05; sigma = 0.2\n", 35 | "M = 50; dt = T / M; I = 250000\n", 36 | "\n", 37 | "# Simulating I paths with M time steps\n", 38 | "S = np.zeros((M + 1, I))\n", 39 | "S[0] = S0\n", 40 | "for t in range(1, M + 1):\n", 41 | " z = np.random.standard_normal(I) # pseudorandom numbers\n", 42 | " S[t] = S[t - 1] * np.exp((r - 0.5 * sigma ** 2) * dt\n", 43 | " + sigma * math.sqrt(dt) * z)\n", 44 | " # vectorized operation per time step over all paths\n", 45 | "\n", 46 | "# Calculating the Monte Carlo estimator\n", 47 | "C0 = math.exp(-r * T) * np.sum(np.maximum(S[-1] - K, 0)) / I\n", 48 | "\n", 49 | "# Results output\n", 50 | "tnp1 = time() - t0\n", 51 | "print \"European Option Value %7.3f\" % C0\n", 52 | "print \"Duration in Seconds %7.3f\" % tnp1" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 39, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "European Option Value 8.037\n", 65 | "Duration in Seconds 2.208\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "%run mcs_vector_numpy.py" 71 | ] 72 | } 73 | ], 74 | "metadata": { 75 | "kernelspec": { 76 | "display_name": "Python [conda env:py27]", 77 | "language": "python", 78 | "name": "conda-env-py27-py" 79 | }, 80 | "language_info": { 81 | "codemirror_mode": { 82 | "name": "ipython", 83 | "version": 2 84 | }, 85 | "file_extension": ".py", 86 | "mimetype": "text/x-python", 87 | "name": "python", 88 | "nbconvert_exporter": "python", 89 | "pygments_lexer": "ipython2", 90 | "version": "2.7.15" 91 | } 92 | }, 93 | "nbformat": 4, 94 | "nbformat_minor": 2 95 | } 96 | -------------------------------------------------------------------------------- /6) Mathematical Tools.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Approximation " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "%matplotlib inline" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "def f(x):\n", 28 | " return np.sin(x) + 0.5 * x" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "x = np.linspace(-2 * np.pi, 2 * np.pi, 50)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 4, 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "data": { 47 | "text/plain": [ 48 | "Text(0,0.5,'f(x)')" 49 | ] 50 | }, 51 | "execution_count": 4, 52 | "metadata": {}, 53 | "output_type": "execute_result" 54 | }, 55 | { 56 | "data": { 57 | "image/png": "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\n", 58 | "text/plain": [ 59 | "
" 60 | ] 61 | }, 62 | "metadata": {}, 63 | "output_type": "display_data" 64 | } 65 | ], 66 | "source": [ 67 | "plt.plot(x, f(x), 'b')\n", 68 | "plt.grid(True)\n", 69 | "plt.xlabel('x')\n", 70 | "plt.ylabel('f(x)')" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "### REGRESSION" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 6, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "reg = np.polyfit(x, f(x), deg=1)\n", 87 | "ry = np.polyval(reg, x)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 7, 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "Text(0,0.5,'f(x)')" 99 | ] 100 | }, 101 | "execution_count": 7, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | }, 105 | { 106 | "data": { 107 | "image/png": "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oUWLFrz88suAnTzv4osvJj4+nmbNmvHf//6XnJwc+vbtS7NmzWjevDnPPvssALfddhtvv/02AIsXL6ZVq1Y0b96cXr16ceTIEQAaNGjA0KFDSUhIoHnz5mze7OmB4kp5zuuvw7p1MKlnOtGdL6XhtGm2vyD/tSkpCQYNcjQZQFlMCMc6aB59tOAffAlt2bKFHj168MknnzB16lQWLVrE6tWrad26NePGjePw4cPcddddzJ8/n88//5y9e/ee8P6MjAzee+89Zs2axdSpU6lWrRorV65k5cqVTJkyhe3btzNr1iw6derEmjVrWLt2LfHx8axZs4Y9e/awfv161q1bx+23337Cfg8fPsxtt93Gm2++ybp168jOzmbixInHX69ZsyarV6+mX79+PPPMMyH5WSilinb4sL0MJSZCh6g0OHoUk5vreD+BP2UvITjUQVO/fn3atWvH8uXL2bhxI+3btyc+Pp7XXnuNnTt3snnzZho1akRD3/DDm2+++YT3d+nShYoVKwKwcOFCZsyYQXx8POeffz779u3jm2++oU2bNkyfPp1hw4axbt06qlSpQqNGjdi+fTv9+/dnwYIFVK1a9YT9btmyhYYNG3LOOecA0LNnTz777LPjr19//fUAJCYmnjAFh1LKIb4WijkD0/nuO3j6aSiXkgwxMeSWK+d4P4E/Za8P4VgHzbESrhD94CtVqgTYPoSOHTvyxhtvnPD6l19+GdD7j+3j+eefp1OnTidt99lnn/Hhhx/SvXt3Bg4cSI8ePVi2bBnLli3jxRdf5K233mLatGkn7MufChUqABAVFUV2drb/k1RKBcfXQiFHj3JtTgz3n7+YDh2SANtPsGPaNBr16uV401Bhyt4dwrEOmuHDHannbdeuHUuXLmXr1q0AHDp0iK+//prGjRuzbdu245/C33zzzUL30alTJyZOnEhWVhYAX3/9Nb///js7d+6kdu3a9O7dmzvuuIPVq1fz888/k5ubyw033MDw4cNZvXr1Cftq3LgxO3bsOB7PzJkzueSSS0J6zkqpAPlaKExODtEc5aG2aX++lpTEd926uZYMoCzeIYD9gTv0Q69VqxavvvoqN9988/HO2xEjRnDOOefw0ksv0blzZ2rWrElbP2vi3XnnnezYsYOEhAREhFq1avHuu++SlpbGmDFjiI6OpnLlysyYMYMffviBnj17Hn/v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\n", 108 | "text/plain": [ 109 | "
" 110 | ] 111 | }, 112 | "metadata": {}, 113 | "output_type": "display_data" 114 | } 115 | ], 116 | "source": [ 117 | "plt.plot(x, f(x), 'b', label='f(x)')\n", 118 | "plt.plot(x, ry, 'r.', label='regression')\n", 119 | "plt.legend(loc=0)\n", 120 | "plt.grid(True)\n", 121 | "plt.xlabel('x')\n", 122 | "plt.ylabel('f(x)')" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 8, 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "reg = np.polyfit(x, f(x), deg=5)\n", 132 | "ry = np.polyval(reg, x)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 10, 138 | "metadata": {}, 139 | "outputs": [ 140 | { 141 | "data": { 142 | "text/plain": [ 143 | "Text(0,0.5,'f(x)')" 144 | ] 145 | }, 146 | "execution_count": 10, 147 | "metadata": {}, 148 | "output_type": "execute_result" 149 | }, 150 | { 151 | "data": { 152 | "image/png": "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\n", 153 | "text/plain": [ 154 | "
" 155 | ] 156 | }, 157 | "metadata": {}, 158 | "output_type": "display_data" 159 | } 160 | ], 161 | "source": [ 162 | "plt.plot(x, f(x), 'b', label='f(x)')\n", 163 | "plt.plot(x, ry, 'r.', label='regression')\n", 164 | "plt.legend(loc=0)\n", 165 | "plt.grid(True)\n", 166 | "plt.xlabel('x')\n", 167 | "plt.ylabel('f(x)')" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 11, 173 | "metadata": {}, 174 | "outputs": [ 175 | { 176 | "data": { 177 | "text/plain": [ 178 | "Text(0,0.5,'f(x)')" 179 | ] 180 | }, 181 | "execution_count": 11, 182 | "metadata": {}, 183 | "output_type": "execute_result" 184 | }, 185 | { 186 | "data": { 187 | "image/png": "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PPbYY4BbPO+kk06iU6dOdOjQgffee49oNMoVV1xBhw4d6NixIw888AAAF198MS+//DIA4XCYY445ho4dO3LJJZdQUlICQHZ2NqNGjaJz58507NiRzz/39UJxpXznuedgxQp3MVow6HU0qZgQYvf7cttt7n/jlBS++OILLrroIubPn89TTz3FggULWLZsGV26dOH++++nuLiYyy+/nHnz5vH++++zYcOGHd5fUFDAnDlzeP7553nqqado2rQpH330ER999BFPPPEEX3/9Nc8//zw9e/Zk+fLlfPLJJ3Tq1Inly5ezfv16PvvsM1asWMGgQYN2OG5xcTEXX3wxL774IitWrKCsrIzJkydvf75Zs2YsW7aMoUOHct9998XlZ6GUqlpxsXsZysmBZFmalHoJwbbduuJx3myiTZs2dO/encWLF7Nq1SqOP/54OnXqxDPPPMM333zD559/Trt27WgbW354wQUX7PD+Pn360KBBAwDefvttpk+fTqdOnTj22GPZuHEj//nPf+jatSvTpk1j9OjRrFixgsaNG9OuXTu+/vprrrnmGt58802aNGmyw3G/+OIL2rZty6GHHgrAwIEDeffdd7c/37dvXwBycnJ2KMGhlEqsRx5x90m+5x6o4Qhz3KXeHEIo5PbN4rzZRMOGDQF3DuHUU0/lhRde2OH5jz/+uFrv33aMhx56iJ49e/7hde+++y6vv/46AwYM4MYbb+Siiy5i0aJFLFq0iEceeYSXXnqJqVOn7nCs3cnMzAQgEAhQVla2+0YqpWrPcdg6z+btiSF69rRIpp10Uy8hWJa7J2nFzSbiuJdA9+7dueqqq/jqq684+OCD+e233ygsLOTwww9nzZo1rF27luzsbF588cVKj9GzZ08mT55Mjx49yMjI4Msvv+TAAw/kp59+4sADD2Tw4MH8+uuvLFu2jDPOOIPy8nLOO+88DjroIC6++OIdjnX44Yezdu3a7fHMmDGDk08+OW7tVUrtgdiQdbA4wiwJsu5v3pSoqEzqJQRwk0CC7vVt3rw5Tz/9NBdccMH2yds777yTQw89lEcffZRevXrRrFkzunXrVukxLrvsMtauXUvnzp0REZo3b87s2bOxbZt7772XjIwMGjVqxPTp01m3bh0DBw7c/t5x48btcKysrCymTZtGv379KCsro2vXrlxxxRUJabtSqgq2jUQiBMQt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\n", 188 | "text/plain": [ 189 | "
" 190 | ] 191 | }, 192 | "metadata": {}, 193 | "output_type": "display_data" 194 | } 195 | ], 196 | "source": [ 197 | "reg = np.polyfit(x, f(x), 7)\n", 198 | "ry = np.polyval(reg, x)\n", 199 | "plt.plot(x, f(x), 'b', label='f(x)')\n", 200 | "plt.plot(x, ry, 'r.', label='regression')\n", 201 | "plt.legend(loc=0)\n", 202 | "plt.grid(True)\n", 203 | "plt.xlabel('x')\n", 204 | "plt.ylabel('f(x)')" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": {}, 210 | "source": [ 211 | "### A brief check reveals that the result is not perfect:" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 12, 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "data": { 221 | "text/plain": [ 222 | "False" 223 | ] 224 | }, 225 | "execution_count": 12, 226 | "metadata": {}, 227 | "output_type": "execute_result" 228 | } 229 | ], 230 | "source": [ 231 | "np.allclose(f(x), ry)" 232 | ] 233 | }, 234 | { 235 | "cell_type": "markdown", 236 | "metadata": {}, 237 | "source": [ 238 | "### the mean squared error (MSE) is not too large—at least, over this narrow range of x values:" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "execution_count": 13, 244 | "metadata": {}, 245 | "outputs": [ 246 | { 247 | "data": { 248 | "text/plain": [ 249 | "0.0017769134759517793" 250 | ] 251 | }, 252 | "execution_count": 13, 253 | "metadata": {}, 254 | "output_type": "execute_result" 255 | } 256 | ], 257 | "source": [ 258 | "np.sum((f(x) - ry) ** 2) / len(x)" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "### Individual basis functions" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 14, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "matrix = np.zeros((3 + 1, len(x)))\n", 275 | "matrix[3, :] = x ** 3\n", 276 | "matrix[2, :] = x ** 2\n", 277 | "matrix[1, :] = x\n", 278 | "matrix[0, :] = 1" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 15, 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "#### The sublibrary numpy.linalg provides the function lstsq to solve least-squares optimization problems" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 16, 293 | "metadata": {}, 294 | "outputs": [ 295 | { 296 | "name": "stderr", 297 | "output_type": "stream", 298 | "text": [ 299 | "C:\\ProgramData\\Anaconda3\\envs\\py27\\lib\\site-packages\\ipykernel\\__main__.py:1: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n", 300 | "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n", 301 | " if __name__ == '__main__':\n" 302 | ] 303 | } 304 | ], 305 | "source": [ 306 | "reg = np.linalg.lstsq(matrix.T, f(x))[0]" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 17, 312 | "metadata": {}, 313 | "outputs": [ 314 | { 315 | "data": { 316 | "text/plain": [ 317 | "array([ 1.52685368e-14, 5.62777448e-01, -1.11022302e-15, -5.43553615e-03])" 318 | ] 319 | }, 320 | "execution_count": 17, 321 | "metadata": {}, 322 | "output_type": "execute_result" 323 | } 324 | ], 325 | "source": [ 326 | "reg" 327 | ] 328 | } 329 | ], 330 | "metadata": { 331 | "kernelspec": { 332 | "display_name": "Python [conda env:py27]", 333 | "language": "python", 334 | "name": "conda-env-py27-py" 335 | }, 336 | "language_info": { 337 | "codemirror_mode": { 338 | "name": "ipython", 339 | "version": 2 340 | }, 341 | "file_extension": ".py", 342 | "mimetype": "text/x-python", 343 | "name": "python", 344 | "nbconvert_exporter": "python", 345 | "pygments_lexer": "ipython2", 346 | "version": "2.7.15" 347 | } 348 | }, 349 | "nbformat": 4, 350 | "nbformat_minor": 2 351 | } 352 | -------------------------------------------------------------------------------- /7) Excel Spreadsheet Interaction in Py27.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Basic Spreadsheet Interaction" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np\n", 17 | "import pandas as pd\n", 18 | "import xlrd, xlwt\n", 19 | "import xlsxwriter\n", 20 | "path = 'C:/Users/Taymour/Python For Finance/'" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "wb = xlwt.Workbook()" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 3, 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "data": { 39 | "text/plain": [ 40 | "" 41 | ] 42 | }, 43 | "execution_count": 3, 44 | "metadata": {}, 45 | "output_type": "execute_result" 46 | } 47 | ], 48 | "source": [ 49 | "wb" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 4, 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "" 61 | ] 62 | }, 63 | "execution_count": 4, 64 | "metadata": {}, 65 | "output_type": "execute_result" 66 | } 67 | ], 68 | "source": [ 69 | "wb.add_sheet('first_sheet', cell_overwrite_ok=True)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 5, 75 | "metadata": {}, 76 | "outputs": [ 77 | { 78 | "data": { 79 | "text/plain": [ 80 | "0" 81 | ] 82 | }, 83 | "execution_count": 5, 84 | "metadata": {}, 85 | "output_type": "execute_result" 86 | } 87 | ], 88 | "source": [ 89 | "wb.get_active_sheet()" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 6, 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "" 101 | ] 102 | }, 103 | "execution_count": 6, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "ws_1 = wb.get_sheet(0)\n", 110 | "ws_1" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 7, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "ws_2 = wb.add_sheet('second_sheet')" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 8, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "data = np.arange(1, 65).reshape((8, 8))" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 9, 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "data": { 138 | "text/plain": [ 139 | "array([[ 1, 2, 3, 4, 5, 6, 7, 8],\n", 140 | " [ 9, 10, 11, 12, 13, 14, 15, 16],\n", 141 | " [17, 18, 19, 20, 21, 22, 23, 24],\n", 142 | " [25, 26, 27, 28, 29, 30, 31, 32],\n", 143 | " [33, 34, 35, 36, 37, 38, 39, 40],\n", 144 | " [41, 42, 43, 44, 45, 46, 47, 48],\n", 145 | " [49, 50, 51, 52, 53, 54, 55, 56],\n", 146 | " [57, 58, 59, 60, 61, 62, 63, 64]])" 147 | ] 148 | }, 149 | "execution_count": 9, 150 | "metadata": {}, 151 | "output_type": "execute_result" 152 | } 153 | ], 154 | "source": [ 155 | "data" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 10, 161 | "metadata": {}, 162 | "outputs": [], 163 | "source": [ 164 | "ws_1.write(0, 0, 100) # write 100 in cell \"A1\"" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 11, 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "for c in range(data.shape[0]):\n", 174 | " for r in range(data.shape[1]):\n", 175 | " ws_1.write(r, c, data[c, r])\n", 176 | " ws_2.write(r, c, data[r, c])" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 12, 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "wb.save(path + 'workbook.xls')" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "## GENERATING WORKBOOKS (.XSLX)" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 13, 198 | "metadata": {}, 199 | "outputs": [], 200 | "source": [ 201 | "wb = xlsxwriter.Workbook(path + 'workbook.xlsx')" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 14, 207 | "metadata": {}, 208 | "outputs": [], 209 | "source": [ 210 | "ws_1 = wb.add_worksheet('first_sheet')\n", 211 | "ws_2 = wb.add_worksheet('second_sheet')" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 15, 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "for c in range(data.shape[0]):\n", 221 | " for r in range(data.shape[1]):\n", 222 | " ws_1.write(r, c, data[c, r])\n", 223 | " ws_2.write(r, c, data[r, c])" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 16, 229 | "metadata": {}, 230 | "outputs": [], 231 | "source": [ 232 | "wb.close()" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 17, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | "wb = xlsxwriter.Workbook(path + 'chart.xlsx')\n", 242 | "ws = wb.add_worksheet()\n", 243 | "\n", 244 | "# write cumsum of random values in first column\n", 245 | "values = np.random.standard_normal(15).cumsum()\n", 246 | "ws.write_column('A1', values)\n", 247 | "\n", 248 | "# create a new chart object\n", 249 | "chart = wb.add_chart({'type': 'line'})\n", 250 | "\n", 251 | "# add a series to the chart\n", 252 | "chart.add_series({'values': '=Sheet1!$A$1:$A$15',\n", 253 | " 'marker': {'type': 'diamond'},})\n", 254 | "# series with markers (here: diamond)\n", 255 | "\n", 256 | "# insert the chart\n", 257 | "ws.insert_chart('C1', chart)\n", 258 | "\n", 259 | "wb.close()" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": {}, 265 | "source": [ 266 | "## READING FROM WORKBOOKS" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 18, 272 | "metadata": {}, 273 | "outputs": [ 274 | { 275 | "data": { 276 | "text/plain": [ 277 | "" 278 | ] 279 | }, 280 | "execution_count": 18, 281 | "metadata": {}, 282 | "output_type": "execute_result" 283 | } 284 | ], 285 | "source": [ 286 | "book = xlrd.open_workbook(path + 'workbook.xlsx')\n", 287 | "book" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 19, 293 | "metadata": {}, 294 | "outputs": [ 295 | { 296 | "data": { 297 | "text/plain": [ 298 | "[u'first_sheet', u'second_sheet']" 299 | ] 300 | }, 301 | "execution_count": 19, 302 | "metadata": {}, 303 | "output_type": "execute_result" 304 | } 305 | ], 306 | "source": [ 307 | "book.sheet_names()" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 20, 313 | "metadata": {}, 314 | "outputs": [ 315 | { 316 | "data": { 317 | "text/plain": [ 318 | "" 319 | ] 320 | }, 321 | "execution_count": 20, 322 | "metadata": {}, 323 | "output_type": "execute_result" 324 | } 325 | ], 326 | "source": [ 327 | "sheet_1 = book.sheet_by_name('first_sheet')\n", 328 | "sheet_2 = book.sheet_by_index(1)\n", 329 | "sheet_1" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 21, 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "data": { 339 | "text/plain": [ 340 | "u'second_sheet'" 341 | ] 342 | }, 343 | "execution_count": 21, 344 | "metadata": {}, 345 | "output_type": "execute_result" 346 | } 347 | ], 348 | "source": [ 349 | "sheet_2.name" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 22, 355 | "metadata": {}, 356 | "outputs": [ 357 | { 358 | "data": { 359 | "text/plain": [ 360 | "(8, 8)" 361 | ] 362 | }, 363 | "execution_count": 22, 364 | "metadata": {}, 365 | "output_type": "execute_result" 366 | } 367 | ], 368 | "source": [ 369 | "sheet_1.ncols, sheet_1.nrows" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 26, 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "data": { 379 | "text/plain": [ 380 | "1.0" 381 | ] 382 | }, 383 | "execution_count": 26, 384 | "metadata": {}, 385 | "output_type": "execute_result" 386 | } 387 | ], 388 | "source": [ 389 | "cl = sheet_1.cell(0, 0)\n", 390 | "cl.value" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 28, 396 | "metadata": {}, 397 | "outputs": [ 398 | { 399 | "data": { 400 | "text/plain": [ 401 | "2" 402 | ] 403 | }, 404 | "execution_count": 28, 405 | "metadata": {}, 406 | "output_type": "execute_result" 407 | } 408 | ], 409 | "source": [ 410 | "cl.ctype" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 29, 416 | "metadata": {}, 417 | "outputs": [ 418 | { 419 | "data": { 420 | "text/plain": [ 421 | "[number:25.0,\n", 422 | " number:26.0,\n", 423 | " number:27.0,\n", 424 | " number:28.0,\n", 425 | " number:29.0,\n", 426 | " number:30.0,\n", 427 | " number:31.0,\n", 428 | " number:32.0]" 429 | ] 430 | }, 431 | "execution_count": 29, 432 | "metadata": {}, 433 | "output_type": "execute_result" 434 | } 435 | ], 436 | "source": [ 437 | "sheet_2.row(3)" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": 30, 443 | "metadata": {}, 444 | "outputs": [ 445 | { 446 | "data": { 447 | "text/plain": [ 448 | "[number:4.0,\n", 449 | " number:12.0,\n", 450 | " number:20.0,\n", 451 | " number:28.0,\n", 452 | " number:36.0,\n", 453 | " number:44.0,\n", 454 | " number:52.0,\n", 455 | " number:60.0]" 456 | ] 457 | }, 458 | "execution_count": 30, 459 | "metadata": {}, 460 | "output_type": "execute_result" 461 | } 462 | ], 463 | "source": [ 464 | "sheet_2.col(3)" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 31, 470 | "metadata": {}, 471 | "outputs": [ 472 | { 473 | "data": { 474 | "text/plain": [ 475 | "[28.0, 29.0, 30.0, 31.0]" 476 | ] 477 | }, 478 | "execution_count": 31, 479 | "metadata": {}, 480 | "output_type": "execute_result" 481 | } 482 | ], 483 | "source": [ 484 | "sheet_1.col_values(3, start_rowx=3, end_rowx=7)" 485 | ] 486 | }, 487 | { 488 | "cell_type": "code", 489 | "execution_count": 32, 490 | "metadata": {}, 491 | "outputs": [ 492 | { 493 | "data": { 494 | "text/plain": [ 495 | "[28.0, 36.0, 44.0, 52.0]" 496 | ] 497 | }, 498 | "execution_count": 32, 499 | "metadata": {}, 500 | "output_type": "execute_result" 501 | } 502 | ], 503 | "source": [ 504 | "sheet_1.row_values(3, start_colx=3, end_colx=7)" 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": 33, 510 | "metadata": {}, 511 | "outputs": [ 512 | { 513 | "name": "stdout", 514 | "output_type": "stream", 515 | "text": [ 516 | "1 2 3 4 5 6 7 8\n", 517 | "9 10 11 12 13 14 15 16\n", 518 | "17 18 19 20 21 22 23 24\n", 519 | "25 26 27 28 29 30 31 32\n", 520 | "33 34 35 36 37 38 39 40\n", 521 | "41 42 43 44 45 46 47 48\n", 522 | "49 50 51 52 53 54 55 56\n", 523 | "57 58 59 60 61 62 63 64\n" 524 | ] 525 | } 526 | ], 527 | "source": [ 528 | "for c in range(sheet_1.ncols):\n", 529 | " for r in range(sheet_1.nrows):\n", 530 | " print '%i' % sheet_1.cell(r, c).value,\n", 531 | " print" 532 | ] 533 | }, 534 | { 535 | "cell_type": "markdown", 536 | "metadata": {}, 537 | "source": [ 538 | "## USING OPENPYXL" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": 38, 544 | "metadata": {}, 545 | "outputs": [], 546 | "source": [ 547 | "import openpyxl as oxl" 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "execution_count": 39, 553 | "metadata": {}, 554 | "outputs": [], 555 | "source": [ 556 | "wb = oxl.Workbook()" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": 40, 562 | "metadata": {}, 563 | "outputs": [], 564 | "source": [ 565 | "ws = wb.create_sheet(index=0, title='oxl_sheet')" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": 47, 571 | "metadata": {}, 572 | "outputs": [], 573 | "source": [ 574 | "wb = oxl.load_workbook(path + 'workbook.xlsx')" 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "execution_count": 48, 580 | "metadata": {}, 581 | "outputs": [ 582 | { 583 | "name": "stderr", 584 | "output_type": "stream", 585 | "text": [ 586 | "C:\\ProgramData\\Anaconda3\\envs\\py27\\lib\\site-packages\\ipykernel\\__main__.py:1: DeprecationWarning: Call to deprecated function get_active_sheet (Use the .active property).\n", 587 | " if __name__ == '__main__':\n" 588 | ] 589 | } 590 | ], 591 | "source": [ 592 | "ws = wb.get_active_sheet()" 593 | ] 594 | }, 595 | { 596 | "cell_type": "code", 597 | "execution_count": 49, 598 | "metadata": {}, 599 | "outputs": [], 600 | "source": [ 601 | "cell = ws['B4']" 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": 50, 607 | "metadata": {}, 608 | "outputs": [ 609 | { 610 | "data": { 611 | "text/plain": [ 612 | "'B'" 613 | ] 614 | }, 615 | "execution_count": 50, 616 | "metadata": {}, 617 | "output_type": "execute_result" 618 | } 619 | ], 620 | "source": [ 621 | "cell.column" 622 | ] 623 | }, 624 | { 625 | "cell_type": "code", 626 | "execution_count": 51, 627 | "metadata": {}, 628 | "outputs": [ 629 | { 630 | "data": { 631 | "text/plain": [ 632 | "4" 633 | ] 634 | }, 635 | "execution_count": 51, 636 | "metadata": {}, 637 | "output_type": "execute_result" 638 | } 639 | ], 640 | "source": [ 641 | "cell.row" 642 | ] 643 | }, 644 | { 645 | "cell_type": "code", 646 | "execution_count": 52, 647 | "metadata": {}, 648 | "outputs": [ 649 | { 650 | "data": { 651 | "text/plain": [ 652 | "12L" 653 | ] 654 | }, 655 | "execution_count": 52, 656 | "metadata": {}, 657 | "output_type": "execute_result" 658 | } 659 | ], 660 | "source": [ 661 | "cell.value" 662 | ] 663 | }, 664 | { 665 | "cell_type": "code", 666 | "execution_count": 53, 667 | "metadata": {}, 668 | "outputs": [ 669 | { 670 | "data": { 671 | "text/plain": [ 672 | "((,),\n", 673 | " (,),\n", 674 | " (,),\n", 675 | " (,))" 676 | ] 677 | }, 678 | "execution_count": 53, 679 | "metadata": {}, 680 | "output_type": "execute_result" 681 | } 682 | ], 683 | "source": [ 684 | "ws['B1':'B4']" 685 | ] 686 | }, 687 | { 688 | "cell_type": "code", 689 | "execution_count": 54, 690 | "metadata": {}, 691 | "outputs": [ 692 | { 693 | "name": "stdout", 694 | "output_type": "stream", 695 | "text": [ 696 | "9\n", 697 | "10\n", 698 | "11\n", 699 | "12\n" 700 | ] 701 | } 702 | ], 703 | "source": [ 704 | "for cell in ws['B1':'B4']:\n", 705 | " print cell[0].value" 706 | ] 707 | }, 708 | { 709 | "cell_type": "markdown", 710 | "metadata": {}, 711 | "source": [ 712 | "## USING PANDAS FOR READING AND WRITING" 713 | ] 714 | }, 715 | { 716 | "cell_type": "code", 717 | "execution_count": 59, 718 | "metadata": {}, 719 | "outputs": [], 720 | "source": [ 721 | "df_1 = pd.read_excel(path + 'workbook.xlsx',\n", 722 | " 'first_sheet', header=None)\n", 723 | "df_2 = pd.read_excel(path + 'workbook.xlsx',\n", 724 | " 'second_sheet', header=None)" 725 | ] 726 | }, 727 | { 728 | "cell_type": "code", 729 | "execution_count": 60, 730 | "metadata": {}, 731 | "outputs": [ 732 | { 733 | "data": { 734 | "text/plain": [ 735 | "['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']" 736 | ] 737 | }, 738 | "execution_count": 60, 739 | "metadata": {}, 740 | "output_type": "execute_result" 741 | } 742 | ], 743 | "source": [ 744 | "import string\n", 745 | "columns = []\n", 746 | "for c in range(data.shape[0]):\n", 747 | " columns.append(string.uppercase[c])\n", 748 | "columns" 749 | ] 750 | }, 751 | { 752 | "cell_type": "code", 753 | "execution_count": 61, 754 | "metadata": {}, 755 | "outputs": [], 756 | "source": [ 757 | "df_1.columns = columns\n", 758 | "df_2.columns = columns" 759 | ] 760 | }, 761 | { 762 | "cell_type": "code", 763 | "execution_count": 62, 764 | "metadata": {}, 765 | "outputs": [ 766 | { 767 | "data": { 768 | "text/html": [ 769 | "
\n", 770 | "\n", 783 | "\n", 784 | " \n", 785 | " \n", 786 | " \n", 787 | " \n", 788 | " \n", 789 | " \n", 790 | " \n", 791 | " \n", 792 | " \n", 793 | " \n", 794 | " \n", 795 | " \n", 796 | " \n", 797 | " \n", 798 | " \n", 799 | " \n", 800 | " \n", 801 | " \n", 802 | " \n", 803 | " \n", 804 | " \n", 805 | " \n", 806 | " \n", 807 | " \n", 808 | " \n", 809 | " \n", 810 | " \n", 811 | " \n", 812 | " \n", 813 | " \n", 814 | " \n", 815 | " \n", 816 | " \n", 817 | " \n", 818 | " \n", 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 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | " \n", 862 | " \n", 863 | " \n", 864 | " \n", 865 | " \n", 866 | " \n", 867 | " \n", 868 | " \n", 869 | " \n", 870 | " \n", 871 | " \n", 872 | " \n", 873 | " \n", 874 | " \n", 875 | " \n", 876 | " \n", 877 | " \n", 878 | " \n", 879 | " \n", 880 | " \n", 881 | " \n", 882 | " \n", 883 | " \n", 884 | " \n", 885 | " \n", 886 | " \n", 887 | "
ABCDEFGH
019172533414957
1210182634425058
2311192735435159
3412202836445260
4513212937455361
5614223038465462
6715233139475563
7816243240485664
\n", 888 | "
" 889 | ], 890 | "text/plain": [ 891 | " A B C D E F G H\n", 892 | "0 1 9 17 25 33 41 49 57\n", 893 | "1 2 10 18 26 34 42 50 58\n", 894 | "2 3 11 19 27 35 43 51 59\n", 895 | "3 4 12 20 28 36 44 52 60\n", 896 | "4 5 13 21 29 37 45 53 61\n", 897 | "5 6 14 22 30 38 46 54 62\n", 898 | "6 7 15 23 31 39 47 55 63\n", 899 | "7 8 16 24 32 40 48 56 64" 900 | ] 901 | }, 902 | "execution_count": 62, 903 | "metadata": {}, 904 | "output_type": "execute_result" 905 | } 906 | ], 907 | "source": [ 908 | "df_1" 909 | ] 910 | }, 911 | { 912 | "cell_type": "code", 913 | "execution_count": 63, 914 | "metadata": {}, 915 | "outputs": [ 916 | { 917 | "data": { 918 | "text/html": [ 919 | "
\n", 920 | "\n", 933 | "\n", 934 | " \n", 935 | " \n", 936 | " \n", 937 | " \n", 938 | " \n", 939 | " \n", 940 | " \n", 941 | " \n", 942 | " \n", 943 | " \n", 944 | " \n", 945 | " \n", 946 | " \n", 947 | " \n", 948 | " \n", 949 | " \n", 950 | " \n", 951 | " \n", 952 | " \n", 953 | " \n", 954 | " \n", 955 | " \n", 956 | " \n", 957 | " \n", 958 | " \n", 959 | " \n", 960 | " \n", 961 | " \n", 962 | " \n", 963 | " \n", 964 | " \n", 965 | " \n", 966 | " \n", 967 | " \n", 968 | " \n", 969 | " \n", 970 | " \n", 971 | " \n", 972 | " \n", 973 | " \n", 974 | " \n", 975 | " \n", 976 | " \n", 977 | " \n", 978 | " \n", 979 | " \n", 980 | " \n", 981 | " \n", 982 | " \n", 983 | " \n", 984 | " \n", 985 | " \n", 986 | " \n", 987 | " \n", 988 | " \n", 989 | " \n", 990 | " \n", 991 | " \n", 992 | " \n", 993 | " \n", 994 | " \n", 995 | " \n", 996 | " \n", 997 | " \n", 998 | " \n", 999 | " \n", 1000 | " \n", 1001 | " \n", 1002 | " \n", 1003 | " \n", 1004 | " \n", 1005 | " \n", 1006 | " \n", 1007 | " \n", 1008 | " \n", 1009 | " \n", 1010 | " \n", 1011 | " \n", 1012 | " \n", 1013 | " \n", 1014 | " \n", 1015 | " \n", 1016 | " \n", 1017 | " \n", 1018 | " \n", 1019 | " \n", 1020 | " \n", 1021 | " \n", 1022 | " \n", 1023 | " \n", 1024 | " \n", 1025 | " \n", 1026 | " \n", 1027 | " \n", 1028 | " \n", 1029 | " \n", 1030 | " \n", 1031 | " \n", 1032 | " \n", 1033 | " \n", 1034 | " \n", 1035 | " \n", 1036 | " \n", 1037 | "
ABCDEFGH
012345678
1910111213141516
21718192021222324
32526272829303132
43334353637383940
54142434445464748
64950515253545556
75758596061626364
\n", 1038 | "
" 1039 | ], 1040 | "text/plain": [ 1041 | " A B C D E F G H\n", 1042 | "0 1 2 3 4 5 6 7 8\n", 1043 | "1 9 10 11 12 13 14 15 16\n", 1044 | "2 17 18 19 20 21 22 23 24\n", 1045 | "3 25 26 27 28 29 30 31 32\n", 1046 | "4 33 34 35 36 37 38 39 40\n", 1047 | "5 41 42 43 44 45 46 47 48\n", 1048 | "6 49 50 51 52 53 54 55 56\n", 1049 | "7 57 58 59 60 61 62 63 64" 1050 | ] 1051 | }, 1052 | "execution_count": 63, 1053 | "metadata": {}, 1054 | "output_type": "execute_result" 1055 | } 1056 | ], 1057 | "source": [ 1058 | "df_2" 1059 | ] 1060 | }, 1061 | { 1062 | "cell_type": "markdown", 1063 | "metadata": {}, 1064 | "source": [ 1065 | "# Scripting Excel with Python Using DataNitro Add-ins" 1066 | ] 1067 | }, 1068 | { 1069 | "cell_type": "code", 1070 | "execution_count": null, 1071 | "metadata": {}, 1072 | "outputs": [], 1073 | "source": [ 1074 | "#\n", 1075 | "# Plotting with DataNitro in Excel\n", 1076 | "# dn_plotting.py\n", 1077 | "#\n", 1078 | "import pandas.io.data as web\n", 1079 | "import nitroplot as nplt\n", 1080 | " # wrapper for matplotlib.pyplot (plt)\n", 1081 | "\n", 1082 | "# make a new workbook\n", 1083 | "\n", 1084 | "wb = new_wkbk()\n", 1085 | "active_wkbk(wb)\n", 1086 | "rename_sheet(\"Sheet1\", \"Apple_Stock\")\n", 1087 | "\n", 1088 | "# read Apple Inc. stock data\n", 1089 | "\n", 1090 | "aapl = web.DataReader('aapl', data_source='yahoo')[['Open', 'Close']]\n", 1091 | "\n", 1092 | "# write the data to the new workbook\n", 1093 | "\n", 1094 | "Cell(\"A1\").df = aapl\n", 1095 | "\n", 1096 | "# generate matplotlib plot\n", 1097 | "\n", 1098 | "nplt.figure(figsize=(8, 4))\n", 1099 | "nplt.plot(Cell(\"A2\").vertical, Cell(\"C2\").vertical, label='AAPL')\n", 1100 | "nplt.legend(loc=0)\n", 1101 | "nplt.grid(True)\n", 1102 | "nplt.xticks(rotation=35)\n", 1103 | "\n", 1104 | "# expose plot to Excel spreadsheet\n", 1105 | "\n", 1106 | "nplt.graph()\n", 1107 | " # as plt.show()\n", 1108 | "\n", 1109 | "# save the new workbook with data and plot\n", 1110 | "\n", 1111 | "save('dn_plot.xlsx')" 1112 | ] 1113 | } 1114 | ], 1115 | "metadata": { 1116 | "kernelspec": { 1117 | "display_name": "Python [conda env:py27]", 1118 | "language": "python", 1119 | "name": "conda-env-py27-py" 1120 | }, 1121 | "language_info": { 1122 | "codemirror_mode": { 1123 | "name": "ipython", 1124 | "version": 2 1125 | }, 1126 | "file_extension": ".py", 1127 | "mimetype": "text/x-python", 1128 | "name": "python", 1129 | "nbconvert_exporter": "python", 1130 | "pygments_lexer": "ipython2", 1131 | "version": "2.7.15" 1132 | } 1133 | }, 1134 | "nbformat": 4, 1135 | "nbformat_minor": 2 1136 | } 1137 | -------------------------------------------------------------------------------- /9) Web Integeration.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import ftplib\n", 10 | "import numpy as np\n", 11 | "import pandas as pd\n", 12 | "import httplib\n", 13 | "import urllib\n", 14 | "import bokeh.plotting as bp\n", 15 | "import time\n", 16 | "import datetime as dt\n", 17 | "import requests\n", 18 | "from bokeh.objects import Glyph\n", 19 | "import os\n", 20 | "from sqlite3 import dbapi2 as sqlite3\n", 21 | "from flask import Flask, request, session, g, redirect, url_for, abort, \\\n", 22 | "render_template, flash\n", 23 | "from jinja2 import Template\n", 24 | "from IPython.display import HTML\n", 25 | "from scipy.stats import ncx2\n", 26 | "from werkzeug.wrappers import Request, Response" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 1, 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "import ftplib\n", 36 | "import numpy as np" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 11, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "import urllib" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 14, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "url = 'https://ichart.finance.yahoo.com/table.csv?g=d&ignore=.csv'\n", 55 | "url += '&s=YHOO&a=01&b=1&c=2014&d=02&e=6&f=2014'" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 20, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "url = 'https://github.com/datasets/s-and-p-500-companies/blob/master/data/constituents.csv'" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 21, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "connect = urllib.urlopen(url)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 22, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "data = connect.read()" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "# Web Plotting\n", 90 | "## STATIC PLOTS" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 1, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "import numpy as np\n", 100 | "import pandas as pd\n", 101 | "%matplotlib inline" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 2, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "url = 'https://raw.githubusercontent.com/alperenguman/csv-stock-price-processor/master/examples/table.csv'\n", 111 | "data = pd.read_csv(url, parse_dates=['Date'])" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 3, 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "data": { 121 | "text/html": [ 122 | "
\n", 123 | "\n", 136 | "\n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | "
DateOpenHighLowCloseVolumeAdj Close
02013-02-08474.00478.81468.25474.9822597100474.98
12013-02-07463.25470.00454.12468.2225163600468.22
22013-02-06456.47466.50452.58457.3521203800454.70
32013-02-05444.05459.74442.22457.8420476700455.19
42013-02-04453.91455.94442.00442.3217039900439.76
\n", 202 | "
" 203 | ], 204 | "text/plain": [ 205 | " Date Open High Low Close Volume Adj Close\n", 206 | "0 2013-02-08 474.00 478.81 468.25 474.98 22597100 474.98\n", 207 | "1 2013-02-07 463.25 470.00 454.12 468.22 25163600 468.22\n", 208 | "2 2013-02-06 456.47 466.50 452.58 457.35 21203800 454.70\n", 209 | "3 2013-02-05 444.05 459.74 442.22 457.84 20476700 455.19\n", 210 | "4 2013-02-04 453.91 455.94 442.00 442.32 17039900 439.76" 211 | ] 212 | }, 213 | "execution_count": 3, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "data.head()" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 4, 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "" 231 | ] 232 | }, 233 | "execution_count": 4, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | }, 237 | { 238 | "data": { 239 | "image/png": "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\n", 240 | "text/plain": [ 241 | "
" 242 | ] 243 | }, 244 | "metadata": {}, 245 | "output_type": "display_data" 246 | } 247 | ], 248 | "source": [ 249 | "data.plot(x='Date', y='Close')" 250 | ] 251 | } 252 | ], 253 | "metadata": { 254 | "kernelspec": { 255 | "display_name": "Python [conda env:py27]", 256 | "language": "python", 257 | "name": "conda-env-py27-py" 258 | }, 259 | "language_info": { 260 | "codemirror_mode": { 261 | "name": "ipython", 262 | "version": 2 263 | }, 264 | "file_extension": ".py", 265 | "mimetype": "text/x-python", 266 | "name": "python", 267 | "nbconvert_exporter": "python", 268 | "pygments_lexer": "ipython2", 269 | "version": "2.7.15" 270 | } 271 | }, 272 | "nbformat": 4, 273 | "nbformat_minor": 2 274 | } 275 | -------------------------------------------------------------------------------- /C) Dates and Times.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Python" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "data": { 17 | "text/plain": [ 18 | "datetime.datetime(2018, 8, 9, 14, 36, 51, 331000)" 19 | ] 20 | }, 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "output_type": "execute_result" 24 | } 25 | ], 26 | "source": [ 27 | "import datetime as dt\n", 28 | "dt.datetime.now()" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "data": { 38 | "text/plain": [ 39 | "datetime.datetime(2018, 8, 9, 15, 0, 1, 783000)" 40 | ] 41 | }, 42 | "execution_count": 2, 43 | "metadata": {}, 44 | "output_type": "execute_result" 45 | } 46 | ], 47 | "source": [ 48 | "to = dt.datetime.today()\n", 49 | "to" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 3, 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "3" 61 | ] 62 | }, 63 | "execution_count": 3, 64 | "metadata": {}, 65 | "output_type": "execute_result" 66 | } 67 | ], 68 | "source": [ 69 | "to.weekday() # zero-based numbering; 0 = Monday" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 4, 75 | "metadata": {}, 76 | "outputs": [ 77 | { 78 | "data": { 79 | "text/plain": [ 80 | "datetime.datetime(2016, 10, 31, 10, 5, 30, 500000)" 81 | ] 82 | }, 83 | "execution_count": 4, 84 | "metadata": {}, 85 | "output_type": "execute_result" 86 | } 87 | ], 88 | "source": [ 89 | "d = dt.datetime(2016, 10, 31, 10, 5, 30, 500000)\n", 90 | "d" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 5, 96 | "metadata": {}, 97 | "outputs": [ 98 | { 99 | "name": "stdout", 100 | "output_type": "stream", 101 | "text": [ 102 | "2016-10-31 10:05:30.500000\n" 103 | ] 104 | } 105 | ], 106 | "source": [ 107 | "print d" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 7, 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "name": "stdout", 117 | "output_type": "stream", 118 | "text": [ 119 | "2016\n", 120 | "10\n", 121 | "31\n", 122 | "10\n" 123 | ] 124 | } 125 | ], 126 | "source": [ 127 | "print d.year\n", 128 | "print d.month\n", 129 | "print d.day\n", 130 | "print d.hour" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 9, 136 | "metadata": {}, 137 | "outputs": [ 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "736268" 142 | ] 143 | }, 144 | "execution_count": 9, 145 | "metadata": {}, 146 | "output_type": "execute_result" 147 | } 148 | ], 149 | "source": [ 150 | "o = d.toordinal()\n", 151 | "o" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 10, 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "data": { 161 | "text/plain": [ 162 | "datetime.datetime(2016, 10, 31, 0, 0)" 163 | ] 164 | }, 165 | "execution_count": 10, 166 | "metadata": {}, 167 | "output_type": "execute_result" 168 | } 169 | ], 170 | "source": [ 171 | "dt.datetime.fromordinal(o)" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": 11, 177 | "metadata": {}, 178 | "outputs": [ 179 | { 180 | "data": { 181 | "text/plain": [ 182 | "datetime.time(10, 5, 30, 500000)" 183 | ] 184 | }, 185 | "execution_count": 11, 186 | "metadata": {}, 187 | "output_type": "execute_result" 188 | } 189 | ], 190 | "source": [ 191 | "t = dt.datetime.time(d)\n", 192 | "t" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 12, 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "data": { 202 | "text/plain": [ 203 | "datetime.date(2016, 10, 31)" 204 | ] 205 | }, 206 | "execution_count": 12, 207 | "metadata": {}, 208 | "output_type": "execute_result" 209 | } 210 | ], 211 | "source": [ 212 | "dd = dt.datetime.date(d)\n", 213 | "dd" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 13, 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "data": { 223 | "text/plain": [ 224 | "datetime.datetime(2016, 10, 31, 10, 5)" 225 | ] 226 | }, 227 | "execution_count": 13, 228 | "metadata": {}, 229 | "output_type": "execute_result" 230 | } 231 | ], 232 | "source": [ 233 | "d.replace(second=0, microsecond=0)" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 14, 239 | "metadata": {}, 240 | "outputs": [ 241 | { 242 | "data": { 243 | "text/plain": [ 244 | "datetime.timedelta(-648, 68294, 339000)" 245 | ] 246 | }, 247 | "execution_count": 14, 248 | "metadata": {}, 249 | "output_type": "execute_result" 250 | } 251 | ], 252 | "source": [ 253 | "td = d - dt.datetime.now()\n", 254 | "td" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": null, 260 | "metadata": {}, 261 | "outputs": [], 262 | "source": [ 263 | "td.days" 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": 15, 269 | "metadata": {}, 270 | "outputs": [ 271 | { 272 | "name": "stdout", 273 | "output_type": "stream", 274 | "text": [ 275 | "-648\n", 276 | "68294\n", 277 | "339000\n", 278 | "-55918905.661\n" 279 | ] 280 | } 281 | ], 282 | "source": [ 283 | "print td.days\n", 284 | "print td.seconds\n", 285 | "print td.microseconds\n", 286 | "print td.total_seconds()" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 16, 292 | "metadata": {}, 293 | "outputs": [ 294 | { 295 | "data": { 296 | "text/plain": [ 297 | "'2016-10-31T10:05:30.500000'" 298 | ] 299 | }, 300 | "execution_count": 16, 301 | "metadata": {}, 302 | "output_type": "execute_result" 303 | } 304 | ], 305 | "source": [ 306 | "d.isoformat()" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 18, 312 | "metadata": {}, 313 | "outputs": [ 314 | { 315 | "name": "stdout", 316 | "output_type": "stream", 317 | "text": [ 318 | "Monday, 31. October 2016 10:05AM\n", 319 | "2017-03-31 00:00:00\n", 320 | "2016-04-30 00:00:00\n" 321 | ] 322 | } 323 | ], 324 | "source": [ 325 | "print d.strftime(\"%A, %d. %B %Y %I:%M%p\")\n", 326 | "print dt.datetime.strptime('2017-03-31', '%Y-%m-%d') # year first and four-digit year\n", 327 | "print dt.datetime.strptime('30-4-16', '%d-%m-%y') # day first and two-digit year" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": 19, 333 | "metadata": {}, 334 | "outputs": [ 335 | { 336 | "data": { 337 | "text/plain": [ 338 | "'2016-10-31 10:05:30.500000'" 339 | ] 340 | }, 341 | "execution_count": 19, 342 | "metadata": {}, 343 | "output_type": "execute_result" 344 | } 345 | ], 346 | "source": [ 347 | "ds = str(d)\n", 348 | "ds" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 20, 354 | "metadata": {}, 355 | "outputs": [ 356 | { 357 | "data": { 358 | "text/plain": [ 359 | "datetime.datetime(2016, 10, 31, 10, 5, 30, 500000)" 360 | ] 361 | }, 362 | "execution_count": 20, 363 | "metadata": {}, 364 | "output_type": "execute_result" 365 | } 366 | ], 367 | "source": [ 368 | "dt.datetime.strptime(ds, '%Y-%m-%d %H:%M:%S.%f')" 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": 21, 374 | "metadata": {}, 375 | "outputs": [ 376 | { 377 | "name": "stdout", 378 | "output_type": "stream", 379 | "text": [ 380 | "2018-08-09 15:12:52.277000\n", 381 | "2018-08-09 10:12:52.277000\n" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "print dt.datetime.now()\n", 387 | "print dt.datetime.utcnow()" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 22, 393 | "metadata": {}, 394 | "outputs": [ 395 | { 396 | "data": { 397 | "text/plain": [ 398 | "u'United States'" 399 | ] 400 | }, 401 | "execution_count": 22, 402 | "metadata": {}, 403 | "output_type": "execute_result" 404 | } 405 | ], 406 | "source": [ 407 | "import pytz\n", 408 | "pytz.country_names['US']" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": 23, 414 | "metadata": {}, 415 | "outputs": [ 416 | { 417 | "data": { 418 | "text/plain": [ 419 | "[u'Europe/Brussels']" 420 | ] 421 | }, 422 | "execution_count": 23, 423 | "metadata": {}, 424 | "output_type": "execute_result" 425 | } 426 | ], 427 | "source": [ 428 | "pytz.country_timezones['BE']" 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": 24, 434 | "metadata": {}, 435 | "outputs": [ 436 | { 437 | "data": { 438 | "text/plain": [ 439 | "[u'Asia/Karachi']" 440 | ] 441 | }, 442 | "execution_count": 24, 443 | "metadata": {}, 444 | "output_type": "execute_result" 445 | } 446 | ], 447 | "source": [ 448 | "pytz.country_timezones['PK']" 449 | ] 450 | }, 451 | { 452 | "cell_type": "code", 453 | "execution_count": 25, 454 | "metadata": {}, 455 | "outputs": [ 456 | { 457 | "data": { 458 | "text/plain": [ 459 | "['Pacific/Wake',\n", 460 | " 'Pacific/Wallis',\n", 461 | " 'US/Alaska',\n", 462 | " 'US/Arizona',\n", 463 | " 'US/Central',\n", 464 | " 'US/Eastern',\n", 465 | " 'US/Hawaii',\n", 466 | " 'US/Mountain',\n", 467 | " 'US/Pacific',\n", 468 | " 'UTC']" 469 | ] 470 | }, 471 | "execution_count": 25, 472 | "metadata": {}, 473 | "output_type": "execute_result" 474 | } 475 | ], 476 | "source": [ 477 | "pytz.common_timezones[-10:]" 478 | ] 479 | }, 480 | { 481 | "cell_type": "markdown", 482 | "metadata": {}, 483 | "source": [ 484 | "# Numpy" 485 | ] 486 | }, 487 | { 488 | "cell_type": "code", 489 | "execution_count": 26, 490 | "metadata": {}, 491 | "outputs": [ 492 | { 493 | "data": { 494 | "text/plain": [ 495 | "numpy.datetime64('2015-10-31')" 496 | ] 497 | }, 498 | "execution_count": 26, 499 | "metadata": {}, 500 | "output_type": "execute_result" 501 | } 502 | ], 503 | "source": [ 504 | "import numpy as np\n", 505 | "nd = np.datetime64('2015-10-31')\n", 506 | "nd" 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": 27, 512 | "metadata": {}, 513 | "outputs": [ 514 | { 515 | "data": { 516 | "text/plain": [ 517 | "'2015-10-31'" 518 | ] 519 | }, 520 | "execution_count": 27, 521 | "metadata": {}, 522 | "output_type": "execute_result" 523 | } 524 | ], 525 | "source": [ 526 | "np.datetime_as_string(nd)" 527 | ] 528 | }, 529 | { 530 | "cell_type": "code", 531 | "execution_count": 28, 532 | "metadata": {}, 533 | "outputs": [ 534 | { 535 | "data": { 536 | "text/plain": [ 537 | "('D', 1)" 538 | ] 539 | }, 540 | "execution_count": 28, 541 | "metadata": {}, 542 | "output_type": "execute_result" 543 | } 544 | ], 545 | "source": [ 546 | "np.datetime_data(nd)" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 29, 552 | "metadata": {}, 553 | "outputs": [ 554 | { 555 | "data": { 556 | "text/plain": [ 557 | "datetime.datetime(2016, 10, 31, 10, 5, 30, 500000)" 558 | ] 559 | }, 560 | "execution_count": 29, 561 | "metadata": {}, 562 | "output_type": "execute_result" 563 | } 564 | ], 565 | "source": [ 566 | "d" 567 | ] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "execution_count": 30, 572 | "metadata": {}, 573 | "outputs": [ 574 | { 575 | "data": { 576 | "text/plain": [ 577 | "numpy.datetime64('2016-10-31T10:05:30.500000')" 578 | ] 579 | }, 580 | "execution_count": 30, 581 | "metadata": {}, 582 | "output_type": "execute_result" 583 | } 584 | ], 585 | "source": [ 586 | "nd = np.datetime64(d)\n", 587 | "nd" 588 | ] 589 | }, 590 | { 591 | "cell_type": "code", 592 | "execution_count": 34, 593 | "metadata": {}, 594 | "outputs": [], 595 | "source": [ 596 | "dtl = np.arange('2016-01-01T00:00:00', '2016-01-02T00:00:00',\n", 597 | " dtype='datetime64[h]')" 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": 37, 603 | "metadata": {}, 604 | "outputs": [ 605 | { 606 | "data": { 607 | "image/png": "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\n", 608 | "text/plain": [ 609 | "
" 610 | ] 611 | }, 612 | "metadata": {}, 613 | "output_type": "display_data" 614 | } 615 | ], 616 | "source": [ 617 | "import matplotlib.pyplot as plt\n", 618 | "%matplotlib inline\n", 619 | "\n", 620 | "np.random.seed(3000)\n", 621 | "rnd = np.random.standard_normal(len(dtl)).cumsum() ** 2\n", 622 | "\n", 623 | "\n", 624 | "fig = plt.figure(figsize= (15, 8))\n", 625 | "plt.plot(dtl.astype(dt.datetime), rnd) # convert np.datetime to datetime.datetime\n", 626 | "plt.grid(True)\n", 627 | "fig.autofmt_xdate() # autoformatting of datetime x-ticks" 628 | ] 629 | } 630 | ], 631 | "metadata": { 632 | "kernelspec": { 633 | "display_name": "Python [conda env:py27]", 634 | "language": "python", 635 | "name": "conda-env-py27-py" 636 | }, 637 | "language_info": { 638 | "codemirror_mode": { 639 | "name": "ipython", 640 | "version": 2 641 | }, 642 | "file_extension": ".py", 643 | "mimetype": "text/x-python", 644 | "name": "python", 645 | "nbconvert_exporter": "python", 646 | "pygments_lexer": "ipython2", 647 | "version": "2.7.15" 648 | } 649 | }, 650 | "nbformat": 4, 651 | "nbformat_minor": 2 652 | } 653 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python - for - Finance 2 | Simulation of Financial Models 3 | Valuation Framework 4 | Derivatives and Portfolio Valuation 5 | Volatility Options 6 | 7 | ## Python 2.7 is used for Computation & Analytics 8 | 9 | 10 | ## SHORT RATE CLASS WITH GUI 11 | ### short_rate_GUI.py 12 | #### Description 13 | Guided User Ineterface for Short Rate Class below: 14 | 15 | ![short rate gui](https://user-images.githubusercontent.com/30389323/43771663-5c40ccae-9a59-11e8-8018-328fc3e3ac1f.PNG) 16 | 17 | ## Extended SHORT RATE CLASS WITH GUI 18 | ### extended_short_rate_GUI.py 19 | #### Description 20 | Guided User Ineterface for Extended Short Rate Class below: 21 | 22 | ![extended_short_rate_gui](https://user-images.githubusercontent.com/30389323/43772860-11b35054-9a5d-11e8-828a-56e70beac4c6.PNG) 23 | 24 | ## CASH FLOW SERIES CLASS WITH GUI 25 | ### cash_flow_series_GUI.py 26 | #### Description 27 | Guided User Ineterface for CASH FLOW SERIES CLASS WITH GUI below: 28 | 29 | ![cash_flow_series_gui](https://user-images.githubusercontent.com/30389323/43773198-62309ea0-9a5e-11e8-907f-94fbce795e02.PNG) 30 | 31 | 32 | ## Cash Flow Series Result GUI 33 | 34 | ![cahs flow series result gui](https://user-images.githubusercontent.com/30389323/43773646-d2917498-9a5f-11e8-89d5-205b3f8920e4.PNG) 35 | 36 | 37 | # TradeChat Room 38 | ## Allow Users to sign in and chat with market brokers 39 | ## A simple example for a web-based chat room based on Flask and SQLite3. 40 | Usage From Command Line 41 | taymour$- python tradechat.py 42 | ### table.sql 43 | Schema design for SQLite3 44 | 45 | ### End GUI 46 | #### Home Page 47 | ![tradechat1](https://user-images.githubusercontent.com/30389323/43886724-1c5c5f9e-9bd6-11e8-928f-3ba4b248d0cf.PNG) 48 | 49 | #### Register Page 50 | ![tradechat2](https://user-images.githubusercontent.com/30389323/43886942-b2f4a5d8-9bd6-11e8-81fd-56476fa5ebb9.PNG) 51 | 52 | #### Chat Page 53 | ![tradechat3](https://user-images.githubusercontent.com/30389323/43886946-b97a1e1a-9bd6-11e8-83c8-cf15393aa5e3.PNG) 54 | 55 | #### Posts with time and user name 56 | ![tradechat4](https://user-images.githubusercontent.com/30389323/43886956-c38a24ea-9bd6-11e8-836a-218ff990ffe1.PNG) 57 | -------------------------------------------------------------------------------- /cash_flow_series_GUI.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taymourniazi/Python-for-Finance/5f43f9774915d266244cec560baba9c5fdec80c7/cash_flow_series_GUI.PNG -------------------------------------------------------------------------------- /cash_flow_series_GUI.py: -------------------------------------------------------------------------------- 1 | import traits.api as trapi 2 | import traitsui.api as trui 3 | import numpy as np 4 | 5 | class cash_flow_series(trapi.HasTraits): 6 | name = trapi.Str 7 | short_rate = trapi.Range(0.0, 0.5, 0.05) 8 | time_list = trapi.Array(dtype=np.float, shape=(1, 6)) 9 | cash_flows = trapi.Array(dtype=np.float, shape=(1, 6)) 10 | disc_values = trapi.Array(dtype=np.float, shape=(1, 6)) 11 | present_values = trapi.Array(dtype=np.float, shape=(1, 6)) 12 | net_present_value = trapi.Float 13 | update = trapi.Button 14 | def _update_fired(self): 15 | self.disc_values = np.exp(-self.short_rate * self.time_list) 16 | self.present_values = self.disc_values * self.cash_flows 17 | self.net_present_value = np.sum(self.present_values) 18 | v = trui.View(trui.Group(trui.Item(name = 'name'), 19 | trui.Item(name='short_rate'), 20 | trui.Item(name='time_list', label='Time List'), 21 | trui.Item(name='cash_flows', label='Cash Flows'), 22 | trui.Item('update', show_label=False), 23 | trui.Item(name='disc_values', 24 | label='Discount Factors'), 25 | trui.Item(name='present_values', 26 | label='Present Values'), 27 | trui.Item(name='net_present_value', 28 | label='Net Present Value'), 29 | show_border=True, label='Calculate Present Values'), 30 | buttons = [trui.OKButton, trui.CancelButton], 31 | resizable = True) 32 | 33 | cfs = cash_flow_series() 34 | cfs.configure_traits() -------------------------------------------------------------------------------- /extended_short_rate_GUI.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taymourniazi/Python-for-Finance/5f43f9774915d266244cec560baba9c5fdec80c7/extended_short_rate_GUI.PNG -------------------------------------------------------------------------------- /extended_short_rate_GUI.py: -------------------------------------------------------------------------------- 1 | import traits.api as trapi 2 | import traitsui.api as trui 3 | import numpy as np 4 | 5 | class short_rate(trapi.HasTraits): 6 | name = trapi.Str 7 | rate = trapi.Float 8 | time_list = trapi.Array(dtype=np.float, shape=(1, 5)) 9 | disc_list = trapi.Array(dtype=np.float, shape=(1, 5)) 10 | update = trapi.Button 11 | def _update_fired(self): 12 | self.disc_list = np.exp(-self.rate * self.time_list) 13 | v = trui.View(trui.Group(trui.Item(name = 'name'), 14 | trui.Item(name='rate'), 15 | trui.Item(name='time_list', 16 | label='Insert Time List Here'), 17 | trui.Item('update', show_label=False), 18 | trui.Item(name='disc_list', 19 | label='Press Update for Factors'), 20 | show_border=True, label='Calculate Discount Factors'), 21 | buttons = [trui.OKButton, trui.CancelButton], 22 | resizable = True) 23 | 24 | sr = short_rate() 25 | sr.configure_traits() -------------------------------------------------------------------------------- /short rate GUI.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taymourniazi/Python-for-Finance/5f43f9774915d266244cec560baba9c5fdec80c7/short rate GUI.PNG -------------------------------------------------------------------------------- /short_rate_GUI.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import traits.api as trapi 3 | 4 | 5 | class short_rate(trapi.HasTraits): 6 | name = trapi.Str 7 | rate = trapi.Float 8 | time_list = trapi.Array(dtype=np.float, shape=(5,)) 9 | def get_discount_factors(self): 10 | return np.exp(-self.rate * self.time_list) 11 | 12 | sr = short_rate() 13 | sr.configure_traits() -------------------------------------------------------------------------------- /stock.csv: -------------------------------------------------------------------------------- 1 | date,close_price,high_price,low_price,open_price,volume 2 | 07/08/2017,10.2435,10.2997,10.2247,10.2622,35013023 3 | 08/08/2017,10.2153,10.3185,10.2059,10.2716,26322101 4 | 09/08/2017,10.2435,10.2716,10.159,10.2059,32155872 5 | 10/08/2017,10.1028,10.2341,10.1028,10.2059,31903827 6 | 11/08/2017,10.1028,10.1684,10.0934,10.1215,32300117 7 | 14/08/2017,10.2341,10.2716,10.1215,10.1497,26413474 8 | 15/08/2017,10.1684,10.3185,10.1637,10.2435,29266299 9 | 16/08/2017,10.1309,10.2247,10.1121,10.1872,28316308 10 | 17/08/2017,9.9808,10.1309,9.9433,10.1215,35518834 11 | 18/08/2017,9.9058,9.9714,9.8213,9.962,43998743 12 | 21/08/2017,9.9151,9.9949,9.8682,9.8776,30152540 13 | 22/08/2017,9.9902,10.0652,9.9527,9.9527,28676062 14 | 23/08/2017,10.0465,10.1121,9.9339,9.9527,35405768 15 | 24/08/2017,10.0465,10.1309,10.0277,10.084,33584388 16 | 25/08/2017,10.1497,10.2059,10.0934,10.1028,35926827 17 | 28/08/2017,10.1215,10.2059,10.0652,10.1872,22307395 18 | 29/08/2017,10.1684,10.2153,10.0652,10.084,29807261 19 | 30/08/2017,10.2622,10.2622,10.1028,10.1497,23629293 20 | 31/08/2017,10.3466,10.5061,10.2716,10.2904,54208921 21 | 01/09/2017,10.6468,10.7219,10.4498,10.4874,64560278 22 | 05/09/2017,10.6562,10.6843,10.5436,10.6562,44000160 23 | 06/09/2017,10.7875,10.8157,10.6834,10.6843,43279041 24 | 07/09/2017,10.6937,10.8063,10.6281,10.8063,30271005 25 | 08/09/2017,10.6562,10.6843,10.5905,10.6374,26633932 26 | 11/09/2017,10.7031,10.7406,10.675,10.6937,43375019 27 | 12/09/2017,10.872,10.947,10.6843,10.7219,41386669 28 | 13/09/2017,10.9001,10.9095,10.8063,10.8813,23302152 29 | 14/09/2017,10.8438,10.9564,10.7688,10.8813,31696274 30 | 15/09/2017,10.9001,10.9095,10.7781,10.825,30865470 31 | 18/09/2017,10.9095,11.0033,10.8766,10.9095,25132356 32 | 19/09/2017,10.9939,11.0127,10.9001,10.9095,26392861 33 | 20/09/2017,10.9845,11.0643,10.9142,10.9564,26705319 34 | 21/09/2017,10.9939,11.0877,10.9658,10.9845,40319429 35 | 22/09/2017,11.1065,11.1346,10.9939,11.0127,30196459 36 | 25/09/2017,11.2003,11.3128,11.1065,11.144,40766002 37 | 26/09/2017,11.1909,11.2566,11.1627,11.2096,30646723 38 | 27/09/2017,11.2096,11.2753,11.1252,11.2378,28412202 39 | 28/09/2017,11.219,11.2472,11.1627,11.2096,23105656 40 | 29/09/2017,11.2284,11.2753,11.1815,11.2284,31227515 41 | 02/10/2017,11.341,11.341,11.2284,11.2566,36019960 42 | 03/10/2017,11.5755,11.6599,11.4629,11.5567,65641714 43 | 04/10/2017,11.538,11.6881,11.5192,11.5661,52909843 44 | 05/10/2017,11.4911,11.5942,11.3973,11.5755,48145783 45 | 06/10/2017,11.5473,11.5661,11.4371,11.4442,35091790 46 | 09/10/2017,11.5755,11.6411,11.4911,11.5661,28924795 47 | 10/10/2017,11.6224,11.6505,11.4911,11.5755,40586234 48 | 11/10/2017,11.613,11.6599,11.5473,11.5661,34953438 49 | 12/10/2017,11.3691,11.5567,11.3597,11.538,45924434 50 | 13/10/2017,11.3035,11.416,11.1346,11.3128,44597334 51 | 16/10/2017,11.3691,11.3973,11.219,11.2472,32349675 52 | 17/10/2017,11.5098,11.5473,11.3691,11.3785,55273235 53 | 18/10/2017,11.4348,11.5849,11.416,11.5192,30783686 54 | 19/10/2017,11.4723,11.4911,11.3035,11.3879,29678158 55 | 20/10/2017,11.4913,11.5293,11.3963,11.5103,28171651 56 | 23/10/2017,11.4343,11.5768,11.4343,11.5008,21504813 57 | 24/10/2017,11.5768,11.6432,11.4827,11.5008,34651185 58 | 25/10/2017,11.4343,11.5388,11.3678,11.5388,47674841 59 | 26/10/2017,11.6527,11.7192,11.4533,11.5863,49003126 60 | 27/10/2017,11.4533,11.6243,11.4059,11.6148,33925366 61 | 30/10/2017,11.4913,11.5388,11.3488,11.4058,36457435 62 | 31/10/2017,11.6527,11.6812,11.5188,11.5388,42010246 63 | 01/11/2017,11.7287,11.8427,11.6577,11.7762,43495830 64 | 02/11/2017,11.7952,11.8047,11.6432,11.7097,40923421 65 | 03/11/2017,11.7382,11.8332,11.7002,11.7857,33220261 66 | 06/11/2017,11.7097,11.8047,11.6812,11.7382,20178513 67 | 07/11/2017,11.5483,11.7572,11.5008,11.7287,41536291 68 | 08/11/2017,11.4533,11.5483,11.4058,11.5293,34127543 69 | 09/11/2017,11.4343,11.4438,11.3298,11.4058,26257259 70 | 10/11/2017,11.4058,11.4818,11.3773,11.3963,35298374 71 | 13/11/2017,11.5483,11.6053,11.3678,11.4058,30415855 72 | 14/11/2017,11.4153,11.5483,11.3868,11.4913,25893421 73 | 15/11/2017,11.3963,11.4248,11.2729,11.3678,28441307 74 | 16/11/2017,11.4343,11.4438,11.3298,11.3963,28269046 75 | 17/11/2017,11.4058,11.4533,11.3821,11.4153,31117727 76 | 20/11/2017,11.5198,11.5388,11.4153,11.4248,32352040 77 | 21/11/2017,11.5103,11.61,11.5103,11.5293,28510260 78 | 22/11/2017,11.4628,11.5388,11.4438,11.5008,36184010 79 | 24/11/2017,11.4913,11.5388,11.4248,11.4913,9549629 80 | 27/11/2017,11.5008,11.5768,11.4533,11.4818,28525156 81 | 28/11/2017,11.5958,11.6243,11.4723,11.5388,33199323 82 | 29/11/2017,11.9282,11.9377,11.6148,11.6243,64865974 83 | 30/11/2017,11.8902,12.0136,11.7952,11.8997,49224189 84 | 01/12/2017,11.9471,12.0611,11.7287,11.9851,52458736 85 | 04/12/2017,11.9946,12.1656,11.9566,12.0136,39558857 86 | 05/12/2017,11.8047,11.9851,11.7762,11.7952,45527163 87 | 06/12/2017,11.7572,11.8047,11.6622,11.7477,28453762 88 | 07/12/2017,11.8997,11.9566,11.7097,11.9424,25417119 89 | 08/12/2017,11.9756,11.9756,11.8047,11.8997,21981870 90 | 11/12/2017,11.9471,11.9946,11.8807,11.9377,44194633 91 | 12/12/2017,11.9661,11.9994,11.8807,11.9661,54370612 92 | 13/12/2017,11.9946,12.0849,11.9566,11.9756,31858995 93 | 14/12/2017,11.8332,12.0516,11.7857,12.0136,37073960 94 | 15/12/2017,11.9471,12.0231,11.8712,11.8807,48655453 95 | 18/12/2017,12.0231,12.1086,11.9756,12.0231,25022657 96 | 19/12/2017,12.0516,12.1371,12.0231,12.0706,23056884 97 | 20/12/2017,12.0801,12.1086,12.0136,12.0801,18989429 98 | 21/12/2017,11.9946,12.1276,11.9946,12.0991,21004663 99 | 22/12/2017,11.9471,12.0231,11.9282,12.0231,17876156 100 | 26/12/2017,11.9661,12.0136,11.9187,11.9377,11664564 101 | 27/12/2017,11.8712,11.9471,11.8237,11.9377,17005626 102 | 28/12/2017,11.9471,11.9471,11.8427,11.8522,14793534 103 | 29/12/2017,11.8617,11.9756,11.8617,11.9471,18362455 104 | 02/01/2018,12.0231,12.0231,11.8712,11.8902,20773320 105 | 03/01/2018,12.1181,12.1561,12.0326,12.0421,29765638 106 | 04/01/2018,12.327,12.384,12.1276,12.1371,37478200 107 | 05/01/2018,12.536,12.555,12.384,12.403,46121873 108 | 08/01/2018,12.4885,12.555,12.4505,12.5455,33828330 109 | 09/01/2018,12.422,12.555,12.422,12.517,27924109 110 | 10/01/2018,12.3745,12.478,12.308,12.403,56517139 111 | 11/01/2018,12.498,12.536,12.346,12.365,28342293 112 | 12/01/2018,12.5644,12.6214,12.441,12.441,56979186 113 | 16/01/2018,12.441,12.8019,12.3555,12.6404,53961375 114 | 17/01/2018,11.5673,11.9471,11.4913,11.9471,132412533 115 | 18/01/2018,11.4628,11.5863,11.4153,11.5673,66541729 116 | 19/01/2018,11.3963,11.5103,11.3109,11.5103,51303747 117 | 22/01/2018,11.4153,11.4723,11.3014,11.4153,52851915 118 | 23/01/2018,11.3583,11.4248,11.3014,11.4248,51830968 119 | 24/01/2018,11.4438,11.4818,11.3203,11.3963,63300483 120 | 25/01/2018,10.988,11.3298,10.8645,11.3298,114886820 121 | 26/01/2018,11.0639,11.1114,10.9215,11.007,52496001 122 | 29/01/2018,10.8207,11.1612,10.8109,11.1126,55113971 123 | 30/01/2018,10.7623,10.9277,10.7525,10.7915,52068187 124 | 31/01/2018,10.6747,10.8158,10.6066,10.7915,57644576 125 | 01/02/2018,10.626,10.7039,10.5579,10.6552,41352192 126 | 02/02/2018,10.4217,10.5871,10.3341,10.5871,72312922 127 | 05/02/2018,9.9644,10.5093,9.9644,10.4898,96756955 128 | 06/02/2018,10.4704,10.4995,9.9157,9.9935,139938127 129 | 07/02/2018,10.4704,10.7428,10.412,10.4606,68041787 130 | 08/02/2018,10.1492,10.5677,10.1395,10.4995,73990734 131 | 09/02/2018,10.2465,10.3536,9.9644,10.2855,72103620 132 | 12/02/2018,10.412,10.5287,10.2598,10.3828,49068946 133 | 13/02/2018,10.3049,10.4022,10.2465,10.3439,36884488 134 | 14/02/2018,10.4509,10.4606,10.2174,10.266,27844338 135 | 15/02/2018,10.4704,10.5093,10.3536,10.5093,28208311 136 | 16/02/2018,10.3244,10.5287,10.2368,10.412,41041761 137 | 20/02/2018,10.3439,10.3828,10.266,10.2952,27617865 138 | 21/02/2018,10.3147,10.4606,10.3049,10.3633,36037720 139 | 22/02/2018,10.3439,10.4412,10.2757,10.3147,25409561 140 | 23/02/2018,10.412,10.4217,10.3341,10.3828,21786781 141 | 26/02/2018,10.5969,10.6552,10.412,10.4509,27157756 142 | 27/02/2018,10.3244,10.6942,10.3147,10.6358,43502012 143 | 28/02/2018,10.3244,10.4995,10.2855,10.3925,41321429 144 | 01/03/2018,10.013,10.4022,9.9254,10.3633,75841414 145 | 02/03/2018,10.12,10.1395,9.867,9.9644,60491864 146 | 05/03/2018,10.2952,10.3439,10.0227,10.0325,44021329 147 | 06/03/2018,10.3439,10.3925,10.1882,10.3633,30978946 148 | 07/03/2018,10.3439,10.3536,10.1492,10.2271,30046598 149 | 08/03/2018,10.3244,10.3925,10.1979,10.3633,26947958 150 | 09/03/2018,10.4412,10.4412,10.2855,10.3439,26684375 151 | 12/03/2018,10.519,10.5579,10.3925,10.4022,33800918 152 | 13/03/2018,10.4898,10.6844,10.4412,10.5482,44456812 153 | 14/03/2018,10.7234,11.132,10.7136,10.9472,91985319 154 | 15/03/2018,10.772,10.9472,10.6552,10.7525,47645277 155 | 16/03/2018,10.8499,10.918,10.7623,10.8207,80684224 156 | 19/03/2018,10.7136,10.8693,10.5774,10.8499,63122538 157 | 20/03/2018,10.6942,10.8304,10.6747,10.7525,45612813 158 | 21/03/2018,10.8012,10.8839,10.6358,10.7039,38550957 159 | 22/03/2018,10.4606,10.7623,10.4412,10.7039,51280905 160 | 23/03/2018,10.2757,10.5579,10.2271,10.4995,39950867 161 | 26/03/2018,10.5385,10.5774,10.3925,10.4509,52325512 162 | 27/03/2018,10.5385,10.626,10.4314,10.5579,40677320 163 | 28/03/2018,10.5677,10.6552,10.4412,10.5385,42263662 164 | 29/03/2018,10.7817,10.8304,10.6212,10.6358,39863962 165 | 02/04/2018,10.5677,10.7915,10.412,10.7623,43598094 166 | 03/04/2018,10.8499,10.879,10.6066,10.7136,42523917 167 | 04/04/2018,11.025,11.0542,10.5093,10.5774,44834639 168 | 05/04/2018,11.0445,11.0737,10.9277,11.0347,28755606 169 | 06/04/2018,10.879,11.0445,10.772,10.9764,31920686 170 | 09/04/2018,10.9472,11.0737,10.8985,10.9472,36462658 171 | 10/04/2018,11.1418,11.2391,11.1029,11.132,44005015 172 | 11/04/2018,11.1223,11.1807,10.9958,11.0737,32979038 173 | 12/04/2018,11.0055,11.2294,10.9472,11.1904,47133732 174 | 13/04/2018,10.9764,11.0834,10.9277,11.0445,34598783 175 | 16/04/2018,11.0737,11.1418,10.9666,11.0542,32803268 176 | 17/04/2018,11.0737,11.1418,10.9958,11.1223,30906803 177 | 18/04/2018,11.025,11.171,10.9958,11.0737,46226082 178 | 19/04/2018,10.8081,11.0934,10.6996,11.025,49154173 179 | 20/04/2018,10.67,10.8771,10.6306,10.8574,44930027 180 | 23/04/2018,10.887,10.887,10.6799,10.6897,31936522 181 | 24/04/2018,10.8081,11.0151,10.7785,10.8968,39624986 182 | 25/04/2018,10.956,11.0053,10.7193,10.8081,40356076 183 | 26/04/2018,11.2715,11.3702,11.1335,11.2617,80676755 184 | 27/04/2018,11.3307,11.3997,11.2222,11.242,33375943 185 | 30/04/2018,11.0842,11.5625,11.0645,11.3702,66090895 186 | 01/05/2018,11.1039,11.1927,10.9461,11.094,61430446 187 | 02/05/2018,11.0546,11.1088,10.9658,11.1039,41899467 188 | 03/05/2018,11.0447,11.0546,10.8179,11.0151,38907404 189 | 04/05/2018,11.2025,11.2518,10.9363,11.0053,32043468 190 | 07/05/2018,11.1828,11.2814,11.1532,11.2025,27510279 191 | 08/05/2018,11.1138,11.2124,11.0792,11.1631,25754109 192 | 09/05/2018,10.9067,11.1236,10.8672,11.0546,43731958 193 | 10/05/2018,11.0546,11.094,10.8672,10.887,32023835 194 | 11/05/2018,11.0349,11.0891,11.0053,11.0645,19837675 195 | 14/05/2018,11.025,11.1335,11.0151,11.0743,27903121 196 | 15/05/2018,11.0645,11.094,10.9067,10.9461,26950114 197 | 16/05/2018,11.242,11.242,11.0447,11.0546,28976692 198 | 17/05/2018,11.3011,11.3209,11.2222,11.242,20741087 199 | 18/05/2018,11.1729,11.311,11.1433,11.2814,23893731 200 | 21/05/2018,11.3504,11.3899,11.2321,11.2617,31011916 201 | 22/05/2018,11.3603,11.4737,11.3504,11.4195,22360885 202 | 23/05/2018,11.2814,11.3899,11.1729,11.3406,23595004 203 | 24/05/2018,11.4589,11.4885,11.2814,11.2913,34876334 204 | 25/05/2018,11.3504,11.4441,11.311,11.3997,19337470 205 | 29/05/2018,11.2814,11.4589,11.2025,11.4392,31324274 206 | 30/05/2018,11.3899,11.449,11.311,11.3702,25554593 207 | 31/05/2018,11.3899,11.5723,11.2025,11.4885,61563249 208 | 01/06/2018,11.5477,11.6068,11.449,11.5082,35406189 209 | 04/06/2018,11.5772,11.6216,11.5279,11.5772,25141346 210 | 05/06/2018,11.666,11.703,11.5181,11.5772,31036704 211 | 06/06/2018,11.8041,11.8336,11.6561,11.7054,31110458 212 | 07/06/2018,11.8632,11.9816,11.7942,11.8041,47314073 213 | 08/06/2018,11.9323,11.952,11.8336,11.8731,28371881 214 | 11/06/2018,11.8632,11.9816,11.8534,11.9323,30398078 215 | 12/06/2018,11.9421,11.9816,11.8632,11.9027,51395448 216 | 13/06/2018,11.8534,11.9323,11.7942,11.9323,28406733 217 | 14/06/2018,11.7252,11.8435,11.6759,11.8336,34523019 218 | 15/06/2018,11.7153,11.8632,11.6364,11.6759,56326835 219 | 18/06/2018,11.8238,11.8731,11.6463,11.6561,32706527 220 | 19/06/2018,11.7252,11.7252,11.5082,11.6561,40064785 221 | 20/06/2018,11.7054,11.8829,11.666,11.8041,31964792 222 | 21/06/2018,11.5477,11.6659,11.4786,11.6364,33316702 223 | 22/06/2018,11.4885,11.7054,11.4589,11.5871,38207303 224 | 25/06/2018,11.3406,11.5082,11.2222,11.4688,36101893 225 | 26/06/2018,11.3603,11.4688,11.3307,11.3997,36627672 226 | 27/06/2018,11.2617,11.4786,11.242,11.38,27241994 227 | 28/06/2018,11.1236,11.242,10.9954,11.2124,43836444 228 | 29/06/2018,10.9165,11.2124,10.8771,11.1631,43615655 229 | 02/07/2018,10.9461,10.951,10.7588,10.8672,37892751 230 | 03/07/2018,10.8376,10.9954,10.7883,10.9461,16544777 231 | 05/07/2018,10.8968,10.9856,10.8672,10.9461,32008544 232 | 06/07/2018,10.9067,10.9461,10.7686,10.887,25487567 233 | 09/07/2018,11.0447,11.1039,10.8771,10.9461,23916802 234 | 10/07/2018,11.094,11.1039,11.0151,11.0447,21231537 235 | 11/07/2018,10.9165,11.0151,10.8968,10.9954,30030119 236 | 12/07/2018,10.8968,10.9856,10.8475,10.9461,27025237 237 | 13/07/2018,10.8278,10.8968,10.7588,10.8672,36537177 238 | 16/07/2018,10.6996,10.8179,10.6108,10.7982,46156833 239 | 17/07/2018,10.7094,10.7489,10.6503,10.6503,37584265 240 | 18/07/2018,10.7193,10.744,10.6601,10.6996,36420018 241 | 19/07/2018,10.67,10.7489,10.6207,10.739,40308773 242 | 20/07/2018,10.56,10.72,10.51,10.68,41447134 243 | 23/07/2018,10.47,10.57,10.42,10.56,34941983 244 | 24/07/2018,10.57,10.74,10.5,10.51,47302950 245 | 25/07/2018,10.52,10.57,10.12,10.32,92610535 246 | 26/07/2018,9.89,10.16,9.84,10.14,103893039 247 | 27/07/2018,9.93,10.05,9.91,9.96,45933084 248 | 30/07/2018,10.07,10.1,9.93,9.96,35877009 249 | 31/07/2018,10.04,10.11,10,10.11,38026871 250 | 01/08/2018,9.9,10.0785,9.82,10.06,44126692 251 | 02/08/2018,9.92,9.98,9.84,9.9,40318865 252 | 03/08/2018,10.04,10.06,9.93,9.93,25925122 253 | -------------------------------------------------------------------------------- /tradechat/static/style.css: -------------------------------------------------------------------------------- 1 | body { font-family: sans-serif; background: #eee; } 2 | a, h1, h2 { color: #0066cc; } 3 | h1, h2 { font-family: 'Helvetica', sans-serif; margin: 0; } 4 | h1 { font-size: 1.4em; border-bottom: 2px solid #eee; } 5 | h2 { font-size: 1.0em; } 6 | 7 | .page { margin: 2em auto; width: 35em; border: 1px solid #ccc; 8 | padding: 0.8em; background: white; } 9 | .comments { list-style: none; margin: 0; padding: 0; } 10 | .comments li { margin: 0.8em 1.2em; } 11 | .comments li h2 { margin-left: -1em; } 12 | .add-comment { color: #0066cc; font-size: 0.7em; border-bottom: 1px solid #ccc; } 13 | .add-comment dl { font-weight: bold; } 14 | .metanav { text-align: right; font-size: 0.8em; padding: 0.3em; 15 | margin-bottom: 1em; background: #fafafa; } 16 | .flash { color: #b9b9b9; font-size: 0.7em; } 17 | .error { color: #ff4629; font-size: 0.7em; padding: 0.5em; } -------------------------------------------------------------------------------- /tradechat/table.sql: -------------------------------------------------------------------------------- 1 | drop table if exists comments; 2 | create table comments ( 3 | id integer primary key autoincrement, 4 | comment text not null, 5 | user text not null, 6 | time text not null 7 | ); 8 | 9 | drop table if exists users; 10 | create table users ( 11 | id integer primary key autoincrement, 12 | name text not null, 13 | password text not null 14 | ); 15 | -------------------------------------------------------------------------------- /tradechat/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | Tradechat 3 | 5 |
6 |

Tradechat

7 |
8 | {% if not session.logged_in %} 9 | log in
10 | register 11 | {% else %} 12 | log out 13 | {% endif %} 14 |
15 | {% for message in get_flashed_messages() %} 16 |
{{ message }}
17 | {% endfor %} 18 | {% block body %}{% endblock %} 19 |
-------------------------------------------------------------------------------- /tradechat/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

Login

4 | {% if error %}

Error: {{ error }}{% endif %} 5 |

6 |
7 |
Username 8 |
9 |
Password 10 |
11 |
12 |
13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /tradechat/templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

Register

4 | {% if error %}

Error: {{ error }}{% endif %} 5 |

6 |
7 |
Username 8 |
9 |
Password 10 |
11 |
12 |
13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /tradechat/templates/show_entries.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {% if session.logged_in %} 4 |
5 |
6 |
What's up? 7 |
8 |
9 |
10 |
11 | {% endif %} 12 |
    13 | {% for comment in comments %} 14 |
  • {{ comment.comment|safe }} 15 | ({{ comment.user }} @ {{ comment.time }}) 16 | {% else %} 17 |
  • No comments so far. 18 | {% endfor %} 19 |
20 | {% endblock %} -------------------------------------------------------------------------------- /tradechat/tradechat.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taymourniazi/Python-for-Finance/5f43f9774915d266244cec560baba9c5fdec80c7/tradechat/tradechat.db -------------------------------------------------------------------------------- /tradechat/tradechat.py: -------------------------------------------------------------------------------- 1 | # Tradechat 2 | # 3 | # A simple example for a web-based chat room 4 | # based on Flask and SQLite3. 5 | # 6 | 7 | import os 8 | import datetime as dt 9 | from sqlite3 import dbapi2 as sqlite3 10 | from flask import Flask, request, session, g, redirect, url_for, abort, \ 11 | render_template, flash 12 | 13 | 14 | # the application object from the main Flask class 15 | app = Flask(__name__) 16 | 17 | # override config from environment variable 18 | app.config.update(dict( 19 | DATABASE=os.path.join(app.root_path, 'tradechat.db'), 20 | # the SQLite3 database file ("TC database") 21 | DEBUG=True, 22 | SECRET_KEY='secret_key', 23 | # use secure key here for real applications 24 | )) 25 | app.config.from_envvar('TC_SETTINGS', silent=True) 26 | # do not complain if no config file exists 27 | 28 | def connect_db(): 29 | ''' Connects to the TC database.''' 30 | rv = sqlite3.connect(app.config['DATABASE']) 31 | rv.row_factory = sqlite3.Row 32 | return rv 33 | 34 | 35 | def get_db(): 36 | ''' Opens a new connection to the TC database. ''' 37 | if not hasattr(g, 'sqlite_db'): 38 | # open only if none exists yet 39 | g.sqlite_db = connect_db() 40 | return g.sqlite_db 41 | 42 | 43 | def init_db(): 44 | ''' Creates the TC database tables.''' 45 | with app.app_context(): 46 | db = get_db() 47 | with app.open_resource('tables.sql', mode='r') as f: 48 | db.cursor().executescript(f.read()) 49 | # creates entries and users tables 50 | db.commit() 51 | 52 | 53 | @app.teardown_appcontext 54 | def close_db(error): 55 | ''' Closes the TC database at the end of the request. ''' 56 | if hasattr(g, 'sqlite_db'): 57 | g.sqlite_db.close() 58 | 59 | 60 | @app.route('/') 61 | def show_entries(): 62 | ''' Renders all entries of the TC database. ''' 63 | db = get_db() 64 | query = 'select comment, user, time from comments order by id desc' 65 | cursor = db.execute(query) 66 | comments = cursor.fetchall() 67 | return render_template('show_entries.html', comments=comments) 68 | 69 | 70 | @app.route('/register', methods=['GET', 'POST']) 71 | def register(): 72 | ''' Registers a new user in the TC database. ''' 73 | error = None 74 | if request.method == 'POST': 75 | db = get_db() 76 | if request.form['username'] == '' or request.form['password'] == '': 77 | error = 'Provide both a username and a password.' 78 | # both fields have to be nonempty 79 | else: 80 | db.execute('insert into users (name, password) values (?, ?)', 81 | [request.form['username'], request.form['password']]) 82 | db.commit() 83 | session['logged_in'] = True 84 | # directly log in new user 85 | flash('You were sucessfully registered.') 86 | app.config.update(dict(USERNAME=request.form['username'])) 87 | return redirect(url_for('show_entries')) 88 | return render_template('register.html', error=error) 89 | 90 | 91 | @app.route('/login', methods=['GET', 'POST']) 92 | def login(): 93 | ''' Logs in a user. ''' 94 | error = None 95 | if request.method == 'POST': 96 | db = get_db() 97 | try: 98 | query = 'select id from users where name = ? and password = ?' 99 | id = db.execute(query, (request.form['username'], 100 | request.form['password'])).fetchone()[0] 101 | # fails if record with provided username and password 102 | # is not found 103 | session['logged_in'] = True 104 | flash('You are now logged in.') 105 | app.config.update(dict(USERNAME=request.form['username'])) 106 | return redirect(url_for('show_entries')) 107 | except: 108 | error = 'User not found or wrong password.' 109 | return render_template('login.html', error=error) 110 | 111 | 112 | @app.route('/add', methods=['POST']) 113 | def add_entry(): 114 | ''' Adds entry to the TC database. ''' 115 | if not session.get('logged_in'): 116 | abort(401) 117 | db = get_db() 118 | now = dt.datetime.now() 119 | db.execute('insert into comments (comment, user, time) values (?, ?, ?)', 120 | [request.form['text'], app.config['USERNAME'], str(now)[:-7]]) 121 | db.commit() 122 | flash('Your comment was successfully added.') 123 | return redirect(url_for('show_entries')) 124 | 125 | 126 | @app.route('/logout') 127 | def logout(): 128 | ''' Logs out the current user. ''' 129 | session.pop('logged_in', None) 130 | flash('You were logged out') 131 | return redirect(url_for('show_entries')) 132 | 133 | # main routine 134 | if __name__ == '__main__': 135 | init_db() # comment out if data in current 136 | # TC database is to be kept 137 | app.run() --------------------------------------------------------------------------------