Visualizing Financial Market Data With Django, Bokeh & AlphaVantage API
Tags: python, datascience, django
Published: 2020-03-16 13:46:49

*As a web developer and a beginner enthusiast about applying data-science concepts to finance, I was searching for a way a show data with Django. I notice that there are not enough resources about so I decided to share how you can do it.*
In this post, We will build a web app with [Django](https://www.djangoproject.com/) to visualize with [Bokeh](https://docs.bokeh.org/en/latest/docs) the market data about **EUR/USD**.
I assume that you understand Python programming language and Django.
You'll also need an API key from [AlphaVantage](https://www.alphavantage.co/support/#api-key). They provide free Real-Time data about stock, forex and crypto markets.

## Step 1: Set up the environment 

We need to create an isolated Python environment. For this tutorial, I will use `virtualenv`.
```bash
mkdir RealFx
cd RealFx
virtualenv --python=/usr/bin/python3.8 env
source env/bin/activate
```
Now, we'll install the packages and create the Django app.
```bash
pip install django bokeh pandas 
django-admin startproject RealFx .
django-admin startapp mysite
```
Don't forget to add the app to your project settings. 
```python
#RealFx/settings.py

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    #others app
    'mysite',
]
```
Start the server.
```bash
python manage.py runserver
```
![Django Server](https://res.cloudinary.com/kolawole31/image/upload/v1584364117/1_6IZ-sXbX5_jo5oShyh1gRQ_iwhdnl.png)

## Step 2 : Utilities functions

To visualize data with Django & Bokeh, we first need to make an API call to AlphaVantage API. Then, we are going to convert the JSON response into dataframe pandas format that we'll use with Bokeh in your view.
As you see, it's already a lot of things and one function can't handle that.
So in `mysite` app folder, create a file `utils.py`. Let's add the first function.
```python
#mysite/utils.py
import requests
import pandas as pd
def get_data(from_symbol, to_symbol, API_KEY):
    r = requests.get('https://www.alphavantage.co/query?function=FX_DAILY&from_symbol=' + from_symbol + '&to_symbol=' + to_symbol + '&apikey=' + API_KEY)

    dataIntraday = r.json()

    return dataIntraday['Time Series FX (Daily)']
```
The second function will use pandas to convert the dictionary returned (dataIntraday['Time Series FX (Daily)']) of `get_data()` in dataframe pandas format.
```python
#mysite/utils.py
def convert_to_df(data):
    """Convert the result JSON in pandas dataframe"""
    
    df = pd.DataFrame.from_dict(data, orient='index')
    
    df = df.reset_index()

    #Rename columns

    df = df.rename(index=str, columns={"index": "date", "1. open": "open",
    "2. high": "high", "3. low": "low", "4. close": "close"})
    
    #Change to datetime

    df['date'] = pd.to_datetime(df['date'])

    #Sort data according to date

    df = df.sort_values(by=['date'])

    #Change the datatype

    df.open = df.open.astype(float)
    df.close = df.close.astype(float)
    df.high = df.high.astype(float)
    df.low = df.low.astype(float)
    
    #Checks
    df.head()
    df.info()

    return df
```
Now we can work on the view. 

# Step 3: Setting up the View

In view of the application, we can now use the power of Bokeh. The chart will be visualized as [Japanese candlesticks](https://www.babypips.com/learn/forex/what-is-a-japanese-candlestick).
```python
from django.shortcuts import render
from bokeh.plotting import figure, output_file, show
from bokeh.embed import components
import pandas as pd
from math import pi
import datetime
from .utils import get_data, convert_to_df

def homepage(request):
    
    #We use get_data method from utils

    result = get_data('EUR','USD', 'You_own_api_key') #Add your own APIKEY

    source = convert_to_df(result)

    # These lines are there to color
    # the red and green bars for down and up days

    increasing = source.close > source.open
    decreasing = source.open > source.close
    w = 12 * 60 * 60 * 1000
```
First, we use the methods of our `utils.py` file. We then convert the result into dataframe. The last lines are important for coloring and as we want to visualize in half-day.
```python
    TOOLS = "pan, wheel_zoom, box_zoom, reset, save"

    title = 'EUR to USD chart'

    p = figure(x_axis_type="datetime", tools=TOOLS, plot_width=700, plot_height=500, title = title)
    p.xaxis.major_label_orientation = pi / 4
    
    p.grid.grid_line_alpha = 0.3
    
    p.segment(source.date, source.high, source.date, source.low, color="black")
```
As we are dealing with time-series data, it's desirable to have an axis that can display labels that's are appropriate to different dates and time scales.
```python
    p.vbar(source.date[increasing], w, source.open[increasing], source.close[increasing],
        fill_color="#D5E1DD", line_color="black"
    )
    p.vbar(source.date[decreasing], w, source.open[decreasing], source.close[decreasing], 
        fill_color="#F2583E", line_color="black"
    )

    script, div = components(p)

    return render(request,'pages/base.html',{'script':script, 'div':div })

```
# Step 3: Show the data into the browser

Send data to HTML files in Django requires to store our templates files delicately.
In `mysite` application folder, create a folder `templates`. Then inside this folder, create another folder `mysite` (same name as your app). Then create a folder named `pages` and (We're almost done 😆), create HTML file `base.html`
If you noticed in the view file, the function `homepage` returns a dictionary of objects.
We need the HTML file to contain a div where the visualization will be displayed and the Bokeh dependencies in the file. 
CSS files in the head, and JS files at the end of the code. For the sake of performance.

```html
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>Financial Data</title>
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" />
</head>


<body>
	<nav class="navbar hero is-dark is-bold has-text-centered" role="navigation" aria-label="main navigation">
		<div class="navbar-brand">
			<a class="navbar-item">
				<h1 class="title has-text-weight-normal is-1 has-text-white">
					Django-Bokeh-AlphaVantage
				</h1>
			</a>
		</div>
	</nav>
	<section class="container">
		<div class="columns">
			<div class="column">

			</div>
			<div class="column is-6">
				{{ div | safe }}
			</div>
			<div class="column">

			</div>
		</div>
	</section>


	<script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.4.0/bokeh.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.4.0/bokeh-widgets.min.js"></script>
	{{ script | safe }}
</body>

</html>
```

# Step 5: URLs to views and Final configuration

We must indicate the routes to the views of our application.
Create `urls.py` in `mysite` folder and add these lines.
```python
#mysite/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.homepage, name='homepage')
]
```
Because we separated the URLs file, we should notify it in the project urls file.
```python
#RealFx/urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
    path('admin/', admin.site.urls),
    #mysite url file
    path('', include('mysite.urls')),
]
```
Now we're done. Let's see the data. 
![Result](https://res.cloudinary.com/kolawole31/image/upload/v1584363999/Screenshot_2020-03-16_Financial_Data_vfjgbv.png)
And Voilà.

## Conclusion

In this post, I showed you how to visualize financial data with Django & Bokeh. Every article can be made better, so please leave your suggestions and contributions in the comments below. If you have questions about any of the steps, you are welcome in the comment section.
Check the [Github repo](https://github.com/Kolawole39/RealStock).