AFL of the week: Anti-Martingale Trading system

On our readers request, we will explore dynamic position sizing using Amibroker this week. Also we shall go over Anti-Martingale Trading system in the same context. In Trading system terminology, dynamic position sizing is referred to a strategy where position size may vary with each trade or during the course of a particular trade depending on some pre-defined rules. For Ex: Suppose a trader implements a Trading system which performs comparatively bad during Quarter 4 every year, however its performance during other Quarters is quite impressive. In this case, the Trading system can be modified in such a way that Position size is decreased automatically during Quarter 4 and it’s increased during Quarter 1, 2 and 3. This would overall increase the performance of the system. It’s imperative for your trading success that you should be very careful in selecting the position size and hence it’s very important to give utmost attention to this topic.

Anti-Martingale system using Dynamic Position Sizing

Martingale or Anti-Martingale systems are widely popular across casinos across the globe. In Martingale system, the gambler doubles up his bet size on every loss so that he covers up all his loss through a single win. While in Anti-Martingale system, the gambler doubles up his bet size on every profit. The same concepts can be applied in Trading systems too. In Anti Martingale trading system, the trader increases his position size gradually if the trade goes in his favour, while the position size is decreased if the trade goes against him. The basic assumption behind this strategy is that profits from your winning trades is always higher than the losses from your losing trades. This strategy is particularly very helpful in trending markets. It’s a statistically proven fact that Anti-Martingale strategy performs better that Martingale strategy over a long term.

Amibroker has dynamic position sizing capabilities which would enable us to devise and backtest Anti Martingale strategy. In Amibroker terminology, increasing your position size is termed as Scaling-In, while decreasing your position size is termed as Scaling-Out. Two special constants: sigScaleIn / sigScaleOut provide means to tell the backtester when you want to scale-in/out

In order to change the position size you have to:

  • Assign sigScaleIn to BUY/SHORT variable if you want to scale-in (increase size of) LONG/SHORT position.
  • Assign sigScaleOut to BUY/SHORT variable if you want to scale-out (decrease size of) LONG/SHORT position.

Read our article on AFL tutorial here.

AFL Overview

Paramter Value
Preferred Timeframe No Constraint
Indicators Used MACD, Signal
Positions Long only
Buy Condition MACD crosses above Signal line
Sell Condition MACD crosses below Signal line
Stop Loss No fixed Stoploss
Targets No fixed target
Position Size – Initial Position size (150 fixed)

– Increase position size by 150 with every 100 points gain since Buy.

– Decrease position size by 75 with every 50 points loss since Buy.

Initial Equity 100000
Brokerage 50 per order
Margin 10%

AFL Code

//------------------------------------------------------
//
//  Formula Name:    Anti-Martingale Trading system
//  Author/Uploader: Trading Tuitions
//  E-mail:          support@tradingtuitions.com
//  Website:         www.tradingtuitions.com
//------------------------------------------------------

_SECTION_BEGIN("Anti Martingale Trading Syatem");

SetTradeDelays( 1, 1, 1, 1 );
SetOption( "InitialEquity", 100000);
SetOption("FuturesMode" ,True);
SetOption("MinShares",1);
SetOption("CommissionMode",2);
SetOption("CommissionAmount",50);
SetOption("AccountMargin",10);
SetOption("RefreshWhenCompleted",True);
SetOption( "AllowPositionShrinking", True );
BuyPrice=Open;
SellPrice=Open;
ShortPrice=Open;
CoverPrice=Open;

//Specify ScaleIn and ScaleOut parameters
ScaleInPoints=100;
ScaleOutPoints=50;
ScaleInSize=150;
ScaleOutSize=75;


//Buy and Sell Condition
Buy = Cross( MACD(), Signal() );
Sell = Cross( Signal(), MACD() );

BuyPrice=ValueWhen(Buy,C);

for( i = 1; i < BarCount; i++ ) { Profit[i]=Close[i]-BuyPrice[i]>=ScaleInPoints;
    Loss[i]=Close[i]-BuyPrice[i]<=-ScaleOutPoints;
    if(Profit[i]==1)
    ScaleInPoints=(Close[i]-BuyPrice[i])+100;
    if(Loss[i]==1)
    ScaleOutPoints=-(Close[i]-BuyPrice[i])+50;
    if(Sell[i])
    {
    ScaleInPoints=100;
    ScaleOutPoints=50;
    }
}

InTrade = Flip( Buy, Sell );

