Australian (ASX) Stock Market Forum

Amibroker FAQ

Okay I have modified my code using the XAO as the filter code.

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

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

SetBacktestMode( backtestRotational );

// offsetting by large positive number 
// makes sure that our score is always positive and we don't enter short trades

SetForeign("XAO");
Filter = Cross( EMA(C,180), EMA(C,50));
RestorePriceArrays();

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

The results are not as I have expected.

It has made a correct entry point [when condition TRUE on Filter = Cross( EMA(C,180), EMA(C,50));]

but closes the position unexpectedly [no negative crossover FALSE on Filter = Cross( EMA(C,180), EMA(C,50));] a few days later,

then makes a new entry a month or so later - at a time when no positive cross [TRUE] has occurred and then closes again without a negative crossover.

Hopefully what I have explained is somewhat clear.


Your Filter is wrong

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

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

SetBacktestMode( backtestRotational );


SetForeign( "XAO" );
Filter =  EMA( C, 50 ) > EMA( C, 180 );
RestorePriceArrays();

// 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();
}
 
Hi all I'm back from a holiday down the Goldie and am back into it.

Sometimes my EOD exploration returns over 100 results( today I have 330 odd).
My IBlive database can only track 100 symbols(god bless TWS!)
So I'm gunna muck round with position score to get my optimum results first but I need to cap the explore results to 100.
I have buggered round trying this looping to only get the first 100 results from one watchlist and save em in another.

My code.

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


mysymbols = CategoryGetSymbols( categoryWatchlist, listnumallsymb );//retrieve comma seperated list of symbols from watchlist //listnumallsymb(currently WL 973) of norgateDB


numofsymbols=0; //references numofsymbols to 0 and declares "numofsymbols as a global Variable

function AddToWatchlist( WLnumcappedsymb,mysymbols )// this section is supposed to add the first
//100 symbols from WL number "listnumallsymb" to watchlist "WLnumcappedsymb"
{
//iterate through WL number "listnumallsymb" and add to WL number "WLnumcappedsymb"
for ( numofsymbols = 0; numofsymbols < 100; numofsymbols++ )
{
sym = StrExtract( mysymbols,numofsymbols);
CategoryAddSymbol( sym, categoryWatchlist, WLnumcappedsymb );
}
}


if( Status("stocknum") == 0 )// trying to get the function "addtowatchlist" to be called only after exploration has finished analyizing all symbols
//if ( Status( "actionex" ) == 4 )//// trying to get the function "addtowatchlist" to be called only after all exploration has finished analyizing all //symbols
{
AddToWatchlist(WL= WLnumcappedsymb,mysymbols );// this calls the function "addtowatchlist"
}


My method seems a bit clunky (and doesn't work!) so hoping someone (trash... :)) might have a better way.
PS Also stuffed round with ADDRANKCOLUMN() but couldn't find(at this stage) a built in AB function or variable to count number of stocks that have passed the filter.

Hope all is well for you all.
cheers
 
A heads up for anyone who hasn't checked out the AB Knowledge Base recently; TJ has been adding new articles almost daily for the last couple of months so it's worth a visit.

http://www.amibroker.com/kb/

There's an RSS feed link in the right hand corner near the top (under the "Links" heading). I use live bookmarks in Firefox for RSS feeds but most email clients like Thunderbird can subscribe to RSS links and there's also dedicated RSS feed reader software as well.
 
Thanks for the heads up Captain Black. I am always on the look out for Amibroker tips. Some good articles there.

Regards,

Tradezy
 
Thanks for the heads up Captain Black. I am always on the look out for Amibroker tips. Some good articles there.

Regards,

Tradezy

No probs, glad you've found some helpful tips. :)

I've been using Amibroker for over 10 years and learned a couple of new things from TJ's articles so thought it would be worthwhile posting here about the updates to the KB.
 
Hi Captain Black,

Wow 10 Years - I'm impressed!!!:xyxthumbs I've just started using Amibroker in the last couple of months.

I've got my head around writing formulas in arrays. I still pretty green but I can run backtests, scans, explorations, optimizations.

My next step is to understand looping code e.g. for loop, while loop, if then else loop.

My main issue is my lack of understanding of how the looping language is written. Eg. if I see for (i = 0; i < BarCount: i++) - it looks like goobleygoop!

The KB & manual are great. However I can see my lack of knowledge with the looping code is now holding me back understanding the material out there.

Do you have any suggestions as to where I can learn the real basics of this language? Something like "Looping for Dummies" would be great! I guess it is like learning the alphabet before being able to spell.

With thanks again,

Tradezy
 
Do you have any suggestions as to where I can learn the real basics of this language? Something like "Looping for Dummies" would be great! I guess it is like learning the alphabet before being able to spell.

There's a good guide here (click on the PDF link in the first post):

https://www.aussiestockforums.com/forums/showthread.php?t=7206

(Not sure if GP is still around but if you are then many thanks for taking the time to write that guide and for sharing it :) )
 
Hi Captain Black,

Thanks for your help again.

I've seen this document from Great Pig before. I agree, full marks to GP for all of the time & effort in putting it together.

