AmiBroker 6.26.0 BETA released

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


32-bit version:
(2 267 568 bytes)

64-bit version:
(10 620 576 bytes)


DevLog announcement:

Read Me:


This version is a free upgrade only for users who registered AmiBroker after September 26, 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.26.0 (as compared to 6.25.0)

  1. AFL: new static keyword: declare identifier as static variable – a little ‘revolution’ in static variable use, declare variable as static and use as ‘regular’ variable, no need to call functions - this is Private API(1)
  2. AFL Editor: contrast of error location indicator on dark backgrounds increased
  3. AFL Editor: C-style comments /* … */ are now foldable in the editor
  4. AFL Editor: new menu choices View->Fold Comments / Unfold Comments – allow to fold/unfold all multi-line comments (enclosed with /* …. */)
  5. AFL: added constants notifyClicked, notifySetFocus, notifyKillFocus, notifyHitReturn, notifyEditChange, notifySelChange, notifyMouseEnter, notifyMouseLeave
  6. AFL: Another protection against users shooting themselves in foot, VarSet/VarGet now displays error when you try to use characters different than A-Z, 0-9 and ‘_’ in variable names
  7. AFL: Attempt to use single subscript on matrix variable now results in error message “Accessing Matrix elements requires two subscript operators”
  8. AFL: Due to the fact that Windows may send WM_MOUSEMOVE message even if mouse did not move, AmiBroker now has internal check that prevents ReqestMouseMoveRefresh from triggering if mouse position did not change
  9. AFL: GetLastOSError (for getting last error message from Windows)
  10. AFL: GuiButton and GuiToggle in native OS style use background color of the chart for small border instead of default grey
  11. AFL: GuiButton/GuiCHeckBox/GuiToggle/GuiRadio support now new events MouseEnter (64) and MouseLeave(128) which detect hovering without need for constant refreshes
  12. AFL: GuiCheckBox and GuiRadio now support custom colors of text and background
  13. AFL: In 6.25 Gui* keyboard navigation interferred with delete key and possibly other shortcuts due to the way how windows works. Implemented workaround so keys are only intercepted if child window (control) has focus.
  14. AFL: In 6.25 Gui* keyboard navigation was turned on by default, now it is off by default but can be turned on if you use SetOption(“GuiEnableKeyboard”, True )
  15. AFL: In 6.25 GuiGetCheck returned -1 on unchanged. Now it returns only 0 (unchecked) or 1 (checked)
  16. AFL: In case of Windows INET API error, Internet* functions now report Warning 507 instead of generic error 47. Warning 507 is Level-3 warning, i.e. editor-only, which means it will pop up in the formula editor, but won’t break execution in runtime
  17. AFL: Now can use subscript operator [ ] on references to arrays and matrices
  18. AFL: Passing by reference does not create nested references in user-defined function calls
  19. AFL: VoiceSetRate( rate ) – sets SAPI voice (speech synthesis) rate. Rate of 0 (zero) is “normal”, negative is slower, positive is faster (allowable range -10…+10)
  20. AFL: VoiceSetVolume( volume ) – sets SAPI voice (speech synthesis) volume (0…100)
  21. AFL: VoiceWaitUntilDone( timeout ) – waits until voice has finished speaking or specified timeout (1…100ms) has elapsed. Returns True if voice finished, False if the timeout elapsed
  22. broker.master file is saved to a new name and renamed later to avoid corruption when Windows decides to shutdown, restart or sleep during save
  23. Dev: 64-bit new compiler (VC2017) broke backward compatibility with singletons that UI lib uses causing infinite loop when High Contrast scheme was used. Workaround implemented.
  24. Misc: 64-bit: Restored correct manifest (from pre6.22) with compat records so Win 10 does not lie about version number and re-added 24-bit large PNG icon
  25. New Analysis: Added support for clickable links. If you put @link URL in any cell of Analysis result list it creates a clickable row. If you double click on the row while holding down ALT key it will open the link
  26. Edit->Delete Range functionality added to delete all quotes within selected Begin-End range.

(1) - Some APIs are marked as ‘private’ which means that they are fully functional, but don’t come with any help/support except the written documentation provided in the ReadMe/ReleaseNotes/manual. Private APIs are meant for people who are able to figure out things themselves without asking for help.

Few usage examples from the ReadMe:

Example 1.
Update: This functionality belongs to private API (1) - reasons below in this thread.

How to use new static keyword. Static declaration gives you power and persistence of static variables with ease of use of regular variables.

// the pragma below is required to enable support for static declarations 
 // it also defines the prefix which is added to variables declared with static keyword 
 // it is one prefix per formula. 
#pragma enable_static_decl(prefix) 
// it is really good idea to consequently use naming convention that 
 // distinguishes declared static variables from the others 
 // we highly recommend using UNDERSCORE '_' before all declared static variables 
 // so they can be easily spotted in the code 
 // The other choice could be s_ prefix 
