Help with Pairs trading strategy

Hi all,
I am developing a long+short strategy the aims to trade a pair of correlated stocks, i.e. when they occasionally become less correlated, it will BUY the lower performing stock and SHORT the higher performing stock. It will then exit when they become more correlated again.

My code is generating reasonable exploration data however the back-test is only generating signals for one of the stocks. Is there a fundamental concept I'm missing? Any help would be gratefully received. The code is below and I run this against a watchlist that only contains the two stocks.

// Pairs trading strategy

// When the pair of stocks become less correlated, buy the stock that has performed less well and short the stock that has peformed better. Exit trades when the two stocks become more correlated.

SetBarsRequired(sbrAll,0); // use all previous bars and no future bars.

// These are the two stocks in the pair
Stock1Ticker="MA";
Stock2Ticker="V";

// Close arrays...
Stock1C = Foreign(Stock1Ticker,"C",1);
Stock2C = Foreign(Stock2Ticker,"C",1);

Period=10; // This relates to correlation and also ROC 

// close to 1 (e.g. 0.9) indicates pretty good correlation; 0 means no correlation; minus 1 means correlated in opposite way
StockCorrelation = Correlation(Stock1C,Stock2C,Period);


CorrelationEntryThreshold=0.8; // enter (BUY one stock and SHORT the other) when correlation drops to this value
CorrelationExitThreshold=0.95; // exit positions when it recovers to this value.

// crossed the entry threshold
// Trade up to three positions as the stocks become less correlated
EntryLevel1 = (StockCorrelation<=CorrelationEntryThreshold AND Ref(StockCorrelation,-1)>CorrelationEntryThreshold);
EntryLevel2 = (StockCorrelation<=CorrelationEntryThreshold-0.1 AND Ref(StockCorrelation,-1)>CorrelationEntryThreshold-0.1);
EntryLevel3 = (StockCorrelation<=CorrelationEntryThreshold-0.2 AND Ref(StockCorrelation,-1)>CorrelationEntryThreshold-0.2);
GeneralCond1 	= 	(EntryLevel1 OR EntryLevel2 OR EntryLevel3);


// Indicate which of the two stocks should be bought - it'll be the one with lower ROC 
BuyCond2a 	= Name()==Stock1Ticker AND ROC(Stock1C,Period)<ROC(Stock2C,Period);
BuyCond2b 	= Name()==Stock2Ticker AND ROC(Stock2C,Period)<ROC(Stock1C,Period);
BuyCond2	= BuyCond2a OR BuyCond2b;

BuySignal	= GeneralCond1 AND BuyCond2;

// indicate which should be SHORTed - (the one with the higher ROC)
ShortCond2a 	= Name()==Stock1Ticker AND ROC(Stock1C,Period)>ROC(Stock2C,Period);
ShortCond2b 	= Name()==Stock2Ticker AND ROC(Stock2C,Period)>ROC(Stock1C,Period);
ShortCond2	= ShortCond2a OR ShortCond2b;

ShortSignal	= GeneralCond1 AND SHORTCond2;

// Exploration output
AddColumn(EntryLevel1,"EntryLevel1",1.0);
AddColumn(EntryLevel1,"EntryLevel2",1.0);
AddColumn(EntryLevel1,"EntryLevel3",1.0);
AddColumn(GeneralCond1,"GeneralCond1",1.0);
AddColumn(BUYSignal,"BUYSignal",1.0);
AddColumn(ShortSignal,"ShortSignal",1.0);

// The BUY and SHORT signals are generated off yesterday's bar.
Buy		=	Ref(BuySignal,-1);
Short	=	Ref(ShortSignal,-1);

// The exit signals are generated off today's bar
Cover	=	StockCorrelation>=CorrelationExitThreshold;
Sell	=	Cover;

Plot(StockCorrelation,"Stock Correlation",colorBlack);

//=================================================================================
//Interpretation Window
//=================================================================================
printf("ROC1="+ROC(Stock1C,Period) + "\n");
printf("ROC2="+ROC(Stock2C,Period) + "\n");
printf("StockCorrelation="+StockCorrelation + "\n");

Filter=BuySignal OR ShortSignal;

You're not setting a position size, so AB is using all of your equity on the first symbol. Try adding this:

SetPositionSize(50, spsPercentOfEquity);

And make sure you allow Position Size Shrinking either by using SetOption or by ticking the box in the Analysis Settings window.

For future reference, you can get some good clues on problems like this by turning on the Detailed Log in the Analysis Settings / Report tab.

5 Likes

In this regard, if I had to test this type of strategy, I will also evaluate how the results can vary using different PositionSizes for the Long and Short positions, in relation to the general direction of the market/sector.

2 Likes

Thanks Matt. That's a real help.

Thanks Beppe, so for example, in a bullish market, take smaller short positions and visa versa...?
regards, Tim.

Yes. This may be something to explore, but as usual, you should test it very well under multiple conditions, remembering that in any case, such a strategy may loose on both sides too!

This was a very useful post to understand how to trade in pairs. I am close to finishing off but can't get the position sizing to work. Starting balance is 10k. You can see first set of trades don't start with 5k and 5k.
image

Look at the Portfolio tab in your analysis settings. Have you limited the trade size based on the entry bar volume?

image

If that's not the issue, I suggest you turn on the detailed log (Analysis Settings / Report) to get a better idea of what AmiBroker is doing internally.

2 Likes

This worked. Thank you!