Mixing up types, was: Loop Counter Not Working

Objective is to track the relative performance of two symbols (SPY + QQQ), and set a flag indicating whichever one is current doing better. We then do not allow that flag to be changed for 22 bars, after which we set the flag to whichever again is stronger, which might mean no change in flag state or a switch. Once 22 bars have passed we continue to check every bar for the potential change.

I rarely use loops (not very good with them) and attempted to solve this with normal afl array formulas, but failed, so I tried with a loop. I am trying to use the barsinSPY + barsinQQQ variables to track and count # of bars they have been in that state, but I somehow screwed up those counters.

I spend a good amount of time with manual/forum attempting to adapt examples, but not successfully.
Your help is greatly appreciated – I should have been able to do this without bothering you. Code and current explore output enclosed.

_SECTION_BEGIN("Relative Str SPY vs QQQ Index Filter");// 
	SPYTick = ParamStr( "SPY ETF", "SPY" );	
	SPYcl =  Foreign(SPYTick, "C");  //  fc = Foreign( symbol, "C" );
	QQQTick = ParamStr( "QQQ ETF", "QQQ" );	
	QQQcl =  Foreign(QQQTick, "C");
	SPYEMA = Roc(SPYcl,10);  //  
	QQQEMA = Roc(QQQcl,10);
	SwitchIndsignal = iif( SPYEMA >= QQQEMA,1 , 2);

Position = 2;
barsinSPY[ 0 ]=0; 
barsinQQQ[ 0 ] =0;

for( i = 0; i < BarCount; i++ )
if (position[ i ]==1 ) // currently in SPY
  if (SwitchIndsignal[ i ]==2  AND barsinSPY[ i ] >22) // chg to QQQ
  	  Position[ i ] = 2;
	  barsinSPY[ i ] = 0;
	  barsinQQQ[ i ] = 1;
  else if (SwitchIndsignal[ i ]==1)
	{ barsinSPY [ i ]= barsinSPY[ i-1]+1 ; }
if (position[ i ]==2)  // currently in QQQ
  if (SwitchIndsignal[ i ]==1  AND barsinQQQ[ i ] >22) // chg to SPY
  	  Position[ i ] = 1;
	  barsinSPY[ i ] = 1;
	  barsinQQQ[ i ] = 0;
  else barsinQQQ++; // Trying different was to increast counter here

AddColumn(SPYEMA , "SPYEMA", 1.1);
AddColumn(QQQEMA , "QQQEMA", 1.1);
AddColumn(SwitchIndsignal , "SwitchIndsignal", 1.0);
AddColumn(Position , "Position", 1.0);
AddColumn(barsinSPY , "barsinSPY", 1.0);
AddColumn(barsinQQQ , "barsinQQQ", 1.0);type or paste code here

Ami Explore Output counter problem

Basicaly, in my opinion, you are talking about a monthly rotational system. (22 trading day's for me is the same as 1 month)

Therefore why bother making it so complex ? You can use the 1 month rotational systems as example.

Fine ofcourse if you want to make it complex, good learning experience maybe, but for me, not knowing a lot about AFL, I would go the easy route.

Your code is incorrect. You are once treating the barsinQQQ as array (use subscript operator) like this:

barsinQQQ[ i ] = 0;

then few lines after you are treating it as scalar (without subscript), like this:

else barsinQQQ++; 

That is wrong.

You need to single step your code under DEBUGGER to understand what you are doing.

To get better understanding of what is happening in your code and how functions work, use advice given here: How do I debug my formula?

For simplicity you should just use scalar variables (NOT arrays) to keep position and other state variables.

1 Like

Thank you for post Henri.
This is not intended to trade these symbols, rather it was intended as an indicator into another more complex rotation system trading other assets; using the state of this variable is a valuable risk on/risk off vote.
Your post gave me an idea - I might translate this into a quick traditional rotation system and use static var set to store the output for later system.

Thanks Tomasz for taking the time to push me in the right direction. Your brilliant programming and support has been appreciated for many years.

1 Like

As I was struggling with the looping approach, to meet my objective of creating an indicator of relative index strength while restricting frequency of changing "signals", I switched to using a simple rotation code structure. The results in the trade history are exactly as intended, however, short of creating a custom CBT code base to capture/store an array of these trades, I am at a loss how to create a staticvarset with trade results. The existing variables do not capture the information I need, but the final open positions do have what I need.

Specifically, I want to access "open_position" , and store it to a staticvar so that I can use it as an indicator flag in other independent models.

Guidance/suggestions on this is again appreciated!

Enclosed is a simplified version of the rotation code:

SetBacktestMode( backtestRotational); 
SetOption("HoldMinBars", 22 );
SetOption("HoldMinDays", 32 );
SetOption("MaxOpenPositions", 1);

_SECTION_BEGIN("Relative Str SPY vs QQQ Index Filter");// 
{ 	RelStrLB =14;
	ROC14 = 	Roc(c,RelStrLB); 
    RocScore = 	ROC14 + 100;  // Making positive so no shorts

	PositionScore = IIf(OKDay, RocScore, scoreNoRotate) ; 

Open positions are part of ~~~EQUITY symbol.

1 Like

Oh, cool :slight_smile:
I have seen your posts over the years, your coding is world class - thanks for sharing so much great work.

1 Like

OK, maybe this won't work - let me clarify further. The system switches between SPY & QQQ, using combination of the relative strength plus minholding days to result in the position history I want to capture. I need to access the historical array of daily holdings to get the signal (SPY vs QQQ) for that day as an indicator for another system.

I don't think the Foreign( "~~~EQUITY", "I") captures the actual symbol in array.

Any suggestions on how to capture/store that open position history is appreciated!


You didn't say so:

Use mid level CBT and store array result via ATC ( AddToComposite).
Since you only have max. open pos = 1

//check for open positions
 if ( pos.IsOpen ) {
		if ( pos.Symbol == "SPY" )	op_arr[i] = 'S';// SPY
		else						op_arr[i] = 'Q';// QQQ

Then output in Explorer (for example)

op_arr = Foreign("~OpenPos", "C");
Filter = op_arr;
AddColumn(op_arr, "OpenPos Sym", formatChar);



Exactly what I need.
I am truly in your debt and, in theory, much smarter now :wink:
Thank you!

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.