3 min read

H2O Wave App Tutorials

H2O Wave is a new Open Source Pythonic framework for building applications. It lets you focus only on your code without worrying about CSS, Javascript, etc.
H2O Wave App Tutorials
Photo by Silas Baisch / Unsplash

Just like what I did with my general H2O-3 Tutorials, I'm starting a seperate H2O Wave Tutorial post for you all here. I will add to this as I go along and build more apps.

Stock Chart Generator Wave App

This is a simple candlestick chart generator that defaults to JNJ when you load it. All you need to do is add your Alphavantage API key where it says "apikey": "XXXXXXX" } #ENTER YOUR ALPHAVANTAGE KEY HERE

The app is pretty simple and looks like this:

{{< img src="stockchart.png" alt="Wave App Stock Chart Generator" >}}

I need to refactor the code and write it better, but it works!

from h2o_wave import site, ui, app, Q, main

import numpy as np

from bokeh.models import HoverTool
from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import file_html
from bokeh.palettes import Spectral6
from bokeh.models import Span, Label, Title, Legend, LegendItem, ColumnDataSource

from bokeh.io import curdoc, show
from bokeh.models import ColumnDataSource, Grid, Line, LinearAxis, Plot
from bokeh.resources import INLINE

import bokeh.io

from math import pi

import pandas as pd

import requests

import datetime as DT
from datetime import datetime
from datetime import date
import sys, os

import time as tt

@app('/')
async def serve(q: Q):

    print(q.args)

    # Grab a reference to the page at route '/stock'
    #page = site['/stock']

    q.page['title'] = ui.header_card(box='1 1 8 1', title='Stock Chart Generator', icon='shoppingcart', icon_color='yellow', subtitle='')

    # Add a markdown card to the page.
    #q.page['title'] = ui.markdown_card(
    #    box='1 1 8 1',
    #    title='Stock Charts',
    #    content='For the Investors that want to lose Money!',
    #)

    #This does nothing yet.
    #q.page['alpha'] = ui.form_card(box='1 2 2 4', items=[
    #    ui.text_l(content='Enter Your Alphavantage API Key'),
    #    ui.textbox(name='junk', label='Enter API'),
    #    ui.button(name='show_inputs', label='Submit', primary=True),])

    if q.args.textbox:
        q.page['stockform'] = ui.form_card(box='1 2 2 4', items=[
            ui.text_l(content='Enter a Stock Symbol.'),
            ui.textbox(name='textbox', label='Enter a Stock Symbol'),
            ui.button(name='show_inputs', label='Submit', primary=True),]
            )
    else:
        q.page['stockform'] = ui.form_card(box='1 2 2 4', items=[
            ui.text_l(content='Enter a Stock Symbol.'),
            ui.textbox(name='textbox', label='Enter a Stock Symbol'),
            ui.button(name='show_inputs', label='Submit', primary=True),]
                                           )
        q.args.textbox = 'JNJ'
# Get Data

    instrument = q.args.textbox

    API_URL = "https://www.alphavantage.co/query"

    symbol = instrument

    data = { "function": "TIME_SERIES_DAILY",
         "symbol": symbol,
         "outputsize" : "compact",
         "datatype": "json",
         "apikey": "XXXXXXX" } #ENTER YOUR ALPHAVANTAGE KEY HERE

# https://www.alphavantage.co/query?function=SMA&symbol=IBM&interval=weekly&time_period=10&series_type=open&apikey=demo

    response = requests.get(API_URL, data)
    response_json_stock = response.json() # maybe redundant

# Test Chart Building

#Manipulate OHLC Frame
    data = pd.DataFrame.from_dict(response_json_stock['Time Series (Daily)'], orient= 'index').sort_index(axis=1)
    data = data.rename(columns={ '1. open': 'Open', '2. high': 'High', '3. low': 'Low', '4. close': 'Close', '5. volume':'Volume'})
    data = data[['Open', 'High', 'Low', 'Close','Volume']]
    data['Date'] = data.index

    data['Date'] = pd.to_datetime(data['Date'])

# Set up Bokeh Frame
    inc = data.Close > data.Open
    dec = data.Open > data.Close
    w = 12*60*60*1000 # half day in ms

    p = figure(x_axis_type="datetime", sizing_mode='stretch_both', plot_width=800, title = str(instrument) + " Stock")

    p.segment(data.Date, data.High, data.Date, data.Low, color="black")

    p.vbar(data.Date[inc], w, data.Open[inc], data.Close[inc], fill_color="green", line_color="black")
    p.vbar(data.Date[dec], w, data.Open[dec], data.Close[dec], fill_color="red", line_color="black")

    p.xaxis.major_label_orientation = pi/4
    p.grid.grid_line_alpha=0.3

    p.add_layout(Title(text="Date", align="center"), "below")
    p.add_layout(Title(text= str(instrument)+' Price $', align="center"), "left")

# Export html for our frame card
    html = file_html(p, CDN, "plot")

    q.page['chart'] = ui.frame_card(
    box='3 2 6 8',
    title='Stock Chart',
    content=html,
    )

# Finally, save the page.
    await q.page.save()