Cumulative Occurrences of Variable in Data Set

Hello, I am trying to backtest the performance of several combination during an extended period of time. During each bar, I would like to know how many previous bars up to that point, in my data set, have had the same 'combo' variable I just calculated. I get the number on the results tab of the backtest by adding it to custombacktestProc

Previously we have used:

Cum (Combo == XX AND DateNum() >= StartDate AND DateNum() <= EndDate );

Where XX is the combination number, however, I would like to remove the need to specify XX as a static number and just have the formula give me the result for whatever Combo was calculated that row without the need for me to specify. Here is the current code:

BinCondition1 = IIf(TickerOpenChange1 < TickerOpenChange2, 1, 0);
BinCondition2 = IIf(TickerOpenChange1 ==  TickerOpenChange2, 2, 0);
BinCondition1 = IIf(TickerOpenChange1 > TickerOpenChange2, 3, 0);

Bin = BinCondition1 + BinCondition2 + BinCondition3;

	//Now we calculate BinPrevPrev
	
BinPrevCondition1 = IIf(TickerOpenChange2 < TickerOpenChange3, 1, 0);
BinPrevCondition2 = IIf(TickerOpenChange2 ==  TickerOpenChange3, 2, 0);
BinPrevCondition1 = IIf(TickerOpenChange2 > TickerOpenChange3, 3, 0);

BinPrev = BinPrevCondition1 + BinPrevCondition2 + BinPrevCondition3;

Combo = (Bin * 10) + BinPrev;

// StartDate is set to the first available bar in the database
// Identify the first bar with a valid Open value
FirstValidBarIndex = ValueWhen(!IsNull(Open), DateNum(), 1); 

StartDate = FirstValidBarIndex;

StopDate = Status("rangetodate"); 

Combobars = Cum( Combo == ValueWhen(BarIndex() == BarIndex(), Combo) AND DateNum() >= StartDate AND DateNum() <= EndDate );

Thank you

Your current code doesn't work because it can't.

This:

BarIndex() == BarIndex()

Is ALWAYS true (returns True for all bars).

ValueWhen(BarIndex() == BarIndex(), Combo);

is equivalent to:

ValueWhen( True, Combo)

and that is equivalent to just

Combo

What you seem to be trying is recursive formulation. You are changing the value that you are comparing to and you go BACK IN TIME each time. This kind of calculation usually requires double nested loop.

In some cases you can use BarsSinceCompare function that essentially does double loop internally:
http://www.amibroker.com/guide/afl/barssincecompare.html

But this would give you number of bars since comparison was last time true, not cumulative.

So general answer is either use what you have used before:

Cum (Combo == XX AND DateNum() >= StartDate AND DateNum() <= EndDate );

This works because it can be evaluated IN ONE PASS (since "XX" is known literal and array can be evaluated in one pass).

When XX is a "combo" variable itself (or depends on "combo" variable indirectly) you have self-reference (recurrence) and that needs a loop.

2 Likes