Australian (ASX) Stock Market Forum

Amibroker FAQ

Hi All,
I'm a newbie here and just bought Amibroker V5.80 charting software with Premium data EOD ASX.
Interested in learning how to code/design a trading system for the ASX shares to start with. I realised there is no in-built system in AB to learn and practice with.
Problem is that I have no programming background and AFL seems a little bit daunting for a newbie.
What would be the best approach for people new to system trading?
Any good books to read?
Have read Nick Radge's Unholy Grail and been looking for TechTrader's trading system without any luck.
Contemplating to join The Chartist but read somewhere that a decent trading system has to fit the trader's own personality.
Buying "off the shelf" system may or may not work for me.
Any advice much appreciated.
Thanks.:)
Iro

Hi Ironik,
Yes AFL and amibroker will make you strain ya brain while you are learning it (I'm all ways straining mine!) but its good for ya and it will definatly be worth it once you look back as a pro AFL programmer..
Amibroker is (I believe) the only or one of the very few programs around that will let you scan and backtest a whole universe of stocks as well as a single company.
As for Nick Radge his membership entitlles you to a lot of useful educational material not just his trading setups. You can trial his site or just join for a month or so at about $90 a month I think and gain loads of useful trading/charting info(if you need it).
Also once you get a trading strategy in place Nick or I'm sure there are any loads of other top quality AFL programers on this site that you can pay to code your strategy so all you have to do is push a button on amibroker once a day to get ya trades.
But if your like me you probably want to do it yourself(the hard way!) so let the journey begin..
Don't forget the AFL wizard that helps to convert your rules in plain English into afl code (haven't used it myself yet).
I found Howard's free book "introduction to amibroker" indispensable I keep re reading chapter 8 and still haven't got it all..:)

Cheers
 
Greetings --

Download the free pdf version of my "Introduction to AmiBroker" here:
http://www.introductiontoamibroker.com/book.html

Work through the exercises in Chapter 3 -- 30 Minutes to Useful Results.

Best,
Howard


Hi Howard,
Thanks for the link.

Is the following book a good start for people like me? Will newbies benefit from this book? I'm struggling to find materials regarding structured method to trading system design. I see that you have a few books on your website, but not sure which one would suit me at this early stage of my journey (as a newbie).

Quantiative Technical Analysis,
An Integrated Approach to Trading System Development and Trading Management
by Dr. Howard Bandy


The book discusses trading system development and trading management.

Thanks,
Iro
 
Hi Ironik,

As for Nick Radge his membership entitlles you to a lot of useful educational material not just his trading setups. You can trial his site or just join for a month or so at about $90 a month I think and gain loads of useful trading/charting info(if you need it).
Also once you get a trading strategy in place Nick or I'm sure there are any loads of other top quality AFL programers on this site that you can pay to code your strategy so all you have to do is push a button on amibroker once a day to get ya trades.
But if your like me you probably want to do it yourself(the hard way!) so let the journey begin..
Don't forget the AFL wizard that helps to convert your rules in plain English into afl code (haven't used it myself yet).
I found Howard's free book "introduction to amibroker" indispensable I keep re reading chapter 8 and still haven't got it all..:)

Cheers
Hi Amimad,
Thanks for the advice.
As you mentioned above, I would like to learn everything on my own but this approach involves a lot of head banging and frustration which might derail my plan and eventually give up learning altogether.
Yes, downloaded the " intro to amibroker" already and would go through it on the weekend.
The Chartist seems the way to go as Nick uses AB and I agree with his trading philosophy.
I looked into his ASX power set up and that's the one I'm most keen to learn. Might subscribe to this service soon.
Thanks again for your advice.

Iro
 
Hi Wysiwyg,
Finally found TechTrader trading system V4.5.
Will have a close look and try to make sense of this system.
Many thanks again.
All good advice taken on board.


Trash, you are correct regarding the in-built system. Have a lot of work to do as just got this software not too long ago. Many thanks for your advice.

Cheers,:)
Iro
 
