Use StaticVarGetTEXT to get string, was: Error 5: The first argument

I have this #include function:

procedure GetOpenPositions(filename,varname) {
	if (Status("stocknum") == 0) {
		StaticVarRemove(varname);
		my_symbols = "|";
		fh=fopen(filename, "r", True);
		if (fh)
		{
			while (! feof(fh))
			{
				line = StrTrim(StrTrim(fgets(fh),"\n")," ");
				if (line == "") continue;
				if (StrLeft(line,1) == "#" OR StrLeft(line,1) == "/") continue;
				my_symbols+=line+"|";
			}
			fh=fclose(fh);
		}
		StaticVarSetText(varname,my_symbols);
	}
}

And here is how I call it in my main program:

// Exploration Analysis - this column flags if the Sell has been previously bought (based on data in an external file)
MyOpenPositions="";
GetOpenPositions("C:\\Temp\\MyOpenPositions.txt","MyOpenPositions");
MyOpenPositions=StaticVarGet("MyOpenPositions");
find=(StrFind(MyOpenPositions,Name()) != 0);
AddMultiTextColumn(IIf(Sell,find,Null),"No\nYES","In Trade?",0,colorDefault,IIf(find,colorRed,colorDefault));

I get this intermittent error:

image

during Explore and Optimization. If Explore I just click Explore again and it works. However, during a long running Optimization it ruins my day.

The only thing I can figure is there is an occasional situation where I don't have

Status("stocknum") == 0

so the StaticVar doesn't get set, and the calling code sets MyOpenPositions to a number.

However, I'm afraid if I move StaticVarSetText outside the if condition it will kill performance.

So...is there ever a situation where there is no "stocknum==0"?

So I see this in http://www.amibroker.com/guide/afl/status.html

  • "stocknum" - gives you the ordinal number of currently analysed symbol

but to me this isn't clear if there is ever a case during Analysis when I wouldn't have a 0-bar.

When you run any type of Analysis, it is performed on symbols.
StockNum is the 0-based count of symbols in alphabetical order.

if you have 3 symbols, abc, def, ghi, then stocknum will be 0, 1, 2 respectively for each symbol in its own thread.
So we cant have a case where AA runs without any symbols

Got nothing to do with Status.

You have a mistake in your code.

Use StaticVarGetText since you use StaticVarSetText(varname,my_symbols); within GetOpenPositions function.
24

StaticVarGet rather should be used for numbers because when static var is not set it will return empty which is Null and a number. That's why StrFind returns Error 5 because first argument should be type string. On the other hand StaticVarGetText returns empty string when there hasn't been set static var yet. So it still will be type string then and therefore there won't be an error within StrFind even then.

If you would use StaticVarGet() then you should check for type of stored variable.

GetOpenPositions("C:\\Temp\\MyOpenPositions.txt","MyOpenPositions");

MyOpenPositions=StaticVarGet("MyOpenPositions");

if ( typeof(MyOpenPositions) == "string" ) {
    find=(StrFind(MyOpenPositions,Name()) != 0);
    AddMultiTextColumn(IIf(Sell,find,Null),"No\nYES","In Trade?",0,colorDefault,IIf(find,colorRed,colorDefault));
}

Since it may return number or string (and if empty it will be number always).
23

If you want to retrieve STRING (text) you have to use StaticVarGetText()

The difference between StaticVarGet and StaticVarGetText is that if static variable does NOT exist, StaticVarGet would give you NULL (Number) while StaticVarGetText would give you empty string.

This:

// empty string is returned when var does not exist
MyOpenPositions=StaticVarGetText("MyOpenPositions"); 

would solve your problem.

Thanks @fxshrat and @Tomasz.

I acknowledge that my code had a bug, and the suggested fix will solve the problem.

However, as long as

Status("stocknum") == 0

is always true, then my function code should have ran, set the static variable MyOpenPositions as text, and StaticGetVar would return that text.

The code worked most of the time in Explore, Backtest, and Optimization, but would rarely fail during Explore (I would just run Explore again and it would work), never failed in Backtest, and would occasionally fail during Optimization, aborting the long running Optimization.

So what I'm trying to understand: is there ever a situation where there is not a 0th stocknum bar? Is the above paradigm the way to "run once" as opposed to "run once most of the time"?

Thanks...

Your mistake is that you placed Status("stocknum") == 0 inside the INCLUDE, not in actual formula.

AmiBroker checks for Status("stocknum") == 0 WITHOUT executing the formula and if it does not find it in MAIN FORMULA, it runs the code in MULTIPLE threads from the start. So your code was run in multiple threads BEFORE you set the static variable.
Only if AmiBroker sees Status("stocknum") == 0 in MAIN formula it will only run ONE thread and WAIT for completion before starting multiple threads.

Manual: http://www.amibroker.com/guide/h_multithreading.html

Quote:

Caveat: the above statement must NOT be placed inside #include.

2 Likes

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