What's new in latest version?
Highlights of version 5.20
- Smart (non-exhaustive) trading system optimization
AmiBroker now ships with 3 non-exhaustive, evolutionary optimization algorithms:
SPSO (Standard Particle Swarm Optimizer)
TRIBES (Advances Particle Swarm)
CMA-ES (Covariance Matrix Adaptation Evolutionary Strategy
- Support for market-neutral, long-short balanced strategies via MaxOpenLong/MaxOpenShort
control and separate long/short rankings in the backtester
- Performance optimizations in chart drawing engine - charts are orders
of magnitude faster when number of bars displayed is much greater than number
of pixels.
- Log window implemented - allow tracing and run-time error reporting
- QuickAFL implemented
in the Automatic Analysis - speeds up backtests, optimization
and explorations by factor of 2 or more (if range is less than all quotations).
(Note: in order to enable it you need to check "Use QuickAFL" box in the Automatic
Analysis setttings).
- Multiple-segment Volume-At-Price charts (via PlotVAPOverlayA function)
- 32-bit AmiBroker is now LARGEADDRESSAWARE, i.e. can now use upto 4GB of
RAM
- Built-in Quarterly and Yearly intervals
- Automatic summary rows in the explorations (via AddSummaryRows AFL
function)
- Charting enhancements and improvements
- better handling of drawing tools
- better magnet mode
- Fibonacci timezones now include lines 144 and 233
- zooming via scroll bar improved
- Range bars now use per-symbol TickSize as a unit
- new AFL functions:
GetChartBkColor
CategorySetName
PlotVAPOverlayA
AddSummaryRows
DaysSince1900
OptimizerSetEngine
OptimizerSetOption
StrCount
- AFL performance improvements in LinearReg, LinRegSlope, LinRegIntercept,
TSF and StdErr, Day(), Month(), Year(), DaysSince1900(), DayOfWeek(), DayOfYear()
functions (order of magnitude faster)
- Improved AFL functions: queued Say() command
(text-to-speech), improved StrExtract() -
can now refer to items counting from the end
- real-time data plugins updated (IB version 1.2.4, eSignal version 1.9.0),
IBController updated to support latest changes in data sources
Highlights of version 5.10
- Automatic Walk-Forward testing (trading system optimization and validation
technique)
- Floating windows (TRUE multi-monitor charting capability)
ability to "undock" (or "float") the chart window and move it to separate
monitor.
All layout code is also updated to correctly save and restore multi-monitor
chart setups
http://www.amibroker.com/video/FloatAndLink.html
- Symbol and Interval linking
multiple charts can now be linked by symbol and/or by interval using
easy-to-use color-coded links
- AFL Code Profiler - shows code analysis with detailed per-function
timing report (AFL Editor: Tools->Code Check & Profile menu)
- Real-time quote window improvements
- re-ordering of symbols in the RT quote using drag-and-drop
- direct type-in symbols into RT quote window
- ability to separate groups of symbols by inserting empty line
- faster refresh and multi-stage background color fading on quote change
- new/improved AFL functions
- Improved speed of backtesting/optimization (up to 2x in some cases as compared
to v5.00)
- improved chart crosshairs - no flicker, work faster and can be switched
on/off globally
- track more foreign markets: now you can define rates for up to 20 currencies
(different than base currency) for multiple currency backtesting in the preferences
window.
Highlights of version 5.00
- New Watchlist system featuring:
- Support for AFL Code Wizard - brand new automatic formula creation program
for people without any programming experience. For more information about
AFL Code wizard see this introductory video: http://www.amibroker.com/video/amiwiz/AFLWiz1.html
- AFL engine enhancements
- New dedicated memory heap allocators for quotes and trading system signals
resulting in ability to run much longer optimizations than ever without getting
out-of-memory messages
- Two new backtester modes (available using SetBacktestMode function)
allowing handling of unfiltered (raw) entry signals
- User-definable 5-tier commission schedule in the backtest (Automatic Analysis
/ Settings)
- Chart template sharing
now you can save the chart as "Chart Template, Complete
(*.chart)" that stores all layout AND referenced formulas in SINGLE file
that can
be sent to your friend and entire chart will be restored on any computer
with ease, without need to copy individual formulas.
- New-Look charts - divider lines between panes are now single pixel and
no borders around charts giving cleaner, larger and more readable chart display
and printout
- Custom Range Bars (supported in the charts and via TimeFrameSet())
- New Low-level graphics interface (23 new AFL functions)
- HTML Import in Automatic Analysis
- Full screen Anti-Aliasing in 3D optimization chart viewer (beautifully
smooth 3D charts and improved readability)
- Enhanced Real-Time Quote window display (faster updates, dual-color change
marks)
- Control of Time Shift in the ASCII importer
Highlights of version 4.90:
- new Fundamental data support including
- automatic download from free Yahoo Finance site
- access to fundamental data from AFL level
- new fundamental data fields in the Information window
- new Web Research window
- user-definable sites
- multiple on-line research windows open simultaneously
- flexible auto-synchronization options
- new Account Manager
- tracking history of all transactions
- tracking open position unrealized profit
- tracking account equity history
- short and long trades, automatic handling of scaling in/out
- unlimited number of accounts
- per-account settings/commissions
- new Bar Replay tool - great learning
tool, featuring
- re-playing all symbols' data at once
- fast scrolling
- user-definable playback speed and interval
- added Text-To-Speech capability via Say()
AFL function. Now AmiBroker can speak out loud any text, for example it can
say "Buy 100 shares of AAPL at 91". This is controllable from formula
level so you can make it to speak depending on market conditions, signals
generated from your formula, etc.
- added ability to fill indicator background with gradient color - via SetChartBkGradientFill AFL
function.
- new Fast Fourier Transform function
- automatic exploration result sorting from AFL level - via SetSortColumns AFL
function.
- high-resolution performance timing added via GetPerformanceCounter,
per-chart timed refreshes via RequestTimedRefresh
- HoldMinDays / EarlyExitDays feature in the backtester
- 'Every tick' chart refresh capability
added (Professional Edition only)
- MDI Tabs added as UI enhancement.
- OLE interface enhancements/additions
Detailed Change Log
CHANGES FOR VERSION 5.20.0 (as compared to 5.19.0)
- AFL: new function StrCount( "string", "substring" )
Function returns integer which is number of times substring was found in
string. It is case sensitive.
The function can be used for example to count the number of commas in
comma-separated list
tickers = "AAPL,MSFT,INTC";
numtickers = 1 + StrCount( tickers, "," );
- AFL:
StrExtract( "string", item ) now accepts negative item values
allowing to address items counting from the END of the list
tickers = "AAPL,MSFT,INTC";
"The last item is " + StrExtract( tickers, -1 );
printf("listing from the end of the list:\n");
for( item = -1; ( sym = StrExtract( tickers, item ) ) != "";
item-- )
{
printf( sym + "\n" );
}
-
minor fixes
CHANGES FOR VERSION 5.19.0 (as compared to 5.18.0)
- Internal log window deletes all items if "!CLEAR!" text is outputted
(FC 1552)
Example:
_TRACE("!CLEAR!"); // this clears the internal log window.
_TRACE("First line after clear");
- SetOption("RefreshWhenCompleted", True) added. This performs
View->Refresh All once AFTER AA operation is completed
Under normal circumstances it is not needed to use that because AmiBroker
refreshes ticker tree if necessary,
for example if use AddToComposite. It may be useful if you however use OLE
automation inside AA and you don't want to trigger too many refreshes using
RefreshAll().
This only works in Automatic Analysis, when used in indicator code it has
no effect.
- Sometimes AddSummaryRows was not working when AB.RefreshAll() was used
in the formula. Fixed now. (FC1550)
- Date time calendar disappeared when streaming update arrived. Fixed now.
(FC 1572)
- Equity ticker symbols (~~~EQUITY, BESTEQUITY, ISEQUITY, OSEQUITY) marked
with special flag so they are not used (skipped) in backtest
- Fib Timezones tool now displays lines 144 and 233 too. (FC20)
- math functions (sin,cos,log, ...) added to profiler reporting (array versions
only)
- RT quote and log window tab sheet drag-drop marker is visible again
- Y-axis scale labels do not overlap even if chart is very compressed
CHANGES FOR VERSION 5.18.0 (as compared to 5.17.1)
- AFL: CategorySetName() function
CategorySetName( name, category, number )
Function sets the name of category (group,market, watch list, industry)
Arguments;
name - a new name for the category (in case of watch lists it has to be
unique)
category - type of category, one of the following: categoryMarket, categoryGroup,
categorySector, categoryIndustry, categoryWatchlist
number - the number (index) of the category 0.255 for market, group industry,
0..32 for sectors, 0...unlimited for watch lists
Please note that the function will also create watch list of given index
if one does not exist.
- Added protection against trying to use 3d graph on non-exhaust optimization
- ParamToggle default value not shown after "Reset all" in AA [#52129].
Fixed
- added <= 0 check for log10 calls to protect from FPU exceptions when
using log chart scale
- Added error message that prevents from running "Current symbol" backtest
on IS/OOS/Best equity special tickers
- Added symbol validity check in backtest "Apply To: Current symbol"
- In detailed log mode the backtester now reports reason why trade is not
entered
- Line studies were not visible on Yearly and Qtrly charts. Fixed
- Progress window does not steal focus from active window (prevents some
random crashes when "run every" is used)
- When "run every" is used progress window is displayed minimized
when AA is minimized
CHANGES FOR VERSION 5.17.1 (as compared to 5.17.0)
- In 5.17.0 "Current symbol" selection in AA always used first
symbol in the database. Fixed.
CHANGES FOR VERSION 5.17.0 (as compared to 5.16.0)
- Log Window implemented
Log window (View->Log) allows to view:
edit-time errors displayed during formula check
run-time errors that occur when formula is running (not edited)
_trace command output within AmiBroker (without using 3rd party debug view)
To perform tasks such clearing the output, copying, changing settings
use right - mouse click over the log window list.
Double click on the error line brings up the editor, so you can fix the
error easily.
While "edit-time" error list is cleared automatically each time
you check the syntax in the editor, the run-time error list is NOT cleared,
so all errors remain listed, even if they are fixed already, unless you
manually clear the list.
Note that _TRACE output is by default directed to outside debugger (like
DebugView), in order to enable internal display you need to switch appropriate
option in the Tools->Preferences->AFL You can choose to display internally
/ externally or in both places.
Internal _trace has much lower performance penalty (order of magnitude)
than external, but that is achieved by the fact that
internal log window is refreshed only when application is not busy. It
is appropriate for some uses, but you may prefer more immediate
refresh offered by DebugView.
- Zooming via Scroll bar improved. Now it works with wider range of zoom
factors and also does not disable scoll bar when all quotes are visible.
As accessibility feature, you can temporarily DISABLE zoom via scroll bar
by pressing and holding down CTRL key.
- Added extra protection against going out of drawing array bounds in GetNextDrawing
- when broker.master file was loaded, some symbol temporary data were read
from non-zeroed memory, fixed now
- fixed display glitch that occurred on some bars when logarithmic scale
was used and chart was drawn using compression (2x more bars than pixels)
- When application is closed in Minimized state, the x,y co-ords of main
window are not stored
- styleHistogram chart when drawn in compressed mode could fail to display
some negative spikes (below base level) in 5.16. Fixed.
- inQuarterly and inYearly higlighted in AFL editor now
- SetBarFillColor could not make candle with same body and outline color.
Fixed now.
- Fixed handling Null in styleArea chart (Null was ignored in 5.16)
- 32bit AmiBroker is now compiled with LARGEADDRESSAWARE flag, that allows
it to use 3GB on 32 bit Windows versions that have /3GB boot flag enabled
and 4GB on 64 bit Win
- First sorted column is drawn with darker color now (as in Windows explorer)
- Layouts are displayed in alphabetical order now (previously they were sorted
only if files were stored on NTFS partition)
- When from-to range of backtest was small, AB sometimes allocated too large
cache for portfolio backtest than necessary. Now it is fixed and should provide
speed up for short range backtests.
CHANGES FOR VERSION 5.16.0 (as compared to 5.15.0)
- If in-memory cache was too small, it could happen that Walk-Forward kept
old equity values in ~~~BESTEQUITY. Fixed now.
- AFL: Faster LR. Added constant-period version of linear regression calc
- reduces complexitiy from O(N^2) to O(N)
Constant-period LinearReg, LinRegSlope, LinRegIntercept, TSF and StdErr functions
execute now order(s) of magnitude faster.
- AFL: new GetChartBkColor function
Returns RGB color value of chart background. Sample code:
SetChartBkColor( ParamColor("Color", ColorRGB( 255, 255, 255
) ) );
rgb = GetChartBkColor();
red = ( rgb & 255 );
green = floor( (rgb/256) & 255 );
blue = floor( rgb/(256*256) );
Title="R="+ red + " G=" + green + " B=" +
blue;
- Candlestick style switches back to bar chart when number of bars displayed
is twice the number of screen pixels
- eSignal plugin 1.9.0 (fixes to problem with RT update of certain foreign
future markets such as NSF)
- IBController 1.2.0
- following TWS API changes ignoreRth and rthOnly flags are removed
and replaced with single flag: outsideRTH
- IBc now allows to define which error codes should be ignored using
File->Error code ignore list
- upgraded to use latest TWS API 9.41 (tested with latest TWS 885.7,
requires at least 879)
- Improved speed of Day(), Month(), Year(), DaysSince1900(), DayOfWeek(),
DayOfYear() functions on intraday data (upto 20x faster)
- Improved speed of DayOfWeek(), DayOfYear(), DaysSince1900() on EOD data
(upto 2x faster)
- Optimized chart drawing for large number of bars, upto 10x faster when
more than 70000 bars are visible on screen
The drawing algorithm switches to optimized drawing mode when just one line
draw per horizontal pixel is performed if there are 2x or more bars than
screen pixels.
- Say() function has now ability to queue speak requests
Say( "Text", purge = True );
when purge is set to True (the default) - any call to Say() purges all
previous speak requests (queued or in-progress) and speaks
specified text immediatelly.
when purge is set to False - speak request is queued and will be spoken
right after previous requests are done.
Also now Say() function returns the NUMERIC value that indicates how many
speak requests are pending
0 - ERROR - speech engine not installed or not working properly
1 - currently requested text is spoken now (queue was empty)
2 or more - queue was not empty and previous request(s) will be completed
prior to speaking currently specified text
CHANGES FOR VERSION 5.15.0 (as compared to 5.14.0)
- SetForeign called multiple times with "tradeprices" parameter
set to True freed memory only partially. Now fixed.
- Equity() function does not cause exception when running backtest with QuickAFL
enabled
- Equity() function does not require all past bars anymore when used in AA
- OptimizerSetEngine("") in some circumstances selected random
plugin. Fixed now.
- When user has aborted optimization during in-sample step, the previously
used opt params were not freed. Fixed.
- Implemented command line parameter that allows to specify the database
to load at startup. /database "the path to the database here"
- In some places C-runtime mktime() was used leading to problems with dates
prior to 1970. Fixed now.
- During custom backtester phase the ~~~EQUITY ticker is protected from flushing
out of cache (it could only happen if using OLE to access quotes inside CB
proc)
- Now ~~~BESTEQUITY, ~~~ISEQUITY, ~~~OSEQUITY are not flushed out from the
cache during WF even if cache is small (ensures no missing parts in IS/OOS
chart)
- Single-symbol optimization now also uses QuickAFL (when enabled). Requirements
for the first symbol are calculated in setup phase. To get "most safe" requirement
estimation, the setup phase uses maximum values of opt params.
CHANGES FOR VERSION 5.14.0 (as compared to 5.13.0)
- added support for Quarterly and Yearly intervals in all parts of the program
- new menu items under View interval
- new AFL constants inQuarterly, inYearly
- Yearly and Quarterly charts compression
- updated TimeFrame functions
- Changes to drawing made in v5.13 caused improper drawing lines located
PAST the last available quote (trendlines and pitchforks) when timestamping
method was "START TIME of interval". This is fixed now.
- Fixed AddSummaryRows so 'onlycols' parameter default (zero) is applied
properly
- Implemeted "Select all" via Ctrl-A keyboard shortcut for all
list (result list in AA for example)
- Mouse cursor shape (moving/sizing) reflects the selected study priority
when more than one study exists under mouse position
- new multiple Volume At Price charts at user-defined points via new PlotVolumeOverlayA
function
PlotVAPOverlayA( segments, lines = 300, width = 80, color = colorLightGrey,
vapstyle = 4);
segmens - is an array which holds 0 and 1 (False/True) values, where 1
indicates starting/ending point of each VAP segment
AmiBroker will draw as many segments as there are '1' in the array. Note
that minimum segment length is 2, so if entire array is filled with 1-s
only,
it won't draw anything. In other words, there must be zeros (at least one)
between 1's.
Simplest example:
Plot(C, "Close", colorBlack, styleCandle );
segments = IIf( Interval() < inDaily, Day(), Month()
); // draw daily or monthly VAP segments depending
on display interval
segments = segments != Ref(
segments , -1 );
PlotVAPOverlayA( segments );
More complex example:
_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}}
- {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 )
) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style")
| GetPriceStyle()
);
_SECTION_END();
_SECTION_BEGIN("VAP");
segments = IIf( Interval() < inDaily, Day(), Month()
);
segments = segments != Ref(
segments , -1 );
PlotVAPOverlayA( segments , Param("Lines", 300, 100, 1000, 1 ), Param("Width", 80, 1, 100, 1 ), ParamColor("Color", colorGold ), ParamToggle("Side", "Left|Right" )
| 2 * ParamToggle("Style", "Fill|Lines", 0)
| 4*ParamToggle("Z-order", "On
top|Behind", 1 )
);
Plot(segments, "", colorLightGrey, styleHistogram | styleOwnScale );
_SECTION_END();
- QuickAFL can now be used in Automatic Analysis (Settings: General: "Use
QuickAFL" - check this box) - this can speed up explorations, scans
and backtests by factor of 2+ if range is less than "all quotations"
More on QuickAFL feature here: http://www.amibroker.com/kb/2008/07/03/quickafl/
- Range Bars compression now uses TickSize as "1R step". TickSize
defined in the Symbol Information, if its value is zero, then 1R would be
equivalent to 0.01 movement (for backward compat)
- selecting date in multiple linked charts is now faster because redraw is
not made when selected line in higher compressed interval remains in place
- selector line in linked charts works OK now, regardless of selected time
compression timestamping method
- SetBarsRequired accepts now values -2 in special meaning: reference ALL
bars
So
SetBarsRequired( -2, -2 ); // require ALL past and future bars - this turns
OFF quickAFL
(Note that in pre 5.14 versions, such combination does NOTHING, and with
those versions one needed
to write SetBarsRequired( 1000000, 1000000 ) to achieve the same effect)
For readability sbrNoChange (-1) and sbrAll (-2) constants were added
so you can write:
SetBarsRequired( sbrAll, sbrAll );
- Sometimes progress bar did not show the name of optimization engine used.
Now it is fixed
- Status("ActionEx") provides more codes than Status("action")
to detect special executions states
Status("ActionEx") provides more detailed information about action
that triggered AFL execution. Note that 5 first codes are the same as Status("action")
but scope is limited to 'core'
meaning (see notes below).
Possible values
1 - actionIndicator - when indicator is being repainted
2 - actionCommentary (NOTE: commentary only, not interpretaion nor tooltip)
3 - actionScan - when AA Scan is performed
4 - actionExplore - when AA exploration is performed
5 - actionBacktest (NOTE backtest only, no optimization)
8-9 - reserved for future use
10 - actionExAAShowArrows - when AA "Show arrows" command is used
11 - actionExAAParameters - when AA "Parameters" dialog is displayed/updated
12 - actionExEditVerifyFormula - when AFL editor verifies syntax
13 - actionExOptimizeSetup - when Optimize() parameters are read (to setup
optimization engine)
14 - actionExOptimizeBacktest - when Backtest is performed as a part of optimization
process
15- actionExOptimizePortfolio - when portfolio-backtest phase (CUSTOM backtester)
is performed as a part of optimization process
16 - actionExTooltip - when tooltip for given chart is being displayed/updated
17 - actionExInterpret - when the Interpretation window is being updated
18 - actionExInit - when AA needs to initialize QuickAFL bars required information
and/or formula contains functions changing general AA options
NOTE: for backward compatiblity with all formulas you have written already,
the codes for Status("action") did NOT change .
- Streaming chart update could stall if trend line handle was clicked in
attempt to resize and released in the very same position (without moving
the mouse). Now it is fixed.
- TimeFrameMode() now supports mode == 4 - which expresses RANGE bars in
TickSize units (as opposed to mode 3 that uses dollars for backward compatiblity)
- when display chart timing option is turned on and RT stream is active the
application STATUS BAR now displays TOTAL time for all charts, it should
be BELOW 1 second for RT trading
CHANGES FOR VERSION 5.13.0 (as compared to 5.12.2)
- Main app window maximize state on 2nd monitor is saved OK now.
- Trendlines drawn in smaller interval (such as 1-minute), was moved one
bar in higher interval (such as 5 minute) if compressed intraday timestamps
ware set to START time of interval or FIRST tick
- The left-hand handle moved to the next bar when it was off-screen and right-hand
handle was adjusted by the user. Now it is fixed. (FC#890)
- When drawing is clicked without moving the mouse, the co-ordinates stay
untouched ( snap is not activated until you move the mouse)
- AFL: AddSummaryRows changed
AddSummaryRows( flags, format = 0, onlycols = 0, ...)
AddSummaryRows automatically adds "summary" row(s) to the exploration
output.
the flags parameter can be combination of the following
1 - add TOTAL row
2 - add AVERAGE row
4 - add MIN row
8 - add MAX row
16 - add COUNT row
format - defines the numeric formating in WriteVal style so 1.2 for example
means 2 decimal digits.
If default value of zero is used (or parameter not specified) the default
formatting of "maximum precision"
is used - upto 15 digits are printed
onlycols - defines for which columns you want to display summary row values.
Note that if you do not specify any columns - ALL will be printed.
If you are using onlycols, you can define upto 10 columns, columns, like
in SetSortColumns are numbered starting from 1. For example:
AddSummaryRows( 1, 1.2, 3, 5, 7, 9 );
Display sum for columns: 3, 5, 7, and 9.
Generally you should call this funciton only once, using combination of
flags desired.
But it is possible to call AddSummaryRows multiple times and the result
will be "accumulation" (i.e. bitwise OR)
in case of "flag" parameter. format and onlycols are always overwritten
by last call.
Example:
Filter=1;
AddColumn(V, "Volume" );
AddSummaryRows( 31, 1.2 ); // add Total, Average, Min, Max, and Count rows
(1+2+4+8+16)=31 - with two decimal places
summary rows are added at the top of the list
- Handles from selected study line are respected (i.e when study is already
selected, and multiple studies exists under "click" point, the
selection does not change) (FC#726)
- Magnet mode can be asynchronously (temporarily) toggled by holding SHIFT
key while drawing. Toggle means that if you are in magnet mode and hold down
shift it will turn it off and vice versa
- Magnet mode implemented for horizontal price levels and working correctly
now (stay horizontal) (FC#728)
- During optimization Progress bar shows engine ID, opt. target, best value,
step and best combination of parameters found upto "now". These
figures are refreshed every second.
- Optimization (in non-WF mode) results are sorted by optimization target
column (too)
- New optimization engine added: CMAE (Covariance Matrix Adaptation Evolutionary
Strategy) optimizer plug-in
CMA-ES (Covariance Matrix Adaptation Evolutionary Strategy) is state-of-the-art
non-exhaustive optimizer.
For scientific background see:
http://www.bionik.tu-berlin.de/user/niko/cmaesintro.html
According to scientific benchmarks outperforms nine other, most popular evolutionary
strategies (like PSO, Genetic and Differential evolution).
http://www.bionik.tu-berlin.de/user/niko/cec2005.html
The CMAE.DLL plugin implements "Global" variant of search
with several restarts with increasing population size
CMAE.DLL comes with FULL SOURCE CODE (inside "ADK" folder)
By default number of runs (or restarts) is set to 5.
It is advised to leave the default number of restarts.
You may vary it using OptimizerSetOption("Runs", N ) call, where
N should be in range 1..10.
Specifying more than 10 runs is not recommended, although possible.
Note that each run uses TWICE the size of population of previous run so
it grows exponentially.
Therefore with 10 runs you end up with population 2^10 greater (1024 times)
than the first run.
There is another parameter "MaxEval". The default value is
ZERO which means that plugin will automatically calculate MaxEval required.
It is advised to NOT to define MaxEval by yourself as default works fine.
The algorithm is smart enough to minimize the number of evaluations
required and it converges VERY fast to solution point, so usually it
finds solutions way faster than other strategies.
It is normal that the plugin will skip some evaluations steps, if it
detects that solution was found, therefore you should not be surprised
that optimization progress bar may move very fast at some points. The
plugin also has ability to increase number of steps over initially estimated
value if it is needed to find the solution. Due to its adaptive nature,
the "estimated time left" and/or "number of steps" displayed
by the progress dialog is only "best guess at the time" and
may vary during optimization course.
To use CMA-ES optimizer, you just need to add one line to your code:
OptimizerSetEngine("cmae");
This will run the optimization with default settings which are fine
for most cases.
It should be noted, as it is the case with many continouos-space search
algorithms, that decreasing "step" parameter in Optimize()
funciton calls does not significantly affect optimization times. The
only thing that matters is the problem "dimension", i.e. the
number of different parameters (number of optimize function calls). The
number of "steps" per parameter can be set without affecting
the optimization time, so use the finest resolution you want. In theory
the algorithm should be able to find solution in at most 900*(N+3)*(N+3)
backtests where "N" is the dimension. In practice it converges
a LOT faster. For example the solution in 3 (N=3) dimensional parameter
space (say 100*100*100 = 1 million exhaustive steps) can be found in
as few as 500-900 CMA-ES steps.
- New optimization engine added: "Tribes" adaptive PSO optimizer
implemented
Tribes is adaptive, parameter-less version of PSO (particle swarm optimization)
non-exhaustive optimizer.
For scientific background see:
http://www.particleswarm.info/Tribes_2006_Cooren.pdf
In theory it should perform better than regular PSO, because it can automatically
adjust the swarm sizes and algorithm strategy to the problem being solved.
Practice shows that its performance is quite similar to PSO.
To find solutions significantly faster I can recommend CMA-ES (Covariance
Matrix Adaptation Evolutionary Strategy) algorithm instead.
The Tribes.DLL plugin implements "Tribes-D" (i.e. dimensionless)
variant. Based on http://clerc.maurice.free.fr/pso/Tribes/TRIBES-D.zip
by Maurice Clerc. Original source codes used with permission from the author
Tribes.DLL comes with FULL SOURCE CODE (inside "ADK" folder)
Supported parameters:
" MaxEval" - maximum number of evaluations (backtests) per run (default
= 1000).
OptimizerSetOption("MaxEval", 1000 );
You should increase the number of evaluations with increasing number of
dimensions (number of optimization params).
The default 1000 is good for 2 or maximum 3 dimensions.
"Runs" - number of runs (restarts). (default = 5 )
You can leave the number of runs at default value of 5.
By default number of runs (or restarts) is set to 5.
To use Tribes optimizer, you just need to add one line to your code:
OptimizerSetEngine("trib");
OptimizerSetOption("MaxEval", 5000 ); // 5000 evaluations max
CHANGES FOR VERSION 5.12.2 (as compared to 5.12.0)
- In 5.12.0 BETA the walk-forward test was stopping after first in-sample
cycle. Now it is fixed.
- AddSummaryRows total did not include the very first item. Fixed.
CHANGES FOR VERSION 5.12.0 (as compared to 5.11.1)
- ADK: A new interface for external optimization engines, see optimizer.html
- Added two example non-exhaustive optimizers: Standard Particle Swarm Optimizer
(spso), and Monte Carlo (random pick) optimizer( moca)
Note that BOTH optimizers are provided for demonstration purposes.
Particularly Monte Carlo optimizer is meant as a "the most trivial and
simple" or even "dumb" example of optimizer DLL coding.
It works by randomly picking parameter combinations without ANY additional
logic. The results are thus random
and most probably sub-optimum.
On the other hand Standard Particle Swarm Optimizer is based on SPSO2007
code that is supposed to produce
good results provided that correct parameters (i.e. Runs, MaxEval) are
provided for particular problem.
Picking correct options for the PSO optimizer can be tricky therefore results
may significantly vary from case to case.
The source codes for both optimizers are OPEN and provided as illustration
how to implement optimizer engines using
" simple" and "advanced" methods as described in optimizers.html
file. You can find full source codes inside "ADK" subfolder.
In the future, I will provide more robust non-exhaustive optimizers using
various methods.
Example code for Standard Particle Swarm Optimizer:
(finding optimum value in 1000 tests within search space of 10000 combinations)
OptimizerSetEngine("spso");
OptimizerSetOption("Runs", 1 );
OptimizerSetOption("MaxEval", 1000 );
sl = Optimize("s", 26, 1, 100, 1 );
fa = Optimize("f", 12, 1, 100, 1 );
Buy = Cross( MACD( fa, sl ), 0 );
Sell = Cross( 0, MACD( fa, sl ) );
Example Code for Monte Carlo optimizer:
(finding sub-optimum value in 1000 test within search space of 10000 combinations)
OptimizerSetEngine("moca");
OptimizerSetOption("NumSteps", 1000 );
sl = Optimize("s", 26, 1, 100, 1 );
fa = Optimize("f", 12, 1, 100, 1 );
Buy = Cross( MACD( fa, sl ), 0 );
Sell = Cross( 0, MACD( fa, sl ) );
- Increased limit of optimization parameters to 100
- AFL: new OptimizerSetOption("name", value ) function
The function set additional parameters for external optimization engine.
The parameters are engine-dependent.
For example SPSO optimizer supports "Runs" (number of runs) and "MaxEval" (maximum
evaluations (tests)per single run) parameters. Monte Carlo optimizer supports "NumSteps" (number
of steps) parameter.
- AFL: new OptimizerSetEngine("name") function
The function selects external optimization engine defined by name. For demonstration
two engines are provided: Standard Particle Swarm Optimizer ("spso")
and Monte Carlo (random pick) optimizer ("moca")
Example:
OptimizerSetEngine("moca");
- ADK: new example C++ source codes: PSOSample, MOCASample
- AFL: AddSummaryRows( flags )
AddSummaryRows automatically adds "summary" row(s) to the exploration
output.
the flag parameter can be combination of the following
1 - add TOTAL row
2 - add AVERAGE row
4 - add MIN row
8 - add MAX row
16 - add COUNT row
You can call AddSummaryRows multiple times and the result will be "accumulation" (i.e.
bitwise OR)
Example:
Filter=1;
AddColumn(V, "Volume" );
AddSummaryRows( 31 ); // add Total, Average, Min, Max, and Count rows (1+2+4+8+16)=31
summary rows are added at the top of the list
CHANGES FOR VERSION 5.11.1 (as compared to 5.11.0)
- Fixed problem with Walk Forward picking sometimes not the best parameter
when thousand separator was used and metric values were greater than 1000
CHANGES FOR VERSION 5.11.0 (as compared to 5.10.1)
- Backtester: Implemented SeparateLongShortRank
To enable separate long/short ranking use:
SetOption("SeparateLongShortRank", True );
When separate long/short ranking is enabled, the backtester maintains
TWO separate "top-ranked" signal lists, one
for long signals and one for short signals. This ensures that long and
short candidates are independently even if position score
is not symetrical (for example when long candidates have very high positive
scores while short candidates have only fractional negative scores).
That contrasts with the default mode where only absolute value of position
score matters, therefore one side (long/short) may completely dominate
ranking if score values are asymetrical.
When SeparateLongShortRank is enabled, in the second phase of backtest,
two separate ranking lists are interleaved to form final signal list by
first taking top ranked long, then top ranked short, then 2nd top ranked
long, then 2nd top ranked short, then 3rd top ranked long
and 3rd top ranked short, and so on... (as long as signals exist in BOTH
long/short lists, if there is no more signals of given kind, then
remaining signals from either long or short lists are appended)
For example:
Entry signals(score):ESRX=Buy(60.93), GILD=Short(-47.56), CELG=Buy(57.68),
MRVL=Short(-10.75), ADBE=Buy(34.75), VRTX=Buy(15.55), SIRI=Buy(2.79),
As you can see Short signals get interleaved between Long signals even
though their absolute values of scores are smaller than corresponding scores
of long signals. Also there were only 2 short signals for that particular
bar so, the rest of the list shows long signals in order of position score
Although this feature can be used independently, it is intended to be
used in combination with MaxOpenLong and MaxOpenShort options.
- Backtester: MaxOpenLong/MaxOpenShort implemented
MaxOpenLong - limits the number of LONG positions that can be open simultaneously
MaxOpenShort - limits the number of SHORT positions that can be open simultaneously
Example:
SetOption("MaxOpenPositions", 15 );
SetOption("MaxOpenLong", 11 );
SetOption("MaxOpenShort", 7 );
The value of ZERO (default) means NO LIMIT. If both MaxOpenLong and MaxOpenShort
are set to zero (
or not defined at all) the backtester works old way - there is only global
limit active (MaxOpenPositions) regardless of type of trade.
Note that these limits are independent from global limit (MaxOpenPositions).
This means that MaxOpenLong + MaxOpenShort may or may not be equal to MaxOpenPositions.
If MaxOpenLong + MaxOpenShort is greater than MaxOpenPositions
then total number of positions allowed will not exceed MaxOpenPositions,
and individual long/short limits will apply too.
For example if your system MaxOpenLong is set to 7 and maxOpenShort is
set to 7 and MaxOpenPositions is set to 10
and your system generated 20 signals: 9 long (highest ranked) and 11 short,
it will open 7 long and 3 shorts.
If MaxOpenLong + MaxOpenShort is smaller than MaxOpenPositions (but greater
than zero), the system won't be able to
open more than (MaxOpenLong+MaxOpenShort).
Please also note that MaxOpenLong and MaxOpenShort only cap the number
of open positions of given type (long/short).
They do NOT affect the way ranking is made. I.e. by default ranking is
performed using ABSOLUTE value of positionscore.
If your position score is NOT symetrical, this may mean that you are not
getting desired top-ranked signals from one side.
Therefore, to fully utilise MaxOpenLong and MaxOpenShort in rotational
balanced ("market neutral") long/short systems
it is desired to perform SEPARATE ranking for long signals and short signals.
To enable separate long/short ranking use:
SetOption("SeparateLongShortRank", True );
- Added ability to running Walk forward test from OLE, using Optimize(3)
Analysis.Optimize( mode )
when mode == 3 it runs walk forward test
AB = new ActiveXObject("Broker.Application");
AA = AB.Analysis;
AA.Optimize(3);
- AFL: DaysSince1900() function
It returns the number of days that passed since January 1st, 1900,
counting from 1. January 1, 1900 is serial number 1, and January
1, 2008 is serial number 39448 because it is 39,448 days after January
1, 1900. Technically is equal to Windows OLEDATE and Excel's DATEVALUE
function.
The function can be used for calculations that involve calendar
days as opposed to trading days and replaces previously proposed
AFL solution
http://www.amibroker.com/kb/2007/03/15/calendar-day-index/
Now RefDays can be implemeted as follows:
SetBarsRequired( 365, 0 );
function RefDays(
Array, Days )
{
td = DaysSince1900();
result = Null;
if( Days < 0 )
{
for( i = BarCount -1;
i >= -Days; i = i - 1 )
{
backday = td[ i ] + Days; // Days is negative
for( j =
-Days/2; j < i; j++ )
{
if( td[
i - j ] <= backday )
{
result[ i ] = Array[ i - j ];
break;
}
}
}
}
return result;
}
Plot( C, "C", colorRed );
Plot( Ref( C,
-252 ), "Close
252 bars back", colorBlue );
Plot( RefDays( C,
-365 ), "Close
365 days back", colorGreen );
CHANGES FOR VERSION 5.10.0 (as compared to 5.09.0)
- Small improvement in axis font positioning - based on TEXTMETRIC
- Removed
1-pixel rendering overlap in multi-colored chart titles when ClearType
was enabled
- Hi-Res (256x256) alpha Vista icon
- Quote array now uses HeapRealloc instead of HeapAlloc/HeapFree combination
- Fixed rare crash @433F58
- Fixed account manager updating cash after exiting short trade
- Web Browser window does not flicker anymore when resizing
CHANGES FOR VERSION 5.09.0 (as compared to 5.08.0)
- MDI Tab order is now saved in the layout
- Added interface to BugslayerUtil.dll for optional call stack / symbol dump
report in crash recovery window
Now in the bottom of the crash report there is a detailed call stack and
CPU register state. This should allow quicker/easier fixes of any crashes
- New fields in Status() function: pxchart*
Status("pxchartleft") - returns x-coordinate of top-left corner
of chart area
Status("pxcharttop") - returns y-coordinate of top-left corner
of chart area
Status("pxchartright") - returns x-coordinate of bottom-right corner
of chart area
Status("pxchartbottom") - returns y-coordinate of bottom-right
corner of chart area
Status("pxchartwidth") - returns width chart area (right-left)
Status("pxchartheight") - returns width chart area (bottom-top)
Chart co-ordinates are useful because they automatically take into account
selected axis font size, whenever date axis is on or off
and other settings (New Look chart style)
All co-ordinates are in screen pixels. Note that top, left coordinates may
not be zero as chart rectangle is smaller than underlying window because
there is an extra space (padding) around chart.
// Test code:
Title = StrFormat("left=%g,
top=%g, right=%g, bottom=%g, width=%g, height=%g",
left=Status("pxchartleft"),
top=Status("pxcharttop"),
right=Status("pxchartright"),
bottom=Status("pxchartbottom"),
Status("pxchartwidth"),
Status("pxchartheight")
);
GfxSetOverlayMode(1);
GfxRectangle(Left,top,
right, bottom);
============ Overlay sample ================
_SECTION_BEGIN("GfxOverlaySampleNew");
function GetVisibleBarCount()
{
lvb = Status("lastvisiblebar");
fvb = Status("firstvisiblebar");
return Min(
Lvb - fvb, BarCount -
fvb );
}
function GfxConvertBarToPixelX(
bar )
{
lvb = Status("lastvisiblebar");
fvb = Status("firstvisiblebar");
pxchartleft = Status("pxchartleft");
pxchartwidth = Status("pxchartwidth");
return pxchartleft
+ bar * pxchartwidth / ( Lvb - fvb + 1 );
}
function GfxConvertValueToPixelY(
Value )
{
local Miny,
Maxy, pxchartbottom, pxchartheight;
Miny = Status("axisminy");
Maxy = Status("axismaxy");
pxchartbottom = Status("pxchartbottom");
pxchartheight = Status("pxchartheight");
return pxchartbottom
- floor( 0.5 +
( Value - Miny ) * pxchartheight/ ( Maxy - Miny ) );
}
Plot(C, "Price", colorBlack, styleHistogram );
GfxSetOverlayMode(0);
GfxSelectSolidBrush( colorRed );
GfxSelectPen( colorRed );
AllVisibleBars = GetVisibleBarCount();
fvb = Status("firstvisiblebar");
for( i = 0;
i < AllVisibleBars ; i++ )
{
x = GfxConvertBarToPixelX( i );
y = GfxConvertValueToPixelY( C[
i + fvb ] );
GfxRectangle(
x-1, y-1,
x + 2, y+1 );
}
//SetChartBkGradientFill( ColorRGB(200,200,200),
ColorRGB( 255,255,255) );
_SECTION_END();
- OLE: Name property is now writable, allowing switchin currently selected
symbol for the document
Example (JScript):
AB = new ActiveXObject("Broker.Application");
AB.ActiveDocument.Name = "MSFT"; // change the symbol for current
document to "MSFT"
CHANGES FOR VERSION 5.08.0 (as compared to 5.07.0)
- Walk-Forward: "Easy" mode divided into two submodes: EOD and
Intraday
Easy EOD mode assumes that you are using EOD data for walk-forward.
Easy Intraday mode assumes that you are using Intraday data for walk-forward
The difference is that in EOD mode the END date of previous period and START
date of next period are the same - thus avoiding gap
between periods. Intraday mode set START date of the next period as NEXT
DAY after END of previous period. That guarantees
that boundary day is not counted twice when testing on intraday data.
- SetOption("GenerateReport", value )
New option added to SetOption call
" GenerateReport" - 0/1/2
By default backtest reports are generated ONLY for portfolio backtests and
for individual backtests if individual reporting is turned on in the settings.
Reports are disabled for optimization.
Now with the SetOption() function you can either supress report generation
for backtests or enable report generation during certain optimization steps,
all from code level.
SetOption("GenerateReport", 0 ); // suppress generation of report
SetOption("GenerateReport", 1 ); // force generation of full report
SetOption("GenerateReport", 2 ); // only one-line report is generated
(in results.rlst file) viewable as single line in Report Explorer
- Total chart redraw time is calculated properly if multiple documents and
charts are open that results in smoother performance and no update lockup
- When custom color palette is changed, any old RGB color that is not present
in changed palette is matched to closest "standard" color
- Bugfix: when crosshair was enabled and moved OUTSIDE chart windows, then
CPU usage was high. Now it is fixed
- Walk-Forward: when starting date is the last day of the month and step
is n-month then it is treated as special case
AmiBroker now detects that start day is the last day of the month and moves
the window to the last day of NEXT month, even if it is shorter.
That addresses the problem when one starts with January 31 and wants to step
by one month - > since there is NO February 31, previous version
moved to March 3rd. Now it detects that it is last day of the month and moves
to Feb 28 (or 29). Then in next step it will move to March 31.
CHANGES FOR VERSION 5.07.0 (as compared to 5.06.0)
- a bugfix in 5.06 affected Foreign() function so it did not load the data
on very first access - now fixed. This fixes also huge drawdown numbers that
occurred on open positions at the end of trade list if cache size was small
- AFL: SetChartOptions has now 2 more parameters that allow to set custom
scaling
SetChartOptions( Mode = 0, Flags = 0, gridFlags = chartGridMiddle, ymin =
0, ymax = 0 )
new ymin, ymax parameters specify Y-axis minimum and maximum values for custom
scaling.
If you specify any values that meet the condition ymin < ymax, AmiBroker
will turn OFF automatic scaling and use specified min/max values
for Y scale. Note that Mode argument controls when these settings are applied
(0 - only when new chart is created, 1 - always), when modes 2 and 3 are
used - scaling is not changed.
- bugfix: in 5.06.0 deleting the very first symbol raised exception, now
it is fixed
- bugfix: rarely when trade profits gone to absurd levels (for example if
user switched off price checking and used zero as entry price), AmiBroker
would crash when generating profit distribution chart, now it is fixed
- Crosshair moves way faster and flicker is practically eliminated
- Crosshair state is global now and saved between sessions
- Crosshair works now in floating windows and in inactive windows too
- IS, OOS, BEST equity tickers are now put into group 253 and market 253
(composites)
CHANGES FOR VERSION 5.06.0 (as compared to 5.05.1)
- Walk Forward: now you can select "trading days" instead of calendar
days as step unit. Currently it is using simplified method: Mon-Fri as a
trading days
- Walk Forward settings: fixed lockup (due to infinite loop) when step was
set to zero, also added other checks for invalid entries
- RT Quote window: now symbols can be re-arranged by drag-and-drop (simply
click on the symbol, hold and drag to re-arrange order)
- RT Quote window: faster refreshes and multi-step color fading
- RT Quote window: added ability to type-in multiple symbols directly (instead
of selecting one by one or via existing watch list)
- RT Quote window: added ability to insert EMPTY line (to separate symbol
groups)
- Preferences / Currencies: now you can define upto 20 currencies for multiple-currency
backtesting
- New FindSignal function in Backtester object (custom backtester procedure)
allowing fast lookups for signals matching given symbol
bo = GetBacktesterObject();
bo.FindSignal( bar, symbol, type )
where
bar is a bar number
symbol is ticker symbol
type represents type of signal to find: 0 - both entries and exits, 1 -
only entries, 2 - only exits
The function finds for first matching signal that has fPrice != -1 (different
than -1). If 0 is used as type, and entry and exit is on the same bar then
entry signal will be returned. Note: fPrice = -1 is a special marker meaning
that given signal should be ignored.
- Internal symbol pointers stay the same when new symbols are added or deleted.
This addresses exceptions when using AddToComposite during backtests among
other things
This fixes: FC#1101, exceptions when using AddToComposite inside CBT and
exceptions occuring sometimes with COM when adding / removing symbols
- Floating panes are now "sticky" that makes it easier to arrange
the workspace
- Charts: ability to hide vertical quote marker
The control over vertical quote marker is given now via
Parameter dialog -> Axes & Grid -> Vert. quote marker: Show/Hide
And programmatically via SetChartOptions function:
SetChartOptions( 2, chartHideQuoteMarker );
- Bugfix: when "pad and align" was used in AA and reference symbol
did not have all trading days, the data used for very first symbol in the
watch list under test could have been unaligned for the very first AA run,
subsequent runs were OK)
- Alert Output column sizes / layout are now preserved between sessions
- Added two new backtest modes: backtestRegularRaw2 and backtestRegularRaw2Multi
that do not remove excess EXIT signals
The common thing between Raw and Raw2 modes is that they both do NOT remove
excess ENTRY signals.
The difference is that Raw modes remove excess EXIT signals, while Raw2 do
NOT.
In Raw2 modes all exit signals (even redundant ones) are passed
to second phase of backtest just in case that you want implement strategy
that skips first exit. Lets suppose that you want to exit on some condition
from first phase but only in certain hours or after certain numbers of bars
in trade or only when portfolio equity condition is met. Now you can do that
in raw2 modes.
Note that Raw2 modes can get significantly slower when you are using custom
backtester code that iterates thru signals as there can be zillions of exit
signals in the lists even for symbols that never generated any entry signals,
therefore it is advised to use it only when absolutely necessary. Raw2 modes
are also the most memory consuming.
Note also that if you run the system WITHOUT custom backtest procedure
there should be no difference between Raw and Raw2 modes (other than speed & memory
usage) as first matching exit signal is what is used by default.
- 3D chart viewer: process priority is now set to IDLE
- 3D chart viewer: animation is now smoother (upto 100fps vs 25fps)
CHANGES FOR VERSION 5.05.1 (as compared to 5.05.0)
- Walk Forward AA Settings: added error message when start date > end
date
- Walk Forward AA Settings: added "preview" list - showing all
IS and OOS segments with dates
CHANGES FOR VERSION 5.05.0 (as compared to 5.04.2)
- Walk Forward: "Easy" mode in the settings implemented - it sets "out-of-sample" parameters
automatically based on in-sample settings
- GetCursorMouseButtons new flag = 8 - means that current chart just received
mouse click
/////////////////////////////////////////////////
// Low-level graphic + Interactive GUI control
sample
// This example shows:
// 1. how to draw "buttons"
// 2. how to handle mouse clicks
// 3. how to implement event call-backs
///////////////////////////////////////////////////
Version( 5.04 ); //
requires 5.04 or higher
////////////////////////////////////////////////////
// Part 1: DRAWING TABLE OF BUTTONS
//////////////////////////////////////////////////
GfxSetOverlayMode( 2 );
// formatted text output sample via low-level
gfx functions
CellHeight = 20;
CellWidth = 100;
GfxSelectFont( "Tahoma",
CellHeight/2 );
GfxSetBkMode( 1 );
function PrintInCell(
string, row, Col )
{
GfxDrawText( string,
Col * CellWidth, row * CellHeight, (Col + 1 )
* CellWidth, (row + 1 )
* CellHeight, 0 );
}
GfxSelectPen( colorBlue );
for( i = 0;
i < 10 && i < BarCount;
i++ )
{
for( k = 0;
k < 5; k++ )
{
PrintInCell( "Button " +
i + "," + k, i, k );
}
GfxMoveTo( 0,
i * CellHeight );
GfxLineTo( 5 *
CellWidth, i * CellHeight );
}
GfxMoveTo( 0,
i * CellHeight );
GfxLineTo( 5 *
CellWidth, i * CellHeight );
for( Col = 1;
Col < 6; Col++ )
{
GfxMoveTo( Col * CellWidth, 0);
GfxLineTo( Col * CellWidth, 10 *
CellHeight );
}
/////////////////////////////////////////////////////////
// Part 2: MOUSE BUTTON CALL BACKS
//////////////////////////////////////////////////////////
Title="";
function DrawButton(
px, py, Clr1, Clr2, text )
{
Col = floor(
px / CellWidth );
Row = floor(
py / CellHeight );
GfxGradientRect(
Col * CellWidth, row * CellHeight, (Col + 1 )
* CellWidth, (row + 1 )
* CellHeight,
Clr1,
Clr2 );
PrintInCell( text + " " +
row + "," + Col, row, Col
);
}
function OnLMouseButton(x,
y, px, py)
{
_TRACE("LButton
x = " + DateTimeToStr(
x ) + " y = " + y );
DrawButton( px, py, ColorHSB( 50, 255, 255 ), ColorHSB( 90, 255, 255 ), "just
clicked" );
}
function OnRMouseButton(x,
y, px, py)
{
_TRACE("RButton
x = " + DateTimeToStr(
x ) + " y = " + y );
}
function OnMMouseButton(x,
y, px, py)
{
_TRACE("MButton
x = " + DateTimeToStr(
x ) + " y = " + y );
}
function OnHoverMouse(x,
y, px, py)
{
_TRACE("LButton
x = " + DateTimeToStr(
x ) + " y = " + y );
DrawButton( px, py, ColorRGB( 230, 230, 230 ), ColorRGB( 255, 255, 255 ), "mouse
over" );
}
function OnLButtonIsDown(x,
y, px, py)
{
_TRACE("LButton
x = " + DateTimeToStr(
x ) + " y = " + y );
DrawButton( px, py, ColorHSB( 190, 255, 255 ), ColorHSB( 210, 255, 255 ), "down" );
}
/////////////////////////////////////////////////////////
// Part 3: GENERAL PURPOSE EVENT HANDLER (reusable!
- may be put into "include" file)
////////////////////////////////////////////////////////
function EventHandler()
{
local b, x,
y, px, py;
b = GetCursorMouseButtons();
// retrieve co-ordinates in date/value units
x = GetCursorXPosition(0);
y = GetCursorYPosition(0);
// retrieve co-ordinates in pixel units
px = GetCursorXPosition(1);
py = GetCursorYPosition(1);
if( b & 8 ) //
flag = 8 is set when window just received mouse click
{
// not-null means clicked in THIS (current)
window
if(
b & 1 ) OnLMouseButton(
x, y, px, py );
if(
b & 2 ) OnRMouseButton(
x, y, px, py );
if(
b & 4 ) OnMMouseButton(
x, y, px, py );
}
else
{
if(
b == 0 ) OnHoverMouse(
x, y, px, py ); // no button pressed
if(
b == 1 ) OnLButtonIsDown(
x, y, px, py ); // button pressed
}
}
EventHandler();
RequestTimedRefresh( 1 );
- GetCursorXPosition/GetCursorYPosition return non-null values when mouse
is over the current chart regardless if it was clicked or not
- BUGFIX: trend line sometimes moved to the right edge when drawing/moving
them while two charts were opened in different periods
- Selector line is not drawn (does not blink) when GfxOverlayMode is set
to 2
- Walk Forward document can now be closed and/or hidden during WF (it is
not re-opened constantly)
CHANGES FOR VERSION 5.04.2 (as compared to 5.04.1)
- New log scale (5.04.1) was not working nicely for small dynamic range charts
- chart looked compressed. Fixed now.
- Chart Periodicity on MDI tab is now updated when switching
- Trendlines work fine with thick and dotted styles again (broken in 5.04)
- AFL: GetCursorXPosition/GetCursorYPosition functions changed
1. The functions now by default return NULL (empty value) if mouse is OUTSIDE
the current window
2. New "mode" parameter controls what values are returned
GetCursorXPosition( mode = 0 )
GetCursorYPosition( mode = 0 )
mode = -1 - (old compatibility mode) - x - value gives X-coordinate in
DateTime format. y - value gives PRICE. Values are reported no matter where
is the mouse (i.e. may refer to window different than current if mouse
is outside current window).
mode = 0 - (default) x - value gives X-coordinate in DateTime format. y
- value gives PRICE. Returns NULL if mouse is outside current window
mode = 1 - x, y - are mouse coordinates expressed in screen PIXELS. Returns
NULL if mouse is outside current window
CHANGES FOR VERSION 5.04.1 (as compared to 5.04.0)
- WF: Settings "Optimization target" combo box shows all built-in
fields now
- WF: now combined in-sample and out-sample equities are available by ~~~ISEQUITY
and ~~~OSEQUITY composite tickers
(consecutive periods of IS and OOS are concatenated and scaled to maintain
continuity of equity line - this approach assumes that you generally speaking
are compounding profits)
To display IS and OOS equity you may use for example this:
PlotForeign("~~~ISEQUITY","In-Sample
Equity", colorRed, styleLine);
PlotForeign("~~~OSEQUITY","Out-Of-Sample
Equity", colorGreen, styleLine);
Title = "{{NAME}}
- {{INTERVAL}} {{DATE}} {{VALUES}}";
- WF: in-sample best uses "first best" result consistenly instead
of quicksort (that did not prevent original order)
- WF: the output window is re-open when user closes it during Walk Forward
optimization
- Log chart scaling enhanced to handle nicely extreme dynamic range
CHANGES FOR VERSION 5.04.0 (as compared to 5.03.0)
- AFL Formula Editor: Copy-paste does not "eat" last character
- AFL Formula Editor: Edit->Prettify Selection function added
- Calling Activate() method of Window object does not maximize MDI window
any more
- Print Preview works fine now with floating windows
- Walk-Forward Optimization implemented (v1)
CHANGES FOR VERSION 5.03.0 (as compared to 5.02.2)
- Fixed: Pane/Template options do not work on floating window
- Added: Interval linking
- New linking settings are now saved in layouts and restored properly
- (re-)added: Cursor linking - selector line moves together in symbol and/or
linked charts
- Removed File->New->Linked chart (new linking replaces this functionality)
- Fixed: Layouts with old-style linked charts are now automatically converted
into new scheme when loading layout
CHANGES FOR VERSION 5.02.2 (as compared to 5.02.1)
- fixed problem with c-like multi-line comments /* */ that appeared in 5.02.1
beta
CHANGES FOR VERSION 5.02.1 (as compared to 5.01.1)
- Implemented Unlimited nesting of #include and #include_once
- True multi-monitor support. Chart windows can now be floated (outside main
application frame) and moved to different monitors
- Implemented new way of symbol-linking of charts (the button next to scrollbar
allows to choose linked group (1-9))
- Fixed crash when attempting to backtest on empty watch list (bug introduced
in 5.01)
- AFL: SetBarFillColor( colorarray ) allows to independently control candlestick,
bar, cloud, and area chart fill color
- OLE: when Broker.Application reference count drops to zero and AB was not
running prior to CreateObject() then the AB is closed
- Implemented workaround to Windows XP list view drawing bug (MS KB813791)
- Floating pane title is synchronized now (5.02.0 fix)
CHANGES FOR VERSION 5.01.1 (as compared to 5.01.0)
- fixed loading of customized toolbars
- toolbar customizations are now stored in Broker.exe-CommandBars51 (number
increased) to isolate new betas and old versions
CHANGES FOR VERSION 5.01.0 (as compared to 5.00.0)
- Tweaks in backtester for improved performance
Portfolio backtester on average 2x faster for both multiple and single-security
tests (some trivial, frequently trading systems may observe upto 5x speedup
on multiple securities during long analysis periods). Note that AFL engine
speed has NOT changed as compared to 5.00. Speed increase comes from backtester
tweaks alone, so the longer AFL code is the less speed-up you will see,
because backtester processing would account for smaller part of overall
execution time.
- Tweaks in quote handling for improved performance
- Code profiler - shows code analysis with detailed per-function timing report.
Available from AFL Editor: Tools->Code Check & Profile menu
CHANGES FOR VERSION 5.00.0 (as compared to 4.99.0)
- Database Purify: Date column type in set correctly now so clicking on
column sorts by date instead of by alpha (FC#1130)
- Elapsed/estimated time
is updated constantly when running long optimizations (FC#1107)
- Extra characters
in the title occuring when using dynamic color with Null values in Plot()
statements. Fixed. (FC#1129)
- Fixed saving of new commission table (FC#1122)
- In some cases slider did
not allow to reach the upper margin of Param() when step was decimal fraction
like 0.1 due to floating point rounding.
Now it addressed.
(FC#1155)
- Price Chart Style is now saved in a layout/template (FC#1039)
- When Find/Replace
dialog is still open while Formula Editor is closed it does not cause exception
anymore
CHANGES FOR VERSION 4.99.0 (as compared to 4.98.0)
- A warning added when closing the last chart window
- Fixed possible stack overflow when using ASCII importer for files without
extension but with . (dot) in a path (directory) name
- TimeFrameMode(3) (range mode) was not functional in 4.98, now it is fixed
- Fixed calculation of profit of leveraged instruments denominated in non-base
currency when dynamic fx rate was used
- Private heap allocator implemented for quotes and for trading signals
This should resolve problem of getting "out of memory" problem
that could occur during very long optimizations due to poor handling of virtual
memory in Windows.
CHANGES FOR VERSION 4.98.0 (as compared to 4.97.0)
- N-tick intervals from View->Intraday menu are enabled again in tick
databases (were disabled in 4.97 only)
- AFL: Status() function: 2 new fields added
"
axisminy" - retrieves the minimum (bottom) value of Y axis (indicators
only)
"
axismaxy" - retrieves the maximum (top) value of Y axis (indicators
only)
Example 1:
Title = "Axis
Min Y = " + Status("axisminy")
+ "Axis Max Y = " + Status("axismaxy");
Example 2:
SetChartOptions( 3, 0,
ChartGridMiddle );
axismin = Status("axisminy");
axismax = Status("axismaxy");
Plot( C, "Price", colorBlack, styleBar );
// draw exactly 5 grid lines
for( i = 0;
i < 5; i++ )
{
y = axismin + i * (axismax - axismin)/4;
PlotGrid(
y, colorRed );
}
- HTML export / import now store extra information about the kind of file
exported so when you export optimization result and re-import it later you
will be able to use optimization graph (FC#: 1029)
- HTML import: sometimes when importing large files duplicate rows appeared
at the end - now it is fixed (FC#1024)
- Fixed formatting of numeric values above 100000 after HTML import when
comma used as thousands separator (FC#: 1029)
- Added protection against using file-system reserved characters (*?#:|></"\)
in watch list names
- Implemented 5-tier commission schedule table in backtester (AA->Settings:
Commission table : DEFINE...) (FC#270)
- Account Manager: commission was not subtracted from equity when scaling-in
position that was open in previous amibroker run, now it is fixed
- Fixed problem with "Use only local database for this symbol" being
set to "yes" during loading of the database with absent broker.master
file
CHANGES FOR VERSION 4.97.0 (as compared to 4.96.0)
- Range Bar compression implemented now (FC#: 210, 1041,897,284)
Range Bars are price-driven bars, with each bar having a required minimum
high-low range. Source data are consolidated into one bar until the range
requirement is reached, then a new bar is started. It works best with tick
data that have only one price per data point. You can use it with other base
time intervals as well, but please note that if single source bar H-L range
exceedes desired range, the output will be single bar that has range higher
than requested. In other words source bars exceeding desired range won't
be splitted into several range bars. For example if you use 1 minute bars
and there is $3 dollar movement and you have selected $1 range bars it won't
be splitted into 3 bars. Instead you will get single bar with original $3
range.This is so because AB has no idea what happened *inside* the bar. Prices
could move first downwards and later upwards or opposite or zigzaging several
times or making any other pattern inside bar and this information is not
available from source bar that only has OHLC prices. Note that range bar
compression is not standarised. Some other softwares may attempt to split
to several artificial bars when range is exceeded, but we belive it is wrong
since it is based on assumptions about price action inside bar that may and
usually are wrong.
Range bars can now be selected as custom compression from Tools->Preferences->IntradayRange
bars are also available via TimeFrameMode() function
TimeFrameMode( 3 ); //
turn on range bars
TimeFrameSet( 1.5 ); //
set compression to 1.5$ range bar
- Mersene Twister MT19937 random number generator added
Two new AFL functions:
mtRandom( seed = Null ) - returns single random number (scalar) in the range
[0,1)
mtRandomA( seed = Null ) - returns array of random numbers in the range of
[0,1)
seed is random generator seed value. If you don't specify one, the random
number generator
is automatically initialized with current time as a seed that guarantees
unique sequence
Both functions use Mersene Twister mt19973ar-cok algorithm.
(Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura.)
Mersene Twister is vastly superior to C-runtime pseudo-random generator
available via Random() function.
It has a period of 219973 = approx 2.9*106012 For more information visit:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
See also:
M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3--30.
- AFL: PopupWindow() function added (FC#: 840)
SYNTAX:
PopupWindow( bodytext, captiontext, timeout = 5, left = -1, top = -1 );
bodytext - the string containing the text of the window body
caption - the string containing the text of window caption
timeout - auto-close time in seconds (default 5 seconds)
left - top-left corner X co-ordinate (default = -1 -means auto-center)
top - top-left corner Y co-ordinate (default = -1 - means auto-center)
Example code:
if( ParamTrigger("Display
Popup Window", "Press
here" ) )
{
PopupWindow("Current
time is: " + Now(),"Alert", 2, 640*mtRandom(), 480*mtRandom());
}
- ASCII Importer: $TIMESHIFT option added (FC# 1094)
Added ability to time-shift data at the time of the import.
$TIMESHIFT shift_in_hours
For example:
$TIMESHIFT 2
will import with date/time stamps shifted 2 hours forward
$TIMESHIFT -11.5
will import with date/time stamps shifted 11 and half hour backward
Please note that only INTRADAY data (with TIME component provided) are shifted.
EOD data (without time field) are unaffected.]
- AFL: GetPlaybackDateTime() (FC#: 837)
pt = GetPlaybackDateTime(); //
new function to retrieve playback position date/time,
//returns zero if bar replay is NOT active
if( pt )
{
Title = "Playback
time: " + DateTimeToStr(
pt );
}
else
{
Title = "Bar
Replay not active";
}
It returns zero if bar replay is not active.
- Fixed lockup when bar replay was attempted on base time interval = tick
- Fixed passing IDispatch parameters to OLE/COM method calls
- Fixed error message typo in SetCustomBacktestProc (FC: 1085) "exit" vs "exist"
- 3D optimization chart viewer: added 4x4 Full Screen Anti-Aliasing for
beautifully smooth 3D charts and improved readability
4x4 Full-Screen Anti-Aliasing (FSAA) feature is available only on graphic
cards that support this in hardware (all NVidia GeForce cards, and most recent
graphic cards that have 3D acceleration). It is not available for low-end
graphic cards sometimes found in the cheapest notebooks.
If FSAA is not supported by the hardware View->Anti-aliasing menu item
will be disabled (grayed).
If FSAA is supported in hardware then it will be turned on by default.
Note that animation speed with FSAA turned on may be lower on slower graphic
cards. If speed is not acceptable you can turn off anti aliasing by unchecking
View->Anti-aliasing menu (or turning off "A" button in the toolbar)
of 3D chart viewer (O3G.exe).
CHANGES FOR VERSION 4.96.0 (as compared to 4.95.0)
- HTML Import to AA result list implemented (FC#579)
Note that this feature is intended to import only HTML files exported by
AmiBroker. The HTML parser used is specifically written for this particular
purpose and expects certain layout of HTML file. HTML files saved by other
programs can not be imported. Use Automatic Analysis -> File -> Import
to access this feature.
- Account manager: added "per-trade" commission setting (FC#: 973)
- Two new backtester modes that do not remove redundant signals (FC#: 105)
- RAW MODE: signal-based backtest, redundant (raw) signals are NOT
removed, only one position per symbol allowed:
- RAW MODE WITH MULTIPLE POSITIONS - signal-based backtest, redundant
(raw) signals are NOT removed, MULTIPLE positions per symbol will be
open if BUY/SHORT signal is "true" for more than one bar
and there are free funds, Sell/Cover exit all open positions on given
symbol, Scale-In/Out work on all open positions of given symbol at
once.
- AFL: new function SetBacktestMode( mode )
Sets working mode of the backtester:
// default, as in 4.90, regular, signal-based
backtest, redundant signals are removed
SetBacktestMode(
backtestRegular );
// signal-based backtest, redundant (raw)
signals are NOT removed, only one position per symbol allowed
SetBacktestMode(
backtestRegularRaw );
// signal-based backtest, redundant (raw)
signals are NOT removed,
// MULTIPLE positions per symbol will
be open if BUY/SHORT signal is "true" for more than one bar and there
are free funds
// Sell/Cover exit all open positions
on given symbol, Scale-In/Out work on all open positions of given
symbol at once.
SetBacktestMode(
backtestRegularRawMulti );
// rotational trading mode - equivalent
of EnableRotationalTrading() call
SetBacktestMode(
backtestRotational );
- AA window: custom draw buttons (with arrows) are redrawn on killfocus
event to prevent flickering
- Fix: when symbol is deleted from database it is removed from all new watchlists
as well
- Attempt to assign value to the element of the array named the same as the
function inside the function declaration produces error 33 now instead of
crash (FC#: 1011)
- Clicking RMB->Watchlist->Remove inside watch list node was removing
symbol from all watch lists. Now it is fixed.
- Fixed cell text truncation that could happen randomly when using HTML
export
- Position of compound drawings (retracements/cycles) is updated correctly
now when "Properties" dialog was choosen from without selecting
the drawing via LMB click
- Stops were reset to default values (from settings) when custom backtest
routine was stored in separate file (not embedded or included in the formula).
Now it is fixed
CHANGES FOR VERSION 4.95.0 (as compared to 4.94.0)
- Added support for AFL Code Wizard (Analysis->AFL Code Wizard menu
and toolbar button)
AFL Code Wizard is a new add-on for AmiBroker. It allows creation
of trading system formulas without ANY programming experience. It is available
for purchase for $49 one-time fee. Further upgrades are free. AmiBroker
comes with trial version that has all functionality *including* export
of auto-generated AFL formula to AmiBroker. The only missing feature in
trial version of AFL COde wizardis saving the project in .awz format.
To run it select Analysis->AFL Code Wizard menu.
AFL Code Wizard instructional video can be found at: http://www.amibroker.com/video/amiwiz/AFLWiz1.html
- Symbol Tree->Right click->Watch List->Type In works from any
node now (FC#991)
- Filter window supports more than 256 watchlists (FC#1006)
- Aliases are properly recognized when adding symbols to new watchlists
CHANGES FOR VERSION 4.94.0 (as compared to 4.93.0)
- AFL: 23 new low-level graphic functions allowing Windows GDI-like painting
Completely new low-level graphic AFL interface allows complete flexibility
in creating any kind of user-defined display.
The interface mimics closely Windows GDI API, with same names for most functions
for easier use for GDI-experienced programmers. The only differences are:
1. compared to Windows GDI all functions are prefixed with 'Gfx'
2. pen/brush/font creation/selection is simplified to make it easier to use
and you don't need to care about deletion of GDI objects
3. Three overlay modes are available so you can mix low-level graphics with
regular Plot() statements
(mode = 0 (default) - overlay low-level graphic on top of charts, mode =
1 - overlay charts on top of low-level graphic, mode =2 - draw only low-level
graphic (no regular charts/grid/titles/etc))
Low-level graphics tutorial: http://www.amibroker.com/guide/h_lowlevelgfx.html
Available low-level gfx functions (click on the links for detailed explanation):
GfxMoveTo( x, y ) http://www.amibroker.com/f?gfxmoveto
GfxLineTo( x, y ) http://www.amibroker.com/f?gfxlineto
GfxSetPixel( x, y, color ) http://www.amibroker.com/f?gfxsetpixel
GfxTextOut( "text", x, y ) http://www.amibroker.com/f?gfxtextout
GfxSelectPen( color, width = 1, penstyle = penSolid ) http://www.amibroker.com/f?gfxselectpen
GfxSelectSolidBrush( color ) http://www.amibroker.com/f?gfxselectsolidbrush
GfxSelectFont( "facename", pointsize, weight = fontNormal,
italic = False, underline = False, orientation = 0 ) http://www.amibroker.com/f?gfxselectfont
GfxRectangle( x1, y1, x2, y2 ) http://www.amibroker.com/f?gfxrectangle
GfxRoundRect( x1, y1, x2, y2, x3, y3 ) http://www.amibroker.com/f?gfxroundrect
GfxPie( x1, y1, x2, y2, x3, y3, x4, y4 ) http://www.amibroker.com/f?gfxpie
GfxEllipse( x1, y1, x2, y2 ) http://www.amibroker.com/f?gfxellipse
GfxCircle( x, y, radius ) http://www.amibroker.com/f?gfxcircle
GfxChord( x1, y1, x2, y2, x3, y3, x4, y4 ) http://www.amibroker.com/f?gfxchord
GfxArc( x1, y1, x2, y2, x3, y3, x4, y4 ) http://www.amibroker.com/f?gfxarc
GfxPolygon( x1, y1, x2, y2, ... ) http://www.amibroker.com/f?gfxpolygon
GfxPolyline( x1, y1, x2, y2, ... ) http://www.amibroker.com/f?gfxpolyline
GfxSetTextColor( color ) http://www.amibroker.com/f?gfxsettextcolor
GfxSetTextAlign( align ) http://www.amibroker.com/f?gfxsettextalign
GfxSetBkColor( color ) http://www.amibroker.com/f?gfxsetbkcolor
GfxSetBkMode( bkmode ) http://www.amibroker.com/f?gfxsetbkmode
GfxGradientRect( x1, y1, x2, y2, fromcolor, tocolor ) http://www.amibroker.com/f?gfxgradientrect
GfxDrawText( "text", left, top, right, bottom, format
= 0 ) http://www.amibroker.com/f?gfxdrawtext
GfxSetOverlayMode( mode = 0 ) http://www.amibroker.com/f?gfxsetoverlaymode
- AFL: Two new fields in Status() functions: pxwidth and pxheight (
Status("pxwidth") - gives pixel width of chart window (useful for
low level graphics functions that operate on pixels)
Status("pxheight") - gives pixel height of chart window
- Better scaling and no more black rectangle on the bottom in images created
via Edit->Image->Copy / Export
- "New Look" charts (switchable via Tools->Preferences "Charting")
- give cleaner, larger and more readable chart display and printout
- Printing/copy-metafile function uses now Enhanced Metafile format that
handles clipping regions (styleClipMinMax)
CHANGES FOR VERSION 4.93.0 (as compared to 4.92.0)
- Fixed exception that maight occur when copying to clipboard very long lines
from AA result list
- CategoryGetName() now returns empty string for non-existing categories
instead of some uninitialized (random) string
- Fixed exception when trying to apply commentary on blank chart pane
- AFL editor fix: right Alt + z does not trigger 'undo' anymore (allows
to enter Polish z (z-dot-above) letter)
- Fixed exception occuring when Symbol Information was edited at the same
time while first auto-analysis was run
- Fixed bar replay not functioning when viewing interval was the same as
base time interval and set to less than 5 minute, mixed mode was off, and
no afterhours/weekend filtering was enabled (FC#: 899)
- Fix: defined FXRate for the very first symbol in the database is used
correctly now (FC#: 975)
- When LoadFormula() method of Analysis object is called parameters are
reset now (FC#: 958)
- Ability to export Chart in "portable" format so you can distribute
chart templates to others and they will be restored together with all linked
formulas (FC#: 96)
This feature is available from RIGHT CLICK on chartTemplate->Save...Template->Load...
menus.
In addition to old local template format a new one is added with .chart extensionthat
keeps not only window sizes and formula references (paths) but also formulas
themselves,so all you need to do is to save your chart into one file (Chart
Template, Complete *.chart)and copy that file onto different computer and
chart will be recreated with all formulas linked to it.
To Save chart into new format do the following:
1. Click with RIGHT MOUSE button over the chart and select Template->Save...
2. In the file dialog, "Files of type" combo select "Chart
Template, Complete (*.chart)"
3. Type the file name and click Save.
To load previously saved complete chart do the following:
1. Click with RIGHT MOUSE button over the chart and select Template->Load...
2. In the file dialog, select previously saved *.chart file and press "Open"
Note: The procedure AmiBroker does internally is as follows: When you save
the chart into new format it saves XML file with:
a) names of all sheets, panes, their sizes, locations and other settings
b) paths to all formulas used by all panes
c) the text of formulas themselves
When you load the chart in new format AmiBroker:
a) sets up the sheets/panes according to information stored in the file
b) for each formula stored in the file it checks if the same formula exists
already on target computer:
- if it does not exist - it will create one
- if it exists and the contents is identical to the formula stored in .chart
file it will do nothing
- if it exists and the contents is different then it will create NEW formula
filewith _imported.afl suffix (so old file is not touched) and will reference
the pane to the _imported.afl formula instead.
IMPORTANT NOTE: if you use any #include files AmiBroker will store the contentsof
include files as well inside chart file and will attempt to recreate them
on target machine.Please note that in case of includes it will check if it
exists and if it is different.If both conditions are met (different file
exists already) it will ask to replace or not.If you choose to replace -
it will replace and make backup of existing one with .bak extensionIf you
are using any files in "standard include files and include them using <> braces,
AmiBroker will restore files in target machine standard include folder as
well evenif the standard include folder path is different on the source machine).
Note also - that this functionality is a bit experimental and pretty complex
internally. There may be some bugs even though it was tested on number of
different setups. Feedback is welcome. It is intended to be used to port
charts between different computers. For storing layouts/templates on local
computer you should rather use old formats as they consume much less space
(they store only references,not the formulas themselves). One may however
use new format for archiving purposes as itkeeps formulas and all references
in one file that is very convenient for backups.
CHANGES FOR VERSION 4.92.0 (as compared to