amibroker

HomeKnowledge Base

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…)

How to change property for multiple symbols at once.

In order to automatically change a property for many symbols – instead of manual action in Symbol -> Information dialog one can use OLE automation.
For example – to unmark “Use only local database” option for all the symbols, it’s enough to run such SCAN:

– Analysis -> Formula Editor:
– enter:

AB CreateObject("Broker.Application");
st AB.Stocks(Name());
st.DataSource 0;
Buy 0

– Tools -> Send to Auto-analysis
– Apply to: All Symbols, N-last quotations = 1
– press SCAN

The other example shows how to rename all the symbols and replace .TO suffix with -TC (this may be useful when we want to use the existing historical data with a new datasource which uses a different symbology).

– Analysis -> Commentary
– enter:
AB CreateObject("Broker.Application");
sts AB.Stocks();
Qty sts.Count;
for( 
Qty 1>= 0)
{
 
st sts.Item);
 
Ticker st.Ticker;
 
printf("changing " ticker "\n" );
 
Length StrLen(Ticker );
 if( 
StrFind(ticker".TO") )
      
st.Ticker StrLefttickerLength-3)+"-TC";

– press APPLY
– use: VIEW -> Refresh All to see the changes in the symbol tree.

CAVEAT: The commentary formula above iterates through ALL SYMBOLS in the database, therefore, if your database is big (has more than 100 symbols) it may be SLOW, and you may experience “not responding” message, but it is NORMAL. It does not mean that program has stopped working. It just means that it has not completed iteration yet. In that case just WAIT and don’t touch it.

Price chart with independent style

If one wants to display a Candlesticks in one chart pane and Bars in another one, then it’s necessary to use a formula which does not read the settings from: View -> Price Chart Style.

The following custom Price formula allows to achieve this: (more…)

AmiBroker for Forex

Here is an article that tells you everything you need to know about using AmiBroker for trading FOREX markets. (more…)

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…)

Discretionary Equity

In the March 2006 “Letters to S&C” section I found the following request:

“I am looking for and add-on […] that would enable me to build an equity curve from buy/sell signals that the trader directly draws over the price graph of a commodity; for example, using specific active vertical lines. Such a software would be of great help for discretionary traders to validate their semiautomatic systems. — PH CHAMBAULT”

And I just thought that it would be nice example of using AFL’s Equity() function and ParamTrigger()

(more…)

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== HHVH10 ); // REPLACE THIS WITH YOUR OWN BUY RULE
Sell == LLVL10 ); // REPLACE THIS WITH YOUR OWN SELL RULE

PositionSize = -20;
SetOption("MaxOpenPositions"); 

// 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 IIfBuysigScaleInFalse ); // 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=0bar<BarCountbar++) 
   { 
        for ( 
sig=bo.GetFirstSignal(bar); sigsig=bo.GetNextSignal(bar) ) 
        {     
           
// first handle exit signals 
           
if (sig.IsExit() AND sig.Price != -
           { 
            
// Exit Signal 
               
bo.ExitTrade(bar,sig.symbol,sig.Price); 
           } 
        } 


        
// update stats after closing trades 
        
bo.UpdateStats(bar); 
       
        
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 != -AND 
              
IsNullbo.FindOpenPossig.Symbol ) ) ) 
          { 
           
// Entry Signal 
            
if( bo.EnterTrade(barsig.symbolsig.IsLong(), 
                
sig.Price,sig.PosSize) == 
           { 
             
// 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 
   

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…)

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…)

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…)

« Previous PageNext Page »