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

The ChartIQ Format for Time-Series Data

This tutorial explains the input format for time-series chart data. Whenever data is sent into a chart, it must conform to the format defined below. This includes both primary and secondary time-series.

Please read Data Integration: Considerations and Overview if you haven't already.

Note: Date values for all input data must be consistent with the chart's periodicity! See Periodicity and Your Master Data for a complete explanation.

Data Format

Data can be entered into a chart using different methods (i.e. pushed, pulled, or streamed), but the data format is always the same: a JavaScript array of chronologically ordered time-series objects.

The library can support trading based 'OHLC' objects as well as generic 'Date/Value' data.
OHLC simply stands for Open-High-Low-Close...named after the most commonly reported price movements for a financial instruments.

Sample of an OHLC data object:

{
	"Date": "1993-01-29",
	"Open": 43.97,
	"High": 43.97,
	"Low": 43.75,
	"Close": 43.94,
	"Volume": 1003200
}

Sample of a generic data object:

{
	"Date": "1993-01-29",
	"Value": 43.97
}

The full breakdown of ChartIQ's OHLC object format (i.e. a single array element in the data) is shown below:

Field Required Description
DT Maybe A JavaScript Date() object or a value that can be coerced into a Date() object (epoch or a ISO 8601 standard string) representing the start time of the bar or tick.
Date Maybe A date string in format described below, representing the start time of the bar or tick, in case a DT compatible value is not available.
Close Maybe Closing price for the bar. Excluding or setting this field to null will cause the chart to display a gap for this bar.
Open Maybe Opening price for the bar. Required for candle charts only.
High Maybe High price for the bar. Required for candle charts only.
Low Maybe Low price for the bar. Required for candle charts only.
Volume No Trading volume for the bar in whole numbers.
Adj_Close No Closing price adjusted price after splits or dividends. This is only necessary if you wish to give users the ability to display both adjusted and unadjusted values.

The full breakdown of ChartIQ's generic data object format (i.e. a single array element in the data) is shown below:

Field Required Description
DT Maybe A JavaScript Date() object or a value that can be coerced into a Date() object (epoch or a ISO 8601 standard string) representing the start time of the bar or tick.
Date Maybe A date string in format described below, representing the start time of the bar or tick, in case a DT compatible value is not available.
Value Maybe A price or numerical value for the bar. Excluding or setting this field to null will cause the chart to display a gap for this bar.

Important:

  • Field names are Capitalized.
  • Value, Open, High, Low, Close & Volume must be numbers, not strings. (Use parseFloat to convert if your data server provides strings.)
  • Only date (either DT or Date) is required. All other fields are optional.
  • JavaScript epochs are the number of milliseconds since 1970 GMT. If your server sends "unix epochs" (number of seconds since 1970) then be sure to multiply by 1,000.
  • The date for an OHLC bar is the starting point for the interval. For instance, a 5 minute bar represents activity from 05:00:00.000 to 05:04:59:999.
  • Weeks start on Sunday and data records MUST be dated that way unless a market definition exists to indicate Sunday is not a market day, in which case the next market day will be used. Instructions to set a market for the chart can be found here: CIQ.Market
Supported Date field formats
  • 'yyyymmddhhmmssmmm'
  • 'yyyymmddhhmm'
  • 'yyyymmdd'
  • 'yyyy-mm-ddThh:mm:ss.SSS'
  • 'yyyy-mm-dd hh:mm:ss AM/PM'
  • 'yyyy-mm-dd hh:mm:ss'
  • 'yyyy-mm-dd'
  • 'mm-dd-yyyyThh:mm:ss.SSS'
  • 'mm-dd-yyyy hh:mm:ss'
  • 'mm-dd-yyyy'
  • No time zone offset should be used in the 'Date' field.

Notes:

  • Both slashes (/) and hyphens (-) are supported
  • The date format must follow "US style" rather than "European style". The month comes before the day, even when the year is the last field.
Common errors when using the DT field
  • Only use JavaScript Date() objects or values that can be coerced into a Date() object (epoch or a ISO 8601 standard string)
  • Omitting T or Z in a date-time string can give different result in different browsers.
  • Some Browsers assume a string date is in GMT when no time portion is provided.

