AmiBroker 6.26.0 BETA released


Thank you @fxshrat and @Milosz,
Ok no dynamically constructed name, but what is the purpose of the keyword( prefix ) - does it mean that every variable that has this keyword is static ?
It seems that I cannot call the variable using the prefix without using StaticVarget ()

// deifining a dynamic variable 
VarSet ( "xyz_ATR", 0 ); 
// can call it this way : 
xyz_atr ;

// defining a static variable 
#pragma enable_static_decl(some_prefix)
static _var;

_var = 1; 

// can call it this way - no prefix  !?!
_var ; 

// can call it this way 
StaticVarGet ( "some_prefix_var" ); 

// but cannot call it this way 
some_prefix_var ; 


@Tomasz thank you very much for the new static variable enhancements. This will help us avoid shooting ourselves in the foot when copying formulas and running multiple formulas concurrently using the same static variables.

It would be even better if we could do something like the code below to prevent similar formulas from using the same static variables. Haven’t tried this, but I expect it will not work. I just think it would be nice to write this line of code once without having to remember to change it for each new formula.

#pragma enable_static_decl(GetFormulaPath())

Moderator comment: Prefix is literal string. Even if you write it like this it will take literal string and prepend it as prefix. It won’t call any function



The last line is wrong. Don’t mix up things with varset/varget. Forget about that.

If not using staticvarget then prefix is only used for declaration via #pragma. Just look at my last examples again. In your case you only have to use _var without prefix (if not using staticvarget).

Evry variable that is defined in after static, yes.



Yes, that was my point as well:
unless you are using StaticVarget (), you cannot call the variable by its prefix that is used to declare it as static, but you can do it instead using only the suffix.

I cannot seem to figure out where and why would I use this form - what’s the benefit?
I’m a little perplexed.


The purpose is to make code faster and easier to write.

Instead of doing this:

x = Nz( StaticVarGet("_x" ) );
y = Nz( StaticVarGet("_y" ) );


StaticVarSet("_x", x );
StaticVarSet("_y", y );

you write

#pragma enable_static_decl

static _x, _y;

_x++; // this is static variable and will keep value between executions
_y++; // this too

If you have lots of static variables, it makes code a whole lot shorter if you don’t need to write StaticVarGet/StaticVarSet each time you access the static var.


With the new static keyword, does it mean StaticVarGet and StaticVarSet are no longer useful? Are there coding situations when StaticVarGet and StaticVarSet are more suitable to be used than static?


There are examples in this thread showing that in some cases StaticVarSet/StaticVarGet are still necessary - for example when static variables have dynamically constructed names or (probably) when we want our static vars to be persistent (retrieve their values after AB restart).


Also note that #pragma like #include is a pre-processor directive, which means it is seen only by pre-processor before your code. Anything inside #pragma is NOT code. It is just literal string. The literal string inside pragma is taken as prefix. There is no execution or evaluation here. The string it taken as it is and prepended to identifiers of static variables declared with static keyword.

#pragma enable_static_decl(literal_string_goes_here)

static _x; // this static will have "public" name of "literal_string_goes_here_x"

_x = 7;

The other formula could access that variable for example by writing


Those two methods (declaration and Static*) complement each other. Static declaration may be considered as syntactic sugar to existing method.

Why there are prefixes added at all?

