Thursday 5 January 2023

Scream if you want to go faster

Happy new year.

I didn't post very much in 2022, because I was in the process of writing a new book (out in April!). Save a few loose ends, my work on that project is pretty much done. Now I have some research topics I will be looking at this year, with the intention of returning to something like a monthly posting cycle. 

To be clear this is *not* a new years resolution, and therefore is *not* legally or morally binding.

The first of these research projects relates to expensive (high cost) trading strategies. Now I deal with these strategies in a fairly disdainful way, since I'm conservative when it comes to trading fast and I prefer to avoid throwing away too much return on (certain) costs in the pursuit of (uncertain) returns. 

Put simply: I don't trade anything that is too quick. To be more precise, I do not allocate risk capital to trading rules where turnover * cost per trade > 'speed limit'. The effect of this is that instruments that are cheaper to trade get an allocation to expensive trading rules that have a high turnover; but most don't. And there are a whole series of potential trading rules which are far too rich for all but the very cheapest instruments that I trade.

My plan is to do a series of posts that explore in more depth whether this is the correct approach, and whether there is actually some room for faster trading strategies in my quiver. Broadly speaking, it might be that eithier:

  • The layers of buffering and optimisation in my system mean it is possible to add faster strategies without worrying about the costs they incur. 
  • Or there could be some other way of smuggling in faster trading, perhaps via an additional execution layer that optimises the execution of orders coming from the (slow) core strategy. 

Part of the motivation for this is that in my new book I introduce some relatively quick trading strategies which are viable with most instruments, but which require a different execution architecture from my current system (a portfolio that is dynamically optimised daily, allowing me to include over 100 instruments despite a relatively modest capital base). Thus the quicker strategies are not worth trading with my retail sized trading account; since to do so would result in a severe loss of instrument diversification which would more than negate any advantages. I'll allude to these specific strategies further at some point in the series, when I determine if there are other ways to sneak them into the system.

For this first post I'm going to explore the relationship between instrument cost and momentum performance. Mostly this will be an exercise in determining whether my current approach to fitting instrument and forecast weights is correct, or if I am missing something. But it will also allow me to judge whether it is worth trying to 'smuggle in' faster momentum trading rules that are too pricey for most instruments to actually trade.

The full series of posts:

  • This is the first post
  • The second post discusses whether fast trading rules can be 'smuggled in' to my existing system

Note 1: There is some low quality python code here, for those that use my open source package pysystemtrade. And for those who haven't yet pre-ordered the book, you may be interested to know that this post effectively fleshes out some more work I present in chapter nine around momentum speed.

