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. The both provide an object of the following format:

{
	"symbol": "IBM",
	"symbolObject": { "symbol": "IBM" },
	"period": 1,
	"interval": 5,
	"timeUnit": "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... */
	]
});
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.

This interface would gracefully manage symbol changes, comparisons, and periodicity changes.

Code Example:

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

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); // lead 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);
	}
});

stxx.loadChart("ibm");

Important: when attaching a quote feed that uses asynchronous streaming for updates, always be sure to set the refreshInterval parameter to 0 ( zero) when attaching it to the chart engine, to prevent conflicts with your asynchronous updates.

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: