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:
And my backtest settings for futures mode:
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.
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