Here is a relatively simple pair trading script. This uses actual 5 sec Oanda data for BCO and WTICO (the two types of oil). It does not trade based on bars, but rather with each tick. A position is entered when the other asset moves by more than the spread, and it is always closed with the next tick.
#define ASSET_0 "WTICO/USD"
#define ASSET_1 "BCO/USD"
#define SPREAD_0 0.003 // Actual Oanda spread
#define SPREAD_1 0.003
var tick_price[2] = {1, 1};
var prev_tick_price[2] = {1, 1};
void tick() {
// Determine for which asset this tick arrived
int asset_id = -1;
if(strcmp(Asset, ASSET_0) == 0) {
asset_id = 0;
} else if(strcmp(Asset, ASSET_1) == 0) {
asset_id = 1;
}
// Store this and the prior tick's price
prev_tick_price[asset_id] = tick_price[asset_id];
tick_price[asset_id] = priceClose();
// Close position after one tick
exitLong("**");
exitShort("**");
// If current tick changes the price by more than the spread,
// buy (resp. sell) the other asset if the price goes up (resp. down)
var price_change = tick_price[asset_id] / prev_tick_price[asset_id] - 1;
if(abs(price_change) >= max(SPREAD_0, SPREAD_1)) {
// Trade the asset which did *not* receive the current tick
if(asset_id == 0) {
asset(ASSET_1);
} else {
asset(ASSET_0);
}
// Buy if uptick, sell if downtick
if(price_change > 0) {
enterLong();
} else {
enterShort();
}
}
}
function run() {
if(is(INITRUN)) {
set(TICKS, LOGFILE);
StartDate = 2015;
EndDate = 2021;
BarPeriod = 60;
LookBack = 2;
Lots = 1000;
asset(ASSET_0);
Spread = SPREAD_0;
asset(ASSET_1);
Spread = SPREAD_1;
}
}
Running this script in Test mode yields a rather astounding performance (see attached chart):
Monte Carlo Analysis... Median AR 5516%
Win 1436370€ MI 19389€ DD 1385€ Capital 4535€
Trades 32051 Win 65.5% Avg +5.3p Bars 1
AR 5130% PF 3.40 SR 14.71 UI 0% R2 0.76
Now, not to disappoint anyone -- unfortunately, it doesn't look nearly as lucrative in real trading (imagine if it did)...
So, what's going on here?
The problem appears to be with Zorro's backtesting ticks: When a tick arrives, it updates the asset price accordingly, but the other assets still have their previous prices. So, when choosing a different asset, enterLong/enterShort will actually trade
at a previous tick's price.
Since oil prices, like many currency prices, move more or less in unison, receiving a tick for one type of oil tells you more often than not what the other oil will do, and Zorro lets you trade at a price from the past.
What I would expect Zorro to do when testing in tick mode is to enter or exit at the next tick's price -- as you would in live trading --, as opposed to the previous one's.
(Let me know if you would like the Oanda data to reproduce this.)