Australian (ASX) Stock Market Forum

Amibroker FAQ

Code:
long = 0; // long backtest true/false

period = 20; // number of averaging periods 
m = MA( Close, period ); // simple moving average


if ( long )
{
    Buy = Cross( Close, m ); // buy when close crosses ABOVE moving average
    Sell = Cross( m, Close ); // sell when closes crosses BELOW moving average

    SetFormulaName( Name() + "_Long Backtest" ); // displayed in the backtest result explorer.
}
else
{
    Short = Sell;
    Cover = Buy;

    SetFormulaName( Name() + "_Short Backtest" );  // displayed in the backtest result explorer.
}

or create one or two clones of a symbol (like ~AAPL_1 and ~AAPL_2 ) via addtocomposite
and then you could use individual backtester (not portfolio BT) to run over group 253:

Code:
period = 20; // number of averaging periods 
m = MA( Close, period ); // simple moving average
         
if ( StrFind( Name(), "_1" )  && groupID() == 253 )
{
    Buy = Cross( Close, m ); // buy when close crosses ABOVE moving average
    Sell = Cross( m, Close ); // sell when closes crosses BELOW moving average

    SetFormulaName( Name() + "_Long Backtest" );  // displayed in the backtest result explorer.
}

if( StrFind( Name(), "_2" )  && groupID() == 253 )
{
    Short = Sell;
    Cover = Buy;

    SetFormulaName( Name() + "_Short Backtest" );  // displayed in the backtest result explorer.
}

Well Short cover rules in those examples should be

Code:
Short = Cross( m, Close );
Cover = Cross( Close, m );
 
Thanks Trash, your material is always of ultra-high quality.