static _myvar;  // this var will also be accessible by StaticVarGet("prefix_myvar") 
printf( "This variable is really static %g", _myvar++ ); 

// keep in mind that for speed static variable is read only once at the declaration 
 // and saved only once - when formula execution is completed 
 // This way declared static variables offer same speed as regular variables (no speed penalty)

Example 2.

The example shows how to use notifyMouseEnter/notifyMouseLeave to handle hovering events without timed/mousemove refresh.

#pragma enable_static_decl(myprefix) 
static _counter; 

 flags = notifyMouseEnter | notifyMouseLeave; 

GuiButton("test", 1, 20, 20, 100, 100, flags); 
GuiCheckBox("test 2", 2, 200, 20, 200, 20, flags ); 

GuiSetColors( 2, 2, 0, colorRed, colorBlue ); 

Title = StrFormat( "%s. Refresh # %g\n", GuiGetEvent( 0, 2 ), _counter++ ); 

 nc = GuiGetEvent( 0 , 1 ); 

if( nc == notifyMouseEnter ) GfxTextOut( "MOUSE ENTER", 200, 50 ); 
if( nc == notifyMouseLeave ) GfxTextOut( "MOUSE LEAVE", 200, 50 ); 

_TRACE(Title );

Example 3.

Using GetLastOSError to handle file and internet errors

// Example A: 
 fh = fopen("non_existing_file.txt", "r" ); 

if( ! fh ) 
    printf("File can not be open because: %s", GetLastOSError() ); 

// Example B: 
 ih = InternetOpenUrl("" ); 

if( ! ih ) 
    printf("Internet connection can not be open because: %s", GetLastOSError() ); 

Example 4.

New Voice (Speech API) control functions

VoiceSetRate( -10 ); 
Say("I am speaking slowly", False); 

while( ! VoiceWaitUntilDone( 100 ) ); 
printf("Done 1\n"); 

VoiceSetRate( 0 ); 
Say("I am speaking normally", False); 

while( ! VoiceWaitUntilDone( 100 ) ); 
printf("Done 2\n"); 

VoiceSetRate( 5 ); 
Say("I am speaking fast", False); 

Example 5.

Clickable links in Explorations

Filter = Status("lastbarinrange");
AddTextColumn("@link", "double click me with ALT key"); 

// Hidden links are possible if you add the @link in the column past the last defined one 
AddRow( "ticker\tdatetime\ttest\t@link" ); 

(1) - ‘Private API’ means that functionality is working, but does not come with any help/support except the written documentation provided in the ReadMe/ReleaseNotes/manual. Private APIs are meant for people who are able to figure out things themselves without asking for help.


@Tomasz thank you very much for this great release with so many new, interesting features :slight_smile: It will take us some time to grasp them all…

Personally I’m especially thankful for expanding GuiButton features, new Speech synthesis functionalities, clickable links in Analysis result list, implementing a way to handle Internet errors and so on … ( It would be easier to mention the things which I don’t find useful if there were any :wink: ) I’m sure @SpinTrader - Herman (apart from many other features) will be delighted with the easy hovering detection :slight_smile: Every user will appreciate the new /easy way of using static variables.

I think everybody would agree, that now you deserve at least a full week on some tropical Island - preferably without the Internet :smiley:

–> :trophy: --> :airplane: --> :desert_island: :desert_island::beach_umbrella: :beach_umbrella: :beach_umbrella: :desert_island: :desert_island:


After run Portfolio Backtest:

        Chg = 100 * ( -1 + eq[ i ] / LastMoValue );
        VarSet( "ChgMon" + yr[ i ] + "-" + _mon

Error 66.
Invalid variable identifier. The identifier must begin with letter or '_'.  The rest can only contain letters, digits or '_'.

Minus "-" sign is NOT correct character in the variable name. You need to replace minus sign with "_" - underscore.

You can download the file from here and place it in:

Formulas\Report Charts\3. Profit

folder. This will fix the issue.

UPDATE: I have already updated the setup program so if you download now, you will get the setup that already includes this file and it will work fine out of the box.

1 Like

Other problem. Fold/unfold doesn’t work.

Please, before reporting “problems” please spend MORE time reading the read me. It works. Really.
Comment folding folds MULTI-LINE comments and ONLY those which use /* … */ style

/* This is C-style multi line
comment that will be folded

// but this is C++ comment (single line)
// that is non-folding comment (BY DESIGN)

It is done for purpose. This way you can write “foldable” and “not-foldable” comments according to your needs.

I’m sorry. My fault.
Great work.

This release is beyond expectations: I cannot remember a more exiting one. This will keep me busy for a few days and allow me to clean up my programs quite a bit!

Thank you Tomasz; you must have been burning the mid-night oil!

I am just on the way out but wanted to join in the applause for this release.

Great work!


Yes it was quite a lot of work and it was stressful as I knew that many wait for this release and the pressure was building (which I did not like) but I did not want to release it too early half-cooked.


I started exploring the new functions. Hover works great and I already upgraded my functions accordingly :slightly_smiling_face:

Regarding the new static declaration. Perhaps I am missing something but is there a way to automatically declare variables static, perhaps based on a common prefix they share?

I am using many (hundreds) of static variables of which many are dynamically named. It would not be possible to declare them all ahead of time. Is there a way around this?


1 Like

Awesome update!
Thank you.

Thank you Tomasz for the new Version.

Please, can we have one example with the GuiToggle()?

Hello Panagioti :slight_smile:

You can take a look at this example of using GuiToggle():

GuiToggle( "State is OFF - Click to turn ON", 1, 10, 40, 180, 30, 1 );

id = GuiGetEvent( 0, 0 ); event = GuiGetEvent( 0, 1 );

if( id == 1 And event == 1 ) Say( "Toggle button clicked" );

if( GuiGetCheck( 1 ) ) // If Toggle Button's state is 1
    GuiSetText( "State is On - Click to turn OFF", 1 );
    // ... your code, for example:
    GfxFillSolidRect( 10, 80, 190, 100, colorGreen );
else // If Toggle Button's state is 0
    // ... your code, for example:
    GfxFillSolidRect( 10, 80, 190, 100, colorRed );


The state of the button is not preserved when we close AB, so if we want to retrieve it after AB restart, we probably still need to use static vars. By default the state is OFF.

No additional refreshes required.




Static variables need to be declared with static keyword. You can do many in one line like this:

// pragma is only required once at the top of the formula
#pragma enable_static_decl(some_perfix_here)

// static declarations can be anywhere in the formula
static _myvar1, _othervar, _somethingelse, var2, var3;

Only regular (non-static) variables don’t require declarations.

As for variables with dynamically constructed names in runtime - it works the same as with regular variables. If you need to use dynamic identifier of regular variable you need to write:

VarSet( "dynamic_name"+GetChartID(), 1 );

In similar fashion if you need static variable with dynamically constructed name in runtime there is no other way than to use StaticVarSet function

StaticVarSet( "dynamic_name"+GetChartID(), 1 );

@Milosz Thank you for replying with this simple example.
My mistake was that I didn’t use GuiGetCheck function.
i am fine now… I got it.

1 Like

Hello @Tomasz,
Thank you for the update,
I’m struggling a little bit with the new functionality of static keyword.
I would appreciate if you could show me how to get via static variable declaration of the following :

symbol = Name (); 
StaticVarSet ( symbol + "ATR", ATR (20) ); 
StaticVarSet ( symbol + "RSI", RSI()); 


This is how I understand it…

If using that new (additional) method of AB static variables universe then


//'symbol' prefix is part of static keyword (so not dynamic one), 
// for dynamic naming you would need to use StaticVarSet instead
#pragma enable_static_decl(symbol)

static _ATR, _RSI;

_ATR = ATR(20);
_RSI = RSI();

printf( "ATR: %g, RSI: %g", StaticVarGet( "symbol_ATR" ), StaticVarGet( "symbol_RSI" ) );

Could be wrong understanding but I was just trying to save Tomasz some time. :wink:

Moderator comment: That is perfectly correct understanding. Prefix is literal string


If I understood correctly the new functionalities (but I may be wrong :wink: ) @aron 's static vars cannot be declared the new way, as they have dynamically constructed names. The only way is via StaticVarSet/StaticVarGet.

… and for this reason, @fxshrat 's example can be probably simplified:

#pragma enable_static_decl(symbol)

static _ATR, _RSI;

_ATR = ATR(20);
_RSI = RSI();

printf( "ATR: %g, RSI: %g", _ATR, _RSI );

… but it this case it doesn’t need any static vars …

Because of this :

… I wonder if it is possible to make these static variables persistent or not (without using StaticVarSet) ? Probably not.

I have used StaticVarGet in printf just to make it clear what each part of keyword means.
Of course you can just write _ATR _RSI in printf.

That’s what my post was trying to say via quoting T.J.

As for calling set static vars in other AFL different from the one they were created you just do this

First AFL: setting static vars

#pragma enable_static_decl(symbol)

static _ATR, _RSI;

_ATR = ATR(20);
_RSI = RSI();

Second AFL (option 1): calling static vars of first AFL (in different chart pane for example)

#pragma enable_static_decl(symbol)

static _ATR, _RSI;

printf( "ATR: %g, RSI: %g", _ATR, _RSI );


second AFL (option 2): calling static vars of first AFL (in different chart pane for example)

printf( "ATR: %g, RSI: %g", StaticVarGet( "symbol_ATR" ), StaticVarGet( "symbol_RSI" ) );