Position Ranking in Amibroker: AFL Code Included

Let’s say you have a super successful trading system which works on almost all the stocks. Also, you do have a AFL code for the same which signals you buy sell opportunities real-time. What’s next? Probably you would think of getting live with this system and start making money. And that’s the correct thing to do. However, what if your system signals trading opportunities for multiple stocks simultaneously. Obviously, you cannot trade on all of them as your capital is limited. Position ranking is the method to overcome this dilemma. Position ranking in Amibroker uses a special variable called PositionScore to rank the multiple simultaneous trading signals. The rank is based on a predefined logic which can be coded in AFL. Higher the rank, better is the signal. For example: if your max allowed positions at a time is 5, then the symbols with top 5 Position scores would be selected for trade.

Check out our Amibroker tutorial series here.

Position Ranking in Amibroker: AFL Illustration

Below is the simple AFL for moving average crossover system which ranks the positions based on ADX value. Higher the ADX value, higher is the possibility of ongoing trend which can result in a profitable trade. Amibroker uses PositionScore variable to decide which trades should be entered if there are more entry signals on different securities than maximum allowable number of open positions or available funds.

//------------------------------------------------------
//
//  Formula Name:    Position Ranking
//  Author/Uploader: Trading Tuitions
//  E-mail:          support@tradingtuitions.com
//  Website:         www.tradingtuitions.com
//------------------------------------------------------

SetBarsRequired( sbrAll );
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C ));

//Initial Parameters
SetTradeDelays( 1,1,1, 1 );
SetOption( "InitialEquity", 100000);
SetOption("FuturesMode" ,True);
SetOption("MinShares",1);
SetOption("CommissionMode",2);
SetOption("CommissionAmount",100);
SetOption("AccountMargin",10);
SetOption("RefreshWhenCompleted",True);
SetOption( "AllowPositionShrinking", True );
SetOption("MaxOpenPositions", 5);
PositionSize = -20; // invest 20% of portfolio equity in single trade
RoundLotSize = 1;

Plot( Close, "Price",colorWhite, styleCandle );

//Parameters

MALength1 = 5;
MALength2 = 20;

//Buy-Sell Logic

Buy = Cross(ema( C, MALength1 ),ema( C, MALength2 ));
Sell =Cross( ema( C, MALength2 ), ema( C, MALength1 )) ;

Buy = ExRem( Buy, Sell );
Sell = ExRem( Sell, Buy );
Short = Sell;
Cover = Buy;

PositionScore = ADX(14); // prefer stocks that have higher ADX

Plot(ema( C, MALength1 ),"5EMA",colorWhite);
Plot(ema( C, MALength2 ),"20EMA",colorBlue);

/* Plot Buy and Sell Signal Arrows */
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Buy, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Cover, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Cover, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Cover, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Sell, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);
PlotShapes(IIf(Short, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Short, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Short, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);

Let’s break down this AFL and understand it’s underlying logic:

Position Logic: Buy when EMA(5) crosses over EMA(20), Short when EMA (20) crosses over EMA(5). Similar for Sell and Cover.

Initial Equity: 100000

Max Position at a time: 5

Position Size: 20% of equity per position

Position Score: ADX(14). This means if there are more than 5 signals at a time, then the top 5 signals would be selected based on ADX value. (Descending order)

This AFL is just for illustration purpose. Please don’t use it for real trades.

In order to verify the Signals generated and positions taken based on PositionScore, switch to Detailed log mode in backtester settings.

Position Ranking in Amibroker

Check out the below results from backtesting in detailed log mode. Click on image to zoom it.

Amibroker Detailed Backtest Log

It is evident from the screenshot that 10 signals were generated simultaneously, out of which 5 positions were taken based on PositionScore.

Position Ranking in Amibroker is very simple and straightforward, you need not to write complex logic to rank your signals. Everything is taken care by a single PositionScore variable. Try out different strategies based on position ranking and let us know if you find something interesting.

Leave a Reply

Your email address will not be published. Required fields are marked *