June 20, 2008 15:47

__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.12.0 beta" written in the About box.

**See CHANGE LOG below for detailed list of changes.**

**CHANGE LOG**

**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 rowYou 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)=31summary 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 simultaneouslyExample:

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 testAB = 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**);

**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