Either save your exploration as project file (.apx extension) after setting Apply to: to Filter -> including your watchlist (side note, project files save all backtest and toolbar settings plus your entire AFL code)

or/and

In your exploration block you add InWatchlist( wlnum )

Ie.

Code:
wlnum = 0; // your watchlist number

if ( Status("actionex") == actionExplore and InWatchlist( wlnum ) )
{ 
  // your exploration code here

  Filter = ....
}

Hello Trash and everyone

My EOD exploration is preformed after the close of markets using norgate premium data EOD database.
This exploration has 3 columns, ticker, date/time and buyprice (as computed by AA exploration).
When I save these results to a watchlist only the tickers are saved not the date/time and buyprice column?
So I can "copy all" results to excel so I can save the file as a csv which will give me all 3 columns of data.

Next morning before market opens I open up AB and the working database is IB live database plugin (not EOD norgate database). I now need to either import the CSV file from last night(into IB live database) or I need to access this file somehow from afl RT scan formula.
Then my rt scan coding will be circa:

scan all tickers continuously that are in csv file( or last nights EOD exploration)
buy= current RT price or ask < buyprice(from CSV file or last nights Buyprice column in lastnights exploration)
stop buying when positions = posqty (in my case approx 5)

Referencing the csv tickers and their corresponding buyprice in the RT database is what I'm having trouble coding, the rest I should be right with for now.


Code:

wlnum = 0; // your watchlist number

if ( Status("actionex") == actionExplore and InWatchlist( wlnum ) )
{
// your exploration code here

Filter = ....
}


Trash this code still references wlnum in RT database not norgate eod database, even if exploration is saved as project with AA filter set for watchlist in Norgate eod database?

Hope I have explained my prob clear enough or that I haven't missed something really obvious in your reply Trash..:eek:
Only learning as I go..

Once again thanks in advance for any help from anyone much appreciated.
Cheers
 
You didn't say that you run two DBs.

You can save the BuyPrice of your scans to Persistent variables using i.e.

StaticvarSet( "NorgateDB_BuyPrice_" + Name(), Lastvalue( BuyPrice ), storage = True );

in the exploration code you use in your Norgate DB.

Then after closing AB and reopening on next day you can access them in IAB DB using mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + GetFnData( "Alias" ) );
In Alias field of symbol's Information window of IAB DB you enter the name of the Norgate DB's according symbol in case it is different from IAB symbology. If symbol names are the same ones then use mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + Name() );

As for running first exploration in Norgate DB only use example jscript to load that DB and execute project file there.

Code:
AB = new ActiveXObject( "Broker.Application" ); // creates AmiBroker object

AB.LoadDatabase( "C:\\Program Files\\NorgateDB\\" ); // insert path to norgate database

try 
{ 
    NewA = AB.AnalysisDocs.Open( "C:\\analysis1.apx" ); // opens previously saved analysis project file 
    // NewA represents the instance of New Analysis document/window 

    if ( NewA ) 
    { 
         NewA.Run( 1 ); // start exploration

         while ( NewA.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 

         //NewA.Export( "test.html" ); // export result list to HTML file

         WScript.echo( "Exploration Completed" ); 

         NewA.Close(); // close new Analysis 
     } 
} 
catch ( err ) 
{ 
     WScript.echo( "Exception: " + err.message ); // display error that may occur
}
 
Hi Howard,
Thanks for the link.

Is the following book a good start for people like me? Will newbies benefit from this book? I'm struggling to find materials regarding structured method to trading system design. I see that you have a few books on your website, but not sure which one would suit me at this early stage of my journey (as a newbie).

Quantiative Technical Analysis,
An Integrated Approach to Trading System Development and Trading Management
by Dr. Howard Bandy


The book discusses trading system development and trading management.

Thanks,
Iro
You are asking the restaurant owner whether the food is any good.

Shameless self promotion aside -- yes, this will be the best systems development book available by far.

Best regards,
Howard
 
Do you want to explain your statement? Astonish us with a shock revelation that you're actually Tomasz?

No, I'm not Tomasz. No I'm not Polish. No, I'm not a Martian.

Are you the troll/whiner of the season? What's your agenda? BTW the one and only aggression has been coming right from your direction the whole time.

Waiting for next issue...
 
You didn't say that you run two DBs.

You can save the BuyPrice of your scans to Persistent variables using i.e.

StaticvarSet( "NorgateDB_BuyPrice_" + Name(), Lastvalue( BuyPrice ), storage = True );

in the exploration code you use in your Norgate DB.

Then after closing AB and reopening on next day you can access them in IAB DB using mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + GetFnData( "Alias" ) );
In Alias field of symbol's Information window of IAB DB you enter the name of the Norgate DB's according symbol in case it is different from IAB symbology. If symbol names are the same ones then use mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + Name() );

