Sunday, October 16, 2016

Stock charts with bokeh

Stock chart revisited

In the last blog entry we developed a stock chart using Bokeh's advanced features. One problem of that implementation was that all the parameters were passed into the chart generator in the form of dictionaries; these dictionaries are easy to use, but are prone to typing errors.

Today we'll take advantage of Python's OO features to make this library less error-prone, intuitive, and extensible. An OO version of this library will allow a good IDE help developers navigate the available classes to generate charts.

The main two goals in today's changes are:

* Change the library so that I can inject my own indicators.
* Use a builder pattern to easily generate charts.  The builder pattern is excellent to create interfaces with a large number of sparse parameters.
In [6]:
from bokeh.io import output_notebook, show
import pandas as pd
from stockcharts import *
output_notebook()
Loading BokehJS ...

The main classes

We will not go over the details on these changes. If you are really interested in the code or a working version of this ipython notebook, you can access my github account.

However, let's have a look at the prototype of the main classes:

StockChart: main class - creates stock charts.

class StockChart:
    def __init__(self, data):
    def set_title(self, title):
    def set_days(self, days):
    def set_look_and_feel(self, look_and_feel):     
    def add_indicator(self, indicator):
    def get_stock_chart(self):

LookAndFeel: encapsulates look and feel for this chart.

class LookAndFeel:
    def __init__(self):        
    def set_color_up(self, color):
    def set_color_down(self, color):
    def set_height(self, height):
    def set_width(self, width):

Indicator: extend this class to add your own indicators.

class Indicator(object):    
    def __init__(self, data, **kwargs):    
    def add_to_chart(self, stock_data, chart):

A basic chart

In [7]:
df = pd.read_csv("./data/spy.csv", nrows=350)
p= StockChart(df).get_stock_chart()
show(p)
Out[7]:

<Bokeh Notebook handle for In[7]>

Chart with some parameters and look and feel settings

In [8]:
df = pd.read_csv("./data/spy.csv", nrows=350)
p= StockChart(df) \
    .set_title("SPY") \
    .set_days(50) \
    .set_look_and_feel(LookAndFeel() \
                       .set_height(350) \
                       .set_width(800)) \
    .get_stock_chart()

show(p)
Out[8]:

<Bokeh Notebook handle for In[8]>

Chart with look and feel and indicators

In [9]:
df = pd.read_csv("./data/spy.csv", nrows=350)
p= StockChart(df) \
    .set_title("SPY") \
    .set_days(200) \
    .set_look_and_feel(LookAndFeel().set_width(800)) \
    .add_indicator(EmaIndicator(df, period=14)) \
    .add_indicator(BollingerIndicator(df, period=14)) \
    .get_stock_chart()

show(p)
Out[9]:

<Bokeh Notebook handle for In[9]>