As such, if your fetch functions are creating a JavaScript date form a string for the DT, be aware of this and adjust as needed or allow the library to do the conversion by instead setting the Date field.

Examples of ambiguous date parameters:

Code var dt = new Date("2018-10-29"); Result : Sun Oct 28 2018 20:00:00 GMT-0400 (Eastern Daylight Time)

Code: var dt = new Date("2018-10-29 00:00:00"); Result: varies depending on browser

Examples of exact date parameters:

Code: var dt = new Date(2018,9,29); Result: Mon Oct 29 2018 00:00:00 GMT-0400 (Eastern Daylight Time)

Code: var dt = new Date("2018-10-29T00:00:00"); Result: Mon Oct 29 2018 00:00:00 GMT-0400 (Eastern Daylight Time)

Here is sample code to properly create a JavaScript date from a string date with no time portion:

if( Object.prototype.toString.call(date) == ‘[object String]’ && date.length<=10){
    // only date portion provided on string, adjust implied time zone
    date=new Date(date);
    date.setMinutes(date.getMinutes()+date.getTimezoneOffset());
}

For more details on the difference between Date and DT see the Dates and Time Zones tutorial.

Data ordering

Data lists sent into the chart must always be in ascending chronological order.

This means that array[0] should be the oldest date on the list and array[array.length-1] should be the most current date on the list. Failure to do so, will prevent the data from being properly loaded and displayed.

Example of a properly ordered data list:

[
	{
		"DT": "1993-01-29T09:30:00.000-0500",
		"Open": 43.97,
		"High": 43.97,
		"Low": 43.75,
		"Close": 43.94,
		"Volume": 1003200
	},
	{
		"DT": "1993-02-01T09:30:00.000-0500",
		"Open": 43.97,
		"High": 44.25,
		"Low": 43.97,
		"Close": 44.25,
		"Volume": 480500
	},
	{
		"DT": "1993-02-02T09:30:00.000-0500",
		"Open": 44.22,
		"High": 44.38,
		"Low": 44.13,
		"Close": 44.34,
		"Volume": 201300
	}
]

Example of a incorrectly ordered data list:

[
	{
		"DT": "1993-02-10T09:30:00.000-0500",
		"Open": 43.97,
		"High": 43.97,
		"Low": 43.75,
		"Close": 43.94,
		"Volume": 1003200
	},
	{
		"DT": "1993-02-09T09:30:00.000-0500",
		"Open": 43.97,
		"High": 44.25,
		"Low": 43.97,
		"Close": 44.25,
		"Volume": 480500
	},
	{
		"DT": "1993-02-08T09:30:00.000-0500",
		"Open": 44.22,
		"High": 44.38,
		"Low": 44.13,
		"Close": 44.34,
		"Volume": 201300
	}
]

Examples

The following example shows a data array with just two OHLC objects. Note the objects in the array must be ordered from oldest to newest -- this means that your data[0] object will be the oldest and your data[length-1] object will be the most current.

[
	{
		"Date": "1993-01-29",
		"Open": 43.97,
		"High": 43.97,
		"Low": 43.75,
		"Close": 43.94,
		"Volume": 1003200
	},
	{
		"Date": "1993-02-01",
		"Open": 43.97,
		"High": 44.25,
		"Low": 43.97,
		"Close": 44.25,
		"Volume": 480500
	}
]

Here's a snippet from a more realistic dataset of daily data for a symbol (i.e. a specific security):

[
	{
		"DT": "1993-01-29T09:30:00.000-0500",
		"Open": 43.97,
		"High": 43.97,
		"Low": 43.75,
		"Close": 43.94,
		"Volume": 1003200
	},
	{
		"DT": "1993-02-01T09:30:00.000-0500",
		"Open": 43.97,
		"High": 44.25,
		"Low": 43.97,
		"Close": 44.25,
		"Volume": 480500
	},
	{
		"DT": "1993-02-02T09:30:00.000-0500",
		"Open": 44.22,
		"High": 44.38,
		"Low": 44.13,
		"Close": 44.34,
		"Volume": 201300
	}
]

