Australian (ASX) Stock Market Forum

Amibroker FAQ

Thank You.

Just a quick question is there such thing as an Intraday Buy and Sell signal Formula ?.

There multiple code examples in the AB help file, in the users library, in this thread, in other threads on different websites etc. And as CanOz has already posted there is a Introduction book by H Bandy with simple examples.
 
Hi All,

I am looking to learn AFL and I am wondering whats the best way to get started is there any online tutorials on using AFL ?.

I am looking to create a easy Formula for scanning Buy and Sell signals, can you anyone tell me a buy & sell formula explaining what triggers it for a buy and sell ?.

Sorry for such a novice question.

Thanks in advance

Use the code wizard which is included with the software for starters, and you'll see how English commands get translated to AFL. Analysis -> AFL code wizard.
 
There multiple code examples in the AB help file, in the users library, in this thread, in other threads on different websites etc. And as CanOz has already posted there is a Introduction book by H Bandy with simple examples.

I am the author of "Introduction to AmiBroker." The book is free for personal use. It is downloadable in pdf format.
http://www.introductiontoamibroker.com/

The link to the download is on the /book page.

Best regards,
Howard
 
Position size method?

Code:
SetOption("UseCustomBacktestProc", True );

if( Status("action") == actionPortfolio )
{
    // retrieve the interface to portfolio backtester
    bo = GetBacktesterObject();   
    bo.PreProcess();

    for( bar = 0; bar < BarCount; bar++ )
    {
         // this for loop iterates through all trade signals and adjust pos size
         for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) )
         {
            // if long then $ value else if short then percent of equity
             sig.PosSize = IIf( sig.IsLong(), 1000/*position value - $*/, -20/*position value - percent of equity*/ );  
         }

         bo.ProcessTradeSignals( bar );
     }

    bo.PostProcess();
}

CCI0  = CCI(20);

Buy   = Cross( CCI0, 100 ); 
Sell  = Cross( 100, CCI0 ); 
Short = Cross( -100, CCI0 );
Cover = Cross( CCI0, -100 );
BuyPrice = SellPrice = ShortPrice = CoverPrice = O;

SetTradeDelays( 1, 1, 1, 1 );
SetOption("MaxOpenPositions", 1 );
SetOption("InitialEquity", 100000 );
SetOption("FuturesMode", False );
SetOption("UsePrevBarEquityForPosSizing", True);
 
Position size method?

Code:
SetOption("UseCustomBacktestProc", True );

if( Status("action") == actionPortfolio )
{
    // retrieve the interface to portfolio backtester
    bo = GetBacktesterObject();   
    bo.PreProcess();

    for( bar = 0; bar < BarCount; bar++ )
    {
         // this for loop iterates through all trade signals and adjust pos size
         for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) )
         {
            // if long then $ value else if short then percent of equity
             sig.PosSize = IIf( sig.IsLong(), 1000/*position value - $*/, -20/*position value - percent of equity*/ );  
         }

         bo.ProcessTradeSignals( bar );
     }

    bo.PostProcess();
}

CCI0  = CCI(20);

Buy   = Cross( CCI0, 100 ); 
Sell  = Cross( 100, CCI0 ); 
Short = Cross( -100, CCI0 );
Cover = Cross( CCI0, -100 );
BuyPrice = SellPrice = ShortPrice = CoverPrice = O;

SetTradeDelays( 1, 1, 1, 1 );
SetOption("MaxOpenPositions", 1 );
SetOption("InitialEquity", 100000 );
SetOption("FuturesMode", False );
SetOption("UsePrevBarEquityForPosSizing", True);

sig is default key word? No need to declare?

If I just want to like...whenever buy then just 20% of all cash, but whenever sell 100%, how to do that?
 
sig is default key word? No need to declare?

you can use sig, siggy, crunchor, whatever

Code:
SetOption("UseCustomBacktestProc", True );

if( Status("action") == actionPortfolio )
{
    // retrieve the interface to portfolio backtester
    bo = GetBacktesterObject();   
    bo.PreProcess();

    for( bar = 0; bar < BarCount; bar++ )
    {
         // this for loop iterates through all trade signals and adjust pos size
         for( crunchor = bo.GetFirstSignal( bar ); crunchor; crunchor = bo.GetNextSignal( bar ) )
         {           
            crunchor.PosSize = IIf( crunchor.IsLong(), 1000/*position value - $*/, -20/*position value - percent of equity*/ );  
         }

         bo.ProcessTradeSignals( bar );
     }

    bo.PostProcess();
}