DoScaleIn = InTrade AND Profit;
DoScaleOut= InTrade AND Loss;


Buy = Buy + sigScaleIn * DoScaleIn + sigScaleOut * DoScaleOut;

PositionSize = IIf( DoScaleOut,ScaleOutSize, ScaleInSize); 

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

SetPositionSize(PositionSize,spsShares);

PlotShapes(IIf(Cross( MACD(), Signal() ), shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Cross( MACD(), Signal() ), shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Cross( MACD(), Signal() ), shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Cross( Signal(), MACD() ), shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Cross( Signal(), MACD() ), shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Cross( Signal(), MACD() ), shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);
PlotShapes(IIf(DoScaleIn, shapeSmallUpTriangle, shapeNone),colorBlue, 0, L, Offset=-45);
PlotShapes(IIf(DoScaleOut, shapeSmallDownTriangle, shapeNone),colorBlue, 0, H, Offset=-45);
_SECTION_END();

AFL Screenshot

The up and down arrows represent Buy and Sell signals respectively. Blue up triangle represents Scale-In, while Blue down triangle represents Scale-Out.

See how the position is gradually increased for profitable trade:

scale in

See how the position size is gradually decreased for loss making trade:

Scale Out

Backtest Report

Below is the backtest report for this strategy. Please note that backtester treats trade that you scale-in/out as SINGLE trade (i.e. will show single row in trade list). The only difference versus plain trade is that it will calculate average entry price based on all partial entries and average exit price based on all partial exits and will show average prices in entry/exit price field. The commission is of course applied correctly to each (partial) entry/exit depending on partial buy/sell size. If you want to see details about scaling you have to run backtest in “DETAIL LOG” mode as only then you will see how scaling-in /out works and how average prices are calculated.

 Paramter Value
  NSE Nifty
Initial Capital  100000
Final Capital 1752936.03
Backtest Period 11-Apr-2000 to 23-Feb-2016
Timeframe Daily
Net Profit % 1652.94%
Annual Return % 19.39%
Number of Trades 146
Winning Trade % 43.56%
Average holding Period 14.89 periods
Max consecutive losses 8
Max system % drawdown -65.87%
Max Trade % drawdown -85.83%

Download the detailed backtest report here.

Please note that you can expect even better results if you allow compounding of your returns.

Equity Curve

 

Additional Amibroker settings for backtesting

Goto Symbol–>Information, and specify the lot size and margin requirement. The below screenshot shows lot size of 75 and margin requirement of 10% for NSE Nifty:

Symbol Info_Nifty

Disclaimer:

All the AFL’s posted in this section are for learning purpose. Trading Tuitions does not necessarily own these AFL’s and we don’t have any intellectual property rights on them. We might copy useful AFL’s from public forums and post it in this section in a presentable format. The intent is not to copy anybody’s work but to share knowledge. If you find any misleading or non-reproducible content then please inform us at support@tradingtuitions.com

8 Comments

  1. Hello and thanks very much for this code.

    — ScaleInPoints – is this the number of points needed to move up before adding a position?
    — ScaleInSize – is this the number of contracts? For stocks, can I change it to 10000/C as a fixed $ size?

    Could you add commentary for this section please?

    for( i = 1; i =ScaleInPoints;
    Loss[i]=Close[i]-BuyPrice[i]<=-ScaleOutPoints;
    if(Profit[i]==1)
    ScaleInPoints=(Close[i]-BuyPrice[i])+100;
    if(Loss[i]==1)
    ScaleOutPoints=-(Close[i]-BuyPrice[i])+50;
    if(Sell[i])
    {
    ScaleInPoints=100;
    ScaleOutPoints=50;
    }
    }

    • Hi,
      Yes, ScaleInPoints is the number of points needed to move up before increasing size of your long/short position. And ScaleInSize is the number of shares which would be increased whenever ScaleIn condition is met. You can modify ScaleInSize as per your risk management strategy. We would try to add commentary to the section you mentioned very soon.

    • Hi Fabio,
      You would need to change ‘Buy and Sell’ to ‘Short and Cover’ respectively in the AFL provided. Also you can change the Shorting strategy if needed.

  2. HELLO THERE,

    VERY NICE SYSTEM

    CAN YOU CREATE A THIS SYSTEM IN OPPOSITE MANNER,
    STARTING WITH 3 LOTS INITIALLY AND SCALING OUT AFTER EVERY 50 POINTS IN PROFIT BUT IN BOTH LONG AND SHORT POSITION

Leave a Reply

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