5.1.7Aggregation to higher timeframes

(Note: requires version 2 of the Framework. Present in v1, but limited: aggregated candles do not have derived properties, and aggregated stores cannot be updated with additional data.)

It is common to need multiple timeframes on a single market, such as both M30 and H1. Rather than making two separate candle requests, it can be more efficient to make a request only for the lower timeframe, such as M30, and then to create the higher timeframe(s), such as H1, by aggregating upwards.

Obvious note: the disadvantage of aggregation compared to a separate candle request is that you get fewer candles on the higher timeframe(s). If aggregating from M30 to H1, then N candles on M30 become N/2 candles on H1. An aggregation such as H1 to D1 causes a much larger reduction in data: the number of available daily candles is the number of hourly candles divided by 24.

You can create aggregated candles using the Aggregate() function. This creates a copy of a candle store, including any technical analysis calculations, and combines the candles into a higher timeframe. The new candle store can then subsequently be updated in the usual way, using LoadData(). For example:

// Request M30 candles

Framework.RequestCandles({"instrumentId": "EUR/USD", timeframe: 1800}, function(Msg) {

// If this is the first call, create a store for the M30 candles, including an ATR calculation

if (!Framework.$myM30) Framework.$myM30 = new FXB.CandleStore({

ta: [new FXB.ta.ATR({period: 14})]

});

// Load initial or subsequent candles into the M30 store

Framework.$myM30.LoadCandles(Msg.candles);

// If this is the first call, create an aggregated H1 store from the M30 store.

// The aggregated H1 store will automatically also have an ATR calculation.

if (!Framework.$myH1) {

// Creates H1 candles from the M30 initial candles which have just been loaded

Framework.$myH1 = Framework.$myM30.Aggregate(3600);

} else {

// If it's not the initial load of candles, then update the H1 store

// using the new M30 candles

Framework.$myH1.LoadCandles(Msg.candles);

}

});

As in the above example, Aggregate() requires a timeframe parameter for the aggregation, such as 3600 (=H1).

For timeframes between H2 and D1 inclusive, there is a further consideration: the time zone for the aggregation. Like the time zone when making candle requests, you may want to specify how the candles should be combined. Aggregate() can be given a time zone as a second parameter. For example:

// Aggregate into daily candles, using standard fx time (UTC+2/3 changing on US schedule)

cs.Aggregate(86400, {offset: 120, dstMode: 1});

If you don't provide a time zone parameter, then the default is UTC (and the setting is redundant and ignored if the timeframe is below H1 or above D1).

In a widget or script, you can get the user's standard time zone for charts using Framework.GetUserChartTimezone(). For example:

cs.Aggregate(86400, Framework.GetUserChartTimezone());

In a UDI, you can get the time zone of the indicator's chart from the context. For example:

cs.Aggregate(86400, data.context.timezone);