AmiBroker 6.27.1 BETA released


A new beta version (6.27.1) of AmiBroker, with lots of new AFL functionality has been released.


32-bit version:
(2 271 480 bytes)

64-bit version:
(10 623 744 bytes)


DevLog announcement:

Read Me:


This version is a free upgrade only for users who registered AmiBroker after October 31, 2015. Users who registered earlier, would need to purchase license upgrade. To find out the version you currently have use Account Information page at

CHANGES FOR VERSION 6.27.1 (as compared to 6.26.0)

  1. AFL edit: preprocessor command (#include/#include_once/#pragma) are highlighted with different color to give visual clue that preprocessor command is NOT regular code
  2. AFL: #pragma enable_static_decl accepts prefix given in quotation marks (as regular string).
  3. AFL: due to changes in 6.25 BETA TimeFrameSet applied on 1-tick base interval could result in division by zero exception. Fixed.
  4. AFL: Error 66 has new meaning now. It is issued to prevent attempts to mix static declarations with old style access. Error 66. Variables with ‘—’ prefix are inaccesible via StaticVarGet/Set/Remove in this formula. This prefix is reserved by #pragma ena
  5. AFL: Removed Error 66: invalid identifier from VarSet/VarGet. Instead of issuing error message, VarGet/VarSet automatically sanitizes invalid identifiers by replacing all characters other than digits and A-Z, a-z letters by underscore
  6. AFL: runtime tokens {chartid}, {symbol}, {interval} are now supported in #pragma enable_static_decl
  7. AFL: SetFormulaName - displays error 67 if user tries to use file-system forbidden characters for formula name
  8. AFL: StaticVarRemove() when called with EMPTY string: StaticVarRemove("") nullifies all static variables declared with static keyword within given formula
  9. AFL: when declared static variable is assigned the NULL value, it will be removed from memory when formula finishes
  10. ASCII importer: importer logged “ran of industry space” even if it didn’t. Fixed.
    CBT: If user called ApplyStop AND calls EnterTrade from low-level backtest and did not switch backtestRegular mode to raw mode (which should be done), backtester would automatically turn on 2nd phase stops handling to prevent crash
  11. Charts: a crash could occur if user had lots of drawn trendlines on multiple panes and some of them had start date BEFORE first available bar and RT stream was frequently updating. Fixed.
  12. Make #pragma enable_static_decl is now private functionality. This means that it will work just fine but we don’t provide any help/support except of what is written in readme/manual
  13. New Analysis: you can now copy dates between “From” and “To” date pickers (right click menu or Ctrl+C/Ctrl+V)
  14. UI: Bar replay From-to controls support copy-paste (right click or Ctrl+C/Ctrl+V)
  15. UI: added preprocessor color picker in Tools->Preferences, “Editor”
  16. 6.27.1 fix: In 6.27.0 VarSet did not work properly. Fixed.
  17. 6.27.1 fix: Backtest: since 6.25 crash could occur if “detailed log” was enabled. Fixed.

(1) - Some APIs are marked as ‘private’ which means that they are fully functional, but don’t come with extra help/support except the written documentation provided in the ReadMe/ReleaseNotes/manual.

This thread continues the discussion from AmiBroker 6.26.0 BETA released

AmiBroker 6.26.0 BETA released
AmiBroker 6.28.0 BETA released

Thank you very much.

I noticed when using VarSet within functions they are not global anymore. Has it changed to previous versions?

function test()
    VarSet( "var", 1 );
    return 0;

x = test();

printf( "%g", var );

It returns Error 29.
“var” is not recognized.

Error in VarSet(), VarGet() in outdated 6.27.0 BETA

This was genuine bug. It is now fixed in 6.27.1 (download links are updated in the first post)


You can now have declared static variable with unique prefix that includes current chartID, interval or symbol.
To do so use {chartid}, {interval} or {symbol} runtime tokens in the prefix string. They will get replaced in runtime by corresponding values.

// Example - if you want per-chartID declared static variables
#pragma enable_static_decl "myprefx{chartid}"
static x; // this static will really have name of myprefixIDx where ID is a current chartID


Tomasz, once again thanks for static var feature! It starts growing on me and now with dynamic naming it is heavy contender to old way. :slight_smile:

I’m not 100% sure but I might have noticed something too but regarding that new feature. I know it is private API. So I would just need “yes” or “no” on whether it is applied wrong.

It seems that if using {symbol} token then static var in different pane remains at Null. {chartid} and {interval} tokens work fine.

In detail with examples:

First using chartid token
AFL for first pane

#pragma enable_static_decl "myprefix{chartid}"

static _myvar;  

printf( "This variable is really static %g", _myvar++ ); 

So since the chart id of first pane is 1418 in my example I insert it in second pane

prefix = "myprefix";
token = "1418";

printf( StaticVarInfo( prefix + "*", "list" ) );

s = StaticVarGet( prefix + token + "_myvar" );
printf( "\nstatic var of first pane returns: %g", s );

//StaticVarRemove( prefix + "*" );

And indeed it works just fine

Second, using interval token… and once again it returns just fine
AFL of first pane

#pragma enable_static_decl "myprefix{interval}"

static _myvar; 

printf( "This variable is really static %g", _myvar++ ); 

AFL of second pane

prefix = "myprefix";
token = Strformat( "%g", Interval());

printf( StaticVarInfo( prefix + "*", "list" ) );

s = StaticVarGet( prefix + token + "_myvar" );
printf( "\nstatic var of first pane returns: %g", s );

//StaticVarRemove( prefix + "*" );


Third, using symbol token
AFL of first pane

#pragma enable_static_decl "myprefix{symbol}"

static _myvar; 

printf( "This variable is really static %g", _myvar++ ); 

AFL of second pane

prefix = "myprefix";
token = Name();

printf( StaticVarInfo( prefix + "*", "list" ) );

s = StaticVarGet( prefix + token + "_myvar" );
printf( "\nstatic var of first pane returns: %g", s );

//StaticVarRemove( prefix + "*" );

And here it returns Null

Same for

prefix = "myprefix";
token = "AAPL";//Name();

printf( StaticVarInfo( prefix + "*", "list" ) );

s = StaticVarGet( prefix + token + "_myvar" );
printf( "\nstatic var of first pane returns: %g", s );

//StaticVarRemove( prefix + "*" );

On the other hand this one runs fine in 2nd pane

#pragma enable_static_decl "myprefix{symbol}"
static _myvar;

s = _myvar;
printf( "\nstatic var of first pane returns: %g", s );

as well as for example

#pragma enable_static_decl "myprefixAAPL"
static _myvar;

s = _myvar;
printf( "\nstatic var of first pane returns: %g", s );

Any wrong doing on my end?
Just “yes” or “no” would be fine for me.


There might be problem with case sensitivity. If you use {symbol} it would create static variable that has name in original case (possibly) UPPER case, but StaticVarGet always gets lowercase (it converts passed name to lowercase). If your selected symbol was all lowercase then your 3rd example would work. I would need to change that so {symbol} gets converted to lowercase to maintain backward compatibility.


@Tomasz: Thank you for implementing an elegant automatic sanitizing solution for the (prior) error 66s and thus preserving backward compatibility of existing code.


You’re very welcome.


Thankyou Tomasz for item 5. and all the other upgrades



hello @Tomasz,
Declared static variable is not accepting “close” as a value, is this intentional ?



You need calculated value, not built-in array. _a = 1 * Close; would give you calculated value equal to close.


Hi Tomasz,

the new features look great. do you have a planned formal release date?



Official 6.30 should be available in January or later depending when it is ready. The software is released when it is ready not when some artificial calendar date arrives.


Normally, you can use Nz to initialize static variables to a specific value. However, this doesn’t work with declared static variables, because they initialize to zero, not Null. Therefore, it’s impossible to determine if a variable is zero due to being initialized or due to being explicitly set to zero. Also, even if Nz did work, it would only be usable with numeric variables, not with declared static string variables. I was able to work around this with the following code:

#pragma enable_static_decl(myPrefix)
static _myVar1, _myVar2;
if (IsNull(StaticVarGet("firstRun"))) {
	StaticVarSet("firstRun", False);
	_myVar = "Some initial string";
	_myVar2 = 1; 

Using a dedicated non-declared static variable allows us to check if this is the first run or not. Although this works, I don’t think it’s a great solution as it’s non-intuitive and inelegant. It would be better if there was a way to specify the initial value for declared static variables. For example:

static _myVar1 = "Some initial string", _myVar2 = 1;


This works exactly like in C/C++. Declared static variables without initializers are automatically filled with zero:

Non-zero initializers will be introduced at some point.


@Tomasz, could you please give basic example on this new AFL feature

and how it differs to previous referencing of array elements. Thank you in advance.


That entry in read-me refers to bug fix, not new feature. It simply allows to modify individual array elements passed by reference (see previous readmes for instructions how to pass reference), short sample:

function myfun( x )
  x[ 0 ] = 5;

z = 99;
z[0] = 98;
myfun( &z ); // pass array by reference (would modify it)
// now z[0] is 5


Continued in AmiBroker 6.28.0 BETA released