Stops priority in the default backtest procedure in AmiBroker
The order stops are triggered in the backtest is the following:
– Fixed Ruin stop (loosing 99.96% of the starting capital)
– Max. loss stop
– Profit target stop
– Trailing stop
– N-bar stop* (see below)
In versions 4.61 and higher: you can decide if N-BAR stop has the lowest or the highest priority. (more…)
Filed by AmiBroker Support at 6:48 am under Stops
Comments Off on Stops priority in the default backtest procedure in AmiBroker
August 9, 2006
AmiBroker for Forex
Here is an article that tells you everything you need to know about using AmiBroker for trading FOREX markets. (more…)
Filed by AmiBroker Support at 2:56 am under Data
3 Comments
How to display arrows for trades generated in backtest?
In order to display trade arrows, first of all – it’s necessary to enable the arrows for particular chart. To do so – right-click on the chart pane of your choice, choose: Parameters -> Axes&Grid, then set: Show trading arrows to YES, as shown in the screenshot. (more…)
Filed by AmiBroker Support at 2:54 am under Backtest,Indicators
5 Comments
April 24, 2006
Using redundant signals for entries
NOTE: THIS ARTICLE IS NOW OUTDATED AS AMIBROKER SUPPORTS NEW BACKTEST MODE THAT HANDLES THIS NATIVELY http://www.amibroker.com/f?setbacktestmode
The sample code below shows how to use custom portfolio backtester procedure to change the way backtester works. Normally buy is matched against sell and redundant buy signals between initial buy and matching sell are removed as shown in the picture there:
http://www.amibroker.com/gifs/bt_regular.gif
The procedure below changes this behaviour and allows to use redundant signals (they are not removed).
This is done by changing Buy array values from “true” to sigScaleIn (this prevents redundant signals from being removed because scale-in marks are kept untouched) and modifying standard procedure to treat scale-in signals as normal buys (no scaling).
Note that there are many ways to achieve the same effect. The technique presented here was choosen because it is easy-to-use (does not require changes in your core trading system code – all it needs is to plug-in the custom backtest part). Longer implementation would be required if you do not want to (ab)use scaling signals.
One thing worth mentioning is the fact that since scaling-in signals do not store position score this example formula does not support ranking of signals according to user-defined scores.
// YOUR TRADING SYSTEM HERE
Buy= H == HHV( H, 10 ); // REPLACE THIS WITH YOUR OWN BUY RULE
Sell = L == LLV( L, 10 ); // REPLACE THIS WITH YOUR OWN SELL RULE
PositionSize = -20;
SetOption("MaxOpenPositions", 5 );
// END OF TRADING SYSTEM HERE
// COMMON CODE PART
// TO BE COPY-PASTED if you want keep redundant signals
// This is long-only version.
// It is easy to extend to handle short trades as well
Buy = IIf( Buy, sigScaleIn, False ); // replace regular buy signals by scale in
// so they do not get filtered
SetOption("UseCustomBacktestProc", True );
if( Status("action") == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
for(bar=0; bar<BarCount; bar++)
{
for ( sig=bo.GetFirstSignal(bar); sig; sig=bo.GetNextSignal(bar) )
{
// first handle exit signals
if (sig.IsExit() AND sig.Price != -1 )
{
// Exit Signal
bo.ExitTrade(bar,sig.symbol,sig.Price);
}
}
// update stats after closing trades
bo.UpdateStats(bar, 1 );
bContinue = True;
for ( sig=bo.GetFirstSignal(bar); sig AND bContinue;
sig=bo.GetNextSignal(bar))
{
// enter new trade when scale-in signal is found
// and we don't have already open position for given symbol
if (sig.IsScale() AND sig.Price != -1 AND
IsNull( bo.FindOpenPos( sig.Symbol ) ) )
{
// Entry Signal
if( bo.EnterTrade(bar, sig.symbol, sig.IsLong(),
sig.Price,sig.PosSize) == 0 )
{
// if certain trade can not be entered due to insufficient funds
// or too small value (less than "MinPositionValue") or
// to few shares (less than "MinShares"
// then do NOT process any further signals
bContinue = False;
}
}
}
bo.UpdateStats(bar,1); // MAE/MFE is updated when timeinbar is set to 1.
bo.UpdateStats(bar,2);
}
bo.PostProcess(); // Finalize backtester
} 
Filed by Tomasz Janeczko at 5:50 am under Custom Backtest
Comments Off on Using redundant signals for entries
April 4, 2006
Adding custom metric: Average adverse excursion
Here is a sample that shows how to create custom metric based on per-trade statisitics.
In this example we will calculate the average value of MAE (maximum adverse excursion) from all trades.
(more…)
Filed by Tomasz Janeczko at 3:20 pm under Custom Backtest
Comments Off on Adding custom metric: Average adverse excursion
March 19, 2006
How does the intraday-to-daily compression work?
When you are using intraday database daily candles are usually constructed by time-compression of intraday (for example 1-minute data). AmiBroker offers lots of flexibility when it comes to defining intraday-to-daily time compression.
(more…)
Filed by AmiBroker Support at 7:31 pm under Data
2 Comments
March 11, 2006
How to create copy of portfolio equity?
As you know Portfolio backtester creates special ticker “~~~EQUITY” which holds portfolio-level equity of the system under test. Some may find it useful to save this equity into another symbol after backtest for future analysis and/or comparison. Good news is that it is possible to do that automatically using custom backtester procedure and AddToComposite function. The formula below shows how.
(more…)
Filed by Tomasz Janeczko at 2:32 pm under Custom Backtest
3 Comments
March 6, 2006
Re-balancing open positions
Here is an example that shows how to code rotational trading system with rebalancing. The system buys and shorts top 20 securities according to absolute value of positionscore (user definable – in this example we used 20 day rate-of-change) – each at 5% of equity then each day it rebalances existing positions to 5% if only the difference between current position value and “ideal” value is greater than 0.5% and bigger than one share.
Note that this code sample uses Custom Backtester interface that is documented here.
EnableRotationalTrading();
EachPosPercent = 5;
PositionScore = ROC( C, 20 );
PositionSize = -EachPosPercent;
SetOption("WorstRankHeld", 40 );
SetOption("MaxOpenPositions", 20 );
SetOption("UseCustomBacktestProc", True );
if( Status("action") == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
for(bar=0; bar < BarCount; bar++)
{
bo.ProcessTradeSignals( bar );
CurEquity = bo.Equity;
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
posval = pos.GetPositionValue();
diff = posval - 0.01 * EachPosPercent * CurEquity;
price = pos.GetPrice( bar, "C" );
// rebalance only if difference between desired and
// current position value is greater than 0.5% of equity
// and greater than price of single share
if( diff != 0 AND
abs( diff ) > 0.005 * CurEquity AND
abs( diff ) > price )
{
bo.ScaleTrade( bar, pos.Symbol, diff < 0, price, abs( diff ) );
}
}
}
bo.PostProcess(); // Finalize backtester
Filed by Tomasz Janeczko at 3:50 pm under Custom Backtest
Comments Off on Re-balancing open positions
Preventing exit during first N bars
Here is sample technique that allows to prevent exiting position during first N bars since entry. The implementation uses loops that checks for signals in Buy array and if it finds one it starts counting bars in trade. During first N bars all sell signals are then removed (set to zero) only once counter reaches user-defined limit sell signals are accepted.
(more…)
Filed by Tomasz Janeczko at 9:15 am under Backtest
Comments Off on Preventing exit during first N bars