Case Study
February 17, 2023

How To Build a Stock Trading App

Combine data from IEX Cloud Apperate with IBKR’s brokerage API to build a trading app.

Cloud icon

Adrian Smart

https://iexcloud.io/community/blog/how-to-build-a-stock-trading-app
@iexcloud
https://iexcloud.io/community/blog/how-to-build-a-stock-trading-app
@iexcloud

Overview

What we'll build:

This article shows you how to create a web application that queries IEX Cloud Apperate (iexcloud.io) for information on publicly traded stocks such as price data, company financial metrics and recent news articles about the stock.

In addition, Interactive Brokers, a popular brokerage platform, is used to allow users to enter and execute stock orders directly from the web page.

By the end of this article, you’ll learn how to create rich web applications for your own use case that combine both data from Apperate and execute trades using a brokerage service, using the details in this article as a roadmap for your own implementation.

Target Audience

The target audience for this article is developers with moderate experience building web applications and integrating APIs. All code used to implement the example in this article is available on github.

Technology Stack

A web framework is dedicated software running on a server that accepts inbound HTTP requests, directs the request to the appropriate end point, and sends the response back to the requestor. There are many widely-used web frameworks such as Flask and Django. Django was ultimately chosen for this article.

Django

Django is an open-source web framework that uses the model-template-views architecture strategy to respond to web requests. The urls.py file maps incoming web requests to the views.py file which can load a specific HTML file in the templates folder. Consult the Django website for information on how to install and configure Django.

Chart.js

A key component of this project was a price chart that would constantly update the latest price data from Apperate at a regular time interval. Chart.js was identified as an easy-to-use solution. Consult the Chart.js docs for more information about this product.

HTML

HTML was used for the front end of this project. The user interface was chosen to be functional for the purposes of the demonstration. You can make many enhancements to the UI in your implementation, for instance using Cascading Style Sheets (CSS) and other solutions. The user interface designed for this article was chosen to be simple on purpose.

Interactive brokers

Interactive brokers (IBKR) is an online brokerage with a robust API that allows developers to enter orders programmatically. IBKR has two products, Trader Workstation and IB Gateway, that can be configured to receive and execute commands from another locally run program. In this example, TWS was chosen to process buy orders created from user input on our web page running locally. For instructions on how to download and install TWS please visit their documentation here.

Building the Price Chart

To build a price chart into a dashboard, start with pulling your data from IEX Cloud Apperate.