The regular backtester is either long or short (a single symbol). The portfolio backtester will allow for simultaneous long and short positions, but appears to only be with different symbols (according to the documentation ; makes sense, it's a portfolio test).

When "independently" evaluating the entry/exit rules for long and short strategies, there are many instances where both positions will be held simultaneously. Yes, at times I will be both long and short a given symbol.

I want to backtest, in a single "run", long and short strats for a single symbol.
 
I have already told you how to do that. If you want to do individual backtest for single symbols and separate short and long backtest in one run then create two clones before (done in one second via scan).

You can use this AFL as example (it's a summation of second example of previous page)

Code:
SetOption( "GenerateReport", 1 );  // 0 - suppresses generation of report 
                                   // 1 - force generation of full report
                                   // 2 - only one-line report is generated (in results.rlst file) viewable as single line in Report Explorer 
SetOption( "RefreshwhenCompleted", True );

period = 20; // number of averaging periods 
m = MA( Close, period ); // simple moving average
         
if ( StrFind( Name(), "_1" ) && groupID() == 253 )
{
    Buy = Cross( Close, m ); // buy when close crosses ABOVE moving average
    Sell = Cross( m, Close ); // sell when closes crosses BELOW moving average

    SetFormulaName( Name() + "_Long Backtest" );  // displayed in the backtest result explorer.
}

if( StrFind( Name(), "_2" ) && groupID() == 253 )
{
    Short = Cross( m, Close );
	Cover = Cross( Close, m );

    SetFormulaName( Name() + "_Short Backtest" );  // displayed in the backtest result explorer.
}

if ( Status( "action" ) == actionScan )
{
    atcmode = atcFlagDefaults;

    for ( i = 1; i < 3; i++ )//create two clones
    {
        indexname = "~" + Name() + "_" + i;

        AddToComposite( Open, indexname, "O", atcmode );
        AddToComposite( High, indexname, "H", atcmode );
        AddToComposite( Low, indexname, "L", atcmode );
        AddToComposite( Close, indexname, "C", atcmode );
        AddToComposite( Volume, indexname, "V", atcmode );
        AddToComposite( OI, indexname, "I", atcmode );
    }

    Buy = 0;
}

First you set to current in "Apply to" and click scan to create your two clones (this is a one time process if quotes don#t change).
Then you code your systems and move the rules in between the two if conditions for long/short.
In "Apply to" you now set to Filter and include group 253.
Then you click individual backtest button and two separate reports for long and short of same symbol are created after one click. But you can not create one report that includes separate long and short report because if so then it would be a portfolio backtest. And that's not what you want AFAIU.

Anyway see here picture after individual backtest. All created composites are moved to group 253 by default. I have renamed group 253 to "Composites".

pvzWNRR.png
 
Again, thanks for the help Trash!!

Looks like I need to run the clones through the Portfolio backtester. It seems odd (to me at least) that the Individual backtest does not allow simultaneous longs and shorts. Of course, I guess everything is possible with "custom backtest" procedures.
 
Looks like I need to run the clones through the Portfolio backtester.

Huh? But not if you are after separate individual reports per symbol.

It seems odd (to me at least) that the Individual backtest does not allow simultaneous longs and shorts. Of course, I guess everything is possible with "custom backtest" procedures.

Individual backtest means individual separate reports. A separate just Long system is an individual system as well as separate just Short system is an individual system. Both create separate reports with separate performance charts etc. So both have to run sequentially. Got nothing to do with CBT. Also it's not odd. You just don't seem to understand yet.

Another method (alternative to the two mentioned ones in previous posts) is to create two AFLs... one containing your Long only system and the other AFL containing your short only system. If you wanna make multiple individual backtest of multiple symbols then before doing that create two clones for each symbol as shown (this time "Apply to" set to All symbols or Filter) and move the Clones with appendix "_1" to watchlist 1 and move Clones with appendix "_2" to Watchlist 2. Now open two analysis tabs. In first one you apply the Long only AFL with Filter set to "Include: Watchlist 1". in Second analysis tab you apply the short system AFL with Filter set to "Include: Watchlist 2". Then run both at same time and go shopping or do a quickie or whatever.
 
Pardon me for just barging in the convo, but does any one have a link that has detailed library explaining what each formulas function is. I have a general idea of my trading strategy but its difficult for me to translate it into the program because the functions of each formula is to technical and so I don't know which formula to choose. Even a simple formula such as entering when a 52 week high is breached is confusing.

Thanks
 
Pardon me for just barging in the convo, but does any one have a link that has detailed library explaining what each formulas function is. I have a general idea of my trading strategy but its difficult for me to translate it into the program because the functions of each formula is to technical and so I don't know which formula to choose. Even a simple formula such as entering when a 52 week high is breached is confusing.

Thanks

Its a long road particularly from scratch---but you have years on your side.

http://www.blueowlpress.com/

Introduction to Amibroker.
 
Pardon me for just barging in the convo, but does any one have a link that has detailed library explaining what each formulas function is. I have a general idea of my trading strategy but its difficult for me to translate it into the program because the functions of each formula is to technical and so I don't know which formula to choose. Even a simple formula such as entering when a 52 week high is breached is confusing.

Thanks

There's an online AFL function reference that lists each function by category. Each has a link to a detailed explanation of the function plus a list of formulas the function is used in that are in the AFL library. The same list is also in the user's guide that is under the "help" menu in Amibroker.

https://www.amibroker.com/guide/a_catfunref.html


There is also a "code wizard" under the "analysis" menu that simplifies some of the code construction.

http://www.amibroker.com/devlog/2007/05/18/introducing-afl-code-wizard/


There's also a "snippets" menu for the formula editor that allows you to insert either prebuilt code or custom snippets into the formula.

http://www.amibroker.com/guide/h_snippets.html


The official AFL library is here:

http://www.amibroker.com/library/list.php
 
Hi all, I'm thinking about getting the new version of amibroker. Can someone that has the new version show what the volume profile addition can do? Or point me to an explanation of it as I cannot seem to find any detail on it.
 
Hi all, I'm thinking about getting the new version of amibroker. Can someone that has the new version show what the volume profile addition can do? Or point me to an explanation of it as I cannot seem to find any detail on it.

G'day CanOz, I have the latest version but can't find any mention of a volume profile addition? There is a volume at price overlay function that may be what you're after?

dax_market_profile.jpg

This is the 3-minute DAX from this morning. The interval is set to daily but can be adjusted to whatever time frame suits.

The formula for this chart is in the example here:

http://www.amibroker.com/guide/afl/plotvapoverlaya.html

All my time goes into testing VPA/VSA stuff so I'm not all that knowledgeable with market profile but hope the chart above might help you out.

Cheers
Steve
 
VAP - Volume At Price histogram
Volume At Price histogram is also known as "Volume Profile" chart.

To turn it on simply go to Tools->Preferences and change Type of the VAP from "NONE" to "Left-side solid area chart, behind" for example

VAP shows total volume of trading that occurred at given price level. VAP is calculated from data bars that are currently visible.

Actual algorithm involves not ONE price but High-Low price RANGE.

AmiBroker DISTRIBUTES equally bar's volume over High-Low range to produce VAP histogram. For example if bar's volume is 10000 and H-L range spans 3 'lines" of VAP histogram than each of 3 lines
involved gets added 10000/3 to produce statistics. This gives much more accurate results than using single price
as some other implementations do.

To turn VAP on/off use: Tools->Preferences->Main chart
You can also add VAP to your own custom charts using PlotVAPOverlay AFL function

PlotVAPOverlay
- plot Volume-At-Price overlay chart Exploration / Indicators
(AFL 2.4)


SYNTAX PlotVAPOverlay( lines = 300, width = 5, color = colorGreen, vapstyle = 0 );
RETURNS NOTHING
FUNCTION Plots Volume-At-Price (VAP) overlay chart. Please note that there must be at least one regular Plot function in your formula for this to work, and there can be only one PlotVAPOverlay in one indicator. This function plots single segment for visible bars only. To plot multiple-segment VAP chart use PlotVAPOverlayA function.
vapstyle = 0 - left side, area fill, on top of all plots
vapstyle = 1 - right side, area fill, on top of all plots
vapstyle = 2 - left side, lines only, on top of all plots
vapstyle = 3 - right side, lines only, on top of all plots
vapstyle = 4 - left side, area fill, behind all plots
vapstyle = 5 - right side, area fill, behind all plots
vapstyle = 6 - left side, lines only, behind all plots
vapstyle = 7 - right side, lines only, behind all plots

EXAMPLE Plot( Close, "Price", colorWhite, styleCandle );
PlotVAPOverlay( Param("lines",300,10,1000,1), Param("width",10,1,99,1), ParamColor("color", colorDarkBlue), Param("style",0,0,7,1) );
SEE ALSO PLOT() function , PlotVAPOverlayA() function

References:
The PlotVAPOverlay function is used in the following formulas in AFL on-line library:
Code snippets is handy to learn about coding for us code dummies
 
Thanks for the replies Captain and Julieta.

I have version 5.50 and i use the VAP. My thoughts were that "Volume Profile" meant that there might have been something new. I guess it looks like i have the feature that they are referring to anyway and I've been using it for sometime. I was thinking there might have been a package with VWAP etc...

Cheers,


Steve
 

Attachments

  • amiVP.JPG
    amiVP.JPG
    20.4 KB · Views: 59
  • GCVP.png
    GCVP.png
    39.2 KB · Views: 5
I have been running a backtest which has a filter for EMA. I have had assistance with this backtest about a month ago.

The code currently is:

Code:
MaxPositions = 4;
SetOption("MaxOpenPositions", MaxPositions  );
SetOption("WorstRankHeld", MaxPositions + 2 );
SetPositionSize( 100 / MaxPositions, spsPercentOfEquity ); 

// trade on next day open
BuyPrice = Open;
SetTradeDelays( 1, 1, 1, 1 );


SetBacktestMode( backtestRotational );


SetForeign( "XAO" );
FastMALength = Optimize("FMA",62,30,70,2);
SlowMALength = Optimize("SMA",182,180,200,2);


Filter1 =  EMA( C, FastMALength ) > EMA( C, SlowMALength );
RestorePriceArrays();


//This is the additional filter I have introduced to try and filter out low volume stocks
VolA = Volume * C;
MAVol = MA( VolA, 15 );
Filter = Filter1 AND MAVol > 350000;


// offsetting by large positive number 
// makes sure that our score is always positive and we don't enter short trades
PositionScore = Iif( Filter, 10000 - ROC( C, 252 ), 0 );



StaticVarSet( Name() + "Score", 10000 - ROC( C, 252 ) );

SetCustomBacktestProc("");
if ( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();
    bo.backtest( 1 );

    // closed trades
    for ( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
    {   // two additional columns
        trade.addcustomMetric( "Score@entry", Lookup( StaticVarget( trade.symbol + "Score" ), trade.EntryDateTime ) );
        trade.addcustomMetric( "Score@exit", Lookup( StaticVarget( trade.symbol + "Score" ), trade.ExitDateTime ) );
    }
    
    // open trades
    for ( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
    {   // two additional columns
        trade.addcustomMetric( "Score@entry", Lookup( StaticVarget( trade.symbol + "Score" ), trade.EntryDateTime ) );
        trade.addcustomMetric( "Score@exit", Lookup( StaticVarget( trade.symbol + "Score" ), trade.ExitDateTime ) );
    }

    bo.listTrades();
}

The issue I am having is the EMA 62 is below EMA 182 on "XAO" and has been throughout December. The backtest has however entered into trades for 1 or two days, firstly entering 3 trades on 1 December [closing 2 December] and then entering another trade on 8 December before closing the next day.

Very strange - I note that both sets of trades have occurred on the Monday... possibly a coincidence, but....

Does anyone have an idea where this is messing up...
 
I have been running a backtest which has a filter for EMA. I have had assistance with this backtest about a month ago.

The code currently is:

Code:
MaxPositions = 4;
SetOption("MaxOpenPositions", MaxPositions  );
SetOption("WorstRankHeld", MaxPositions + 2 );
SetPositionSize( 100 / MaxPositions, spsPercentOfEquity ); 

// trade on next day open
BuyPrice = Open;
SetTradeDelays( 1, 1, 1, 1 );


SetBacktestMode( backtestRotational );


SetForeign( "XAO" );
FastMALength = Optimize("FMA",62,30,70,2);
SlowMALength = Optimize("SMA",182,180,200,2);


Filter1 =  EMA( C, FastMALength ) > EMA( C, SlowMALength );
RestorePriceArrays();


//This is the additional filter I have introduced to try and filter out low volume stocks
VolA = Volume * C;
MAVol = MA( VolA, 15 );
Filter = Filter1 AND MAVol > 350000;


// offsetting by large positive number 
// makes sure that our score is always positive and we don't enter short trades
PositionScore = Iif( Filter, 10000 - ROC( C, 252 ), 0 );



StaticVarSet( Name() + "Score", 10000 - ROC( C, 252 ) );

SetCustomBacktestProc("");
if ( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();
    bo.backtest( 1 );

    // closed trades
    for ( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
    {   // two additional columns
        trade.addcustomMetric( "Score@entry", Lookup( StaticVarget( trade.symbol + "Score" ), trade.EntryDateTime ) );
        trade.addcustomMetric( "Score@exit", Lookup( StaticVarget( trade.symbol + "Score" ), trade.ExitDateTime ) );
    }
    
    // open trades
    for ( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
    {   // two additional columns
        trade.addcustomMetric( "Score@entry", Lookup( StaticVarget( trade.symbol + "Score" ), trade.EntryDateTime ) );
        trade.addcustomMetric( "Score@exit", Lookup( StaticVarget( trade.symbol + "Score" ), trade.ExitDateTime ) );
    }

    bo.listTrades();
}

The issue I am having is the EMA 62 is below EMA 182 on "XAO" and has been throughout December. The backtest has however entered into trades for 1 or two days, firstly entering 3 trades on 1 December [closing 2 December] and then entering another trade on 8 December before closing the next day.

Very strange - I note that both sets of trades have occurred on the Monday... possibly a coincidence, but....

Does anyone have an idea where this is messing up...

Code:
PositionScore = Iif( Filter, 10000 - ROC( C, 252 ), scoreNoRotate );
 
Code:
PositionScore = Iif( Filter, 10000 - ROC( C, 252 ), scoreNoRotate );

Trash, thanks for the input.

Unfortunately the change doesn't give me what I have expected, in fact it returns no results on my selected watchlist of about 50 stocks when run over the past three months.

When I run it against all ASX stocks over the same period it brings up one trade [SEK - opens 15 Nov 2014 and remains open]

Just for certainty I have replaced

Code:
PositionScore = Iif( Filter, 10000 - ROC( C, 252 ), 0 );

with your suggested code.
 
The issue I am having is the EMA 62 is below EMA 182 on "XAO" and has been throughout December. The backtest has however entered into trades for 1 or two days, firstly entering 3 trades on 1 December [closing 2 December] and then entering another trade on 8 December before closing the next day.
Even though the 62 period exponential moving average close value of the XAO is clearly under the 182 period exponential moving average close value of the XAO, a scan on just that filter alone brings up stocks. Why, I don't know either.
 
Top