SetForeign (ab)use - create composites ONCE, was: StaticVarAdd help

if(Status("actionEx")==actionScan)
{
   if(Status("stocknum")== 30)
  {   StaticVarSet("~lhitadd1",StaticVarGet("~lhitaddsva"),persist=false);

   StaticVarRemove("~lhitaddsva");
   }
StaticVarAdd("~lhitaddsva",lhitadd,keepAll=True,persist=False);
}
type or paste code here

Hi
I am unable to run above code,
type unsupported for static variable error is shown at staticvaradd row.

i want to create composite ~lhitaddsva (by adding lhitadd(array) for every stock) in first scan
and then assign its value(at last stock-30 in first scan) to ~lhitadd1 so that i can use ~lhitadd1 value in next scan.
please let me know where i am doing wrong.

Hi Guys

Could someone please look at the below code to see why is is so slow, i think it maybe something to do with StaticVarAdd.

I am trying to run the code over a watchlist and generate sector momentum based on each symbols ROC.

When i run the 'Verify Syntax' button it takes a few seconds but doesn't show any errors and also when the code is incorporated in a system and plotted on a chart it is very slow.

I have tried to debug but cannot find the solution in the documentation or in the forum.

Thanks, please find the code below.

inList = CategoryGetSymbols(categoryWatchlist, 60); // show symbols in the lists


if( Status( "stocknum" ) == 0 )
{

    StaticVarRemove( "~Equal*"  );
    StaticVarRemove("~stockcount*" );
	
    for( i = 0; ( sym = StrExtract( inList, i ) ) != ""; i++ )
    {
		SetForeign(sym);
		StockSector = StrLeft( GicsID( 0 ),2);
		sec = "";

		if( stocksector == "10" )
			sec = "$XEJau";

		if( stocksector == "15" )
			sec = "$XMJau";

		if( stocksector == "20" )
			sec = "$XNJau";

		if( stocksector == "25" )
			sec = "$XDJau";

		if( stocksector == "30" )
			sec = "$XSJau";

		if( stocksector == "35" )
			sec = "$XHJau";

		if( stocksector == "40" )
			sec = "$XFJau";

		if( stocksector == "45" )
			sec = "$XIJau";

		if( stocksector == "50" )
			sec = "$XTJau";

		if( stocksector == "55" )
			sec = "$XUJau";

		if( stocksector == "60" )
			sec = "$XREau";


		
        stockmom = ROC( C, 12);
        sect = sec;
        RestorePriceArrays();
        

		StaticVarAdd("~Equalweightmom_"+ sect, stockmom); // add momemtum calc to relevent sector
		StaticVarAdd("~stockcount_"+ sect, 1);  // count stocks in each sector
    }
}

No, it is not StaticVarAdd. StaticVarAdd is blazing fast. It is calling SetForeign hundreds or thousands of times that makes your code slow. You should not be doing that.
You should be creating composites (that include StaticVarAdd) in a separate scan that is run ONCE ONLY to create composite. Once composite is created it can be used many times without calculating it over and over again (which is big no-no).
http://www.amibroker.com/guide/a_addtocomposite.html

See: https://forum.amibroker.com/search?q=SetForeign

3 Likes

There is a growing number of codes that abuse SetForeign in a loop. This is all wrong. Composites should NOT be re-calculated over and over again. They should be calculated JUST ONCE using process described in the manual:
http://www.amibroker.com/guide/a_addtocomposite.html

StaticVarAdd may be added instead of AddToComposite BUT the procedure should stay the same, i.e. run scan ONCE to create static variable and don't use SetForeign AT ALL.

These four lines are supposed to be run ONCE

There is example in the MANUAL how you should use StaticVarAdd
http://www.amibroker.com/guide/afl/staticvaradd.html

if( status("stocknum") == 0 ) 
{ 
   // remove any earier composite values 
   StaticVarRemove("~Composite"); 
} 

StaticVarAdd( "~Composite", MACD() > Signal() );  // create multi-security statistic
Buy = 0;

As you can see there is NO SETFOREIGN call.

3 Likes

Thankyou Tomasz

All sorted