Quick Start

Connect a Chart to a Live Data Source

ChartIQ charts pull data from live data sources as needed, automatically retrieving data in response to user interaction or elapsed time.

Charts acquire data by means of callbacks that connect with the data source. The ChartIQ chart engine executes the callbacks whenever the chart needs data, which is whenever the chart:

  • loads or reloads in a web page,
  • scrolls forward or backward in time (referred to as pagination), or
  • requires real-time updates.

The callbacks are made available to the chart engine as methods of a JavaScript object known as a quote feed.

In this tutorial

You will attach a quote feed to a basic chart.

Before you begin

This tutorial is a continuation of the Quick Start introduction. Please complete the introductory tutorial before proceeding.

About quote feeds

A quote feed contains three callback methods:

  • fetchInitialData — Called when the chart loads or reloads
  • fetchUpdateData — Called when the chart requires real-time updates
  • fetchPaginationData — Called when the chart paginates (scrolls forward or backward in time)

The basic JavaScript structure of a quote feed is:

const quoteFeed = {};
quoteFeed.fetchInitialData = function(symbol, startDate, endDate, params, cb) {};
quoteFeed.fetchUpdateData = function(symbol, startDate, params, cb) {};
quoteFeed.fetchPaginationData = function(symbol, startDate, endDate, params, cb) {};

The parameters are similar for the three methods:

Parameter Type Description
symbol string A stock symbol, such as SPY
startDate Date The starting date of the fetched time series data
endDate Date The ending date of the fetched time series data
params object Additional information about the data request, such as:
  • interval — time unit of the data points (minute, day, week, etc.)
  • period — length of the interval (for example, 5)
    Interval and period combine to specify the periodicity of the data; for example, five minutes, where each data point represents a span of five minutes.
  • extended — whether to include extended trading hours data for stock quote feeds
cb function A callback function that makes the response from the data provider available to the chart engine. The callback function has an object parameter, which should contain the response from the data provider. The response is either an array of data or an error message; for example { quotes: quotesArray } or { error: errorTextOrStatusCode }.

The chart engine provides arguments for all of the parameters. The intelligence built into the chart engine enables it to formulate the start and end dates and other parameter values for each of the callback functions.

Attaching a quote feed

A quote feed is added to the chart engine by means of the engine's attachQuoteFeed method. The method signature is:

attachQuoteFeed(quoteFeed, behavior, filter)
  • quoteFeed — A quote feed object.

  • behavior — An object that contains various settings related to the quote feed, such as the refresh interval (the time span for repeatedly requesting real-time updates).

  • filter — A function that determines whether the quote feed is used for a particular instrument, such as a specific stock. The filter function takes an object parameter typically containing symbolObject, symbol, and interval properties. The properties associate the quote feed with an instrument. If the filter function returns true, the quote feed is used for the instrument. Multiple quote feeds can be attached to the chart engine; filters enable selective use of the quote feeds.

Creating a quote feed

You create quote feeds to provide your charts with data. The quote feed callback functions make API calls to a data source. The response of a successful API call contains the requested data, which is returned to the chart engine and displayed on your charts.

Let's look at an example that uses a RESTful API.

The sampleQuoteFeed.js file in the chartiq/examples/feeds folder creates a basic quote feed. Open the file in your editor.

Source code

Let's look at the key pieces of sampleQuoteFeed.js.

Quote feed object

const quoteFeed = {};

The quote feed object contains the callback functions called by the chart engine. The quote feed is made available to the chart engine by means of the chart engine's attachQuoteFeed method.

Quote feed URL

quoteFeed.url = "https://simulator.chartiq.com/datafeed";

The quote feed URL is the endpoint of the HTTP requests made by the quote feed callback functions. The endpoint of the sample quote feed is the ChartIQ quote feed simulator, which simulates a real-time stock quote data feed. The simulator is useful for development. However, in production applications, you will set the URL to a real data provider.

fetchInitialData

quoteFeed.fetchInitialData = function (symbol, startDate, endDate, params, cb) {
    var queryUrl = this.url +
        "&identifier=" + symbol +
        "&startdate=" + startDate +
        "&enddate=" + endDate +
        "&interval=" + params.interval +
        "&period=" + params.period +
        "&extended=" + 1;

    this.sendAjax(queryUrl, function (status, response) {
        if (status == 200) {
            var newQuotes = quoteFeed.formatChartData(response);
            cb({ quotes: newQuotes });
        } else {
            cb({ error: response ? response : status });
        }
    });
};

The fetchInitialData callback function is called when the chart loads or reloads in a web page.