As for running first exploration in Norgate DB only use example jscript to load that DB and execute project file there.

Code:
AB = new ActiveXObject( "Broker.Application" ); // creates AmiBroker object

AB.LoadDatabase( "C:\\Program Files\\NorgateDB\\" ); // insert path to norgate database

try 
{ 
    NewA = AB.AnalysisDocs.Open( "C:\\analysis1.apx" ); // opens previously saved analysis project file 
    // NewA represents the instance of New Analysis document/window 

    if ( NewA ) 
    { 
         NewA.Run( 1 ); // start exploration

         while ( NewA.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second 

         //NewA.Export( "test.html" ); // export result list to HTML file

         WScript.echo( "Exploration Completed" ); 

         NewA.Close(); // close new Analysis 
     } 
} 
catch ( err ) 
{ 
     WScript.echo( "Exception: " + err.message ); // display error that may occur
}


Hey Trash your the man!!:cool: (not trying to be gender specific...)
That coding has got me up and goin.
Lots more testing and polishing of code then on to paper trading account for a while..
Will keep on learning.
Thanks again I really value your help and I know your replies would take some time to compile.

Cheers:)
 
I just thought of a different method where values can be immediately read back in IAB DB while Norgate is still open (or closed).
That way uses the AmiBroker Osaka plugin (32-bit/64-bit).

The below AFL saves the buyprices during exploration or in chart pane (by opening param window and clicking button to export) in a binary file table (csv is possible too but not necessary).

u9xIdJRl.jpg
 
Cool thanks for that got the "staticvarset" system going so far so if I have hassles moving forward I will fall back to the osaka plugin.

Then after closing AB and reopening on next day you can access them in IAB DB using mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + GetFnData( "Alias" ) );
In Alias field of symbol's Information window of IAB DB you enter the name of the Norgate DB's according symbol in case it is different from IAB symbology. If symbol names are the same ones then use mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + Name() );


If you know of a way of scripting AB to check if my saved watchlist(tickers) from Norgate DB are the same of different to IB's symbols would be great. Sometimes I will have 100+ symbols to check in the watchlist.
Thanx mate.

Cheers
 
Cool thanks for that got the "staticvarset" system going so far so if I have hassles moving forward I will fall back to the osaka plugin.

Then after closing AB and reopening on next day you can access them in IAB DB using mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + GetFnData( "Alias" ) );
In Alias field of symbol's Information window of IAB DB you enter the name of the Norgate DB's according symbol in case it is different from IAB symbology. If symbol names are the same ones then use mybuyprice = StaticVarGet( "NorgateDB_BuyPrice_" + Name() );


If you know of a way of scripting AB to check if my saved watchlist(tickers) from Norgate DB are the same of different to IB's symbols would be great. Sometimes I will have 100+ symbols to check in the watchlist.
Thanx mate.

Cheers


Sorry typo error!
If you know of a way of scripting AB to check if my saved watchlist(tickers) from Norgate DB are the same OR different to IB's symbols would be great. Sometimes I will have 100+ symbols to check in the watchlist.
 
Take a look at CategoryGetSymbols() to get comma separated list of symbols of a category (i.e. in Norgate DB). Then you can save that one by whatever method and call it in IAB DB.

