Having problems with risk-based position sizing in futures mode

Hi All,

I am struggling to successfully implement a risk based position sizing approach that uses an ATR-based stop as an input, for futures trading. I have read and re-read the futures backtesting KB, as well as searched in the forum, but i can't quite get my code to work properly.

My objective:

  • Use an elementary ATR-based stop-loss to calculate maximum risk (1R)
  • set a position size for the trade, based on the 1R loss being 1% of my overall equity
  • do this for Forex trading (ie futures mode)

I can't quite get my code to work using the standard AB KB (https://www.amibroker.com/kb/2014/10/12/position-sizing-based-on-risk/) as a guide.

sample code below:

//+=============================================================================================================+
//|																												|
//| general backtesting & system option / parameter setup														|
//|																												|
//+=============================================================================================================+

SetBacktestMode( backtestRegular );
SetOption("FuturesMode", 1);
SetOption("AccountMargin", 100);
SetOption("CommissionMode", 2);
SetOption("CommissionAmount", 0);	// assume zero commission but apply a sprfead for Forex
SetOption("InitialEquity", 20000);
SetChartOptions( 1, chartShowArrows);

Buy = Sell = Short = Cover = BuyPrice = SellPrice = ShortPrice = CoverPrice = 0;

//+=============================================================================================================+
//|																												|
//| specific parameters for this trading system																	|
//|																												|
//+=============================================================================================================+

//fxSpread					= 0;			// assume a 30 points spread (0.00030 for normal pairs; 0.03 for JPY pairs)
fxSpread					= 3 * TickSize;			// assume a 30 points spread (0.00030 for normal pairs; 0.030 for JPY pairs)
Param_LongPeriod			= 200;					// parameter to control long-timeframe signals (eg highs, lows)
Param_MediumPeriod			= 50;					// parameter to control short-timeframe signals (eg ATR retracement period)
Param_ShortPeriod			= 20;					// parameter to control short-timeframe signals (eg ATR retracement period)
RiskAppetitePct				= 1;					// initial risk appetite = 1.5 %
StopLoss_ATR_Range			= 3;					// calculate 1R exit based on 3xATR retracement
Trail_ATR_Range				= 5;					// trail stop based on 4xATR retracement

//+=============================================================================================================+
//|																												|
//| risk calculation																			|
//|																												|
//+=============================================================================================================+

AvgTrueRange			= Ref( ATR( Param_ShortPeriod ), -1);		// calc short period average true range (from prior day data)
StopLossRiskPerShare	= StopLoss_ATR_Range * AvgTrueRange;  		// calc stop loss
TrailExitRiskPerShare	= Trail_ATR_Range * AvgTrueRange;  			// calc trailing stop

//+=============================================================================================================+
//|																												|
//| signals																										|
//|																												|
//+=============================================================================================================+

LongEMA = EMA( Close, Param_LongPeriod );										// long range Exp moving average
MediumEMA = EMA( Close, Param_MediumPeriod );									// long range Exp moving average
ShortEMA = EMA( Close, Param_ShortPeriod );										// long range Exp moving average

Buy = 	Cross( Ref( Close, -1), Ref( MediumEMA, -1) );							// Buy when last bar close crosses ABOVE last bar Short EMA
Short = Cross( Ref( MediumEMA, -1), Ref( Close, -1) );							// Short when last bar close crosses BELOW last bar Short EMA

//+=============================================================================================================+
//|																												|
//| position size	`																							|
//|																												|
//+=============================================================================================================+

SingleTradeEquityRiskPct =  Buy * (RiskAppetitePct * MarginDeposit / ( StopLossRiskPerShare * PointValue) ) + Short * (RiskAppetitePct * MarginDeposit / ( StopLossRiskPerShare * PointValue) );
SetPositionSize( SingleTradeEquityRiskPct, spsPercentOfEquity );

//+=============================================================================================================+
//|																												|
//| add results to explorer																						|
//|																												|
//+=============================================================================================================+

Filter=Buy OR Sell OR Short OR Cover;
//Filter = 1;									 // show all for now

SetOption("NoDefaultColumns", True );
AddColumn( DateTime(), "Date", formatDateTime );
AddTextColumn( Name(), "Stock", formatChar );
AddColumn( Buy, "Buy", 1 );
AddColumn( IIf( Buy, BuyPrice, Null ), "BuyPrice", 1.5 );
AddColumn( Sell, "Sell", 1 );
AddColumn( IIf( Sell, SellPrice, Null), "SellPrice", 1.5 );
AddColumn( Short, "Short", 1 );
AddColumn( IIf( Short, ShortPrice, Null ), "ShortPrice", 1.5 );
AddColumn( Cover, "Cover", 1 );
AddColumn( IIf( Cover, CoverPrice, Null), "CoverPrice", 1.5 );
AddColumn( Open, "Open", 1.5 );
AddColumn( High, "High", 1.5 );
AddColumn( Low, "Low", 1.5 );
AddColumn( Close, "Close", 1.5 );
AddColumn( AvgTrueRange, "ATR", 1.5);
AddColumn( StopLossRiskPerShare, "ATR_SL_Exit", 1.5);
AddColumn( TrailExitRiskPerShare, "ATR_Trail_Exit", 1.5);
AddColumn( Equity(), "Current Equity", 1.2);
AddColumn( PositionSize, "Pozition Size", 1.5);

And i'm just trying to test it with AUD.USD to keep it simple for now.

My Symbol info as it relates to futures mode:
symbolinfo

And my backtest settings for futures mode:
backtestsettings

I get no trades when i run a backtest, and when i explore (results below), i noticed that position size is showing -1000 for most signals.
explorerresults

I'd really appreciate any advice on this, as i have been trying to trouble shoot it unsuccessfully for hours and feel like i'm missing something really fundamental in my approach.

Thanks in advance,
Craig

Try changing point value to 10.000 or 100.000 to simulate mini or standard lots in forex.

Thanks pmxgs, I tried both, still getting some wierd results that i can't quite backsolve for futures. Getting massive position sizes.

I've also tried setting MardinDeposit to -1 (i thought i read somewhere this equated to 100:1 leverage which is what my forex broker offers), I also tried just using a "PositionSize = " reference instead of using SetPositionSize, but getting similar results that i can't decipher.

Going to keep trying different options and debugging, thanks for the option though.

I tested your original code with a point value of 100000 and the position sizes seemed reasonable.

thanks, i hadn't tried that. i completely misunderstood the definition of a point. thanks champ :slight_smile:

@mradtke Matt i seem to be getting the right position size in percentage with that change (in my explorer results), but no trades are being opened in backtesting. the detailed report suggests i'm trying to open a position with less than minimum value.
I have lotsize set to 0, to trade partial contracts but can't figure out why it wont open a position?

positionsizeerror

ignore last (rookie) post - didn't realise that I had min shares = 1 in my backtest settings window (thought this might be overridden in futures mode).

Now working :slight_smile:

1 Like