Indicator.Calculate(MarketSeries.Close.Count - 1) vs Indicator.Result.Last(0)

Created at 10 Oct 2019, 16:58
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
FI

firemyst

Joined 26.03.2019

Indicator.Calculate(MarketSeries.Close.Count - 1) vs Indicator.Result.Last(0)
10 Oct 2019, 16:58


Hi everyone (and Team @Panagiotis :-) This is a continuation of our email exchange from earlier)

What are the differences between calling

Indicator.Calculate(MarketSeries.Close.Count - 1) ;
//vs 
Indicator.Result.Last(0);

Indicator.Calculate(MarketSeries.Close.Count - 1)

  1. Keeps 'lazy loading' ? Thus less memory consumption?
  2. Calculates any internal values for public properties that aren't of type IndicatorDataSeries if said properties are assigned/computed in the Calculate method? So I can then do "value = Indicator.MyProperty;" ?

Indicator.Result.Last(0)

  1. Forces the loading of the latest IndicatorDataSeries results
  2. Will or won't assign values to other public properties if they're in the Calculate method?

@firemyst
Replies

PanagiotisCharalampous
11 Oct 2019, 11:34

Hi FireMyst

Indicator.Calculate(MarketSeries.Close.Count - 1)

will call your indicator's Calculate function for that specific index

Indicator.Result.Last(0);

Will return the last value of the Result series and call the Calculate function for all required indexes if it hasn't been called yet.

Best Regards,

Panagiotis


@PanagiotisCharalampous

firemyst
21 Oct 2019, 04:24

RE:

Panagiotis Charalampous said:

Hi FireMyst

Indicator.Calculate(MarketSeries.Close.Count - 1)

will call your indicator's Calculate function for that specific index

Indicator.Result.Last(0);

Will return the last value of the Result series and call the Calculate function for all required indexes if it hasn't been called yet.

Best Regards,

Panagiotis

Thank you @Panagiotis.

A point of clarification  then regarding the 'lazy loading' of indicators.

Let's use the BollingerBands as an example. That has "Top", "Main", and "Bottom" IndicatorDataSeries objects.

Question #1:

if I call BollingerBands.Main.Last(0), will that update the required indexes for BollingerBands.Top and BollingerBands.Bottom too since it calls the Calculate function? Or only update BollingerBands.Main? For example:

//That is, is this sufficient?
double a = bb.Main.Last(0);
//do the other IndicatorDataSeries objects within the same indicator get updated
//as well from the above call to bb.Main.Last(0) so we can use their latest values?
if (bb.Bottom.Last(0) > 3 && bb.Top.Last(0) > 4) { //... }

//
//**** Or do we still have to call Last(0) for every other IndicatorDataSeries object within 
//an indicator as shown below to have them updated with the latest values too?
//
double a = bb.Top.Last(0);
a = bb.Bottom.Last(0);
if (bb.Bottom.Last(0) > 3 && bb.Top.Last(0) > 4) { //... }

 

Question #2:

if we call Indicator.Calculate(MarketSeries.Close.Count - 1), that will force the latest values to be loaded for all IndicatorDataSeries objects within an Indicator?

For example, are both of these functionally equivalent?

//are these two code examples functionally equivalent?
// #1
double a = bb.Bottom.Last(0);
            a = bb.Main.Last(0);
            a = bb.Top.Last(0);
if (bb.Bottom.Last(0) > 1 && bb.Main.Last(0) > 2 && bb.Top.Last(0) > 3) { //... }

// #2
double a = bb.Calculate(MarketSeries.Close.Count - 1)
if (bb.Bottom.Last(0) > 1 && bb.Main.Last(0) > 2 && bb.Top.Last(0) > 3) { //... }

 

Question #3:

I've done some preliminary performance testing using the C# StopWatch, and doing the following:

//This code runs faster
if (bb.Bottom[latestIndex] > 1&& bb.Main[latestIndex] > 2 && bb.Top[latestIndex] > 3) { //... }

//..than calling the .Last(0) or .LastValue function
if (bb.Bottom.Last(0) > 1&& bb.Main.Last(0) > 2 && bb.Top.Last(0) > 3) { //... }

gives some performance speed increases I'm guessing because of the overhead incurred running the "Last" and "LastValue" functions as opposed to directly accessing the array index.

Given what your team knows of the underlying indicator architecture implementation within cTrader, is this assessment correct?

 

Thank you :-)


@firemyst

srubtsov
25 Oct 2019, 16:08

Hi @FireMyst

You are right, indicators in cBots are lazy, they calculate only when you ask for any of output series.

Answers below for "good" indicator where all output series calculate inside `Calculate` method. If indicator has "strange" implementation, we have "strange" results.

Answer #1:

Calling any output series of indicator by any index will call `Calculate` method from the last calculated index to the last index of MarketSeries. And it updates all output series because of them calculates in `Calculate` method.

Answer #2:

Calling `Indicator.Calculate(MarketSeries.Close.Count - 1)` will calculate only that index. It is a bad practice, look at the method `Indicator.Calculate` like on private method. So those examples don't equivalent, but both first lines don't need here.


@srubtsov