If I just want to like...whenever buy then just 20% of all cash, but whenever sell 100%, how to do that?

Just look at the sample above and adapt.

Code:
crunchor.PosSize = IIf( crunchor.IsLong(), -20/*position value - percent of equity*/, -100/*position value - percent of equity*/ );

float PosSize

requested position size (positive numbers mean dollar value, negative values mean percent of portfolio equity)

I think you should carefully read the manual www.amibroker.com/guide/a_custombacktest.html‎ or users' knowledge base http://www.amibroker.org/userkb/2008/03/16/amibroker-custom-backtester-interface-2/
 
@Richard888,

edited Rel. Performance chart

Move symbols to be charted to a watchlist and choose the watchlist in parameter options.
Also added Fullname or Name option and alignment option. If there is a bug let me know.

2013_07_07_120148.png

Code:
// original by Tomasz Janeczko, edited by trash 2012

wlnum      = Param( "Choose Watchlist Number containing your Symbols", 0, 0, 65, 1 );
N_FN       = ParamToggle( "Show Name or Fullname in Title", "Name|FullName", 0 );
alignmode  = ParamToggle( "Symbol Alignment in Title", "One Row|Multiple Rows", 0 );

if ( N_FN )
    Name_  = FullName();
else 
    Name_  = Name();

if ( alignmode )
    align  = "\n";
else
    align  = "";    

SetChartOptions( 0, chartShowArrows | chartShowDates | chartWrapTitle );

_N( TickerList = CategoryGetSymbols( categoryWatchlist, wlnum ) );

NumBars = 20;
fvb     = Status( "firstvisiblebar" );

Plot( 100 * ( C - C[ fvb ] ) / C[ fvb ], Name_, colorBlue );

for ( i = 0; ( symbol = StrExtract( TickerList, i ) ) != ""; i++ )
{
    SetForeign( symbol );
    fc = Close;

    if ( N_FN )
        symbol = FullName();    

    if ( ! IsNull( fc[ 0 ] ) )
    {
        Plot( 100 * ( fc - fc[ fvb ] ) / fc[ fvb ], align + symbol, colorLightOrange + ( ( 2 * i ) % 15 ), styleLine );
    }
    RestorePriceArrays();
}

PlotGrid( 0, colorYellow );
_N( Title = Name_ + " - Relative Performance [%]: \n{{VALUES}}" );
 
@Richard888,

edited Rel. Performance chart

Move symbols to be charted to a watchlist and choose the watchlist in parameter options.
Also added Fullname or Name option and alignment option. If there is a bug let me know.

2013_07_07_120148.png

Code:
// original by Tomasz Janeczko, edited by trash 2012

wlnum      = Param( "Choose Watchlist Number containing your Symbols", 0, 0, 65, 1 );
N_FN       = ParamToggle( "Show Name or Fullname in Title", "Name|FullName", 0 );
alignmode  = ParamToggle( "Symbol Alignment in Title", "One Row|Multiple Rows", 0 );

if ( N_FN )
    Name_  = FullName();
else 
    Name_  = Name();

if ( alignmode )
    align  = "\n";
else
    align  = "";    

SetChartOptions( 0, chartShowArrows | chartShowDates | chartWrapTitle );

_N( TickerList = CategoryGetSymbols( categoryWatchlist, wlnum ) );

NumBars = 20;
fvb     = Status( "firstvisiblebar" );

Plot( 100 * ( C - C[ fvb ] ) / C[ fvb ], Name_, colorBlue );

for ( i = 0; ( symbol = StrExtract( TickerList, i ) ) != ""; i++ )
{
    SetForeign( symbol );
    fc = Close;

    if ( N_FN )
        symbol = FullName();    

    if ( ! IsNull( fc[ 0 ] ) )
    {
        Plot( 100 * ( fc - fc[ fvb ] ) / fc[ fvb ], align + symbol, colorLightOrange + ( ( 2 * i ) % 15 ), styleLine );
    }
    RestorePriceArrays();
}

PlotGrid( 0, colorYellow );
_N( Title = Name_ + " - Relative Performance [%]: \n{{VALUES}}" );

Minor adjustment:

Replace line
if ( ! IsNull( fc[ 0 ] ) )
with
if ( ! IsNull( fc[ 0 ] ) && symbol != Name_ )
to avoid repeated symbol plotting
 
How to change this AFL codes to
Sell =(SAR() > C) + "only sell if the price is higher than the bought price"?

