Building An Interactive Stock Market Profile Chart Using Streamlit and Python Plotly Library
By: Bee Guan Teo
Tags: Streamlit, Stock Market, Data Science, Plotly, Python

Market Profile Chart Development

Setting Streamlit Configuration

In the beginning, it is important to set our Streamlit app layout in landscape mode to offer an extended horizontal view of our stock market profile.

Line 1: Use Streamlit set_page_config to set the required configuration for the Streamlit app.

Line 2: Define the browser tab title.

Line 3: Set the layout to “wide” so that it can fit all the chart components in a landscape view.

Note: set_page_config must be the first Streamlit command and it can only be set once. Any violation will result in an error.

Create two drop-down lists

Here we create two drop-down lists using Streamlit in the sidebar. One drop-down list is to select an S&P 500 stock and another one is to choose a time interval to query historical stock prices using yFinance at a later stage.

Line 1–3: Use selectbox method to create the first drop-down list. selectbox accepts two parameters: label and options list (e.g. symbols). The selectbox is preceded by sidebar so that the drop-down list is created in the sidebar corner.

Line 4–6: Repeat a similar way above to create another drop-down list to select the time interval of the stock price. We limit our choice to only 4 options (“1m”, “5m”, “15m” and “30m”) with “m” referring to “minutes”.

We can instantly visualize the two drop-down lists we have just created above by running our Streamlit app. To run the app, simply type the following command in our terminal/command prompt.

streamlit run YourPythonFileName.py

The Streamlit app will be up and running on our web browser and we shall see the two drop-down lists appears at the sidebar corner.

Image prepared by the author

Whenever we select a stock or a time interval from the drop-down lists, the chosen values will be stored at the variable ticker and i, respectively.

Create a Numerical Input Field

Now, let us add another numerical input field to the sidebar. The numerical input field will accept an integer to denote the number of end-of-day (EOD) stock prices data.

Line 1: We use the Streamlit number_input method to create a numerical input field. The method enables us to define the minimum input value (min_value), the maximum input value (max_value) and the incremental step (step). Here we limit the input value in a range of 1–30 with an incremental step of 1.

Image prepared by the author

The numerical input field will appear at the sidebar corner below the second drop-down list created earlier.

Acquisition and Processing of EOD Stock Price Data

With the dropdown lists and the input field ready, we can now proceed to use the input values to acquire EOD stock price data using yFinance API.

Line 1: yFinance offers a Ticker object which accepts a ticker symbol as an input parameter. When we choose a ticker symbol from the first drop-down list, the symbol value will be stored at the variable ticker and accepted as an input to the Ticker object. This will prompt the yFinance API to query stock data from Yahoo Finance and return all the relevant stock data to variable stock.

Line 2: We make use of history method to selectively obtain the EOD stock prices within a defined timeframe. We set the interval and the period, using the input time interval, (i) and the number of days, (p) from the second drop-down and the numerical input field, respectively. This will return the EOD stock prices in a dataframe format and store them to the variable history_data.

Line 3–4: Assign closing prices and volume to variable price and volume, respectively.

Line 7–9: We are going to break down our stock prices into 20 bins. To do so we first get the min and max of the stock prices and then use NumPy linspace to create 20 equally distributed bins. (This is a required preliminary step to build a horizontal bar chart at a later stage.)

Line 11: Create a 20-elements zero list, vol_ax, using the Numpy zeros. (This is also a required preliminary step to build a horizontal bar chart at a later stage.)

Accumulating Volume for Each Price Level

At this stage, we have already created 20 equally distributed bins which are stored at the prices_ax list. and each bin represents one price level. As mentioned in the early beginning, a market profile is a chart used to displays the total of stock volumes executed at each price level. To do so, we will need to create a mechanism to accumulate the stock volume for each price level.

Line 1–3: Create a for loop to iterate through the stock prices and check if the current stock prices, prices[i], fall within the range of the first price level, price_ax[0] and the second price level, price_ax[1]. If so, accumulate the current volume, volume[i], to vol_ax[0].

Line 5–60: If prices[i] doesn’t fall within the range of the first and second price level, the app will move the program flow onto the next elif block to check the prices[i] against the subsequent price levels until the condition is met and accumulate current volume, volume[i] to the correct vol_ax element.

Create Plotly Subplots

At last, we are ready to use Plotly Library to create our desired market profile chart which consists of two subplot components.

First subplot: A horizontal bar chart to show the distribution of total volume for each price level. Second subplot: A candlesticks chart to show the fluctuation of stock prices over the time series.

Line 1–6: We use Plotly make_subplots method to define a plot figure made of one row and two columns of subplots. We can also configure the column width and horizontal spacing here.

Line 8–17: Create a horizontal bar chart using Plotly go.bar object. We set the vol_ax as the values of the x-axis and the prices_ax as the values of the y-axis. We display the price level as the annotation text on the bar chart. The orientation is set to “h” so that the bar chart is rendered horizontally.

Once the configuration of the bar chart is done, set the bar chart as the subplot positioned in row-1 and col-1. Use add_trace method to add the first subplot to the plot figure.

Line 19–30: Create candlesticks chart using Plotly go.Candlestick object. Building a candlestick chart in Plotly is as easy as just assigning the opening prices, highest prices, lowest prices, and closing prices values obtained from the yFinance API in the earlier step to the attributes of open, high, low and close in the go.Candlestick object. We also need to set the date & time of the stock prices as the values of the x-attribute.

(There is a caveat to handle the date & time values. We have to convert the date & time into a string format (Line 19). This is to avoid a broken date range in our Candlestick chart due to the stock market closed over the weekend or public holiday)

Once the configuration of the candlestick chart is done, set the chart as the subplot positioned in row-1 and col-2. Use add_trace method to add the second subplot to the plot figure.

Line 32–52: Use the update_layout method to configure the layout of the plot such as setting the title, turning off the x-axis and y-axis labels and aligning the y-axis to the right.

Line 54–56: Add a line drawing toolkit to our generated Plotly chart. This is a useful feature offered by Plotly which enables us to interact with the plot by interactively drawing lines onto the plot surface.

Line 58: At last, we use the Streamlit plotly_chart method to render the completed market profile chart onto the web browser.