The function adds query parameters to the RESTful API endpoint (which is assigned previously in the script). The query parameters provide the specifications for the requested data. (See About quote feeds above.)

Note: The quote feed simulator returns data only during U.S. stock market trading hours for symbols traded on those markets. Market hours are typically 9:30 a.m. to 4:00 p.m. U.S. eastern time, Monday through Friday (excluding holidays). The extended parameter controls whether the simulator also returns data during extended trading hours, 6:00 a.m. to 9:30 a.m. and 4:00 p.m. to 8:00 p.m. U.S. eastern time. To enable extended hours, set extended to 1; to disable extended hours, 0.

The request to the data provider is made by means of the sendAjax method, which is a convenience function defined in sampleQuoteFeed.js. The method makes HTTP requests using XMLHttpRequest objects, but you can use any means required to access your data feed. The arguments provided to the sendAjax method specify the URL of the request and a callback function that is called when the HTTP request returns its response.

The callback function first checks whether the request completed successfully (HTTP status 200 OK). If the request was successful, the function formats the response to be compatible with the data format required by the ChartIQ chart engine (see formatChartData below). Then the callback function (cb) provided by the chart engine is called with the formatted response data (newQuotes) as an argument. If the HTTP request was not successful, the chart engine's callback function is called with an error message or error code as the argument.

fetchUpdateData

quoteFeed.fetchUpdateData = function (symbol, startDate, params, cb) {
    var queryUrl = this.url +
        "&identifier=" + symbol +
        "&startdate=" + startDate +
        "&interval=" + params.interval +
        "&period=" + params.period +
        "&extended=" + 1;

    this.sendAjax(queryUrl, function (status, response) {
        if (status == 200) {
            var newQuotes = quoteFeed.formatChartData(response);
            cb({ quotes: newQuotes });
        } else {
            cb({ error: response ? response : status });
        }
    });
};

The fetchUpdateData callback function is called when the chart requires real-time updates.

The function is very similar to the fetchInitialData callback function. The only difference is the lack of an end date for the data request, because the fetchUpdateData callback function requests all data from the start date (essentially, the current moment) forward into the future.

fetchPaginationData

quoteFeed.fetchPaginationData = function (symbol, startDate, endDate, params, cb) {
    var queryUrl = this.url +
        "&identifier=" + symbol +
        "&startdate=" + startDate +
        "&enddate=" + endDate +
        "&interval=" + params.interval +
        "&period=" + params.period +
        "&extended=" + 1;

    this.sendAjax(queryUrl, function (status, response) {
        if (status == 200) {
            var newQuotes = quoteFeed.formatChartData(response);
            // Provide five days of historical data.
            cb({
                quotes: newQuotes,
                moreAvailable: startDate.getTime() > Date.now() - 86400000 * 5
            });
        } else {
            cb({ error: response ? response : status });
        }
    });
};

The fetchPaginationData callback function is called when the chart scrolls through time — forward or backward.

The important difference in this callback function is the moreAvailable property returned to the chart engine in the argument passed to the chart engine's callback function.

At some point, as the chart scrolls forward or backward through time, no more data may be available. At that point, your callback function needs to inform the chart engine that it can provide no more data; otherwise, the chart engine will continue to make requests. The callback function informs the chart engine by setting moreAvailable to false.

The fetchPaginationData callback function learns that no more data is available when the HTTP request returns a status of 404 or any other status besides success. Different data providers may return different indications of no more data.

The quote feed simulator always returns a status of 200, even when it doesn't provide any more simulated data; and so, the sample quote feed has been rigged to set moreAvailable to false when more than five days of past data is requested.

Note: The days are chronological, including weekends and holidays (on which no stock quote data is created). As a result, you may not see a full five days of data as you scroll back through the sample data.

formatChartData

quoteFeed.formatChartData = function (response) {
    var data = JSON.parse(response);
    var newQuotes = [];
    for (var i = 0; i < data.length; i++) {
        newQuotes[i] = {};
        newQuotes[i].DT = data[i].DT;
        newQuotes[i].Open = data[i].Open;
        newQuotes[i].High = data[i].High;
        newQuotes[i].Low = data[i].Low;
        newQuotes[i].Close = data[i].Close;
        newQuotes[i].Volume = data[i].Volume;
    }
    return newQuotes;
};

The ChartIQ chart engine requires stock quote feed data to be in a specific format. The engine accepts an array of JavaScript object literals formatted as follows:

{
    DT: "2020-01-29T13:30:00.000Z",
    Open: 43.97,
    High: 43.97,
    Low: 43.75,
    Close: 43.94,
    Volume: 1003200
}

The objects represent the chart data points and must be in chronological order in the array based on the DT property.

DT must be an instance of a JavaScript Date object or an ISO 8601 string. All other values must be numbers. Open, High, Low, Close, and Volume represent transaction aspects of stock trades.

You must ensure that the data returned by your data provider is converted to this format. At a minimum, the response (which is typically an array of JSON data) must be converted to an array of JavaScript objects (which is accomplished by the call to JSON.parse() in formatChartData).

Attach the sample quote feed

The helloworld.html file in the chartiq folder of your library displays a chart using a static data source. Open the file in your code editor, and we'll update helloworld.html to use the sample quote feed.

First, include the sample quote feed in the application by adding the following import statement after the import of sample5min from STX_SAMPLE_5MIN.js:

import quoteFeed from "./examples/feeds/sampleQuoteFeed.js";

To get quote feed support, we need to import the file standard.js for its side effects; standard.js is the next step up in functionality from chartiq.js.

Add the following import statement:

import "./js/standard.js";

Place the import immediately above the statement that imports the CIQ namespace, for example:

import "./js/standard.js";
import { CIQ } from "./js/chartiq.js";

Next, remove the masterData parameter from the loadChart function call (the quote feed will now provide the data). The resulting function call should be:

stxx.loadChart("SPY", {
    periodicity: {
        period: 1,
        interval: 5,
        timeUnit: "minute"
    }
});

You can also remove the import statement for the STX_SAMPLE_5MIN.js file:

import sample5min from "./examples/data/STX_SAMPLE_5MIN.js";

Finally, attach the sample quote feed to the chart engine by adding the following line of code:

stxx.attachQuoteFeed(quoteFeed, { refreshInterval: 1 });

Add the statement just after the statement that instantiates the chart engine, for example:

let stxx = new CIQ.ChartEngine({
	container: document.querySelector(".chartContainer")
});

stxx.attachQuoteFeed(quoteFeed, { refreshInterval: 1 });

The refreshInterval setting informs the chart engine to request updates (that is, call fetchUpdateData) every second.

Here's the revised version of helloworld.html:

<!doctype html>
<!--
This file provides an example of the most basic way to load a chart into an HTML page. It includes no UI.
-->
<html>
<head>
<!-- Set the display for mobile devices. -->
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

<!-- Reference the default style sheet. -->
<link rel="stylesheet" type="text/css" href="css/stx-chart.css" media="screen" />
</head>

<body>

<!--
Create the chart container. The container can be positioned anywhere on your web page and sized any way you wish,
but the CSS position property must have the value "relative".
-->
<div class="chartContainer" style="width:800px;height:460px;position:relative;"></div>

<!-- This inline script acts as the entry point, without creating a separate external file. -->
<script type="module" crossorigin="use-credentials">

// Reference a quote feed.
import quoteFeed from "./examples/feeds/sampleQuoteFeed.js";

// Reference functionality of the charting library.
import "./js/standard.js";
import { CIQ } from "./js/chartiq.js";

// Instantiate a CIQ.ChartEngine object, the main object for creating charts.
let stxx = new CIQ.ChartEngine({
    container: document.querySelector(".chartContainer")
});

// Make real-time data available to the chart.
stxx.attachQuoteFeed(quoteFeed, { refreshInterval: 1 });

// Display the chart.
stxx.loadChart("SPY", {
    periodicity: {
        period: 1,
        interval: 5,
        timeUnit: "minute"
    }
});

</script>

</body>
</html>

Load the updated helloworld.html file in your web browser. You should see a candle chart containing five days of simulated data (if no weekends or holidays intervene). Swipe the chart to scroll backward and forward through the data.

Note: If your chart doesn't display data, check whether the stock markets are open. The quote feed simulator returns data only during U.S. stock market trading hours for symbols (such as SPY) traded on those markets; typically, 9:30 a.m. to 4:00 p.m. U.S. eastern time, Monday through Friday (excluding holidays), or 6:00 a.m. to 8:00 p.m. U.S. eastern time if the extended parameter is set to 1 in the quote feed callback functions (see Creating a quote feed above).

Conclusion

The sample quote feed is a fully functional example. Assuming you are using a RESTful API in your production environment, replace the quote feed URL with a real data provider and revise the formatChartData function to properly format the returned data, and you'll have a basic production-ready data feed.

Note: Hang onto your revised version of helloworld.html; we'll use it in the next tutorial.

Next steps