Here is the code:

Buy = SAR() < C;
Sell =SAR() > C;
BuyPrice = SAR() + 0.01;
SellPrice = SAR() - 0.01;
SetPositionSize( 100, spsPercentOfEquity );
 
How to change this AFL codes to
Sell =(SAR() > C) + "only sell if the price is higher than the bought price"?

You will need a stop somewhere. What happens if you buy and the price drops and keeps dropping?

But you could say: Sell = Sellprice>Buyprice;
 
You will need a stop somewhere. What happens if you buy and the price drops and keeps dropping?

But you could say: Sell = Sellprice>Buyprice;

I tried this before but it doesn't work. My codes above would always have either buy or sell signal. Let's say bar 1 is a buy signal, then 100% buy in, then coming bar 2, bar 3, bar 4 all are raising and there are buy signal for these bars too. Then in bar 5, there is sell signal, but then the buyprice would be the bar 4 buyprice instead of my real buy price in bar 1.

I know there should be stop, I just try to do backtest to see what would happen.
 
I tried this before but it doesn't work. My codes above would always have either buy or sell signal. Let's say bar 1 is a buy signal, then 100% buy in, then coming bar 2, bar 3, bar 4 all are raising and there are buy signal for these bars too. Then in bar 5, there is sell signal, but then the buyprice would be the bar 4 buyprice instead of my real buy price in bar 1.

I know there should be stop, I just try to do backtest to see what would happen.

This should work

SetPositionSize( 100, spsPercentOfEquity );
SetBacktestMode( backtestRegular ); //signal-based backtest, redundant signals are removed

BuyPrice = SAR() + 0.01;
SellPrice = SAR() - 0.01;
Buy = Buyprice>=l and Buyprice<=h and cross(C,SAR());
Sell =Sellprice>=l and Sellprice<=h and cross(SAR(), C);
buy = ExRem( buy, sell );
sell = ExRem( sell, buy );
 
This should work

SetPositionSize( 100, spsPercentOfEquity );
SetBacktestMode( backtestRegular ); //signal-based backtest, redundant signals are removed

BuyPrice = SAR() + 0.01;
SellPrice = SAR() - 0.01;
Buy = Buyprice>=l and Buyprice<=h and cross(C,SAR());
Sell =Sellprice>=l and Sellprice<=h and cross(SAR(), C);
buy = ExRem( buy, sell );
sell = ExRem( sell, buy );

thx and I will try this once I get back to home. By the way I found out that the default SAR in Amibroker may has bug. I set the SAR to SAR(0.1,1) and apply to index history with around 10000 - 25000 range normally, and there are always having the exact same SAR in the day right after the SAR switch. That is after switching SAR, let's say becoming a raise one, day 1 and day 2 have the same SAR value. I compare the same data to another program SAR with the same data would not have this problem.

Another issue is the default SAR can only set to maximum 1 but nothing more than 1 in SAR(0.1,1) case, like I cannot set to SAR(0.1,2).
 
How to change this AFL codes to
Sell =(SAR() > C) + "only sell if the price is higher than the bought price"?

Has already been discussed here.

One of million ways:

Code:
SetPositionSize( 10, spsPercentOfEquity );

acc  = 0.02;
accm = 0.2;
sarc = SAR( acc, accm );

Buy   = Sell = 0;
Short = Cover = 0;
YourBuyConditions = SARc < C;
YourSellConditions = SARc > C;

priceatbuy = Null;
patba = Null; // Price At Buy Array (for plotting only)

for( i = 0; i < BarCount; i++ )//
{
  SellSignal = YourSellConditions[ i ] AND Close[ i ] > priceatbuy;

  if( SellSignal AND NOT IsNull( priceatbuy ) )
  {
    Sell[ i ] = 1;
    priceatbuy = Null;
  }

  BuySignal = YourBuyConditions[ i ];

  if( IsNull( priceatbuy ) AND BuySignal )
  {
    Buy[ i ] = 1;
    priceatbuy = BuyPrice[ i ];
  }

  patba[ i ] = priceatbuy; // to plot you need an ARRAY, not scalar
} 