However unfortunately in my previous viewings it has mostly gone over my head. But, I know perserverance is the key whilst learning Amibroker! So I will review it again and hopefully my knowledge has improved a little to understand it.

With thanks,

Tradezy
 
Hi Tradezy --

There are examples in my "Introduction to AmiBroker" book. You can download a free copy from the book's website:
http://www.introductiontoamibroker.com/

Best regards,
Howard

Hi Howard,

Thankyou for you response and the link to you Amibroker book. It is a great manual & it is very generous/ good natured of you to have it available. For any new Amibroker users it is like finding gold! Thank you!!

I know I just have to get my head around the looping basics and I will be right.... I just need to buy a bit of time to do this!

Thanks again,

Tradezy
 
Your Filter is wrong

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

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

SetBacktestMode( backtestRotational );


SetForeign( "XAO" );
Filter =  EMA( C, 50 ) > EMA( C, 180 );
RestorePriceArrays();


// 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();
}

I am trying to add a volume filter into the above code by adding the following code:

Code:
// This is the original filter I have been using
SetForeign( "XAO" );
Filter =  EMA( C, 50 ) > EMA( C, 180 );
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 = MAVol >100000;

RestorePriceArrays();

The result of adding the volume code as above seems to eliminate the EMA cross filter..

If someone could assist me in adding a volume filter that will be very much appreciated.
 
I am trying to add a volume filter into the above code by adding the following code:

Code:
// This is the original filter I have been using
SetForeign( "XAO" );
Filter =  EMA( C, 50 ) > EMA( C, 180 );
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 = MAVol >100000;

RestorePriceArrays();

The result of adding the volume code as above seems to eliminate the EMA cross filter..

If someone could assist me in adding a volume filter that will be very much appreciated.

Code:
// This is the original filter I have been using
SetForeign( "XAO" );
Filter =  EMA( C, 50 ) > EMA( C, 180 );
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 = Filter AND MAVol > 100000;

or

Code:
// This is the original filter I have been using
SetForeign( "XAO" );
Filter1 =  EMA( C, 50 ) > EMA( C, 180 );
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 > 100000;

or

.
.
.
.
 
how can i send from amibroker limit order to IB that have time limit to fill , for example i send buy limit order to IB in 19:01 if in 19:06 the order not fill the order will cancel .
ParentID= ibc.PlaceOrder(Ticker , "BUY", QTY_For_Buy, "LMT", ENTRY_PRICE_LONG, 0, "GTC", False, TICK_SIZE);
How do i change the "GTC"
tnx guys
 
What's the difference between a 'scan' and and 'exploration' in Amibroker?

I've been testing some code and if I use the 'explore' option it gives me a buy signal for today. But if I enlarge the time period (say to one year) it still only gives me the one buy for today.

If I use the 'scan' option for the same code, I get more trading signals, but there's a problem with when the signals arrive. I'm basing the scan on weekly values at the close every Friday. I want to be able to find the trades over the weekend and then enter or exit them on the next Monday. When I use the 'scan' option, I seem to be getting the signals, but a week late.

So, would you write the code differently for a scan as opposed to an 'exploration'? And when would you use a scan instead of an exploration?

So much to learn!!!:)
 
Hi Allan --

I think of Explore as a development tool, Scan as a trading tool.

For example, if I want to learn the relationship between some indicator or pattern and the price change one or two bars ahead, I write an afl statement that computes each of those, put each in a column using AddColumn, set a data range, and click Explore. From there I can sort in place or export to a disc file where a spreadsheet or analysis program can read the data for further analysis.

If I have a system already written and I want to see recent signals, I write the signal statement that compute Buy or Sell in afl, and click Scan. Scan's job is to examine each of the issues in the "Apply To" list and report all Buy or Sell signals within the date range specified.

Scan can be thought of as a subset of Explore. By setting the "filter" used to screen which statements will be reported by the Explore function, Explore can be set up to perform like Scan.

Best regards,
Howard
 
It's pretty simple. There is only one difference between explore and scan .. Explore can do the same as Scan but Scan can not do the same as Explore. In short Explore is advanced Scan. That's all. Personally I use Scan very seldom.

Hi Allan --

I think of Explore as a development tool, Scan as a trading tool.

It's rather Explore a development and trading tool, Scan just a trading tool.
 
Hi All,

I want to backtest Long and Short strats independently (on the same symbol), but want to use the "Long and Short" option in the backtester. IOW, instead of testing Long-only and Short-only, I want the backtester to combine each as if they were run separately. I hope this is clear.

TIA,
RutheezKey

p.s. I have read tons of documentation, but they only seem to address when using different symbols.
 
Hi All,

I want to backtest Long and Short strats independently (on the same symbol), but want to use the "Long and Short" option in the backtester. IOW, instead of testing Long-only and Short-only, I want the backtester to combine each as if they were run separately. I hope this is clear.

TIA,
RutheezKey

p.s. I have read tons of documentation, but they only seem to address when using different symbols.

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.
}
 
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:

Creating two clones

Code:
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;
}
 
Top