Building an Analysis Web Application Using Streamlit
Kenneth See, ACCA
Feb 20, 21
Creating a scalable and user-friendly web application for financial analysis using solely Python code.  *Missing Thumbnail*

Vanilla Python programs and Jupyter Notebook scripts can be very powerful tools to wrangle, analyze, and visualize data. However, they do not have the best user interfaces. What happens when you want your program to be used by a non-technical user that does not know how to operate command-line tools and shells? Building your program as a web application provides the ability to take in input and display output via an interface that most people would be familiar with.

 

My web app

 

In this article, I will be demonstrating how I built a simple web application to retrieve public financial data and calculated an expected share price based on the Discounted Dividend Model (DDM).

DDM formula

 

My application leveraged the Streamlit framework, which is an open-source framework that enables web applications to be built entirely using Python code. To use Streamlit, you will just need to install the package in your virtual environment:

 

pip install streamlit

 

Project structure

 

My project structure for this application is split into three main components: the main file, helper functions, and constants.

 

DDM project structure

 

This allows for greater readability and scalability of my program code.

 

Helper functions

 

As seen in my project structure, I have a file called market_data_helpers.py. The purpose of this script is to maintain functions that would assist with retrieving relevant market data. The following packages will need to be imported at the head of this script to enable the functions to be written to work:

 

import json
import requests

 

I included the retrieve_data function that I had written in a previous article regarding retrieving public financial data via API.

 

def retrieve_data(function: str, symbol: str, api_key: str) -> dict:
    """
    Retrieves data from AlphaVantage's open API.
    Documentation located at: https://www.alphavantage.co/documentation
    """
    # query from API
    url = f'https://www.alphavantage.co/query?function={function}&symbol={symbol}&apikey={api_key}'
    response = requests.get(url)
    # read output
    data = response.text
    # parse output
    parsed = json.loads(data)
    
    return parsed

 

Checking the output of the Overview report, I determined that the "Name" and "DividentPerShare" keys contained the information I needed. I then wrote two more functions in market_data_helpers.py to extract the name and dividend per share values.

 

def extract_name(overview) -> str:
    return overview['Name']


def extract_dividend_per_share(overview) -> float:
    try:
        dps = float(overview['DividendPerShare'])
    except:
        # handle "none"
        dps = 0.0
    return dps

 

Constants

 

I created a file called api_keys.py to store my Alpha Vantage API key. This would allow me to retrieve my API key without having to explicitly write it in my main function.

 

Main

 

The main.py script puts everything all together.

 

To use the streamlit framework, the streamlit package has to be imported in the script.

 

import streamlit as st

 

I also imported my Alpha Vantage API key and the helper functions written above.

 

from constants.api_keys import API_KEYS
from helpers.market_data_helpers import retrieve_data, extract_dividend_per_share, extract_name

 

A function called ddm was created to execute the DDM logic based on the given formula above.

 

def ddm(dividend: float, r: float, g: float) -> float:
    return (dividend * (1 + g))/(r - g)

 

Finally, I implemented the main function which would dictate how the web application works. I used the text_input and number_input methods from the Streamlit library to receive ticker, expected growth rate, and discount rate values from the user.

 

ticker = st.text_input('Please input ticker of stock you wish to analyze')
g = st.number_input('Expected annual growth')
r = st.number_input('Discount rate')

 

I then created a button using the button method in the Streamlit library. 

 

calculate_button = st.button('Calculate DDM')

 

The value returned from this button will be false by default, but will become true once it is clicked. I could then have my program check if the button was clicked by checking the boolean value returned, and execute the DDM analysis if the value is true.

 

The execution of the analysis is as follows:

 

  1. Retrieve the Overview report of the company associated with the given ticker using the retrieve_data helper function.
  2. Extract the name and dividend per share within the Overview report using the extract_name and extract_dividend_per_share helper functions.
  3. Calculate the expected price based on the DDM model using the ddm function created earlier.

The entirety of the main.py script is as follows:

 

import streamlit as st
from constants.api_keys import API_KEYS
from helpers.market_data_helpers import retrieve_data, extract_dividend_per_share, extract_name


def main():
    st.title('Welcome to Fundamentals Analyzer')

    ticker = st.text_input('Please input ticker of stock you wish to analyze')
    g = st.number_input('Expected annual growth')
    r = st.number_input('Discount rate')

    calculate_button = st.button('Calculate DDM')

    if calculate_button:
        if ticker == '':
            st.error('Please provide a ticker.')
        else:
            overview = retrieve_data('OVERVIEW', ticker, API_KEYS['alpha_vantage'])

            name = extract_name(overview)
            dividend = extract_dividend_per_share(overview)

            st.header(f'Analysis for {name}')
            
            st.subheader('Expected Share Price (based on DDM)')
            st.write(str(round(ddm(dividend, r, g), 2)))


def ddm(dividend: float, r: float, g: float) -> float:
    return (dividend * (1 + g))/(r - g)


if __name__ == '__main__':
    main()

 

Deploying the application

Once the code is completed, the application can be deployed locally by navigating to the project folder in the command line and running it using Streamlit:

 

streamlit run main.py

 

The web application should then be launched on localhost and it can be viewed in a browser.

 

Web app

 

To deploy the application to a public domain, where other people would be able to utilize the application by simply navigating to the URL, consider deploying it to a hosting platform. My personal favorite is Heroku, which is free to use and allows for seamless deployment.