Note 2: The title comes from this song, but please don't draw any implications from it. It's not my favourite Geri Halliwell song (that's 'Look at Me'), and Geri isn't even my favourite Spice Girl (that's Emma), and the Spice Girls are certainly not my favourite band (they aren't even in my top 500).

The theories

There are two dogs in this fight. 

Well metaphorical dogs, I don't believe in dog fighting. Don't cancel me! But the fight is very real and not metaphorical at all. 

I'm interested in how much truth there is in the following two hypothesis:

  • We have a prior belief that the expected pre-cost performance for a given trading rule is the same regardless of underlying instrument cost. 
  • "No free lunch": expected pre-cost performance is higher for instruments that cost more to trade, but costs exactly offset this effet. Therefore expected post-cost performance for a given trading rule will be identical regardless of instrument cost.

I use expectations here because in reality, as we shall see, there is huge variation in performance over instruments but quite a lot of that isn't statistically significant.

What implications do these hypothesis have? If the first is true, then we shouldn't bother trading expensive instruments (or at least radically downweight them, since there will be diversification benefits). They are just expensive ways of getting the same pre-cost performance. But if the second statement is true then an expensive instrument is just as good as a cheaper one.

Note that my current dynamic optimisation allows me to side step this issue; I generate signals for instruments regardless of their costs and I don't set instrument weights according to costs, but then I use a cost penalty optimisation which makes it unlikely I will actually trade expensive instruments to implement my view. Of course there are some instruments I don't trade at all, as their costs are just far too high. 

Moving on, the above two statements have the following counterparts:

  • We have a prior belief that the expected pre-cost performance across trading rules for a given instrument is constant. 
  • Expected post-cost performance across trading rules for a given instrument will be identical.

What implications do these theories have for deciding how fast to trade a given instrument, and how much forecast weight to give to a given speed of momentum? If pre-cost SR is equal, we should give a higher weight to slower trading rules; particularly if an instrument is expensive to trade. If post-cost SR is equal, then we should probably give everything equal weights.

Note that I currently don't do eithier of these things: I completely delete rules that are too quick beyond some (relatively arbitrary) boundary, then set the other weights to be equal. In some ways this is a compromise between these two extremes approaches.

A brief footnote: 

You may ask why I am looking into this now? Well, I was pointed to this podcast by an ex-colleague, in which another ex-colleague of mine makes a rather interesting claim:

"if you see a market that is more commoditised [lower costs] you tend to see faster momentum disappear."

Incidentally it's worth listening to the entire podcast, which as you'd expect from a former team member of yours truely is excellent in every way.

Definitely interesting! This would be in line with the 'no free lunch' theory. If fast momentum is only profitable before costs for instruments that cost a lot to trade, then it won't be possible to exploit it. And the implication of this is that I am doing exactly the wrong thing: if an instrument is cheap enough to trade faster momentum, I shouldn't just unthinkingly let it. Conversely if an instrument is expensive, it might be worth considering faster momentum if we can work out some way of avoiding those high costs. 

It's also worth saying that there are already some stylised facts that support this theory. Principally, faster momentum signals stopped working particularly in equity markets in the 1990s; and equity markets became the cheapest instruments to trade in the same period.

Incidentally, I explore the change in momentum profitability over time more in the new book. 

The setup

I started with my current set of 206 instruments, and removed duplicates (eg mini S&P 500, for which the results would be the same as micro), and those with less than one year of history (for reasons that will become clearer later, but basically this is to ensure my results are robust). This left me with 160 instruments - still a decent sample.

I then set up my usual six exponentially weighted moving average crossover (EWMAC) trading rules, all of the form N,4N so EWMAC2 denotes a 2 day span minus an 8 day span: EWMAC2, EWMAC4, EWMAC8, EWMAC16, EWMAC32, EWMAC64.

I'm going to use Sharpe ratio as my quick and dirty measure of performance, and measure trading costs per instruments as the cost per trade in SR units. However because the range of SR trading costs is very large, covering several orders of magnitude (from 0.0003 for NASDAQ to over 90 for the rather obscure Euribor contract I have in my database), I will use log(costs) as my fitting variable and for plotting purposes. 

Before proceeding, there is an effect we have to bear in mind, which is the different lengths of data involved. Some instruments in this dataset have 40+years of data, others just one. But in a straight median or mean over instrument SR they will get the same weighting. We need to check that there is no bias; for example because equities generally have less data and are also the cheapest:

Here the y-axis shows the SR cost per trade (log axis) and the x-axis shows the number of days of data. 

There doesn't seem to be a clear bias, eg more recent instruments especially cheap, so it's probably safe to ignore the data length issue.

Gross SR performance by trading rule versus costs

Now to consider the relationship between the cost of an instrument, and the performance of a given trading rule. Each of these scatter plots has one point per instrument; each point shows the SR cost per trade (log) on the x-axis, and the gross SR performance of a given trading rule on the y-axis. I've also added regression lines, and R squared for those regressions.

If the 'no free lunch' rule of equal post cost SR applied, we'd see a positive slope in these charts, whereas if SR were equal pre-cost we'd see a flat line.

So there is something interesting here. For the very fastest trading rules, there is a weak positive relationship (R squared of 0.075) whereby the more expensive an instrument is, the higher the gross SR. That relationship gets monotonically weaker as we slow down, and completely vanishes for the very slowest momentum rule. This does seem to chime with the 'no free lunch' theory; gross profits on very fast momentum are only available for instruments where that would be too expensive to trade.

Perhaps then there is something in the idea that we can use very fast trading rules on expensive instruments, if we can get round the pesky trading costs!

Net SR performance by trading rule versus costs

What happens if we repeat these plots, but with net performance? If the no free lunch (equal post-cost SR) rule is exactly correct, then this should be a horizontal line with no relationship between net SR and the cost of trading a given instruments. Of course if the other hypothesis (equal pre-cost SR) is true, then we'd see a downward sloping line- and because we have log(costs) on the x-axis it would slope downward exponentially. Let's have a look at the very fastest rule:

I haven't dropped a regression line on here, because there clearly isn't a linear relationship. The red vertical line shows the point at which I'd currently stop trading this rule for a given instrument. Everything to the right of this line is an instrument that is too expensive for this trading rule; a SR cost above 0.0031 units. To the right of this line it's clear that we lose more and more money for more expensive instruments; the small improvement in gross SR we saw before for costlier instruments is completely dominated by much higher costs. 

Technically I should allow for the effect of rolls on turnover but in for simplicity I ignore those when drawing the red line, since roll frequency is different for each instrument. They will only have an effect for very expensive instruments at very slow speeds.

But to the left of it things aren't as obvious:

There aren't that many data points here, but there doesn't seem to be much of an upward or downward slope here, which is what we'd expect from the no free lunch theory; to put it another way if costs aren't too high then we can treat the post cost SR as equal, which is a vindication of my forecast weight allocation process. We can confirm that by adding a regression line, but fitting only on the points to the left of the line:

There is a very slight downward slope; indicating that this very fast momentum might be a little closer to the 'equal pre-cost' than 'equal post-cost' hypothesis. But the R squared is very small, and there aren't many data points, reflecting the very small number of instruments that can trade this rule.

Let's continue using  this approach for slower rules:

By the time we get to the very slowest trading rule, it looks much more like the assumption of equal post cost SR is true. The R squared is barely in double figures, so this isn't a very clear result, but it does look like you would want to downweight expensive instruments, as well as removing those that exceed the cost threshold and are to the right of the red line. This remains true even if we're only trading the very slowest EWMAC64 speed on those instruments, which we would be. 

Indeed, if we trust the regression line it looks the cost ceiling for EWMAC64 (and therefore the global cost ceiling to decide whether to trade an instrument at all, in the absence of any cheaper trading rules) should be something like a log cost of -5, or 0.007 SR cost units (the point at which the regression line crosses the x-axis of zero expected SR). 

That's actually a little more conservative than my current global maximum for instrument costs, which is 0.01 SR units (discussed here), but on the other hand the use of dynamic cost penalties means I can probably relax a little on this front.

Optimal trading speed

Let's return to the second set of statements we want to test:

  1. We have a prior belief that the expected pre-cost performance across trading rules for a given instrument is constant. 
  2. Expected post-cost performance across trading rules for a given instrument will be identical.
To put it another way, in a pre-cost world the optimal trading speed will be eithier:
  1. Identical regardless of instrument costs
  2. Faster for more expensive instruments
And in a post-cost world, optimal trading speed will be:
  1. Slower for more expensive instruments
  2. Identical regardless of instrument costs
How do we measure optimal trading speed? This is a bit tricker than just measuring the SR of the rule, since it's effectively the result of a portfolio optimisation. A full blown optimisation would seem a bit much, but just using the EWMAC with the highest SR would be far too noisy. 

I decided to use the following method, which effectively allocates in proportion to SR (where positive):

speed_as_list = np.array([1,2,3,4,5,6])
def optimal_trading_rule_for_instrument(instrument_code, curve_type="gross"):
sr_by_rule = pd.Series([
sr_for_rule_type_instrument(rule_name, instrument_code, curve_type=curve_type)
for rule_name in list_of_rules])

sr_by_rule[sr_by_rule<0] = 0
if sr_by_rule.sum()==0:
return 7.0

sr_by_rule_as_weight = sr_by_rule / sr_by_rule.sum()
weight_by_speed = sr_by_rule_as_weight * speed_as_list
optimal_speed = weight_by_speed.sum()

return optimal_speed

This returns a 'speed number'. The optimal speed number will be 1 (if EWMAC 2 is the best), 2 (if it's EWMAC 4, or something like a combination of EWMAC2,4, and 8 which works out as an average of 4), 3 (EWMAC8), 4 (EWMAC16).... 6 (EWMAC64) or 7 if there are no trading rules with a positive Sharpe (which could be due to very high costs; or just bad luck).

Optimal trading speed with gross SR

Let's repeat the exercise of scatter plotting. Log(costs) of instrument is still on the x-axis, but on the y-axis we have the optimal trading speed, as a number between 1 (fast!) and 6 (very slow!), or 7 (don't bother).

Well this looks pretty flat. The optimal trading speed is roughly 3.5 (somewhere between EWMAC8 and EWMAC16) for very cheap instruments, and perhaps 3 for very expensive ones. But it's noisy as anything. It's probably safe to assume that there is no clear relationship between optimal speed and instrument costs, if we only use gross returns.

Optimal trading speed with net SR

Now let's do the same thing, but this time we find the optimal speed using net rather than gross returns.

As before I've added a red vertical line. Instruments to the right of this are too expensive to trade, even with 100% weight on my slowest trading rule, since their costs would exceed my speed limit of 0.13 SR units per year. 

There are a lot more '7' here, as you'd expect, especially for high cost instruments (which all have negative SR after costs for all momentum), but there are also quite a few lower cost instruments with the same problem. This is just luck - we know that SR by trading rule is noisy, so by bad luck we'd have a few instruments which have negative SR for all our trading rules. 

As we did before, let's ignore the instruments above the red line, and run a regression on what's left over:

That's certainly a strong result, and very much in favour of trading more slowly as instrument costs rise.

However it might be unduly influenced by the '7' points, so let's drop those and see what it looks like without them:
There is still something there, but it's a bit weaker. Roughly speaking, for the very cheapest instruments the optimal trading speed is around 3.5 (something like an equal weight of EWMAC8 and EWMAC16), and for the costliest it's around 5 (EWMAC32, or equivalently an equal weight of 16,32 and 64). 

It's probably worth contrasting this with the weights I currently allocate. Rule turnovers are roughly 42 (EWMAC2), 20, 9, 3.8, 2.3, and 2.1 (EWMAC64). To trade all six rules I would need an instrument SR cost of less than 0.00283 (assuming quarterly rolls), around -5.9 in log space. Such an instrument would have equal weights across all six rules, and therefore a speed number of around 3.5. That is a little faster than the above regression would suggest (-5.9 is closer to an optimal speed number of 4.1), but the regression is very noisy. 

To trade EWMAC64 and nothing else, I'd require an instrument SR cost of less than 0.021 (again assuming quarterly rolls; it would be higher for monthly rolls), or -3.8 in log space. With costs higher than that I couldn't trade anything at all. 

Note that is to the left of the red line, since the red line ignores the effect of rolling on turnover. 

Just EWMAC64 is a speed number of 6, and the regression suggests a speed number of 5.9 with -3.8 log costs. That is a pretty good match.

Summary and implications

Let's deal with the issue of optimal speed first, since the implications here are more straightforward. Broadly speaking it is correct that pre-cost optimal speed is flat, and therefore we should slow down as instruments get more expensive to trade. Although the results are noisy, they suggest that with my current simplistic method for allocating forecast weights I'm spot on with the most expensive instruments, but I might be trading the very cheapest instruments a tiny bit too quickly. However the difference isn't enough to worry about.

Turning to the issue of performance of momentum according to instrument cost, I draw two main conclusions. 

Firstly, the post-cost results suggest that trading rule performance gets worse for more expensive instruments, even if we're trading them slowly. Hence, if I was trading a static system without dynamic optimisation, then I would give consideration to penalising the instrument weight of instruments with high costs (but which were still cheap enough to trade). It's important to note that this is at odds with the approach I've taken before, and discussed in my first book, where I generally set instrument weights without considering costs (assuming post cost SR is equal). Also, my 'cheap enough to trade' bar of 0.01 SR units may be set a little aggressively; 0.007 could be closer to the mark.

However, as I'm currently using dynamic optimisation with a cost penalty, I'm less worried about these issues. This will naturally allocate less to more expensive instruments, and trade them less.

Secondly, the pre-cost performance of momentum versus instrument costs suggests that there is some truth in the idea that more expensive instruments can be traded with fast momentum if you don't have to worry about costs. This is quite a weak result, but I will bear it in mind when I think about 'smuggling in' faster trading rules.

In conclusion, I'm happy that my current pragmatic and simplistic approach to fitting is good enough, but it's been a useful exercise to properly interrogate my assumptions on trading costs and find some surprising results.