AmiBroker 6.49.1 BETA released

A new BETA version (6.49.1) of AmiBroker is available now.

DOWNLOAD LINKS

32-bit version:
https://www.amibroker.com/members/download.php?AmiBroker6491.exe
(10 437 808bytes)

64-bit version:
https://www.amibroker.com/members/download.php?AmiBroker6491x64.exe
(11 089 448 bytes)

HIGHLIGHTS

The highlights of this new release are:

  • AFL language new features & improvements
  • AFL editor improvements
  • UI improvements

DOCUMENTATION

For the details see ReadMe.html and ReleaseNotes.html inside AmiBroker folder.

UPGRADE POLICY

This version is a free upgrade only for users who registered AmiBroker after September 19, 2021 . Users who registered earlier, would need to purchase license upgrade. To find out the version you currently have use Account Information page at https://www.amibroker.com/members/info.php

CHANGES FOR VERSION 6.49.1 (as compared to 6.49.0)

  1. AFL: formatDateTimeISO was working as formatDateISON (no separators). Fixed so now it includes separators.
  2. AFL: new function trunc() that truncates fractional part, works identically as int(). int() is now marked as obsolete and will be removed in some future. All instances of int() should be replaced by trunc() in new code.
  3. AFL: in 6.49.0 int() function wasn't doing anything (no-op), regression fixed.
  4. UI: in 6.49.0 the interpretation window crashed, regression fixed.

CHANGES FOR VERSION 6.49.0 (as compared to 6.43.1)

  1. Account: Summary page (grid) in dark mode displays read-only items in lighter shade of gray for better readability
  2. AFL Editor: Added simple detector of pasting ChatGPT-generated code. Displays a notice that ChatGPT is not able in most cases to produce valid code. Due to stochastic nature of how ChatGPT produces code it might not detect all cases.
  3. AFL Editor: Fold margin width now scales with font selected / DPI instead of being fixed
  4. AFL Editor: UI, in auto-complete dropdown "Fals" was displayed instead of "False". Typo fixed.
  5. AFL Editor: watch window displays arrays with less than 5 elements entirely without ... (elipssis)
  6. AFL Editor: when symbol has no quotes, the AFL editor will now create synthetic data to allow verify syntax and debugging anyway. Artificial data created is just 1 bar (future), it allows code checking in this edge case
  7. AFL: added support for C++ -style raw strings
  8. AFL: AddToComposite requests are now served by idle message queue (gives slight speed up and allows syncing with post process normalization)
  9. AFL: atcFlagNormalize performs normalization by dividing OHLCV fields by the field given as argument (either "I", "1" or "2") after scan is completed
  10. AFL: Crash could occur if type of second or subsequent argument for function call was invalid, due to uninitialized memory. Fixed.
  11. AFL: experimental - added support for maps (dictionaries of key-value pairs, aka associative arrays), note that all map variables (unlike other types) are really references, so when you pass it to a function you are passing reference and original object - will be documented in subsequent post in this thread
  12. AFL: Matrix( rows, cols, init_val = Null, increment = 0 ) has now new parameter 'increment' that allows to create a matrix with monotonically increasing elements
  13. AFL: micro-allocator block size bumped to 64 bytes in both 32bit and 64bit versions for better alignment with cache line size and better performance
  14. AFL: new Error 74 - AmiBroker now reports invalid non-ASCII characters being used in the formula code. Non-ASCII codes (>127) are only allowed in strings and comments.
  15. AFL: Nz() function now accepts scalars and arrays in ValueIfNull argument (previously only scalar was accepted)
  16. AFL: SafeDivide - added support for 3rd argument (resultIfZeroDiv) to be array in case when 1st and 2nd args are arrays
  17. AFL: Static variable declaration now allows custom initial value. The initial value expression is evaluated and assigned to static variable only if static variable wasn't present before. If initial value is not given, static variable is automatically inti
  18. AFL: StaticVarInfo now adds support for "count" field that allows to count variables based on wildcard mach. StaticVarInfo( "prefix*", "count")
  19. AFL: stricter checking for format string passed to printf() / StrFormat and against types of arguments passed
  20. AFL: SumSince has new optional argument incFirst - SumSince( Condition, Array, incFirst = False ) that decides whenever first bar value when condition is true is included in sum or not
  21. AFL: using PlaySound somehow slowed down other worker threads. Fixed by explicit termination of playback of previous sound.
  22. Charts: flyout buttons for closing/rearranging chart panes now scale properly with changes in screen DPI
  23. Indicator maintenance wizard automatically creates timestamped backup file (broker.newcharts.imYYYYmmddHHMMSS.bak) from broker.newcharts so in case of failure original broker.newcharts can be easily restored
  24. New Analysis: add a notice / info in the backtest report when equity gained more from interest than from trades alone - indicating that results are based primarily on cash sitting idle than trading system
  25. QuickGFX: fixed crash with styleCloud when cloud was totally outside visible area (above top or beyond bottom of chart)
  26. TDL #3818 revisited. There were more cases when worker thread attempted to read string from resources sometimes resource handle was set incorrectly, this caused COleException / unknown error. Fixed by replacing faulty MS CString::LoadString implementation
  27. Tools: Indicator maintenance - added check for valid parent (property sheet)
  28. UI: Edit->Delete range now supports multiple selection in the Symbol pane, so it can delete range of quotations from multiple symbols at once
  29. UI: In XAML markup, units such as pt, in, cm and mm now scale properly to HiDPI
  30. UI: Modal dialog boxes that aren't dismissed first flash but on next wrong click they move to mouse position
  31. UI: Property Grid (Symbol Information/Account summary) expand buttons scale properly to HighDPI displays
  32. UI: Start page uses system icon font and updated design with scalable vector icons
  33. UI: Symbol->Organize Assignments full name column was not always refreshed initially (required click on radio button). Fixed
  34. UI: XAML markup checkboxes now properly scale to HiDPI

