Using Staticvar to generate Ranks on russell 2000 list - norgate data

I have a system which enters limit orders when RSI is below a certain level and certain other conditions (High ADX Value/volatility etc. AM running this on russell 2000.
However, to avoid an unrealistic number of limit orders, i tried using the staticvarset/varget function as explained in the limit order help page. To reduce the number of symbols being ranked . I tried using the iif function as described below:
// value used for scoring
values = IIf(buysignal,(100 - RSI(3)),1000000);

while the ranking happens on watchlist upto 500 stocks it fails on russell 2000 watchlist and i get an error "Error 47.exception occured during AFL formula execution at address : 0000..."

am pasting the code below and would like help in understanding what am missing here. Is the error because there are more than 1024 symbols and also why is the iif condtion mentioned above not influencing the ranking..
Have posted the code below, the relevat portion is from the line having wlnum though i have given the buy condition as well. I have also tried providing the specific Norgate watchlist number but get the same error.

#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"


////////////////////////////////////////////////////
SetFormulaName("MY FIRST SYSTEM");
// Controls	(Top level controls for the trading system)

Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades		(Switch between a portfolio test or an all trades test)
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				// 0 = Same Bar on Close, 1 = Next Bar at Avg Price		(Controls entry timing)
ExitTiming = 0; 				// 0 = Same Bar on Close, 1 = Next Bar at Avg Price		(Controls exit timing)

PosQty = 15;					// Controls portfolio size / total number of positions
Margin = 100;					// Sets account margin. 100 = no margin
pctPosSize = 100/PosQty * 100/Margin;	// Controls the position size for new entries

////////////////////////////////////////////////////


////////////////////////////////////////////////////
// Set up and verify AB environment
SetOption("InitialEquity",IIf(Portfolio,35000,71000*1000));	// If test is portfolio start with $10,000 otherwise start with $1M                  
SetOption("CommissionMode",3);									// Set commision mode to 3 = $ per share/contract              
SetOption("CommissionAmount",IIf(Portfolio, 0.01, 0));			// If test is portfolio set commission to $0.01 per share otherwise zero
SetOption("AllowSameBarExit", True);						// Call same bar exit rule in controls
SetOption("MaxOpenlong",10);		// If test is portfolio allow PosQty (10) positions otherwise 2500               
SetOption("MaxOpenshort",10);		// If test is portfolio allow PosQty (10) positions otherwise 2500               
SetOption("MaxOpenpositions",20);		// If test is portfolio allow PosQty (10) positions otherwise 2500               
SetOption("AccountMargin",IIf(Portfolio,Margin,100));			// If test is portfolio call Margin otherwise leave at 100                  
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True));	// If entry is same bar do not use previous bar for position sizing
SetOption("AllowPositionShrinking", True);						// Allow smaller position size if not enought capital available
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);  // Set trade delays according to timing controls above
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True));		// If exit is same bar do not active stop immediately
//SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsValue,10000)); // Set position size to percent of equity if portfolio test otherwise set to 1 contract
//RoundLotSize = IIf(Portfolio,1,1);								// Round position sizing to 1 share/contract (no fractional shares)
 SetOption("HoldMinBars", 1 );


//////////////////////////////////////////
// Norgate inactive securities (delisted tickers) - see http://www.premiumdata.net/support/amibroker.php

NonTradedPeriod = 30;	//in calendar days
SecurityIsInactive = LastValue(DateTimeDiff(Now(5),DateTimeAdd(DateTime(), NonTradedPeriod, inDaily))) >= 0; // Find inactive security
OnSecondLastBarOfInactiveSecurity = BarIndex() == (LastValue(BarIndex()) -1) AND SecurityIsInactive; // Set second last bar of inactive security
OnLastTwoBarsOfInactiveSecurity = BarIndex() >= (LastValue(BarIndex()) -1) AND SecurityIsInactive;	// Set last two bars of inactive security