As for syncing watchlist IMO you don't need to compare but just erase old watchlist in IAB and add saved symbols to same WL to update it. But I don't know what else you wanna do so ...


Anyway to clean a watchlist ( i.e in IAB DB)

Code:
procedure EraseWatchlist( listnum )
{
    // retrieve comma-separated list of symbols in watch list
    list = CategoryGetSymbols( categoryWatchlist, listnum );
    
    //iterate through watchlist members and remove
    for ( i = 0; ( sym = StrExtract( list, i ) ) != ""; i++ )
    {
        CategoryRemoveSymbol( sym, categoryWatchlist, listnum );
    }
}

//sample use in Exploration
if ( Status( "stocknum" ) == 0 )
{
    EraseWatchlist( WL = 0 );
}

Filter = Status( "lastbarinrange" );
SetOption("RefreshWhenCompleted", True);

To add symbols (i.e. from saved watchlist member list of Norgate DB)

Code:
procedure AddToWatchlist( listnum, List )
{   
    //iterate through symbol list and add to WL
    for ( i = 0; ( sym = StrExtract( list, i ) ) != ""; i++ )
    {
        CategoryAddSymbol( sym, categoryWatchlist, listnum );
    }
}

List = ... your saved comma separated list of wl members of Norgate DB ...;

//sample use in Exploration
if ( Status( "stocknum" ) == 0 )
{
    AddToWatchlist( WL = 0, List );
}

Filter = Status( "lastbarinrange" );
SetOption("RefreshWhenCompleted", True);

Of course both codes can be combined to one execution in Exploration.
 
I just thought of a different method where values can be immediately read back in IAB DB while Norgate is still open (or closed). That way uses the AmiBroker Osaka plugin (32-bit/64-bit).

The below AFL saves the buyprices during exploration or in chart pane (by opening param window and clicking button to export) in a binary file table (csv is possible too but not necessary).

u9xIdJRl.jpg

A short follow up to that one:
As for the bold one ... you can open as many instances as you want so you can have multiple DBs being opened side by side. There is one thing to keep in mind though. Windows OLE is a Microsoft product and it only talks to the first instance of a program (in this case broker.exe of AB). So I assume that since Norgate uses OLE for importing data to update quotes then this means if you work with two or more DBs at the same time via multiple AB instances then in your case the first AB instance should have the Norgate DB being opened. So again this is just the case if one DB uses OLE code for import. If all DBs use streaming quotes via plugin then it doesn't matter which instance uses which database.
 
Take a look at CategoryGetSymbols() to get comma separated list of symbols of a category (i.e. in Norgate DB). Then you can save that one by whatever method and call it in IAB DB.

As for syncing watchlist IMO you don't need to compare but just erase old watchlist in IAB and add saved symbols to same WL to update it. But I don't know what else you wanna do so ...


Anyway to clean a watchlist ( i.e in IAB DB)

Code:
procedure EraseWatchlist( listnum )
{
    // retrieve comma-separated list of symbols in watch list
    list = CategoryGetSymbols( categoryWatchlist, listnum );
    
    //iterate through watchlist members and remove
    for ( i = 0; ( sym = StrExtract( list, i ) ) != ""; i++ )
    {
        CategoryRemoveSymbol( sym, categoryWatchlist, listnum );
    }
}

//sample use in Exploration
if ( Status( "stocknum" ) == 0 )
{
    EraseWatchlist( WL = 0 );
}

Filter = Status( "lastbarinrange" );
SetOption("RefreshWhenCompleted", True);

To add symbols (i.e. from saved watchlist member list of Norgate DB)

Code:
procedure AddToWatchlist( listnum, List )
{   
    //iterate through symbol list and add to WL
    for ( i = 0; ( sym = StrExtract( list, i ) ) != ""; i++ )
    {
        CategoryAddSymbol( sym, categoryWatchlist, listnum );
    }
}

List = ... your saved comma separated list of wl members of Norgate DB ...;

//sample use in Exploration
if ( Status( "stocknum" ) == 0 )
{
    AddToWatchlist( WL = 0, List );
}

