Data Loading

How to integrate data into charts (along with the required format) was introduced in the Developer Overview. This tutorial goes into more depth, covering all the ways data can be loaded into charts along with a few of the pitfalls to avoid.

First, let's review some key terminology.

  • Pushing data refers to taking a fixed set of local data and directly initializing a chart (i.e pushing the data into a chart when it is created).
  • Pulling data refers to periodically fetching (i.e. pulling) data from a remote source and dynamically augmenting a chart with the data (either to the left side of the chart with "old" data or the right side with "new" data).
  • Streaming data refers to asynchronously receiving new data (e.g. from a web socket or using a HTTP Comet model) and adding it to the right side of the chart.
  • Pagination, a new term, specifically refers to adding a "page" of older data on the left side of the chart. Typically, an underlying "pagination event" (i.e. the endDate event) is delivered when the user has scrolled past the end of the chart to the left, then the chart can be augmented on the left with additional data (how is covered below).

An important fact to know is that setting the Close field on a data element to null will cause the candle to be hidden but it's width/space preserved. This may be useful if you want to maintain the spacing between candles even if no data is present for that period. Otherwise if a data element is not present for a particular timeframe, it's place within the chart will not be maintained and the following candle will be drawn in that location.

Here's the outline of the rest of the data-loading tutorial.

Push Methods (i.e Static Initialization)

STXChart can be statically initialized by simply pushing an array of properly formated OHLC objects when calling STXChart#newChart -- this will cause the chart to render using only the quotes stored in the data array.

The following is a simple jsfiddle using an array of objects: (Click on the 'JavaScript' tab to see the code).

Example:

The following is a complete jsfiddle using Ajax/JSON to retrieve 1-day ticks from a quote repository and then 'push' it into a new chart. It assumes the returned data is already in the expected format.

Example:

Simularly, here's what your code might look like:

<!doctype html>
<html>
<head>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <!-- for high pixel devices -->
<link rel="stylesheet" type="text/css" href="stx-chart.css" media="screen" /> <!-- Default style sheet -->
</head>

<body onLoad="displayChart()">

<!-- This is your chart container. Position it anywhere, and in any way that you wish on your web page. -->
<div id="chartContainer" style="width:800px;height:460px;"></div>

<script src="STX_SAMPLE_DAILY.js"></script>    <!-- data source containing JavaScript array of OHLC objects -->
<script src="stxThirdParty.js"></script>    <!-- these are required libraries -- maintain this order -->
<script src="stxTimeZoneData.js"></script>    <!-- these are required libraries -- maintain this order -->
<script src="stx.js"></script>                <!-- these are required libraries -- maintain this order -->
<script src="stxKernelOs.js"></script>         <!-- these are required libraries -- maintain this order -->

<script>

// Declare a STXChart object. This is the main object for drawing charts.
var stxx=new STXChart({container:$$("chartContainer")});    

function displayChart(){
    var symbol = "SPY";

    STX.postAjax("http://jsfiddle.chartiq.com/sample_json.js?symbol="+symbol, null, function (status, response) {
        if (status != 200) {
            return;
        }
        var yourData = JSON.parse(response);
        stxx.newChart(
          symbol, 
          yourData,
          null,
          null,
          {periodicity:{period:1,interval:'day'}}
        ); 

    });
}

</script>
</body>
</html>

Pull Methods (i.e. Continous Augmentation with a QuoteFeed)

For continuous data augmentation, the STX.QuoteFeed object provides the easiest way to integrate your quote data to the chart engine. The 'fetch()' function is the heart of the Quote Feed and is event driven. Once attached, it will call your functions whenever the chart requires data, including pagination and pulling for updates at predefined refresh rates. This is all automatically handled, all you have to do is fill in the blanks on your fetch function.

When using the quoteFeed never include a data array in your newChart() call.

Your call should look like this:

        stxx.newChart(symbol, null, null, function () {    // !!! make sure the dataArray parameter is set to null if you are using a QuoteFeed!!!!
                   // callback - your code to be executed after the chart is loaded
        });

