├── .gitignore ├── stock_int.zip ├── generate_rsa_ssl.sh ├── stock_int ├── templates │ ├── plotly.html │ ├── layout.html │ └── selection.html ├── forms.py ├── static │ └── style.css └── stock_interactive.py ├── setup_server.sh ├── cloud_recipe.txt ├── jupyter_notebook_config.py ├── mykey.key ├── mycert.pem ├── python_setup.sh ├── plotly_cufflinks.ipynb ├── README.md └── quandl_bitcoin.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | *.pyc 4 | .ipynb* 5 | -------------------------------------------------------------------------------- /stock_int.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhilpisch/cloud-python/master/stock_int.zip -------------------------------------------------------------------------------- /generate_rsa_ssl.sh: -------------------------------------------------------------------------------- 1 | openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mykey.key -out mycert.pem -------------------------------------------------------------------------------- /stock_int/templates/plotly.html: -------------------------------------------------------------------------------- 1 | 5 | {% extends "layout.html" %} 6 | 7 | {% block body %} 8 | 9 | 10 |

Results for Symbol {{ symbol }}

11 | 12 | 19 | 20 |

21 | 22 | {{ table | safe }} 23 | 24 | 25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /setup_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Setting up a DigitalOcean Droplet 4 | # with Basic Scientific Python stack 5 | # and Jupyter Notebook 6 | # 7 | # (c) Dr Yves J Hilpisch 8 | # The Python Quants GmbH 9 | # 10 | 11 | MASTER_IP=$1 12 | 13 | IDENTITY=~/.ssh/digital_ocean # change to your identity file 14 | 15 | scp python_setup.sh root@${MASTER_IP}: 16 | scp mycert.pem mykey.key jupyter_notebook_config.py root@${MASTER_IP}: 17 | scp *.ipynb root@${MASTER_IP}: 18 | scp *.zip root@${MASTER_IP}: 19 | ssh root@${MASTER_IP} bash /root/python_setup.sh 20 | -------------------------------------------------------------------------------- /stock_int/forms.py: -------------------------------------------------------------------------------- 1 | # 2 | # Data input form 3 | # forms.py 4 | # 5 | 6 | # install: pip install Flask-WTF 7 | from wtforms import TextField 8 | from wtforms.fields import SubmitField 9 | from wtforms.validators import DataRequired 10 | from flask_wtf import Form 11 | 12 | 13 | class SymbolSearch(Form): 14 | symbol = TextField('Symbol (eg AAPL, MSFT)', 15 | validators=[DataRequired()]) 16 | trend1 = TextField('Trend 1 (eg 20, 42)', 17 | validators=[DataRequired()]) 18 | trend2 = TextField('Trend 2 (eg 100, 252)', 19 | validators=[DataRequired()]) 20 | submit = SubmitField() 21 | -------------------------------------------------------------------------------- /stock_int/templates/layout.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | Historical Stock Prices 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 17 | 18 | 20 | 21 |
22 | 23 | 26 | 27 |
28 | back to search 29 |
30 | {% block body %} 31 | 32 | {% endblock %} 33 |
34 | -------------------------------------------------------------------------------- /cloud_recipe.txt: -------------------------------------------------------------------------------- 1 | STEPS TO SET-UP CLOUD INSTANCE 2 | WITH JUPYTER NOTEBOOK 3 | 4 | Generate private/public RSA key pair 5 | ------------------------------------ 6 | ssh-keygen -t rsa 7 | copy keys to ~/.ssh 8 | 9 | 10 | Set-up DigitalOcean account 11 | --------------------------- 12 | https://m.do.co/c/fbe512dd3dac 13 | (if you register via this link, you get 10 USD bonus) 14 | 15 | 16 | Create a Droplet (provide public RSA key): 17 | ------------------------------------------ 18 | provide public RSA key during creation 19 | copy IP-ADDRESS after creation 20 | 21 | 22 | On the shell do: 23 | ---------------- 24 | git clone http://github.com/yhilpisch/cloud-python 25 | cd cloud-python 26 | bash setup_server.sh IP-ADDRESS (replace with your address!!) 27 | 28 | 29 | Running a Jupyter Notebook server: 30 | ---------------------------------- 31 | http://jupyter-notebook.readthedocs.io/en/latest/public_server.html -------------------------------------------------------------------------------- /jupyter_notebook_config.py: -------------------------------------------------------------------------------- 1 | # set options for certfile, ip, password, and toggle off browser auto-opening 2 | # 3 | # execute the bash script generate_rsa_ssl.sh to generate your certificate files 4 | # replace the following file names (and files used) by your choice/files 5 | c.NotebookApp.certfile = u'/root/mycert.pem' 6 | c.NotebookApp.keyfile = u'/root/mykey.key' 7 | 8 | # set ip to '*' to bind on all interfaces (ips) for the public server 9 | c.NotebookApp.ip = '*' 10 | 11 | # to generate a password hash, do in Python: 12 | # 13 | # from notebook.auth import passwd 14 | # passwd() 15 | # 16 | # here: 'jupyter' as password 17 | # replace the hash key with the one for your password 18 | c.NotebookApp.password = 'sha1:bb5e01be158a:99465f872e0613a3041ec25b7860175f59847702' 19 | 20 | c.NotebookApp.open_browser = False 21 | 22 | # it is a good idea to set a known, fixed default port for server access 23 | c.NotebookApp.port = 8888 24 | -------------------------------------------------------------------------------- /mykey.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKk+VoUlue7/Xkr1 3 | kvU6b1R4jrsPJNgdzGgAXdP72MzNGiOJJ1X+L+FooLNf1qvlh/wecg9tRaDNMfEM 4 | FHrqLOUeEHoptE2oj2Gth7cytaWk4bNhMSixHBrxiM1b6QJVUrRzPjdKNRj2oYI6 5 | TGX0WqNptIiE0ar1YL6f6yx78tu9AgMBAAECgYApAD4rsZES8nDgjg/VMxvnhfFm 6 | JewSI13y0CvrADdsnj+33jFWZucon5VW/1/dcxT3olSVoi5dH3j64adQg8zuK90E 7 | NJq32G6uw7fMVlAJjIIhyOPljBo3UFtVpsZHS1nVqYkM6zr5oT+AoBQVCVMAnDNq 8 | 45PM1/N+AeTBYJ+IYQJBANoDx6Hwqs5OpZtejv8prSxKJIdwAEN89Kf/U9rJ6yjq 9 | jCs/7vl2csijDBbnhxEPGIlIuTnWwEHcHyWlYnlDFeUCQQDGuzCPrqrxwMm0kXpm 10 | REUEz6Hkg6uUmNrA4EUNKLtF3VBTwJW89Eu4fyH2PE0KSDz2YaqUJ9jz6WX5MCV5 11 | v1D5AkEAql1bykt0XmWM+j3JRtI9lieWJhQ60II7+XAICifR0RaAVGfQijaqeekX 12 | 0Go63PTL+rPOsskDUjP+Tv/PVO08lQJAW50HsfUPkQsS8U7vYh2uw50EQNgCTSp6 13 | DdhVfM9+JaL02Oc7IDRug8r32Q/LZCYRFHPJsyr7dNXv0IRFgm6T4QJAKFOjDtZ3 14 | hCgG3dtnwyinPz3j6Qh4H/nmzYU8uxTsJ3+WEtlhlP3eKgyr3sb12yVcaZd/29Tk 15 | fm06t3CxTHaSEQ== 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /mycert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICfDCCAeWgAwIBAgIJAKgmQTbnwNzkMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV 3 | BAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARob21lMQ0wCwYD 4 | VQQKDARBQ01FMRUwEwYDVQQDDAxpbGx1c3RyYXRpb24wHhcNMTYwNjI3MDY1MDI4 5 | WhcNMTcwNjI3MDY1MDI4WjBXMQswCQYDVQQGEwJERTETMBEGA1UECAwKU29tZS1T 6 | dGF0ZTENMAsGA1UEBwwEaG9tZTENMAsGA1UECgwEQUNNRTEVMBMGA1UEAwwMaWxs 7 | dXN0cmF0aW9uMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpPlaFJbnu/15K 8 | 9ZL1Om9UeI67DyTYHcxoAF3T+9jMzRojiSdV/i/haKCzX9ar5Yf8HnIPbUWgzTHx 9 | DBR66izlHhB6KbRNqI9hrYe3MrWlpOGzYTEosRwa8YjNW+kCVVK0cz43SjUY9qGC 10 | Okxl9FqjabSIhNGq9WC+n+sse/LbvQIDAQABo1AwTjAdBgNVHQ4EFgQUbLZseq/j 11 | sE0FO+8js+xgpIQWFNAwHwYDVR0jBBgwFoAUbLZseq/jsE0FO+8js+xgpIQWFNAw 12 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQA2zRh2gK5ZympJ+0/e7FZg 13 | 6GHB0GnJlXvuTW47rsGspYYv0yfuUSyK5/HnIJXbWY4F7xmhbEVkAGc0d8d8uVHu 14 | WuWVBqFfUwkG/mKuLdq1O2X108+siaP8arDq5hbGeQb0KDl7MIvfHB6tZYrjXjIU 15 | TN1GlKASd6OsWbMbPs8zHA== 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /stock_int/static/style.css: -------------------------------------------------------------------------------- 1 | /* style.css 2 | (c) Dr Yves J Hilpisch 3 | The Python Quants GmbH 4 | */ 5 | 6 | body { font-family: 'PT Sans', sans-serif; background: #eee; } 7 | a, h1, h2 { color: #021A80; } 8 | h1, h2 { font-family: 'PT Sans', sans-serif; margin: 0; text-align: center;} 9 | h1 { font-size: 1.4em; border-bottom: 2px solid #eee; } 10 | h2 { font-size: 1.0em; } 11 | 12 | a:link { color: #B40404; text-decoration:none; } 13 | a:visited { color: #B40404; text-decoration:none; } 14 | 15 | .dataframe { margin-left: auto; margin-right: auto;} 16 | 17 | .page { font-family: 'PT Sans', sans-serif; margin: 2em auto; width: 66em; 18 | padding: 0.8em; background: white; color: #021A80} 19 | 20 | .metanav { text-align: right; font-size: 1em; padding: 0.3em; 21 | margin-bottom: 1em; background: #fafafa; } 22 | 23 | .logo img { width: 30%; display: block; margin-right: auto; 24 | margin-left: auto; } 25 | 26 | .errors { font-size: 0.8em; color: red;} 27 | 28 | .form {text-align: center;} 29 | -------------------------------------------------------------------------------- /stock_int/templates/selection.html: -------------------------------------------------------------------------------- 1 | 5 | {% extends "layout.html" %} 6 | 7 | {% macro render_field(field) %} 8 |
{{ field.label }} 9 |
{{ field(**kwargs)|safe }} 10 | {% if field.errors %} 11 | 16 | {% endif %} 17 |
18 | {% endmacro %} 19 | 20 | {% block body %} 21 | 22 |
23 |
25 |
26 |