Filter = Status( "lastbarinrange" );
SetOption("RefreshWhenCompleted", True);

Of course both codes can be combined to one execution in Exploration.


Hi Trash hope your doin well...

I haven't got the jscript going yet I am happy for now doing one exploration in norgate DB then the next one in IB DB. Let me know if this needs to be done now( is it effecting the coding I'm writing?).

I have noted IYO there is no need to sync watclist's. Thanks for that I will of course double check this whilst testing/ paper trading.

In the norgate explore I have saved the list of symbols to a watchlist in norgate DB using the code below( I did all this before your above reply).


if( LastValue( filter) )
// sends results to selected watchlist # listnum
{
CategoryAddSymbol( "", categoryWatchlist, listnum );
}



this saves the .tls file to " C:\premium data alpha test\WatchLists" on my hard drive.

Had this coding at start of both explorations to erase watchlist's so got the empty watcklists sorted..

function EraseWatchlist( listnum )
{
// retrive comma-separated list of symbols in watch list
list = CategoryGetSymbols( categoryWatchlist, listnum );
//iterate through watchlist members and remove
for( i = 0; ( sym = StrExtract( list, i ) ) != ""; i++ )
{
CategoryRemoveSymbol( sym, categoryWatchlist, Listnum );
}
}
//erase watchlist
if( Status("stocknum") == 0 )//if ordinal number(stocknum) of currently analysed symbol equals 0 (at the start) then wipe watchlist
EraseWatchlist( listnum ); //executes the function above called"erasewatchlist"



So now I'm up to retrieving the the symbol list from norgate DB stored in " C:\premium data alpha test\WatchLists" on my hard drive.

With your generously supplied coding below do I need to point out the path to the watchlist or am I getting off track?


procedure AddToWatchlist( listnum, List )
{
//iterate through symbol list and add to WL
for ( i = 0; ( sym = StrExtract( list, i ) ) != ""; i++ )
{
CategoryAddSymbol( sym, categoryWatchlist, listnum );
}
}

List = ... your saved comma separated list of wl members of Norgate DB ...;// do I need to point the path to the norgate DB watchlist because "list" isn't a persistent var?

//sample use in Exploration
if ( Status( "stocknum" ) == 0 )
{
AddToWatchlist( WL = 0, List );
}

Filter = Status( "lastbarinrange" );
SetOption("RefreshWhenCompleted", True);


Yet again thanks for your time mate..:)

Cheers
 
I'm back with another question.

I've been testing a system based on Nick Radge's Weekend Trend Trader. I'm OK with the basic code and have run some back-testing so I can see that the code is working.

One thing I can see is that there are times where the maximum positions (20 stocks) are all used. This means that no new positions can be taken until I exit some positions. Currently the only way I'm exiting is if the stop loss is exceeded which is triggered by either a 40% or 10% decline depending on the direction of the index.

What I'd like to look at is the option of selling positions when I've hit my max position size so I can free up capital to take up new positions. From looking at some charts I can see that some stocks have a good run that then flattens out. The stop loss condition isn't met so there's no sale, but the stock isn't increasing at the rate it once was. However, a new stock comes up on the radar that (potentially) could have better growth over the short term. I'd prefer to purchase this new stock and sell the existing, slower-moving one.

However, if there's no new 'buy' signals for the week, keep holding all the stocks. I'll assume that even a slow growth rate could be better than a cash return.

I know I can do this manually, but I want it as part of the system so I can back test it and see if it makes any difference.

So what I'm trying to understand, is how do I code the following:
  • If maximum positions are taken up AND there's a new 'buy'
  • Find the stock that the portfolio is currently holding that has the lowest Rate Of Change over the past 30 days.
  • Sell that stock
  • Use the sale proceeds to purchase the new 'buy'.

Hopefully this isn't a silly question and there's a way to do it.

Thanks in advance for your help.
 
I'm back with another question.

I've been testing a system based on Nick Radge's Weekend Trend Trader. I'm OK with the basic code and have run some back-testing so I can see that the code is working.