This is continuation of the discussion from AmiBroker 6.43.1 BETA released

16 Likes

Here's an explanation of the code and the new Map/Associative Array/Dictionary object type introduced by AmiBroker 6.49.0 BETA:

Map Initialization

m = Map();

This line creates a new Map object and assigns it to the variable m. In AFL, a Map is a data structure that stores key-value pairs, similar to dictionaries in other programming languages. Map keys are strings. Values can be of any type.

Advanced users may pass hash table size if they want to store lots of data in a map

// larger hash table size improves performance should be prime number larger than number of elements expected 
m = Map( 997 ); 

Populating the Map

m["MSFT"] = 1;
m["NVDA"] = 2;
m["CSCO"] = 3;

Here, the code adds key-value pairs to the Map m. Each key is a stock symbol (e.g., "MSFT," "NVDA," "CSCO"), and each corresponding value is an integer (1, 2, 3).

Accessing a Value by Key

value = m[ Name() ]; // using function return value as a key
value2 = m[ "MSFT" ]; // literal key

This line retrieves a value from the Map m based on the key returned by the Name() function. In this context, Name() is a function that returns the symbol of the current stock or instrument being analyzed.

Checking for Key Existence

value = m[ Name() ];
if (IsNull(value))
{
   printf("Key not found in Map");
}
else
{
   printf("%g", value);
}

Here, the code checks if the value obtained from the Map is IsNull. If it is, it means that the key returned by Name() was not found in the Map, and it prints "Key not found in Map." Otherwise, it prints the value associated with the key.

Passing map arguments to user functions

It's important to note the key point mentioned in the ReadMe: When you pass a Map to a function in AFL, you are passing a reference to the original object. This means that if you modify the Map inside a function, it will also modify the original Map object outside the function. This behavior is different from some other variable types in AFL, which are passed by value.

Here's an example of how the Test function modifies a Map by passing it as a reference:

function Test(x)
{
   x["key"] = 1;
}

m = Map();

// UNLIKE other data types, Maps are always passed by reference so this call modifies its contents
Test(m); 

// Check the modified map
value = m["key"];

if (IsNull(value))
{
   printf("Key not found in Map");
}
else
{
   printf("%g", value);
}

In this code:

  1. The Test function takes a single parameter x, which is expected to be a Map. Inside the function, it assigns the value 1 to the key "key" in the Map x.
  2. We initialize an empty Map m.
  3. We call the Test function and pass the Map m as an argument. Since maps are passed by reference in AFL, any modifications made to x inside the function will also affect the original Map m.
  4. After calling Test, we retrieve the value associated with the key "key" from the modified Map m.
  5. Finally, we check if the value is null (indicating that the key was not found) or print the value if it exists.