Search for a Ticker Symbol


27 | 28 |
Data will be retrieved from Yahoo! Finance.
Make sure to use a valid ticker symbol.


29 | 30 |
{{ render_field( form.symbol ) }}

31 |
{{ render_field( form.trend1 ) }}

32 |
{{ render_field( form.trend2 ) }}

33 |
{{ render_field( form.submit ) }}

34 | 35 |
36 |
37 |
38 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /python_setup.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Python Installation (incl. Jupyter) 3 | # (c) Dr Yves J Hilpisch 4 | # The Python Quants GmbH 5 | # 6 | 7 | # A FEW SYSTEM TOOLS 8 | # ADD THINGS YOU WANT TO USE (e.g. Git) 9 | apt-get install htop unzip -y 10 | apt-get autoremove 11 | 12 | # INSTALL MINICONDA 13 | wget -q http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O Miniconda.sh 14 | bash Miniconda.sh -b 15 | rm Miniconda.sh 16 | export PATH="$HOME/miniconda2/bin:$PATH" 17 | 18 | cat >> ~/.profile <++") 36 | def results(symbol, trend1, trend2): 37 | data = web.DataReader(symbol, data_source='yahoo') 38 | data['Trend 1'] = data['Adj Close'].rolling(int(trend1)).mean() 39 | data['Trend 2'] = data['Adj Close'].rolling(int(trend2)).mean() 40 | url = data[['Adj Close', 'Trend 1', 'Trend 2']].iplot(asUrl=True) 41 | table = data.tail().to_html() 42 | return render_template('plotly.html', symbol=symbol, 43 | plot=url, table=table) 44 | 45 | 46 | if __name__ == '__main__': 47 | app.run(host='0.0.0.0', port=7777, debug=True) 48 | -------------------------------------------------------------------------------- /plotly_cufflinks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"datapark\"" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# pandas, Plotly & Cufflinks" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": null, 20 | "metadata": { 21 | "collapsed": true 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "import warnings; warnings.simplefilter('ignore')" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": { 32 | "collapsed": false 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "import numpy as np\n", 37 | "import pandas as pd\n", 38 | "from pandas_datareader import data as web\n", 39 | "import plotly.plotly as py\n", 40 | "import cufflinks as cf" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": { 47 | "collapsed": false 48 | }, 49 | "outputs": [], 50 | "source": [ 51 | "py.sign_in('Python-Demo-Account', 'gwt101uhh0')" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "## Reading Financial Data" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "metadata": { 65 | "collapsed": false 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "symbols = ['AAPL', 'MSFT', 'YHOO', 'FB']" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": { 76 | "collapsed": true 77 | }, 78 | "outputs": [], 79 | "source": [ 80 | "data = pd.DataFrame()\n", 81 | "for sym in symbols:\n", 82 | " data[sym] = web.DataReader(sym, data_source='yahoo')['Adj Close']" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": { 89 | "collapsed": false 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "data.tail()" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "## Plotting the Data" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": { 107 | "collapsed": false 108 | }, 109 | "outputs": [], 110 | "source": [ 111 | "data.iplot(filename='financial', world_readable=True)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": null, 117 | "metadata": { 118 | "collapsed": false 119 | }, 120 | "outputs": [], 121 | "source": [ 122 | "# daily log returns\n", 123 | "rets = np.log(data / data.shift(1))" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": { 130 | "collapsed": false 131 | }, 132 | "outputs": [], 133 | "source": [ 134 | "rets.iplot(subplots=True, kind='hist', filename='financial_hist',\n", 135 | " world_readable=True)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "\"datpark\"
\n", 143 | "\n", 144 | "datapark.io | @datparkio | team@datapark.io" 145 | ] 146 | } 147 | ], 148 | "metadata": { 149 | "kernelspec": { 150 | "display_name": "Python 2", 151 | "language": "python", 152 | "name": "python2" 153 | }, 154 | "language_info": { 155 | "codemirror_mode": { 156 | "name": "ipython", 157 | "version": 2 158 | }, 159 | "file_extension": ".py", 160 | "mimetype": "text/x-python", 161 | "name": "python", 162 | "nbconvert_exporter": "python", 163 | "pygments_lexer": "ipython2", 164 | "version": "2.7.11" 165 | }, 166 | "widgets": { 167 | "state": {}, 168 | "version": "1.1.2" 169 | } 170 | }, 171 | "nbformat": 4, 172 | "nbformat_minor": 0 173 | } 174 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Interactive Python in the Cloud 2 | 3 | This repository contains a few small files that allow to easily deploy Python (cf. http://python.org) and Jupyter Notebook (cf. http://jupyter.org) in the cloud. 4 | 5 | It all works even on the smallest **DigitalOcean droplet** (cf. https://m.do.co/c/fbe512dd3dac) which currently costs 5 USD per month with 1 CPU core, 512 MB of RAM and 20 GB of SSD storage. 6 | 7 | When setting up such a droplet it is recommended to use a current version of **Ubuntu**. 8 | 9 | I assume that you have **cloned the repository** to your local machine (Linux or Mac): 10 | 11 | ``` 12 | git clone --depth=1 https://github.com/yhilpisch/cloud-python 13 | ``` 14 | 15 | ## DigitalOcean Droplet 16 | 17 | If you do not have a **DigitalOcean account** yet, generate one here 18 | 19 | https://m.do.co/c/fbe512dd3dac 20 | 21 | You will start with 10 USD worth of compute power (= e.g. 2 monthly fees for the smallest droplet) although you'll only get charged the hours your droplet is alive. 22 | 23 | Now **create a droplet** giving it a name like "cloud-python" and chosing the size, location and operating system (e.g. Ubuntu 14.04). 24 | 25 | I recommend to post a public key for easy **ssh access** (cf. the tutorial under http://hilpisch.com/rpi/00_basic_config.html). 26 | 27 | When you have created the droplet, you are redirected to the droplet overview page which shows, among others, the **IP address of the droplet** which you should copy. 28 | 29 | Then navigate to the **repository folder** and do: 30 | 31 | ``` 32 | cd your-path-to/cloud-python 33 | bash setup_server.sh THE-IP-ADDRESS 34 | ``` 35 | 36 | The setup might take a while (about 4 minutes; you'll see the progress on the shell). The last step in the setup fires up a **Jupyter Notebook** server on the **port 8888**. You can access it in the browser under 37 | 38 | ``` 39 | https://THE-IP-ADDRESS:8888 40 | ``` 41 | 42 | There is **SSL encryption** enabled which uses by default the certificate files as provided in the repo (you should replace them by your own; see the comments in the respective Jupyter Notebook configuration file). This feature might require you to add a security exception in your browser due to the nature of the certificate files used. 43 | 44 | There is also **password protection** enabled (the password is by default **jupyter**). You should also replace the password hash key in the Jupyter Notebook config file by one of your own (again see the comments in the configuration file itself). 45 | 46 | After a successful login, you can now click on the example notebooks and play around. 47 | 48 | ## Flask Web app 49 | 50 | In Jupyter Notebook open a new **terminal** and navigate to the stock_int folder: 51 | 52 | ``` 53 | cd stock_int 54 | ``` 55 | 56 | Start the **example Flask application** as follows: 57 | 58 | ``` 59 | python stock_interactive.py & 60 | ``` 61 | 62 | The app should now be reachable under 63 | 64 | ``` 65 | http://THE-IP-ADDRESS:7777 66 | ``` 67 | 68 | ## Security 69 | 70 | Note that all this is quite **insecure**. All is run as root user and there is only password protection and encryption for the notebook server in place. It is only for illustration purposes. However, additional security features (e.g. for the Flask app) can easily be added to the set-up. 71 | 72 | ## datapark.io 73 | 74 | The easiest way to securely use Python, R, Julia, etc. in the cloud is to register under http://datapark.io. 75 | 76 | With a single registration you have a comprehensive set of **techonlogies, libraries and tools** available to do **data science in the browser**. 77 | 78 | ## Copyright, License & Disclaimer 79 | 80 | © Dr. Yves J. Hilpisch \| The Python Quants GmbH 81 | 82 | The code of this repository is BSD licensed (cf. http://opensource.org/licenses/BSD-3-Clause). 83 | 84 | The code in this repository comes with no representations or warranties, to the extent permitted by applicable law. 85 | 86 | http://tpq.io \| team@tpq.io \| 87 | http://twitter.com/dyjh 88 | 89 | **Python for Finance Training** \| http://training.tpq.io 90 | 91 | **datapark.io** \| http://datapark.io 92 | 93 | **Quant Platform** \| http://quant-platform.com 94 | 95 | **Python for Finance (O'Reilly)** \| 96 | http://python-for-finance.com 97 | 98 | **Derivatives Analytics with Python (Wiley Finance)** \| 99 | http://derivatives-analytics-with-python.com 100 | 101 | **For Python Quants Conference** \| http://fpq.io 102 | -------------------------------------------------------------------------------- /quandl_bitcoin.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\"datpark\"
" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Analyzing Bitcoin Data from Quandl.com" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": null, 20 | "metadata": { 21 | "collapsed": true 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "import warnings; warnings.simplefilter('ignore')" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": { 32 | "collapsed": false 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "import json\n", 37 | "import urllib\n", 38 | "import pandas as pd\n", 39 | "import matplotlib as mpl; mpl.use('agg')\n", 40 | "import seaborn as sns; sns.set()\n", 41 | "%matplotlib inline" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": { 48 | "collapsed": false 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "def read_quandl(url):\n", 53 | " d = json.loads(urllib.urlopen(url).read())\n", 54 | " df = pd.DataFrame(d['data'], columns=d['column_names']\n", 55 | " ).set_index('Date').sort_index()\n", 56 | " return df" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "## Number of Bitcoins" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "url = \"https://www.quandl.com/api/v1/datasets/BCHAIN/TOTBC.json\"" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": { 81 | "collapsed": false 82 | }, 83 | "outputs": [], 84 | "source": [ 85 | "number = read_quandl(url)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "Number of **Bitcoins in existence**." 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": { 99 | "collapsed": false 100 | }, 101 | "outputs": [], 102 | "source": [ 103 | "number.plot(figsize=(10, 5));" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "## Bitcoin Rate" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": { 117 | "collapsed": false 118 | }, 119 | "outputs": [], 120 | "source": [ 121 | "url = \"https://www.quandl.com/api/v1/datasets/BAVERAGE/USD.json\"" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": { 128 | "collapsed": false 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "quotes = read_quandl(url)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "**Historical** Bitcoin rate in USD." 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": { 146 | "collapsed": false 147 | }, 148 | "outputs": [], 149 | "source": [ 150 | "quotes[['24h Average', 'Total Volume']][quotes.index > '2012-12-31'].plot(\n", 151 | " subplots=True, figsize=(10, 6));" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "Bitcoin rate to the USD **in 2015** and later." 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [], 168 | "source": [ 169 | "quotes[['24h Average', 'Total Volume']][quotes.index > '2014-12-31'].plot(\n", 170 | " subplots=True, figsize=(10, 6));" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "\"datapark\"
\n", 178 | "\n", 179 | "datapark.io | @dataparkio | team@datapark.io" 180 | ] 181 | } 182 | ], 183 | "metadata": { 184 | "kernelspec": { 185 | "display_name": "Python 2", 186 | "language": "python", 187 | "name": "python2" 188 | }, 189 | "language_info": { 190 | "codemirror_mode": { 191 | "name": "ipython", 192 | "version": 2 193 | }, 194 | "file_extension": ".py", 195 | "mimetype": "text/x-python", 196 | "name": "python", 197 | "nbconvert_exporter": "python", 198 | "pygments_lexer": "ipython2", 199 | "version": "2.7.11" 200 | }, 201 | "widgets": { 202 | "state": {}, 203 | "version": "1.1.2" 204 | } 205 | }, 206 | "nbformat": 4, 207 | "nbformat_minor": 0 208 | } 209 | --------------------------------------------------------------------------------