Apperate is IEX Cloud’s streaming financial data platform. It includes financial data readily available via API (also known as Core Data), as well as a suite of database capabilities that help you build and scale your application backend. For the purposes of this tutorial, you’ll use Apperate’s Core Data functionality. (IEX EDITOR'S NOTE: with the new data bundles introduced as of Feb. 2023 core financial data is offered for purchase through different data bundles. One of our Equities market bundles would be appropriate to use for this tutorial. Users can You can learn more about IEX Cloud Financial Data Bundles here.)

The data on Apperate is updated in real-time by API standards, although for actually executing trades many trading apps get the data from a market data vendor with cross-connect because there is still the latency of retrieving data via API.

There are front-end and back-end components for building a price chart. For simplicity, one HTML file was created for this project that handled displaying all the features including chart, company statistics, news, and user inputs like text fields and buttons. Chart.js provides the API to render datasets and labels.

Theurls.py file maps the incoming requests to the specific file and function that will be called with a simple interface: path('', views.index_entry,name='index').

This path entry means the landing page is mapped to index_entry where the render function is called on the chart.html file in the templates folder.

Insidethe chart.html, notice “myChart” is defined in the canvas id section. HTML will call this javascript variable later in the html file. MyChart is defined as a new Chart object with a constant config variable. The config is how Chart.js sets the type and style of the chart. See Chart.js documentation for further information on available style options. The data field is the most important config field to us. If a list of points is defined in the data list, Chart.js will immediately plot them. However, for our implementation we want a dynamically updating chart every minute as new price data becomes available in IEX Cloud Apperate, so I left the data list empty to start.

A poll function was written to enable the chart to dynamically update. This function is triggered when the “Track this Ticker” button is clicked on the page. It submits an AJAX query (https://en.wikipedia.org/wiki/Ajax_(programming)) to the /ChartData endpoint on the Django backend, passing the ticker from the text field as an input parameter. The update_price function inviews.py performs a Get request to an IEX Cloud Apperate endpoint:

https://cloud.iexapis.com/stable/stock/[ticker]/price?token=[Your token].

Once IEX returns the latest price data, update_price returns it to the front end. The poll function in the html file will create a new label which is today’s date in eastern time zone format and push the price and label into the chart dataset. Then calling chart.update() will force Chart.js to render the latest data to the page.

Displaying Company Data

A key component of our sample fintech application is a dashboard that displays company data and statistics such as market cap, employee headcount, ex-dividend date and the dividend yield. This information is accessible from Apperate with simple HTTP requests. (IEX EDITOR'S NOTE: Access to company data is now available for purchase through one of our Company Data bundles.)

Dashboard

A “Get Stats” button will be added underneath the price chart that displays company statistics from Apperate in a table format. The backend server is responsible for submitting all statistics requests to the individual Apperate endpoints and the front end is responsible for parsing the return package and placing the individual values in rows in the HTML table.

Front End Elements

A “Get Stats” button contains an action to call a JavaScript function. The stats function submits an AJAX query to the /stats endpoint on the server, passing it the ticker symbol from the HTML text field. The reason for usingAJAX queries is to allow the rest of the page to run independently from the stats table. The price chart will continuously update while the stats table is awaiting a response from the server.

The success function of the AJAX query handles processing the returned data. For simplicity, we can return all the statistics data in a JSON object. This is straightforward to parse by calling JSON.parse(data) and then the individual field values are placed in the stats Cells for the HTML table.

Back End Elements

The Django urls.py file maps the stats endpoint to the get_company_stats function in the views.py file. The request enters the function with the ticker symbol captured from the front-end page. The ticker symbol is concatenated with each specific URL string used to make Get requests to Apperate as well as your personal access token. For example, to get the employee headcount for a specific company the request will look like:

"https://cloud.iexapis.com/stable/stock/" +ticker + "/stats/employees?[Personal Token]”

The return from IEX is placed in a dictionary object and serialized to JSON before returning in a HTTP Response.

Displaying News

News headlines are another piece of data that users may like in addition to company statistics. This was captured the same way. On the backend, a news() function was added to views.py that makes a request to:

https://cloud.iexapis.com/stable/stock/[ticker]/news/last/1?token=[PersonalToken].

This request requires a ticker and the last number of news headlines you would like. (IEX EDITOR'S NOTE: Company News access is available for purchase through the Company News data bundle.)

For simplicity, I request only the last headline. This is returned to the web page as a JSON object.

 

On the front end, the news return object needs to be cleaned to remove stray characters like single apostrophes and replace them with double quotes so that JSON parsing will work correctly. After parsing, the headline and summary can be placed into cells in the HTML table.

Submitting Buy Orders to Interactive Brokers

The final feature added to the web application is a button that allows the user to submit a share purchase order to Interactive Brokers (IBKR), a popular online brokerage firm. The buy button submits an AJAX call with the ticker symbol and number of shares from the text field to the /Buy URL on the Django backend. This URL is mapped to the buy_stock function in views.py. All code for communicating with IBKR is written in a separate file called ibkr.py.

Establishing a Connection to IBKR TWS

Interactive Brokers offers a convenient API that allows developers to submit buy/sell orders for financial instruments among other capabilities. After installing the IBKR TWS application, run the GUI and select “Allow connections from localhost only” and enter 7497 (port number for paper trading) in the Socket port number field in the Global Configurations menu.

The TWS API has two classes, EWrapper and EClient that are used and overridden as required by the developer. As per IBKR TWS documentation, create a TestClient and TestWrapper class that inherits from the respective TWSclasses. Then create a third class, TestApp, that initializes the other two class objects.

After successful initialization, a connect request to IBKR’s servers can be attempted via the connect call passing the localhost IP address and the paper trading port number. This call will passthrough the TWS application that is running in the background. A successful connection or refusal message will appear in the TWS application log.

Submitting a Buy order to IBKR TWS

A successful connect request will result in a callback from IBKR. The callback will be intercepted by the next Valid Id function. Override this function in the Test App class and store the next valid order id provided by IBKR on a class member variable. When you submit an order, IBKR will check the next valid order number in the request matches what is stored on their server. A mismatch results in a rejected order.

To facilitate placing a buy order, create a buy function in the Test App class that calls the place Order function in Test Client. Test Client will override the place Order function on TWS’ EClient class, first creating an order and contract object and then calling the place order function on EClient, the parent class, via the super call. Several parameters must be specified in the order object such as the order action, type and total quantity of shares which is passed in from the text field on our web application. The contract object requires the ticker symbol, security type and exchange that lists the ticker. In our application, these parameters are hard coded for simplicity, but a more flexible implementation might allow the user to set these parameters dynamically on the page.

The place order request will pass through the TWS application running in the background and any successful execution or failure messages will appear in the TWS message log. TWS will also add the purchased securities to your portfolio. Once successfully executed, the buy function must increment the next valid order id by 1 to prepare for the next buy request.

 

The last piece that must be implemented to allow the web application to operate independently from the IBKR client is placing the client on a separate thread via Python’s threading library. This is done by creating an exec function and calling app.run() inside this function to start the connection process inside the mainline of the script.

The Python threading library will call the exec function once the thread is started. Without multithreading, the web application will block while our TWS client maintains a connection to IBKR’s servers.

Summary

In this tutorial, you learned how to build a web app that:

1. Pulls financial data from IEX Cloud Apperate and displays it within a dashboard, including stock prices, company data, and other essential stats. (IEX EDITOR'S NOTE: Learn about IEX Cloud Financial Data bundles in our docs.)

2. Integrates a brokerage service API to execute trades.

Keep in mind that if you wanted to bring in data from multiple sources into your app (not just IEX Cloud), the database capabilities included with Apperate help you do that with speed and ease. Learn more about Apperate here.

 I hope you enjoyed this tutorial and learned something new! Thanks for reading.