In this example, the Test function modifies the Map m by adding a key-value pair "key" => 1 to it. When we check the Map after calling the function, it will contain this key-value pair, and the code will print the value 1.

9 Likes

hi, am I correct that the new Map functionality is similar to DataFrames in Pandas?

As explained in earlier post, Map is a data structure that holds key-value pairs. In Python it is called DICTIONARY. In Javascript it is called map. In C++ Std lib it is called unordered map.

1 Like

@Tomasz, a few questions about Map():

  • do keys have to be just strings ?
  • is it possible to use as values scalars, arrays and/or matrices (or columns or rows of matrices), strings?
  • is it possible (out of habit) write the example of call to Test() as Test(&m); ?
1 Like
  1. Yes. Keys in Map are strings only. If you want numeric key you can just use NumToStr, but actually
    if you want numeric key, then the key is just array index, you've got normal arrays and/or matrices that support numeric keys (indices)

  2. Values can be any type

  3. Yes you can use Test(&m), it works equally well.

2 Likes

@Tomasz , it seems to me the function int() is broken:

a	= int(1.7);
_TRACE("a="+a);

I get the result:

a=1.7

after the install of 6.49.0 my charts were messed up and also the default database changed to "data". Didn't mention it yet since I was not sure what the cause was and was waiting for maybe other reports on this.

Just now I wanted to check the "int" function in the interpretation window and when I expanded the Interpretation Window to check, like show in the image, Amibroker crashed. So I went back to 6.43.1 for the time being.

1 Like

Hi,

can someone kindly test this.

If i have a simple printf() statement like printf("hi"); or like in the example in manual,
when interpretation window is not visible code runs "fine"
but when we switch to interpretation window I get this crash window which doesn't recover.

thanks

AmiBroker version 6.49.0.6490
( 64-bit, cooltool.dll 6.49.0,  mfc42.dll 6.49.0,  msvcrt.dll 7.0.22621 )

Microsoft Windows 10 version 10.0 (Build 22621) 
Service Pack 0.0, Common Controls: 6.16
1 Like

i used the entire day and all was fine, even my explorations.

  1. First issue in beta so far was now when opening interpretation window. Code without printf() run ok but when that line comes then there is a problem.

  2. INT() issue reported above also appears in test code.

No sweat, its a beta :slight_smile:

1 Like

ok maybe my layout problem was something else.

1 Like

Sorry I can confirm that int() is a no-op in 6.49.0. This is side effect of some internal experiments that I made and forgot to disable before release.

As a temporary workaround use floor ( for positive numbers) or ceil (for negative numbers)

In the future int() will be marked as obsolete to be replaced by trunc() which will provide same functionality under different name.

These two regressions (Interpretation crash and int() no-op) will be fixed in 6.49.1 to be released today.

Thanks for reporting those problems.

5 Likes

@Tomasz, I saw that the problem reported here related to formatDateTimeISO is still present.
Maybe you could even fix this problem!

2 Likes

Yes, sorry about that. Will be fixed too.

4 Likes

Updated version 6.49.1 is available now: AmiBroker 6.49.1 BETA released

6 Likes

Big thank you @Tomasz 6.49.1 updates work fine.

Multi-symbol + Delete Range works like a charm.

3 Likes

Python script replacing int() with trunc() in all AFL files in the folder "path_src"

import os
from multiprocessing.dummy import Pool as ThreadPool

path_src = 'D:/Soft/AmiBroker/'		# folder with subfolders with AFL files

def replace_text(file_name):
	print(file_name)

	# read from AFL file
	with open(file_name, 'r') as file :
		filedata = file.read()
		file.close()

	# replace 'int(' with 'trunc('
	filedata = filedata.replace(' int(', ' trunc(')
	filedata = filedata.replace('	int(', '	trunc(')
	filedata = filedata.replace('=int(', '=trunc(')
	filedata = filedata.replace('(int(', '(trunc(')

	# write to AFL file
	with open(file_name, 'w') as file:
		file.write(filedata)

if __name__ == '__main__':
	files_list = []

	# read files from all subfolders of path_src
	for root, dirs, files in os.walk(path_src):
		for name in files:
			filename, file_extension = os.path.splitext(name)
			if file_extension=='.afl':
				files_list.append(str(os.path.join(root, name)))

	# multithread  execution
	pool = ThreadPool()
	pool.map(replace_text, files_list)
	pool.close()
	pool.join()

3 Likes