Here's a snippet with 5-minute data for a symbol:

[
	{
		"Date": "2015-04-16 16:00",
		"Open": 152.13,
		"High": 152.19,
		"Low": 152.08,
		"Close": 152.11,
		"Volume": 4505569
	},
	{
		"Date": "2015-04-17 09:30",
		"Open": 151.76,
		"High": 151.83,
		"Low": 151.65,
		"Close": 151.79,
		"Volume": 2799990
	},
	{
		"Date": "2015-04-17 09:35",
		"Open": 151.79,
		"High": 151.8,
		"Low": 151.6,
		"Close": 151.75,
		"Volume": 1817706
	}
]

An example of "tick data". Tick data will have irregular intervals and only a closing price:

[
	{ "Date": "2015-04-16 09:00:01", "Close": 72.11, "Volume": 505569 },
	{ "Date": "2015-04-17 09:00:07", "Close": 71.79, "Volume": 799990 },
	{ "Date": "2015-04-17 09:00:08", "Close": 71.75, "Volume": 817706 }
]

Time zone considerations

Ideally, your data server will support epochs (milliseconds since 1970) or ISO8601 format. ISO8601 is supported by the JavaScript Date object and looks like these:

2015-01-01T09:10:00Z - UTC time

2015-01-01T09:10:00.000Z - With milliseconds

2015-01-01T09:10:00.000-0500 - With time zone offset

If so, dates should be set in the 'DT' field only.

Epochs and ISO8601 formats provide "time zone context". With such date formats, the chart can convert the times into a time that is convenient for the end user. By default, the chart will convert the times to display in the local time zone of the user (the browser's time zone). This is seen on the x-axis of an intraday chart.

Example: 2015-01-01T14:10:00Z will display as "09:10" to a user located in New York. It will display as "08:10" to a user located in Chicago. It will display as "14:10" to a user located in London.

If your server provides string format dates without "time zone context", you should pass them as strings to the Date field on the OHLC object. These dates will be displayed to the user without conversion.

Example: 2015-01-01 14:10:00 will display as "14:10" to all users, regardless of their location.

If you are usig string format dates but you know the time zone of your data server then you can provide this with CIQ.ChartEngine#setTimeZone, so that the chart knows the "time zone context." This will allow the chart engine to convert the times to the user's local time:

Example: 2015-01-01 14:10:00 will be converted to "09:10" (New York), "08:10" (Central), "14:10" (London) if you call stxx.setTimeZone("Europe/London") before passing data.

See the Dates, Times, and Time Zones tutorial for more details.

Extra OHLC Data

As long as the OHLC objects are properly formatted, you can include extra elements in each OHLC object. This extra data has no effect on how the chart is displayed.

Example:

[
	{ "Date": "2015-05-27 15:00:00", "Close": 42.49, "Extra1": 37.31, "YourStudy": 84.57 },
	{ "Date": "2015-05-27 15:30:00", "Close": 42.45, "Extra1": 84.39, "YourStudy": 16.82 }
]

A Special Case: Streaming last-Sale data

For OHLC input data there's one exception to the rule: CIQ.ChartEngine#updateChartData can also support input of "last-sale" data. Last-sale data can be automatically distinguished by the "Last" price. When sending last-sale data, the chart will automatically construct OHLC bars. Note that when sending last-sale data, the "Volume" is interpreted as the volume for the trade (incremental volume). The actual displayed volume for a chart bar will be the sum of these trade volumes for that time period.

Example: Streaming last sale to the chart

[{ "Date": "2015-04-16 09:00:01", "Last": 72.13, "Volume": 505569 }]

When passing last-sale data, the "Bid" and "Ask" price can also be passed for use in ChartIQ's optional Trade From Chart (TFC) plugin.

Example: Sending bid and ask for use by TFC plugin

[{ "Date": "2015-04-16 09:00:01", "Bid": 72.05, "Ask": 72.15, "Last": 72.13, "Volume": 505569 }]

Next steps