There are two reasons:
a) to allow you to make your formula’s declared static variables to be “globally” unique (because static variables can be seen from other formulas, the way to prevent interference is to use unique prefix)
b) to make code shorter (you only need to define the prefix once in #pragma)

Without unique prefix, two formulas will use the same variable if it has same identifier. It is useful too - for sharing parameters for example.

Note that #pragma affects only variables declared with static keyword. Prefix is not prepended to identifiers used by StaticVarGet/StaticVarSet

Also, please really read the whole text of Example 1 (upper in this thread) - including important comments. It is important to read last comment, which explains that the content (or value) of declared static variables is read from ‘global’ memory once (when the variable is declared) and finally written to ‘global’ memory once - when your formula finishes. During your formula execution the variable keeps local copy. That is done for speed because accessing shared resource involves thread lock.

Efficient use of multithreading and static vars
How To - Declare identifier as Static Variable

Consider the following program. I applied it to two panes under a different formula name and I can increment the shared counter from either pane. Questions I still have are:

  1. The literal prefix in the #Pragma, should it be in double quotes? It seems to take both…
  2. How do I assign the ChartID() to this prefix to isolate the static variables to this formula only? Tomasz showed the code below, but I do not understand how this works.
VarSet( "dynamic_name"+GetChartID(), 1 );
  1. How do I clear static variables for a specific prefix?

Thanks for any help you can give!

// Not sure if the Pragma assignment is correct...
// The Remove Declared Static Variables doesn't work. Please Fix if you can.
MySharedPrefix = "MySharedPrefix";

#pragma enable_static_decl( MySharedPrefix ) 

static _MySharedVariable;

RequestTimedRefresh(1); // just to make the count update in the title.

if( ParamTrigger( "Increment Counter", "INCREMENT" ) ) _MySharedVariable++;

if( ParamTrigger( "Remove Static Variables", "REMOVE" ) ) StaticVarRemove( "*" );

if( ParamTrigger( "Remove only Declared Static variables", "REMOVE DECLARED" ) ) StaticVarRemove( "MySharedPrefix"+"*" );

Title = 


Hello Tomasz,
I am trying hard to understand these new static variables.
Could you show me how to write something that is written with old static variables in new ones?
It is a button to activate autotrading:

_SECTION_BEGIN("Button AutoBuy");
AutoBuy=StaticVarGet(SVKey + "AutoBuy");

CursorInAutoBuyBut = MouseX >= X AND MouseX <= X+WidthB AND MouseY >= Y AND MouseY <= Y+HeightB;
AutoBuyPressed = CursorInAutoBuyBut AND LBClick;

StaticVarSet(SVKey + "AutoBuy" , 1);
if(AutoBuy AND AutoBuypressed)
StaticVarSet(SVKey + "AutoBuy", 0);

GfxSelectPen( colorBlack, 2); 
GfxSelectSolidBrush( color); 
GfxSelectFont("Tahoma", SizeB, Thickness );
GfxTextOut(Text, X+10, Y+15 );


Re-read my posts - all info is there. I can’t describe it clearer than I already did. If you still don’t understand you miss understanding of some basic terms and need to first learn what string literal is: and what pre-processor is (it links to C preprocessor, which is NOT the same as AFL pre-processor but AFL pre-processor uses pretty much same concept).
In #pragma you don’t need quotes (braces work as delimiters), but even without quotes it is still string literal.

@Michael - Re-read my posts above - all info is there, I already explained everything, really, but you need to read carefully. Each sentence and each word is very important. Don’t skip a word.


OK :slightly_smiling_face: I agree: I don’t understand 95% of the inner workings of compilers, their terminology, and how AmiBroker works at the nitty-gritty level. That is something I leave up to the experts. I do just fine with most afl programming projects because 99% of what I use came from from code contributed by others. Give me an example and I’ll morph it into something that works for me. I bet a lot of users do the same.

I am just curious, am I the only one who doesn’t know what is wrong with the following statement?

if( ParamTrigger( "Remove only Declared Static variables", "REMOVE DECLARED" ) ) StaticVarRemove( "MySharedPrefix"+"*" );

I’d like to take the opportunity here to give thanks to all who share code so liberally! THANK YOU!



First you would need to explain why do you think it is wrong


Hi Herman,
I dont see anything wrong with your code its just that the formula declaring the variables should not be executing.


Hi Herman,

Tomasz wrote:

the content (or value) of declared static variables is read from ‘global’ memory once (when the variable is declared) and finally written to ‘global’ memory once - when your formula finishes. During your formula execution the variable keeps local copy.

As I understand this, the declared static var is invisible to staticvarremove() / staticvarcount() until the formula finishes execution when the declared variable is written to memory.

In the following snippet if you move staticvarremove() to the end of code it will have no effect.

#pragma enable_static_decl(my_prefix) 

StaticVarRemove ( "my_prefix*");

static _var;
_var ++; 

_TRACE ( "decl var val = " + _var); 



It must be wrong because it doesn’t work. Look below I have the same formula applied to two panes, under different names. First I increment the counter, this works fine. I then remove “ALL” static variables, that works fine too. But when I try to remove only the Statically declared variables the counter doesn’t clear. I use a Timed refresh of 1 second to show the title updates.

Reset Static variables



Thanks Aron,

I moved the triggered remove() to the front of the code and it didn’t clear there either. Also, I think that regardless of where the remove() is called it should clear the Static Variables. When they are then saved at the end they would be saved in a cleared state.



Herman after 60+ min that i spent, finaly below code is working and can REMOVE DECLARED

#pragma enable_static_decl(prfx) 
static _myVar, _x; // this static will have "public" name of "prfx_x"

RequestTimedRefresh(1); // just to make the count update in the title.

if( ParamTrigger( "Increment Counter", "INCREMENT" ) ) _myVar++;
if( ParamTrigger( "Remove Static Variables", "REMOVE" ) ) StaticVarRemove( "*" );

_x = 7;

printf( "x: %g, _myVar %g", StaticVarGet( "prfx_x" ), StaticVarGet( "prfx_myVar" ) );
Title = "\n-----\n _myVar = "+ _myVar + "   \n StatvarGet_myVar = "+  StaticVarGet("prfx_myVar") + "\n X= " + StaticVarGet("prfx_x"); 

if( ParamTrigger( "Remove only Declared Static variables", "REMOVE DECLARED" ) ) 

 StaticVarRemove( "prfx*" );


OK, guys I see you don’t get it.

This functionality will likely be hidden in next release because I am tired explaining that over and over.

I wrote about this already TWICE.

Declared static variable is READ from global (shared) memory at the declaration time and written back to global memory when your formula finishes.

Inside the formula you are operating on copy.

In contrast to that StaticVar* functions operate directly on global memory.

#pragma enable_static_decl(my_prefix)

// here you tell that _myvar will be static
// what it really does is read "my_prefix_myvar" static variable
// and put it in _myvar variable (let us say it is 0)
static _myvar;

// from now on _myvar is basically "normal" variable from execution point of view

_myvar++; // you are modifying _myvar which is local copy of the variable, will be 1
// (it is marked as "dirty") internally

StaticVarGet("my_prefix_myvar"); // this would access GLOBAL memory, NOT the local copy, so it will get 0 (not 1)

StaticVarRemove( "my_prefix_myvar" ); // you are removing from GLOBAL memory
// but you are NOT touching _myvar at all because it is treated as normal variable

// then we arrive at the end of the formula
// and AmiBroker would write BACK the local copy _myvar to GLOBAL memory 
// so it will store 1 into "my_prefix_myvar"

StaticVar* functions operate on GLOBAL memory. But any declared static variable is WRITTEN
to global memory when formula execution FINISHES. So basically the fact that you removed from global store does not matter because it will write back modified values anyway.

Moral story is:
DO NOT MIX / DO NOT CALL StaticVar functions on declared static variables within SAME formula, as they are operating on different memories*

If you want to reset declared static variable do NOT call StaticVarRemove. Just assign 0 (or Null) instead:

static _x;

_x = Null; // THIS should be done instead of StaticVarRemove

_x = 0; // Or this

Use StaticVar** functions on variables that were NOT declared WITHIN given formula.


And the fact that majority don’t care about understanding how it works and don’t bother with details “leaving up to the experts” this functionality will be hidden from public in next release, because apparently it is too complex for public consumption. I don’t want this to become next support nightmare. I implemented it for my own purposes, and it will become private.