Posted By: Morris
>1000% AR? - 03/09/21 20:42
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.
Running this script in Test mode yields a rather astounding performance (see attached chart):
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.)
Code
#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):
Code
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.)
Description: Backtest performance chart