One thing I can see is that there are times where the maximum positions (20 stocks) are all used. This means that no new positions can be taken until I exit some positions. Currently the only way I'm exiting is if the stop loss is exceeded which is triggered by either a 40% or 10% decline depending on the direction of the index.

What I'd like to look at is the option of selling positions when I've hit my max position size so I can free up capital to take up new positions. From looking at some charts I can see that some stocks have a good run that then flattens out. The stop loss condition isn't met so there's no sale, but the stock isn't increasing at the rate it once was. However, a new stock comes up on the radar that (potentially) could have better growth over the short term. I'd prefer to purchase this new stock and sell the existing, slower-moving one.

However, if there's no new 'buy' signals for the week, keep holding all the stocks. I'll assume that even a slow growth rate could be better than a cash return.

I know I can do this manually, but I want it as part of the system so I can back test it and see if it makes any difference.

So what I'm trying to understand, is how do I code the following:
  • If maximum positions are taken up AND there's a new 'buy'
  • Find the stock that the portfolio is currently holding that has the lowest Rate Of Change over the past 30 days.
  • Sell that stock
  • Use the sale proceeds to purchase the new 'buy'.

Hopefully this isn't a silly question and there's a way to do it.

Thanks in advance for your help.

Hi Allan,
Not sure if you know about "positionscore" but you can set criteria for how backtester ranks its buy signals seeing as you have a "posqty=20".

Your sell coding maybe something like:
sell= if (posqty=20) then (your original rules) or ( lowest ROC over 30 days)
else your original sell rules
AB coding will be different still learning it if you don't get more expert help I'll take a look see what I can confuse the issue more with!!

What you want I reckon will be able to be done, AB never ceases to amaze me what it can do it is so versatile with it's coding but it take time to write it(for me at least) !!

Cheers
 
I'm back with another question.

I've been testing a system based on Nick Radge's Weekend Trend Trader. I'm OK with the basic code and have run some back-testing so I can see that the code is working.

One thing I can see is that there are times where the maximum positions (20 stocks) are all used. This means that no new positions can be taken until I exit some positions. Currently the only way I'm exiting is if the stop loss is exceeded which is triggered by either a 40% or 10% decline depending on the direction of the index.

What I'd like to look at is the option of selling positions when I've hit my max position size so I can free up capital to take up new positions. From looking at some charts I can see that some stocks have a good run that then flattens out. The stop loss condition isn't met so there's no sale, but the stock isn't increasing at the rate it once was. However, a new stock comes up on the radar that (potentially) could have better growth over the short term. I'd prefer to purchase this new stock and sell the existing, slower-moving one.

However, if there's no new 'buy' signals for the week, keep holding all the stocks. I'll assume that even a slow growth rate could be better than a cash return.

I know I can do this manually, but I want it as part of the system so I can back test it and see if it makes any difference.

So what I'm trying to understand, is how do I code the following:
  • If maximum positions are taken up AND there's a new 'buy'
  • Find the stock that the portfolio is currently holding that has the lowest Rate Of Change over the past 30 days.
  • Sell that stock
  • Use the sale proceeds to purchase the new 'buy'.

Hopefully this isn't a silly question and there's a way to do it.

Thanks in advance for your help.

Allan you could maybe look at the linear regression of slope function in AB instead of ROC?

LinRegSlope
- linear regression slope Statistical functions
(AFL 1.4)


SYNTAX LinRegSlope( ARRAY, periods )
RETURNS ARRAY
FUNCTION Calculates linear regression line slope from the ARRAY using periods range. The function accepts periods parameter that can be constant as well as time-variant (array).
EXAMPLE x = Cum(1);
lastx = LastValue( x ); Daysback = 10; aa = LastValue( LinRegIntercept( Close, Daysback) );
bb = LastValue( LinRegSlope( Close, Daysback ) );

y = Aa + bb * ( x - (Lastx - DaysBack) ); Plot( Close, "Close", colorBlack, styleCandle );
Plot( IIf( x >= (lastx - Daysback), y, -1e10 ), "LinReg", colorRed );



Cheers
 
Top