NOT like this:

        stxx.newChart(symbol, yourDataArray, null, function () {    // !!! if a data array is sent in, it will be used even if a quoteFeed is attached !!!!!
                   // callback - your code to be executed after the chart is loaded
        });

To implement a custom quote feed, derive a new object from STX.QuoteFeed (see STX.QuoteFeed.Demo in stx.js for a working example)

The following is a functional jsfiddle:

Example:

fetch() provides a set of parameters (params) enabling you to determine what data is being requested, and a call back function (cb) to return the data.

See STX.QuoteFeed#fetch for details on the params. It is important that your code returns the right amount of data in the requested interval (minutes, days, weeks, months).

If your feed requires you to subscribe and un-subscribe instruments as they are added and removed from the chart, you may want to use a subscription quotefeed instead of the standard quotefeed. See STX.QuoteFeed.Subscriptions for all of the details

Four Types of Fetch Requests (Initial Request, Update Request, Pagination Request, Date-Range Request)

The type of data required by the fetch() request will either be:

1- An initial data set request to render the chart

     No dates are set in the params.
     Use params.ticks to determine how much data the chart needs

2- An update request - new ticks on the right

     `params.startDate` is set 

3- A pagination request - older ticks on the left

     `params.endDate` is set, and you must return `moreAvailable` in your callback, to let the engine know if there is more to fetch.
     Use params.ticks to determine how much data the chart needs

4- A date range request - for a series or a study

     Both `params.startDate` and `params.endDate` are set

On initial load or pagination requests, we recommend that fetch() returns about 3,000 ticks or 3 times the params.ticks value. This will provide a smoother scrolling experience.

Make sure that for date range requests, when both startDate and endDate are passed in the params, your code fetches the entire range, regardless of number of ticks to fetch. This will ensure there are not gaps in the data.

For update requests, fetch any new data that is not yet reflected on the chart starting from the startDate to the current time.

Important: Items in the data array must be ordered from oldest to newest. This means that your data[0] element will be the oldest in the set and your data[length-1] element will be the most current.

Your feed will probably return more than just quote elements with the response.

For example an JSON response may look like this:

{
   "status": "Success",
   "quotes": [{"Date": "2015-05-27T15:00:00+00:00", "Close": 42.49}, {"Date": "2015-05-27T15:30:00+00:00", "Close": 42.45}],
   "moreAvailable":"true"
}

