September 9, 2008 19:35
THIS IS A BETA VERSION OF THE SOFTWARE. EXPECT BUGS !!!
Backup your data files and entire AmiBroker folder
first!
INSTALLATION INSTRUCTIONS
IMPORTANT: This archive is update-only. You have to install full version 5.10 first.
Just run the installer and follow the instructions.
Then run AmiBroker. You should see "AmiBroker 5.17.1 beta" written in the About box.
See CHANGE LOG below for detailed list of changes.
CHANGE LOG
CHANGES FOR VERSION 5.17.1 (as compared to 5.17.0)
CHANGES FOR VERSION 5.17.0 (as compared to 5.16.0)
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.
CHANGES FOR VERSION 5.16.0 (as compared to 5.15.0)
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;
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)
CHANGES FOR VERSION 5.14.0 (as compared to 5.13.0)
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();
(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 );
NOTE: for backward compatiblity with all formulas you have written already, the codes for Status("action") did NOT change .
CHANGES FOR VERSION 5.13.0 (as compared to 5.12.2)
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
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.
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)
CHANGES FOR VERSION 5.12.0 (as compared to 5.11.1)
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 ) );
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)
CHANGES FOR VERSION 5.11.0 (as compared to 5.10.1)
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.
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 );
AB = new ActiveXObject("Broker.Application");
AA = AB.Analysis;
AA.Optimize(3);
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
{
if(
td[ i - j ]
{
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 );
HOW TO REPORT BUGS
If you experience any problem with this beta version please send detailed description of the problem (especially the steps needed to reproduce it) to support at amibroker.com