Building a Stock Chart Display Application with Flask and Python

This post describes deploying a Flask-based application on a Linux system (Ubuntu, in this case) to display stock charts using Python.
The simplicity of Flask makes it an ideal choice for DevOps engineers looking to leverage Python for web projects.

Prerequisites

  • A Linux system (Ubuntu preferred)
  • Python installed (Python 3.6 or later recommended)
  • Basic familiarity with terminal commands and the Python environment

Step 1: Setting Up Your Environment

First, ensure you have Python and pip installed on your system. You can install Flask and other necessary libraries using pip. Open your terminal and run:

pip install Flask yfinance plotly pandas

Step 2: Preparing the Application Code

Create a file named app.py and open it in your preferred text editor. This file will contain your Flask application. The application will use yfinance to fetch stock data, plotly to generate candlestick charts, and pandas to manage data, including loading ticker symbols from a CSV file.

from flask import Flask, render_template, request
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd

app = Flask(__name__)

# Load tickers from an external CSV file
def load_tickers():
    df = pd.read_csv('tickers.csv')  # Ensure 'tickers.csv' is in the correct path
    return df['Ticker'].tolist()

def fetch_and_generate_plot(ticker, time_range, interval):
    data = yf.download(ticker, period=time_range, interval=interval)
    fig = go.Figure(data=[go.Candlestick(x=data.index,
                                         open=data['Open'],
                                         high=data['High'],
                                         low=data['Low'],
                                         close=data['Close'])])
    fig.update_layout(title=f'{ticker} Candlestick Chart',
                      xaxis_title='Date',
                      yaxis_title='Price',
                      xaxis_rangeslider_visible=False)
    return fig.to_html(full_html=False)

@app.route('/', methods=['GET', 'POST'])
def chart():
    tickers = load_tickers()
    ticker = request.args.get('ticker', tickers[0])
    time_range = request.args.get('time_range', '1mo')
    interval = request.args.get('interval', '1d')
    plot_div = fetch_and_generate_plot(ticker, time_range, interval)
    return render_template('chart.html', plot_div=plot_div, tickers=tickers, ticker=ticker, time_range=time_range, interval=interval)

if __name__ == '__main__':
    app.run(debug=True, port=8000)

Step 3: Creating the HTML Template

Within the same directory as your app.py, create a folder named templates. Inside this folder, create a file named chart.html. This template will render the form for selecting stock tickers and the plotly chart.

<!DOCTYPE html>
<html>
<head>
    <title>Stock Chart</title>
</head>
<body>
    <form action="/" method="get">
        <label for="ticker">Ticker:</label>
        <select name="ticker" id="ticker">
            {% for ticker in tickers %}
            <option value="{{ ticker }}" {% if ticker == selected_ticker %} selected {% endif %}>{{ ticker }}</option>
            {% endfor %}
        </select>

        <label for="time_range">Time Range (e.g., "1mo", "5d"):</label>
        <input type="text" id="time_range" name="time_range" value="{{ time_range }}">

        <label for="interval">Interval (e.g., "1d", "1h"):</label>
        <input type="text" id="interval" name="interval" value="{{ interval }}">

        <button type="submit">Update Chart</button>
    </form>
    {{ plot_div|safe }}
</body>
</html>

Step 4: Preparing the Ticker CSV File

Create a CSV file named tickers.csv in the same directory as your Flask app. This file should contain the ticker symbols you want to include in your application, with a header named Ticker.

Ticker
BTC-USD
ETH-USD
AAPL
MSFT
AMZN
GOOG
META

Step 5: Running the Application

Back in the terminal, navigate to the directory containing your Flask app and run:

export FLASK_APP=app 
export FLASK_ENV=development 
flask run --host=0.0.0.0 --port=8000

Now, the app is accessible from any device in your network via http://<your-server-ip>:8000.

See a sample page below


FYI: In a future post it will be described how to create a docker image from this python/flask code.

.