Plot(patba, "priceatbuy", colorGreen, styleLine );
Plot( SARc, _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style", styleDots | styleNoLine, maskDefault | styleDots | styleNoLine ) );

I set the SAR to SAR(0.1,1) and apply to index history with around 10000 - 25000 range normally, and there are always having the exact same SAR in the day right after the SAR switch. That is after switching SAR, let's say becoming a raise one, day 1 and day 2 have the same SAR value. I compare the same data to another program SAR with the same data would not have this problem.

Another issue is the default SAR can only set to maximum 1 but nothing more than 1 in SAR(0.1,1) case, like I cannot set to SAR(0.1,2).

What do you mean? Show an example.
 
Hi,

I can't seem to solve this problem, after days of struggling (I'm new to AFL though):

I'm trying to get the highest close since beginning of the trade, Debug view values for highest since buy occasionally shoot up by a huge factor. E.g should be $4.50 and goes up to $800.

Debugview values for close stay correct, but highest close value jumps up by a large factor.

I've included the code below, if any other data would help, let me know.

Huge thanks for any help, very much appreciated.

P.s does anyone have a idea why my posts to the amibroker yahoo forum wouldn't be going thought? Does it take a while for moderator approval?


Code:
///////////////// Custom Backtester/////////////////////
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio)
{			
	bo = GetBacktesterObject(); // Get backtester object
	bo.PreProcess(); 
	dates = DateTime(); 
	bi = BarIndex();
	MaxLoss = 0;
	HC = 0;

	for (i = 0; i < BarCount; i++) 
	{
		for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i))
		{ 
			if (sig.IsEntry() && sig.IsLong()) 
			bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
		}
		for (trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos())
		{
			P = trade.GetPrice(i, "C");// Close at i
[B][COLOR="#FF0000"]			HC = Max(P, HC); ////// Highest close - PROBLEM HERE?????????????
[/COLOR][/B]			Ni = StaticVarGet("MyAtr"+trade.Symbol);// Atr(20) array
			entryBar = LastValue(ValueWhen(trade.EntryDateTime == dates, bi));
			EC = trade.GetPrice(entrybar, "C");// Close[entrybar]
			EN = Ni[entrybar];// Atr(20) at trade entry 
			_TRACE(" " + trade.symbol + ", entrybar = " + entrybar + ", date = " + DateTimeToStr(Dates[i]) + ", HC = " + HC + ", P = " + P+ ", N[eb]"+ Ni[entrybar] + ", EC = " 
			+ EC + ", i = " + i);

			if (HC < EC + EN)
				MaxLoss = EC - 2*EN;
			if (HC >= EC + EN)
				MaxLoss = EC - EN;
			if (HC >= EC + 2*EN)		
				MaxLoss = EC;
			if (HC >= EC + 3*EN)
				MaxLoss = EC + EN;
			if (HC >= EC + 4*EN)
				MaxLoss = EC + 2*EN;
 			if(P < MaxLoss)
			{
				bo.ExitTrade(i, trade.symbol, trade.GetPrice(i, "C"), 1);
				MaxLoss = 0;
				Ni = 0;
				EntryBar = 0;
				HC = 0;
				EC = 0;
				NE = 0;
			}
		} 
		bo.HandleStops(i); // Handle programmed stops at this bar
		bo.UpdateStats(i, 1); // Update MAE/MFE stats for bar
		bo.UpdateStats(i, 2); // Update stats at bar's end
	}

	bo.PostProcess(); 
}
 
User-definable functions -- precise usage

Hi,
first-time post, so thanks in advance for any assistance.



From the Amibroker guide:

'User-definable functions allow to encapsulate user code into easy-to-use modules that can be user in many places without need to copy the same code over and over again.'

The example given is:

-------------------------------------
function IIR2( input, f0, f1, f2 )
{
result[ 0 ] = input[ 0 ];
result[ 1 ] = input[ 1 ];

for( i = 2; i < BarCount; i++ )
{
result[ i ] = f0 * input[ i ] +
f1 * result[ i - 1 ] +
f2 * result[ i - 2 ];
}

return result;
}

Plot( Close, "Price", colorBlack, styleCandle );
Plot( IIR2( Close, 0.2, 1.4, -0.6 ), "function example", colorRed );
-------------------------------------

I would understand the usage of a function would be to save the function once and thereafter call it in any subsequent code -- as suggested in the quote above from the user guide.

So, having saved the above function as IIR2.afl, I would expect to be able to call it within another AFL with the single line:
IIR2( Close, 0.2, 1.4, -0.6 )
-- maybe assigning that value to a variable, or a plot as in the example above.

But I can only get the above example to work if I have the whole function as inline code directly above the call. Clearly this is not the intention. What am I doing wrong? How/where do I save the function so that it is found by a call in another piece of code?
 
Top