//Alternative formula for non-Norgate users

BarsSinceLastChange = BarsSince(C != Ref(C,-1)); // Find the last bar where the price actually changed
LastGoodBar = IIf(IsEmpty(BarsSinceLastChange), 0, BarCount - LastValue(BarsSinceLastChange) - 1);
fDelisted = LastGoodBar < BarCount -1;
inRange = Status("BarInRange") AND IIf(fDelisted, (LastGoodBar - BarIndex()) >= 3, True);
isLastBar = Status("LastBarInRange");  

//////////////////////////////////////////


minVolume = 500*1000;				// Sets minimum volume to 100,000 shares
AvgVolume = MA(Volume,25);		// Calculates 25-day average volume

Liquid =	Ref(AvgVolume,-1) > minVolume AND LLV(V,30) > 50000			// Previous bar's average volume must be greater than minimum volume amount
			AND NOT OnLastTwoBarsOfInactiveSecurity;	// Do not enter if on last two bars of an inactive security

//Position Sizing
Positionrisk = 2 ;
traderisk = 2.5*ATR(10)/C*100 ;
pctsize = Min(100*positionrisk/traderisk,10);
SetPositionSize(pctsize, spsPercentOfEquity); 
//SetPositionSize(1000, spsValue);


//Long system
//ENTER YOUR ENTRY AND EXIT RULES BELOW
cond1 = C > MA(C,150) ;
cond2 = ADX(7) > 45 AND RSI(3) < 30;
cond3 = ATR(10)/C > 0.04;

BuyLimitPrice = Ref(Close,-1) * 0.96;

BuyPrice = Min( Open, BuyLimitPrice );

Buysignal = cond1 AND cond2 AND cond3 AND liquid  AND C > 1  ;
//AND PDI(7) > MDI(7)
// Back Test Parameters

realpos = IIf(Ref(buysignal,-1),1-RSI(3),RSI(3));

//PositionScore = realpos ;			// Ranks duplicate signals in order of RSI(14)


wlnum = GetOption( "FilterIncludeWatchlist" );
List = CategoryGetSymbols( categoryWatchlist, wlnum ) ;

SetOption("MaxOpenPositions", 3);

if ( Status("stocknum") == 0 ) // Generate ranking when we are on the very first symbol
{
     StaticVarRemove( "values*" );

     for ( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++    )
     {
         SetForeign ( symbol );

         // value used for scoring
         values = IIf(buysignal,(100 - RSI(3)),1000000);
         RestorePriceArrays();
         StaticVarSet (  "values"  +  symbol, values );
         _TRACE( symbol );
     }

     StaticVarGenerateRanks( "rank", "values", 0, 2100 );
}

symbol = Name();
values = StaticVarGet ( "values" +  symbol );
rank = StaticVarGet ( "rankvalues" +  symbol );

   
PositionScore = 1- RSI(3);

Buy = Ref(buysignal,-1) ;
Buy = Buy AND L< buylimitprice AND Ref(rank,-1) <=5 ;

1 Like

Why do I get "Error 47" on a backtest? (I am using SetForeign/RestorePriceArrays)
@sudharshangomadam on the Norgate web site you can find this,

In AmiBroker versions prior to v6.13, when SetForeign is used, AmiBroker needs to keep the contents of the foreign symbols in its in-memory cache. If the number of foreign symbols accessed exceeds the cache size then error 47 will be given. You should increase the In-memory cache size in Tools > Preferences > Data. Ensure that "max. symbols" and "max. MegaBytes" have enough size to cache all symbols. Alternatively, upgrade to AmiBroker v6.20.1 or above.

So perhaps you have two ways to fix that: Either increase in memory cache to match the number of symbols you are using or upgrade to version 6.20

4 Likes

Many thanks ! i see that you have given the answer for a similar question in 2017 which did not show up when i was checking yesterday.

Also, i guess that all the parameters for computing the ranking score should be in the "Rank Loop".