You must parse that response and only set the quotes object in the callback to the quotes object in the response. DO not just sent the entire response to the `quotes1 element of the callback. This will not work.

Your quotes array must only have properly OHLC objects (close and Date -or DT- being mandatory)

[{"Date": "2015-05-27T15:00:00+00:00", "Close": 42.49}, {"Date": "2015-05-27T15:30:00+00:00", "Close": 42.45}]

So what you may need to do is first JSON.parse(response) into a temporary object and then just take the 'quotes' sub element and set that to the 'quotes' object in the callback.

Make sure to set moreAvailable on pagination responses. This flag is used by the engine to determine if more data is available should the user continue to scroll to the left to see older data.

Finally, as long as you return properly formated OHLC objects, you can always include extra elements in each quote object to be used in server side studies or series. For example:

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

Once you have the data properly formatted, return it in the callback function (cb). All data, including errors, must be returned using the callback. This is mandatory. Failure to do so may prevent the feed from doing subsequent update calls as it will still be waiting for the callback before it can move on to additional requests.

The Callback Format

This is the format for your callback function:

cb({
    error:status,             
    quotes:newQuotes, 
    moreAvailable:false
   });

Leave error bank, or exclude all together if the request was successful.

See the 'Server side study data' section in the Custom Studies tutorial for more details.

Example Template: Fetch Function and Callback

The following is a basic outline for the fetch function with examples on how to request and convert the data, fill in the blanks as needed by your quote feed:

STX.QuoteFeed.MyFeed=function(){};
STX.QuoteFeed.MyFeed.stxInheritsFrom(STX.QuoteFeed);
STX.QuoteFeed.MyFeed.fetch=function(params, cb){
    // This is an outline for how to implement fetch in your custom feed

    if(params.startDate && params.endDate){
        // This means the chart is asking for a specific data range, 
        // probably to back fill MaterData for a comparison symbol for an existing chart.
        // You must provide data for the entire range or a gap will be produced.
        //
        // Put your code here to fetch and format the response according to the specs and return it in the callback.
        //
    } else if(params.startDate){
        // This means the chart is asking for a refresh (update) of most recent data according to the interval 
        // you have specified in behavior.refreshInterval when you attached the quote feed (attachQuoteFeed). 
        // If you don't support streaming of new ticks then just do nothing and return.
        // Otherwise fetch your data to fill in the gap from the params.startDate until the current time, 
        // and call the callback with your data when it comes in. 
        // See STX.QuoteFeed.Demo for an actual implementation.
        //
        // STX.postAjax(url, null, function(status, response){
        //    if(status!=200){
        //        cb({error:status});    // something went wrong, use the callback function to return your error
        //        return;
        //    }
        //  Put your code here to format the response according to the specs and return it in the callback.
        //  cb({quotes:yourData}); // no need to set moreAvailable for a refresh.
        // });
    }else if(params.endDate){
        // This means the user has scrolled past the end of the chart on the left (pagination). 
        // The chart needs older data, if it's available.
        // If you don't support pagination just return and do nothing.
        // Otherwise fetch your data, probably using Ajax, and call the callback with your data when it comes in. 
        // See STX.QuoteFeed.Demo for an actual implementation.
        //
        // STX.postAjax(url, null, function(status, response){
        //    if(status!=200){
        //        cb({error:status});    // something went wrong, use the callback function to return your error
        //        return;
        //    }
        //  Put your code here to format the response according to the specs and return it in the callback.
        //  cb({quotes:yourData, moreAvailable:false}); // set moreAvailable to true or false if you know that more, older, data is available.
        // });
    }else{
        // The chart needs an initial load. params.tick tells you how many bars are needed to fill up the chart
        // 
        // Fetch your data, probably using Ajax, and call the callback with your data when it comes in. 
        // See STX.QuoteFeed.Demo for an actual implementation.
        //
        // STX.postAjax(url, null, function(status, response){
        //    if(status!=200){
        //        cb({error:status});    // something went wrong, use the callback function to return your error
        //        return;
        //    }
        //  Put your code here to format the response according to the specs and return it in the callback.
        //    Example code:
        //    var newQuotes=[];
        //    for(var i=0;i<quotes.length;i++){
        //        newQuotes[i]={};
        //        newQuotes[i].Date=quotes[i][0]; // Or set newQuotes[i].DT if you have a JS Date
        //        newQuotes[i].Open=quotes[i][1];
        //        newQuotes[i].High=quotes[i][2];
        //        newQuotes[i].Low=quotes[i][3];
        //        newQuotes[i].Close=quotes[i][4];
        //        newQuotes[i].Volume=quotes[i][5];
        //        newQuotes[i].Adj_Close=quotes[i][6];
        //    }
        //  cb({quotes:newQuotes, moreAvailable:false}); // set moreAvailable to true or false if you know that more, older, data is available.
        // });
    }
};

The following outlines how to attach a quotefeed to your chart:

// Declare a STXChart object. This is the main object for drawing charts
var stxx=new STXChart({container:$$("chartContainer")});


// Define the behavior of your feed
var quoteBehavior={
  refreshInterval: 15,            // how often to go back to check for new data and refresh the chart
  callback: quoteFeedCallback    // for performing more tasks after data was fetched, like Comparison Charts
};

// Attach your quotefeed to the chart.
stxx.attachQuoteFeed(new STX.QuoteFeed.MyFeed(),quoteBehavior);

// your code for getting a new symbol

stxx.newChart(symbol, null, null, function(){        // !!! never use a data Array with a quoteFeed. Always set to **null** !!!!!
        // callback - your code to be executed after the chart is loaded
  });

Streaming Methods (Asynchronous to End of Chart)

If you have a streaming information service through a websocket, webservice or similar, and wish to provide a continually updating chart that automatically refreshes as new quotes become available instead of pulling for new data, the library provides the following methods for programatically updating the chart asynchronously:

Your streaming interface should call the streaming method every time new information is received. This call will augment the dataSet and redraw the chart to reflect the new information.

Streaming OHLC Data (i.e. Using appendMasterData)

If you are using this method, your ticks should be fully formed OHLC objects. The chart will not automatically calculate OHLC. Also make sure that you only inject new ticks that are in sync with the appropriate interval for the chart. So if your data is based off of 5 minute bars then your appended data should also be 5 minute bars.

Note: appendMasterData() takes an array of OHLC objects. When streaming a single bar at a time simply pass an array containing a single object.

Sample call:

var newData=[{Date:"01-05-2015 09:32", Open:105, High:107, Low:104, Close:106, Volume:1000}];
stxx.appendMasterData(newData);

If the first OHLC object in the array shares the same time signature as the latest OHLC object in the current chart then it will replace that bar rather than appending (streaming updates).

'Date' must be in the same timezone as the rest of the masterDataSet already sent into the charting engine to prevent tick gaps or overlaps.

Please note that appendMasterData may create a new dataSet with each tick. This means that all of the study calculations are recomputed with each tick. If you need faster performance, and are willing to give up automatically calculated studies, then manually append to stxx.chart.dataSegment (followed by stxx.draw()). Alternativelly, you can throttle inbound ticks. This is done by adjusting the values of the 'maxWait' and/or 'maxTicks' parameters. The higher the values, the larger the interval between updates. As such, fewer refreshes will be rendered on the chart, preventing the animation loop from overloading. See STXChart#streamParameters for more details.

You can set these values as you declare your chart object:

var stxx=new STXChart({container:$$$(".chartContainer"), streamParameters:{"maxTicks":200, "maxWait":200},layout:{"candleWidth": 16, "crosshair":true}});

or by directly setting after the chart object has been declared:

stxx.streamParameters.maxTicks= xT;
stxx.streamParameters.maxWait= xW;

Steaming Last Sale Data (Using streamTrade)

If your real time data feed does not supply OHLC updates but only delivers "last sale" (trade) updates then use STXChart#streamTrade as follows:

stxx.streamTrade({last:price,volume:volume},tick_time);

streamTrade inherits all functionality from appendMasterData but also automatically calculates OHLC bars based on the current periodicity (daily, hourly, minute, etc) as new trades are passed in and redraws the chart.

Time intervals without any trades will gap accordingly once a new trade arrives. On a candle chart these gaps will appear as dashes. Note that this mechanism precisely follows the opening and closing times of the market . Passing in trades after the close of the market will not create new ticks. If handling extended hours trading be sure to set the ending times accordingly. See the Market Hours and the Charts tutorial for additional details on how to adjust market defaults.

Similarly to appendMasterData(), you can throttle inbound ticks to optimize performance and use is in combination with a QuoteFeed.

The following is a simple jsfiddle using the streamTrade() mechanism: (Click on the 'JavaScript' tab to see the code)

Example:

Here's a sample last-sale streaming function using random prices:

function tradeStreamSimulation(){
    var price=200;
    if(stxx.chart.dataSet.length>1){
        price=stxx.chart.dataSet[stxx.chart.dataSet.length-1].Close;
    }
    var change=(price*.02)*Math.random()-(price*.01);    // random change between +/-1% of current price
    price=price+parseFloat(change.toFixed(2));
    var volume=(1000*Math.random()).toFixed(0);    // Volume between 1 and 1000 shares
    var now = new Date().getTime();   // use the epoch as your time, NOT a date object
    stxx.streamTrade({last:price,volume:volume},now); 

    setTimeout(tradeStreamSimulation, 250);
}

// Declare a STXChart object. This is the main object for drawing charts
// Attach to a quote feed

stxx.setPeriodicityV2(1, "day");
stxx.newChart("SPY");
tradeStreamSimulation();

tick_time is an optional argument to specify date of trade. It must be a valid JavaScript date, and if omitted, defaults to "right now". It is important to note that this value must be in the same timezone as the rest of the masterDataSet already sent into the charting engine to prevent tick gaps or overlaps.

Adding a Secondary Data Stream (i.e. Using addSeries + streamTrade)

You can also stream data for a secondary series if needed.

In this case your API call would look like this:

//first add your series
stxx.addSeries("Series-Name", {
  color: "green",
  data: getDataFromServer("someFieldIwantToAdd"),
  marginTop: 100, // give room for the legend
});

// later on in your code you can call streamTrade to update it real time
  stxx.streamTrade({last: series_price}, tick_time, "Series-Name");

Example:

Combining Steaming and Pagination (i.e. appendMasterData/streamTrade + QuoteFeed)

Streaming methods can be used in conjuction with a QuoteFeed. Simply create and attach your QuoteFeed, without setting a 'refreshInterval' ( or set it to 0) and instead use appendMasterData to push the updates. This implies QuoteFeed could be using fetch() to add pagination data to the front while appendMasterData is being used to add streaming data to the end.

The following is a functional jsfiddle of a combined model:

Example:

Periodicity and Your MasterData -- Make Sure They Are in Sync!

This is relevant both when using a quoteDeed or pushing data into a chart. (Of course, if pushing data, you must ensure it is in the right interval, as a fetch() call will not be made)

Important definitions when using setPeriodicityV2:

  • period describes the number of raw ticks from masterData to roll-up together into one data point on the chart (one candle, for example). If set to 30 in a candle chart, for example, each candle will represent 30 raw ticks of interval type.

  • interval describes the type of data to base the period on. This can be any number (which represents minutes, seconds or milliseconds -as per timeUnit- supported by your data feed) or "day","week" or "month". Set to "tick" for variable time x-axis. (This is not how much data you want the chart to show on the screen; for that you can use STXChart#setRange or STXChart#setSpan)

  • timeUnit further qualifies numeric intervals. Valid values are "millisecond","second","minute",null. If not set, will default to "minute".

You can combine the period and interval using setPeriodicityV2 to achieve any periodicity you want to display on your chart depending on the raw data you have available form your feed. The charting library will then translate the request and send the quoteFeed fetch() function the required parameters so you can return the required data back to the chart.

Important definitions when using fetch():

  • period describes the timeframe each returned object represents. For example, if using interval "minute", a period of 30 means your feed must return ticks (objects) with dates 30 minutes apart; where each tick represents the aggregated activity for that 30 minute period). Note that this will not always be the same as the period set in STXChart#setPeriodicityV2, since it represents the aggregation of the raw data to be returned by the feed server, rather than the final data to be displayed.

  • Interval describes type of data your feed will need to provide. Allowable values: "minute","day","week","month".

Your fetch params object for hourly ticks may look like this (only relevant items included):

feed: "delayed"
interval: "minute"
period: 60
symbol: "AA"
ticks: 336

The concept of "hour" or "year" does not exist in periodicity. You have milliseconds, seconds, minutes, days, weeks and months. Of course, in your data interface you should convert the parameters to what is needed on your side. So if your feed requires an aggregation type of 'hours' to be sent, you simply convert the interval and period combination as needed before sending the parameters to your data feed.

In this case fetch it is asking you to return 336 ticks, each one representing 60 "minute" (or 1 hour). Some feeds support any combination so you can send both the period and the interval and the feed will know what to do. For others you have to combine them both and send a single parameter representing the periodicity requested.

Since most data sources do not provide weekly and monthly data, the kernel's default behavior is to derive weekly and monthly charts from daily data. As such, even though the chart interval is month or week, a fetch() call will receive day in the params.interval variable, since that is the data the library need to then roll it into the proper interval.

On the other hand, if you will be loading raw 'week' and 'month' data in the masterData, set the stxx.dontRoll flag to true -before any data is loaded- to bypass this functionality. This will cause the library not to roll daily data. A fetch() call will receive 'month' or 'week' in the params.interval

For all other chart periodicity (minutes, days), you must make sure you are only asking your fetch() call to get intervals your feed supports.

You can specify how you want raw intervals to be rolled up into the final periodicity needed on the chart . This is done by carefully setting setPeriodicityV2(period, interval) in your code so the intervals requested by the user are those supported by your feed. Of course fetch(), can (and should) reject any interval it does not support, but that does not address making sure only the supported intervals are requested.

Lastly, if your data does not have a set periodicity, such as individual trade ticks that come as executions are received, and you wish to display this data in a 'Non-Time-Based' manner, set your interval to 'tick' and the chart will not try to roll any of this data into any other related intervals.

See setPeriodicityV2 specs for all details.

For example, if your feed only supports 1 minute intervals for introday data, you would set your periodicity as follows:

setPeriodicityV2(5, 1);     // to display 5 minute ticks - will request fetch() 'minute' interval with a 'period' of 1 
setPeriodicityV2(15, 1);    // to display 15 minutes tkcs - will request fetch() 'minute' interval with a 'period' of 1 
setPeriodicityV2(30, 1);    // to display 30 minutes ticks - will request fetch() 'minute' interval with a 'period' of 1

Note the value of 'interval' is always 1, since all your feed has is 1 minute data.

The library will then roll the 1 minute ticks into 5, 15 or 30 minute ticks , as specified, before displaying them.

This is an example of how your raw 1 minute data would look coming back form your feed. You can see the Date increases by 1 minute on each tick object.

[
{"Date":"2013-03-04 09:30","Open":151.76,"High":151.83,"Low":151.65,"Close":151.79,"Volume":2799990},
{"Date":"2013-03-04 09:31","Open":151.79,"High":151.8,"Low":151.6,"Close":151.75,"Volume":1817706},
{"Date":"2013-03-04 09:32","Open":151.74,"High":151.96,"Low":151.74,"Close":151.84,"Volume":2127911},
{"Date":"2013-03-04 09:33","Open":151.84,"High":152.03,"Low":151.79,"Close":151.95,"Volume":1640306},
{"Date":"2013-03-04 09:34","Open":151.95,"High":152.09,"Low":151.84,"Close":152.07,"Volume":1420396}
];

The following sample code illustrates how the right periodcity can be adjusted to ensure only one minute ticks are requested:

function changePeriodicity(newInterval){
  var actualPeriod = 1;
  var actualInterval = newInterval;
  if ( newInterval == "5") {
   actualPeriod = 5;        // ask the chart to get 5 one minute ticks and roll them into one
   actualInterval=1;
  } else if ( newInterval == "30") {
   actualPeriod = 30;        // ask the chart to get 30 one minute ticks and roll them into one
   actualInterval=1;
  }
  stxx.setPeriodicityV2(actualPeriod, actualInterval);
}

If your feed supports rolled up minute requests, you can set periodicity as follows, where the feed is assumed to support 5, 15 and 30 minutes.

setPeriodicityV2(1, 5);    // to display 5 minute ticks - will request fetch() 'minute' interval with a 'period' of 5 
setPeriodicityV2(1, 15);    // to display 15 minute ticks - will request fetch() 'minute' interval with a 'period' of 15 
setPeriodicityV2(1, 30);    // to display 30 minute ticks - will request fetch() 'minute' interval with a 'period' of 30

This is an example of how your raw 5 minute data would look coming back form your feed. You can see the Date increases by 5 minutes on each tick object.

[
{"Date":"2013-03-04 09:30","Open":151.76,"High":151.83,"Low":151.65,"Close":151.79,"Volume":2799990},
{"Date":"2013-03-04 09:35","Open":151.79,"High":151.8,"Low":151.6,"Close":151.75,"Volume":1817706},
{"Date":"2013-03-04 09:40","Open":151.74,"High":151.96,"Low":151.74,"Close":151.84,"Volume":2127911},
{"Date":"2013-03-04 09:45","Open":151.84,"High":152.03,"Low":151.79,"Close":151.95,"Volume":1640306},
{"Date":"2013-03-04 09:50","Open":151.95,"High":152.09,"Low":151.84,"Close":152.07,"Volume":1420396}
];

In the above case, the library will just take the raw data, load it and display it without rolling it up.

This is an example of how your raw daily data would look coming back from your feed. You can see the Date increases by one day on each tick object.

[
{"Date":"1993-01-29","Open":43.97,"High":43.97,"Low":43.75,"Close":43.94,"Volume":1003200,"Adj_Close":31.16},
{"Date":"1993-02-01","Open":43.97,"High":44.25,"Low":43.97,"Close":44.25,"Volume":480500,"Adj_Close":31.38},
{"Date":"1993-02-02","Open":44.22,"High":44.38,"Low":44.13,"Close":44.34,"Volume":201300,"Adj_Close":31.44},
{"Date":"1993-02-03","Open":44.41,"High":44.84,"Low":44.38,"Close":44.81,"Volume":529400,"Adj_Close":31.77},
{"Date":"1993-02-04","Open":44.97,"High":45.09,"Low":44.47,"Close":45,"Volume":531500,"Adj_Close":31.91}
];

If you will be rolling up at the server level, use the following consolidation rule:

Volume:     the sum of all volumes for the interval
Open:         the first  price for the interval
Close:         the last price for the interval
High:         the highest price of the interval
Low:         the lowest price of the interval.

Using setPeriodicityV2 with the Push Method

Even thought the library can roll up raw data into different periodicities (1 minute ticks into 5 minute ticks, for example), depending on the interval of the raw data loaded, certain periodicities will require different underlying data. For example, daily data can not be rolled up into 'minutes' ticks. Additionally, even though minute data can be rolled into daily, weekly and monthly periodicity, it may not always be desirable as it could cause serious performance degradation (Example: rolling minute ticks into a monthly tick while displaying a 10 years range or monthly ticks). So use discretion when programming your roll-up methodology.

So before calling setPeriodicityV2, make sure the current data can be rolled; otherwise call newChart(symbol,data) with your new data.

See Periodicity, STXChart#setPeriodicityV2 and for more details.

Here is an example on how to use newChart() to change periodicity while using the Push method.


// call this to render the initial chart
function displayChart(){  
    loadData(1,5,"SPY");
}

// call this from your menu to change perodicity. 
function changePeriodicity(newPeriod, newInterval){
    loadData(newPeriod, newInterval,stxx.chart.symbol);
}

function loadData(period,interval,newSymbol){
      var query;
      // our sample only addresses daily and 5 minute periodicity, you should program as needed by your quote feed.
      if ( interval == 5 ) query = "http://jsfiddle.chartiq.com/sample_json_5MIN.js?";
      else if ( interval == 'day' ) query = "http://jsfiddle.chartiq.com/sample_json.js?";
      else return;
      STXLoader(true);
    STX.postAjax(query+"symbol="+newSymbol+"&period="+period+"&interval="+interval, null, function (status, response) {
        if (status != 200) {
            return;
        }            

        var yourData = JSON.parse(response);
          stxx.newChart(
              newSymbol, 
              yourData, 
              null, 
              cb(stxx.chart.symbol, newSymbol),
              {periodicity:{period:period,interval:interval}}
          );              
    });
 }

Adding More Chart Periods?

The sample templates (e.g. stx-standard.html) have a drop down menu with standard HTML code outlining a list of calls to changePeriodicity, where the argument identifies the requested period.

Numbers represent minutes, and the rest are 'day','week','month'.

changePeriodicity(), will then call setPeriodicityV2() to gather and roll up the data as needed.

Feel free to add any other periods to the HTML oultined below:

   <div id="periodBtn" class="stx-btn stx-menu-btn stxMenu">5 Min<em></em>
        <ul id="periodicity" class="periodicity menuSelect menuOutline" style="display:none">
          <li stxToggle="changePeriodicity('day')">1 D</li>
          <li stxToggle="changePeriodicity('week')">1 W</li>
          <li stxToggle="changePeriodicity('month')">1 Mo</li>
          <li class="stx-menu-divider"></li>
          <li stxToggle="changePeriodicity(1)">1 Min</li>
          <li stxToggle="changePeriodicity(5)">5 Min</li>
          <li stxToggle="changePeriodicity(30)">30 Min</li>
        </ul>
    </div>

Of couse, you can call setPeriodicityV2() programatically with any supported intervals at any time.

Additional Data Notes and Requirements

On Broswer External-Data Requests Please review the following tutorial about data accessibility before attempting to request external data from the browser : Integrating Third Party Data Feeds

On Data Format: Items in the data array must be ordered from oldest to newest. This means that your data[0] element will be the oldest in the set and your data[length-1] element will be the most current.

On Periodicity: Even thought the library can roll up raw data into different periodicities (1 minute ticks into 5 minute ticks, for example), depending on the interval of the raw data loaded, certain periodicities will not work unless you define a dataCallback function to retrieve different necessary underlying data. For example, daily data can not be rolled up into 'minutes' ticks. Additionally, even though minute data can be rolled into daily, weekly and monthly periodicity, it may not always be desirable as it could cause serious performance degradation (Example: rolling minute ticks into a monthly tick while displaying a 10 years range or monthly ticks). So use discretion when programming your roll-up methodology. See Periodicity and STXChart#dataCallback for more details.

On Setting Periodicity: Be sure to set your periodicity to match your data when you call newChart (or before calling it), so they are in sync.

Example 1:

stxx.newChart(
    symbol, 
    yourData, 
    null, 
    function () {
        // callback - your code to be executed after the chart is loaded
    },
    {periodicity:{period:period,interval:interval}}    //  default periodicity you want on the chart
);

Example 2:

stxx.setPeriodicityV2(1, 'month');                 //  default periodicity you want on the chart.
stxx.newChart(symbol, yourData, null, function () {    // call new chart to render your data
        // callback - your code to be executed after the chart is loaded
});

If not explicitly set, the chart defaults will be used as set in the STXChart#layout object (layout.interval and layout.periodicity elements). The library comes programmed with '1 day' as the default periodicity.

On Maximum Ticks: There is a maximum number of ticks the library will load at any given time. It is set to 20000 by default, and is done to protect the chart from performance issues due to an excessive number of elements being loaded at once. See STXChart#maxDataSetSize for details to how to override this default.

Recommendation: Although not required; if you plan on supporting intraday charts, your data server should deliver at least: 1 minute, 5 minute and 30 minute bars. It is not efficient to produce large charts based on 1 minute bars because of the bandwidth necessary to transmit data. On the other hand, it is generally unnecessary for your server to support weekly or monthly data (these can generated automatically for you by the chart).

Data Loading FAQ:

How much data is too much data?

Generally speaking, you can start thinking about too much data at about 100,000 bars. Even though high powered machines perform nicely even at 250,000 bars, on low powered devices such as ipads or older windows boxes initial load can get very sluggish.

Decide how much data you want load depending on the type if devices you will be supporting.

What is the difference between Date and DT?

As a developer, you can use either an epoch date (DT) or a string date (Date) in the OHLC object. This is done to facilitate integration to various feeds that may have dates in various formats.

DT is the primary timestamp field, and what is used internally by the library to reference ticks and derive timezones (see TimeZones and Time Conversion)

When present it will allways take precedence and override the Date field, so there will never be any conflicts between the two. If not present, Date will be converted to an epoch (JS date) and be used to set the DT field.

Do we have to use the documented format for data coming in from the server. Can we change it?

You must use the documented format for the charting engine to properly load the data. Your server data can be formatted differently, but you must reformat it to comply with the exected fromat before it is loaded. See See Data Format for details

If we can use any data format coming in from server, what changes do we need to make in the library for it?

Your 'fetch' function will need to format the data coming back form your server as required by the specs before returing it in the callback. See the 'Pull' section of this tutorial for details.

Do we need to fetch data from our servers with the tick intervals of 1D, 1W and 1M all separately? Can't we get the data for 1D and project it for 1W and 1M tick differences? Same for intraday options: 5m, 10min, 15 min, 30min and 1 Hour We get data for Tick differences of 5m and will be able to project it in 10m, 15m and others in intraday.

Yes, you can have your server just fetch minutes or days and allow the engine to roll up as needed. See the 'Periodicity and your masterData -- make sure they are in sync' section of this tutorial.

Can I use an object instead of a string for the chart symbol so I can have my own elements included?

Yes, a symbol string or an object representing the symbol can be used. Regardless of what you use, after the new chart is initialized, it will contain both a symbol string (stxx.chart.symbol) and a symbol object (stxx.chart.symbolObject). You can send anything you want in the symbol object, but you must always include at least a 'symbol' element. Both these variables will be available for use wherever the STXChart.Chart object is present. For example, if using the fetch() method for gathering data, params.stx.chart.symbolObject will contain your symbol object.