Tutorials
Getting started
Chart interface
Web components
Chart internals
Data integration
Customization
Frameworks and bundlers
Mobile development
Plug-ins
Troubleshooting
Glossary
Reference
JSFiddles

Data Integration: Advanced

Before proceeding, be sure you have read and understood the following:

Multiple Quote Feeds

Your chart implementation may require quotes from more than one data source. For example, maybe you need to get Forex quotes from Xignite, NYSE stock quotes from FIS (SunGard), and everything else from a third source (designated below with the simulator as a stand-in). This can be accomplished by attaching multiple quote feeds to the chart, as seen in the code snippet below.

stxx.attachQuoteFeed(
	new CIQ.QuoteFeed.Xignite(),
	{ refreshInterval: 1, bufferSize: 200 },
	function (params) {
		return (
			CIQ.Market.Symbology.factory(params.symbolObject) == CIQ.Market.FOREX
		);
	}
);

stxx.attachQuoteFeed(
	sgFeed.quoteFeedSunGard,
	{ refreshInterval: 1, bufferSize: 200 },
	function (params) {
		return CIQ.Market.Symbology.factory(params.symbolObject) == CIQ.Market.NYSE;
	}
);

stxx.attachQuoteFeed(
	simFeed.quoteFeedSimulator,
	{ refreshInterval: 1, bufferSize: 200 }
);

Notice how attachQuoteFeed is receiving either two or three arguments. The first argument is the quote feed to attach and the second defines its behavior. The third is the filter function, and its presence allows us to attach multiple quote feeds and define which should be used when.

The way this works is as follows: when the chart requests more quotes, the available quote feeds are traversed in order until a match is found, and then the matching quote feed is used to fetch the data. For each quote feed, if it has a filter function parameter, that function is called with an argument that is an object typically containing symbolObject, symbol, and interval properties. If the filter function returns true, that quote feed is used. Otherwise the next quote feed is checked. If the quote feed is a missing the filter parameter, it acts as a catch-all and for that reason is checked last.

You may add as many quote feeds as you need but only one of them can be "unfiltered." All quote feeds are checked for a match in the order they were attached except the "unfiltered" one, which is always checked last.

Subscription Events

A "quotefeed" can dramatically simplify development efforts by shielding developers from managing chart state. There are times however, when a developer needs to be kept informed about state changes. For instance, an application may want to know which symbols are enabled on the chart in order to keep a trading page up to date. Another example would be combining a quotefeed with an asynchronous streaming service (see "Combining Data Methods" below). They need a mechanism to tell the service to start or stop delivering data for certain symbols.

Implementing "subscriptions" in a quotefeed is how you can keep your code synchronized with the symbols that are enabled in the chart.

In order to receive subscriptions events, it is necessary to load initial data via a fetchInitialData call and add these methods to your quotefeed object:

Code Example: A quotefeed that can handle subscriptions:

{
	subscribe: function(obj) {...your code...}, // new code
	unsubscribe: function(obj) {...your code...}, // new code
	fetchInitialData: function(...) {...your code...}, // required loading method if using subscriptions
	fetchUpdateData: function(...) {...your code...},
	fetchPaginationData: function(...) {...your code...}
}

The signature for subscribe() and unsubscribe() are the same. They both provide an object with the following format:

{
	"symbol": "IBM",
	"symbolObject": { "symbol": "IBM" },
	"period": 5,
	"interval": "minute"
}

Your code may receive several subscribe/unsubscribe events in a row. For instance, when if a new chart is loaded along with comparison symbols, several subscribe events will be triggered.

Combining Data Methods

It is possible to combine the various data methods to suit the specific needs of your data service. The two most common combinations are:

  • Static initialization + quotefeed for updates - Your application initializes a chart with a static array of data but then relies on a quotefeed to periodically poll for updates.
  • quotefeed + streaming updates from an asynchronous feed - Your application lets the chart manage state but uses a subscription to stream asynchronous data into the chart [through a WebSocket].
Static Initialization + quotefeed for updates

In this example, we attach a quotefeed but only provide the fetchUpdateData() method. Since the other methods are not available, the chart will not automatically attempt to fetch historical data as it would normally do with a quotefeed.

Instead, we pass the historical data directly to the chart. As soon as the chart is created, the quotefeed will begin fetching refreshes (once per second in this example).

Code Example:

stxx.attachQuoteFeed(
	{
		fetchUpdateData: function() {
			// ...your code...
		}
	},
	{ refreshInterval: 1 }
);

stxx.loadChart("ibm", {
	masterData: [
		// ...your data...
	]
});

Note Because the quoteDriver will attempt to keep the chart up to date, if you pass static data to the chart while a quoteFeed is attached, the chart will attempt to paginate and fetch data both forwards and backwards until it has enough.

quotefeed + asynchronous streaming

The following example is a hypothetical implementation of a quotefeed for loading historical data which then manages subscriptions to a streaming service that implements a "socket.io" style interface. Notice how symbol, period and interval are combined to form a unique "key". (Through socket.io, and other chat oriented libraries, this key would be implemented as a "room").

Once subscribed, last sale data should start arriving. We have an event handler set up to receive that data and provide it to the chart as asynchronous updates.

Code Example:

myStreamingService.on("quote", function(data) {
	stxx.updateChartData({ Last: 102.05, DT: data.epoch }, null, {
		fillGaps: true,
	});
});

myStreamingService.subscribe = function(symbol, period, interval) {
	socket.join(symbol + period + interval); // join a room "ibm1day"
};

myStreamingService.unsubscribe = function(symbol, period, interval) {
	socket.leave(symbol + period + interval); // leave the room "ibm1day"
};

stxx.attachQuoteFeed(
	{
		fetchInitialData: function() {
			// ...your code...
		},
		fetchPaginationData: function() {
			// ...your code...
		},
		subscribe: function(obj) {
			myStreamingService.subscribe(obj.symbol, obj.period, obj.interval);
		},
		unsubscribe: function(obj) {
			myStreamingService.subscribe(obj.symbol, obj.period, obj.interval);
		}
	},
	{ refreshInterval: 0 }
);

stxx.loadChart("ibm");

Important:

When attaching a quote feed that combines asynchronous streaming for updates, always be sure to set the refreshInterval parameter to 0 (zero), to prevent conflicts with your asynchronous updates.

If using our default templates, you will need to make changes to the behavior.refreshInterval object for the quoteFeeds entry on the Chart Configuration

Working Example: QuoteFeed + streaming

- Click on the 'JavaScript' tab to see the code.

Working Example: Static loading + streaming + animation

- Click on the 'JavaScript' tab to see the code.

Next steps