Stream Indexing

Brief

The section briefly describes how to access to the price stream data

Details

The index of the period

The prices and indicator results are accessed by the "index of bar". The index of bar is an integer number. 0 means the oldest bar in the price collection currently displayed on the chart. The size() - 1 bar means the newest bar in the price collection currently displayed on the chart.

For Marketscope application, this index is related to the time axis. The 0 means the leftmost available position at this scale, the size() - 1 means the rightmost position at this scale.

The indicator outputs is synchronized for the scale, so, it is expected that the indicator value for the Nth bar on the chart is located by the Nth index in the indicator output stream. The indicator core handles synchronization, so, before the Update method of the indicator is called, the core extends/reduces the indicator outputs, so the outputs have appropriate size and the data previously calculated for the source bars are located on the proper positions, even if the position of these bars in the source are changed.

By default, the indicator output has the same size as the indicator source. However, the indicator can make the source shorter or longer than the source using extent parameter of the output.

The first() value of the stream

While the prices are usually defined for every index of the source, the indicator can be not defined for a number of bars at the beginning of the output. For example, the simple moving average (an average price of previous N bars) cannot be calculate for the for the first N-1 bars, there is just no enough data to calculate it.

Therefore, the indicator can define the firstPeriod parameter of the output stream. This value means the index of the oldest bar of the source for which the indicator value is defined. This value is extremely important for both the indicator usage and the indicator calculation, so the developers must handle it extremely carefully.

1) Handling the first() value of the stream during the indicator usage.

When you use the indicator in another indicator or in an strategy, you must not access to the data by the index smaller than the value returned by first() method of the stream. The data is just not defined for these bars. Please, also, pay attention that many of methods requires the data defined in the bar, earlier than the bar referenced. For example core.crosses(stream, 0, P) (check whether the stream crossed the 0-level at the period P) requires the values defined at indexes P and P - 1 (previous bar), so P must be greater than stream:first(). Another example is core.sum(stream, core.rangeTo(P, 10)) (calculate a sum of the values for 10 periods before P (including P itself)), requires the data defined starting at P - 9 period, so P must be greater than stream:first() - 10

2) Handling the first() value of the stream during the indicator development.

It's not easy to recognize problems, related to incorrect handling of the firstPeriod value in the indicator output. If you specify 0 in that parameter and just skip filling the first N values, the indicator will look on the chart exactly the same as the indicator which specifies N in the firstPeriod parameter of the output stream. So, during displaying it looks good enough. But when you try to apply another indicator on the results of such indicator, this indicator can produce wrong values. This happens because the applied indicator tries to use the data which aren't defined. For example the EMA indicator applied on such wrong output will try to account these unfilled value and since EMA depends on it's previous value, the whole indicator result will be affected. So, to let the indicators which use our result work properly you must exactly declare the index of the oldest result you can provide.

Also, because for most of the indicators the source can be any source - prices or result of another indicator, you must always calculate the first available value for against the first value of the source.

However, please do not forget that the indicator's Update function is called for each bar of the source, starting at 0 bar, even if the source or the indicator output is not defined. So, you have to check whether the currently updating bar is after the first bar every time when the Update function is called.

back