Wednesday, 4 November 2026

Why optimising for the left tail of outcomes is like playing chess...

A short one today.

Suppose I offer you N trading strategies to choose between. We can run some kind of bootstrap of their historical returns to get a final distribution of CAGR, with all the caveats implied by that. Or suppose I ask you to pick the correct level of leverage on a trading strategy. Again we can bootstrap historical returns at different leverage levels, giving us a series of N discrete possible leverage levels. How do we do that? Both are equivalent to choosing which of N distributions of possible outcomes we prefer.

The strict expectation method is to pick the option with the distribution that has the best median value, eg 50% distribtional point. As I've discussed before, that is equivalent to the Kelly optimal.

The gambling addict method would be to pick the one with a very good right tail. We might go for the option that has the best 1% right tail. That would be a high leverage option, something with high natural risk like crypto, or a short gamma strategy that doesn't manage to blow up in the best possible alternative histories that generated the bootstrap. Nobody should be a gambler, except sometimes.

The conservative method, which I favour, is the opposite. We might go for the option that has the best 1%, 10% or 25% tail; eg the option that will have the best outcome if bad things happen. 

We can imagine an extreme version of the conservative method where we pick the option with the best worst outcome, i.e. the best minimum value. In fact if we're bootstrapping enough times the lower bound of all distributions will be a final portfolio value very close to zero (with compounded returns and absolute returns>-100% we can't mathemtically below zero) and hard to distinguish; so in practice the most realistic extreme version would be something like picking the option with the most optimal 1% left tail point. Given that is likely to be negative, that would be the option with the least worst 1% tail.

(Frankly more extreme outcomes are highly uncertain, and will probably go beyond what a historical bootstrapping exercise could predict)

The least worst option? That is also the MinMax of game theory, Nash equilibria and all chess playing software.


Credit: Chatgpt, authors own prompt

If you view the market as your adversary, you want to have the least bad outcome in the worst possible state.

Now I am not suggesting you optimise for the 1% point, but they do say that there are no old, bold traders. Good traders know how to quantify and when to take risks, but they also understand the importance of keeping their capital mostly intact in the future. So somewhere around the 10% or 25% point seems appropriate to me. 



Optimisation with costs (oh please seriously Rob, not again...) and a sort of summary

After a summer break, this is post (checks notes) #11 in my 2026 series on portfolio optimisation. Up until now I've been focusing on the optimisation of forecast weights -the weights of signals to predict a given instrument - on a pre cost basis. So now it seems that we should introduce the question of costs.

But if you are a faithful follower of this blog, you may be groaning! I have covered this subject at length before in three substantial posts:

In this ten year old (!) post which is literally called 'optimising with costs'

In this 2023 Geri Halliwell (yes really) themed post on whether performance is identical across instruments on a pre-cost or post cost basis 

In this follow up 2023 movie franchise themed post about the effects of various layers of my strategy on costs

... and this isn't to ignore the numerous posts I've done which talk about costs in some way.

So this post is going to be a bit of a mish mash.  It will be a bit of an abstract 'let us think about this from all possible angles'. It will be a bit of a literature review of previous posts. And there will be at least one new idea for dealing with costs in portfolio optimisation ("no rob haven't we suffered enough"). 


My trading strategy and speed and costs

My strategy consists of lot's of little simple things, but layered together the interactions can get a little complex.

Remember we begin by combining forecasts trading at different speeds for a given instrument. 
Then we allocate an instrument weight. This gives me the ideal portfolio I would trade without worrying about pesky integer contracts. Next, I run a dynamic optimisation ('DO') which does worry about integer contracts. But it also worries about costs. It removes instruments which I've decided are too expensive to trade (as well as those which aren't sufficiently liquid, require too much leverage, or which I can't legally trade). It applies a buffer to the overall trading, which slows down the system's turnover. And it applies a trading cost penalty. The effect of all these cumulatively was discussed in one of the prior posts.

Let us know think about how this affects our decision making. For concreteness, let's assume we have three instruments in the worlds weirdest portfolio: S&P 500 (with 0.00025 SR points of costs per trade, amongst the cheapest I have), Cheese (0.008 SR points, just inside the 0.01 threshold where I'd stop trading it) and Sugar #16 (0.09 SR points, well above my limit). So bear in mind that our trades in Cheese will be severely penalised by the trading cost penalty in the DO. And we won't actually trade Sugar at all, since it will be excluded at the DO stage. 

How should we allocate forecast weights to say a fast, medium and slow trend following rule variation within each of these three instruments? Here are some of the things we need to consider:
  • Should I have some heuristic pre-filtering where I won't use rules where turnover*SR cost>speed limit? How would that work with Sugar where none of the rules would meet that speed limit? [in my current system, I pre-allocate a set of the slowest rules]
  • What is the likely pre-cost SR of these rules, and does it make sense to do some kind of pooling to estimate them? This was discussed in the previous post in this 2026 series. 
  • How does the internal correlation of these rules affect things? For example, we know that fast/slow are more diversifying than medium which will be 0.8 correlation with both.
  • How should we apply trading costs in the optimisation? Should we apply them so we end up putting less into faster variations for Cheese than for S&P 500? [The exact methodology of how costs are applied in optimisation is a seperate subject I will discuss below]
  • How would that work with Sugar, when all of our trading rules would probably have negative SR after costs? 
  • Should we get more diversification by, for example, putting more in fast SP500 trend, even if that doesn't actually make money; as otherwise we wouldn't be able to trade fast trend at all?

Next, how should we allocate instrument weights? I haven't yet addressed this in my posting series, but because of the layers of interaction it does need to be discussed.

  • What is the likely pre-cost SR of instrument performance, and is it effectively flat so it can be set to be equal across instruments?
  • Should we apply trading costs to instrument performance, so we end up allocating less to Cheese and more to S&P?
  • How does that work with Sugar, where we would probably end up negative SR after costs even if the forecast weights were just 100% in the slowest system?
  • Given I am going to apply cost penalties to Milk anyway, does it matter if we apply trading costs?
  • Given we won't actually trade Sugar because of it's trading costs, it's instrument weight will just determine how it influences the positions we do actually trade. So what implications does that have for applying costs?

Applying trading costs in optimisations

Much of this was discussed here, but for the sake of completeness here are the options (including a new one):

  1. Heuristic: apply a maximum cost threshold. This can be applied before, and in addition to, any of the methods below.
  2. Ignore costs, use gross returns. These could be pooled. 
  3. Use net returns. Note if you are pooling across instruments, that implies you should probably pool gross returns then subtract instrument specific costs (I did consider the alternative of pooling costs, or pooling net returns, but this option makes more sense).
  4. Just use costs - set gross returns to some arbitrary equal number.
  5. Subtract costs from gross returns, and multiply costs by a factor >1. This reflects the fact costs are more certain than gross returns.  It will make the results a little more like if you just used costs (option 4). This has the problem of finding the optimal value of 'factor'.
  6. Calculate weights using gross returns, and adjust subsequently for cost levels using some inverse-optimisation-Black-Litterman-Shtick. This is handy if you are pooling weights across instruments, rather than pooling returns. You can get the pooled weights with gross returns and then subtract costs.
  7. NEW (applies only if you are using shrinkage, my preferred option): Get your gross returns, which could be pooled. Shrink the SR estimates. Then subtract costs from the shrunk SR. This reflects the fact costs are more certain than gross returns but without the need to work out a factor as in option 5. If we are then using the averaged of unpooled, pooled and asset class pooled; we can do this for each and then take our average.
Some of these seem silly (2, 4). Some of them seem over complicated (5, 6). 

Then we have the thorny issue of how that would work with a super expensive instrument like Sugar, in which case it's likely that we'd fail both pre-optimisation filtering (1), and also end up with negative SR after applying costs (3 and 7). 

Right now I handle this with forecast weights by using a small subset of really slow trading rules for an instrument which fails the speed limit heuristic test. And I don't use SR at all, which means I ignore costs apart from the speed limit test. And I handle it with instrument weights by not using SR at all, which means once again that I'm basically ignoring costs.And things with SR cost over 0.01 will not actually be traded in DO, irrespective of their instrument weights.


Blimey Rob, it's complicated isn't it

So there is sort of a double standard here. And a bit of a mess. The cliff edge of 0.01 SR instrument costs where we start doing something completely different is a bit distasteful. Probably, as instruments get more expensive, there should be an impact on forecast weights but not neccessarily in a complete 1:1 way. Although this does go against the statement that costs are more predictable than returns. And perhaps the same is true of instrument weights; rather than keeping them but not trading them, perhaps we should be dialling them down somewhat. 

Here is the core dilemna, with DO we are (kind of) not trying to predict the returns of any individual instrument, but find the most cost effective way to implement a portfolio which represents our opinion on pre-cost price movements. But my previous research found that DO isn't completely effective at reducing the trading speed of expensive instruments.

Having given this much thought, I think my new favourite thing to do is this for forecast weights:
  • Set a ceiling on SR costs used for the optimisation at 0.01 SR
  • For pooled optimisations, pool gross returns across all instruments or within asset class, but use the costs for the individual instrument concerned to calculate net returns.
  • Shrink correlations and gross SR estimates
  • Then subtract the per instrument cost from the shrunk SR (#7)
  • Do the optimisation on the shrunk SR net of costs and shrunk correlations
  • Instruments which have current SR costs of greater than 0.01 would be ignored in the dynamic optimisation
Note this makes the cliff edge less problematic. I change my instrument overrides based on current costs much more frequently than my forecast weights. Consider something (instrument A) which has SR cost of 0.02 when I do the forecast weight optimisation, and instrument B with SR 0.005 at that time. We will end up trading the former as if it has a SR cost of 0.01 - so a little too quickly, but it will initially be removed from the forecast weight optimisation. Then suppose A and B swap, so B has SR 0.02 costs and A has 0.005. At this point we're going to be trading A a little too slowly, but fine; and B too quickly. Once I update my overrides though B will be excluded from the dynamic optimisation. I'm still 'trading' it too quickly, but I'm not actually trading it so I can relax.

Although we aren't worrying too much about instrument weights at this stage, we can use a similar approach for those except there is no pooling:
  • Set a ceiling on SR costs used for the optimisation at 0.01 SR
  • Get gross returns for each instrument
  • Shrink correlations and gross SR estimates
  • Then subtract the per instrument cost from the shrunk SR (#7)
  • Do the optimisation on the shrunk SR net of costs and shrunk correlations
  • Instruments which have current SR costs of greater than 0.01 would be ignored in the dynamic optimisation

A summary: 

Although not strictly within the remit of this post I think it is useful to summarise what my 'gold standard' forecast weight optimisation looks like after all the thinking and analysis I've done this year. It's effectively a nested set of functions. Here is some code that illustrates it:

op_shr_deduct_costs = ForecastWeightsOptimiserShrinkageDeductCosts()
opcluster_shr_deduct_costs = ForecastWeightsOptimiserClustering()
opcluster_shr_deduct_costs.set_optimiser(op_shr_deduct_costs)
op_rw_shr_cluster_deduct_costs = ForecastWeightsOptimiserReverseWeights() ## Clustering must go INSIDE reverse weights
op_rw_shr_cluster_deduct_costs.set_optimiser(opcluster_shr_deduct_costs)
op =ForecastWeightsOptimiserAcrossInstrumentsAveragePoolingGrossReturnsDeductCosts()
op.set_optimiser(op_rw_shr_cluster_deduct_costs)
wts = rolling_forecast_weights_optimiser_across_instruments(optimiser=op,
dict_of_instrument_spec=dict_of_instrument_spec,
forecast_pandl_across_instruments_and_forecasts=forecast_pandl_across_instruments_and_forecasts)

Going from the outside, inwards:
  • The outermost wrapper (rolling_forecast_weights_optimiser_across_instruments) does rolling pure out of sample optimisation, rerunning each year on a 30 year expanding then rolling window (in this post I recommended a 40 year EMA but that's equivalent to a 28 year SMA and this is nicer to code). We'll estimate both SR and correlations using this window.
  • Inside that is the pooling code ForecastWeightsOptimiserAcrossInstrumentsAveragePoolingGrossReturnsDeductCosts which does three optimisations for each instrument with different sets of gross returns, but using the costs of the actual instrument.
    • The gross returns of the instrument
    • The pooled gross returns of the asset class it belongs in
    • The pooled gross returns across all instruments
  • We then take an average of those three weights. This approach is justified here.
  • The optimisation inside that is a reverse weights wrapper (ForecastWeightsOptimiserReverseWeights). The reverse weights wrapper finds assets with negative gross p&l and reverses the sign on them. Once the weights are found, it puts a minus sign in front of the weights. This means we have no prior on whether a forecast has (pre-cost) positive p&l, thus reducing tacit fitting and opening up the possibility of finding strategies we didn't realise would work. 
  • Inside that is ForecastWeightsOptimiserClustering. That's a clustering, with a target cluster size of six, as discussed here.
  • Within each cluster we use ForecastWeightsOptimiserShrinkageDeductCosts. As noted above that means we shrink the correlation and gross returns SR (use shrinkage for optimisation with SR shrinkage 0.5, correlation 0.75 unless you have less than five years of data in which case use higher shrinkage) and then deduct costs from the gross returns SR.
The instrument weights code will be exactly the same, but without the pooling step.

Next blogpost will be to do some playing around with this model on a relatively small tractable portfolio.





Tuesday, 3 November 2026

Writing a non fiction book

 I get asked for advice from prospective authors a lot. The purpose of this post is to consolidate that advice into one handy to read place. If you came here for mean variance optimisation in the presence of uncertainty - skip this post.


Am I qualified to answer this?

(This is more from people finding this post randomly). I'd say yes. I've written five books, with total sales of over 40,000 copies (more statistics later) in the eleven years since my first book came out.

A list of my books is here: https://www.systematicmoney.org/. 

But bear in mind my experience is with a single publisher, writing in a specific genre. So I'm not an expert. This is very much my personal take. 


Why write a book?

Broadly speaking, I'd say people write non fiction books:

  1. to make money
  2. to indirectly make money by getting people to buy their course, hire them as consultants, to help get a job (probably only academics get jobs from writing books and not even then!)
  3. to boost their fragile egos
  4. out of a burning desire to teach as many people as possible

Note that 2 and 3 are all about writing a book to boost or burnish your profile in some way; whilst 1 and 2 are about making money. You are unlikely to make a lot of money directly from book royalties - it's a very long tailed, positive skewed call option. 

Of these I'd say 3 and 4 were definitely my main motivations up front; I have had a bit of 1 and 2. 

It's really important to understand why you are writing this book, as it will determine what sort of book you write, and what route you go down. For example:

  1. to have an outside option of making a ton of money write a more popular book through a 'big' publisher or self publish; for a lower standard deviation option write a less accessible, more technical book.
  2. for course selling you probably want an accessible book that you self publish and give away, for more esoteric technical purposes like consulting and academia you want a fancy sounding book through a reputable publisher.
  3. and 4. If you want lots of people to worship you write an accessible book, but you will probably want to do it through a decent publisher to get them to listen to you.


What area and level are you pitching at?

Often trite advice that is given is to imagine exactly who you are writing the book for. It helps if it's a real person! That person is your market. As already noted there is an obvious relationship between market size and accessibility. There is also a relationship with price. Books likely to sell in smaller numbers will have their prices set higher by publishers to cover the fixed costs. 

(Of course you can ignore this advice if you self publish, but you'd be stupid to do so...)

I'd describe my books as 'mid market' in terms of technicality, accessibility and price; ranging from LT (£30) up to AFTS (£60). Something like 'the blue book' would be an example of a highly technical with a very limited market. It's over £100 and has probably sold only a few copies outside of universities. Something like this would be 'mass market' (disclosure: I am in a chapter of that book). It's £30 and has probably sold a zillion copies. You can pick up paperback 'trading' books for £15 to £20.


Publish or self publish

I've published through a publisher for my entire career, whilst my mate Andreas has self published his last few books (disclosure: I wrote a chapter of one of those books).

The main benefit of self publishing is financial; you keep the net sales proceeds rather than just getting a royalty (more of that later). However you will have to pay all the up front costs, plus the production costs on each book. The maths of that means that self publishing won't break even until you've sold a fair amount of books. It's also more work. Although you can outsource most of that work it's a hassle up front to find decent people to do it (editors, designers ...), and they are not cheap. It costs money to do quality work.

There is nothing worse than a self published book that has been done on the cheap; the lack of quality really shines through. People might put up with that for a cheap fiction novel in kindle version, but I think they are less likely to accept it for a non fiction book; particularly in finance. I think it would be okay if you're creating something to give away to sell your dodgy forex course, otherwise quality is important.

I'd say for a first book definitely go through a publisher (which Andreas did, FWIW). Then you can make your own mind up afterwards.


Which publisher?

I've been with Harriman house since the beginning. They are now part of McMillan. They have been great for me, but there are obviously other very good publishers; in particular for more technical books Wiley are the G.O.A.T. whilst O'Reilly are good for tech focused stuff. The academic imprints are also good for textbook adjacent work.

If you're unsure about a publisher, have a look at their other books. There is a specific publisher I am constantly being spammed by on LinkedIn. Their books are of very poor quality. People are probably going to assume yours is as well.

Also, watch out for scams. There is a real trend for authors and potential authors to be scammed. I get these messages about once a week. There is an account of one attempt here.


Money, sales ... what can I expect?

Let me share with you some figures for my 1st book, Systematic Trading (ST) which came out in October 2015. It's sold a total of 20k copies which averages out to 1800 per year. In fact the sales are lumpy, from 1k to 3k copies in a given year. Generally books have a big initial sale period then slow down. ST's initial sales weren't spectacular as I wasn't very well known to begin with. ST did then have a slowing down period, but has since accelerated in the last few years. 

ST is an outlier however; my 2nd book Smart Portfolios didn't sell as well (my only book on investing rather than trading... hmm) and my 3rd book initially sold at a similar rate to ST but has since slowed down. My 4th book had really strong year one sale, much better than ST, but is now selling at a similar rate. Whether that's because I'm more well known now, or because it was a book with a naturally bigger market, I'm not sure.

According to the internet anything selling more than 5k copies in it's lifetime is 'very good', whilst over 10k lifetime copies would be a 'strong success'. Even if all my books were at end of life stage, which hopefully are not, all are in the 'very good' category whilst ST is a 'strong success'. I am a relatively succesful author in terms of my point on the distribution. Most books don't sell that well. There are many, many books with near zero sales.

To repeat you'd have a chance of higher sales with a more accessible book; but also a higher chance of very low sales. These sort of books are very much shit or bust. Sometimes there is a breakthrough and an esoteric book will sell a lot of copies to people who pretend to read it, but that's rare.

My sales are split around 35:65 between kindle and hardback; but I get higher royalties per book from Kindle sales (zero cost of production). Mass market books would have more ebook sales; more technical books would have more hardback.

In an ideal world all copies of my book were sold at full price by the publisher. However books get discounted and book sellers take a cut. As a result the net revenue is lower than the cover price. Books tend to get discounted more as they get older, and more expensive books also get discounted more as a percentage.

Book royalties are eithier paid as a % of the full price, or as a higher % of the net revenue. I can't disclose my royalty rate, but you can ask your favourite LLM for some figures. 

Anyway, in real terms I've made £223,000 from book royalties in the last eleven years. Again, that's lumpy - it will bump when a new book comes out - and it's also been higher in recent years as I've been selling four books at once rather than just one. Because most books slow down in sales (though not, so far, ST...) you really need to keep writing one every few years if you want to maintain a constant income. 

I would say each book takes me about a year of working on average 70% of the time. Call it 2000 hours. That means I've earned about £53 per hour from writing my first book and about £16 per hour from my 2nd and 3rd (my fourth lies in the middle; whilst my fifth isn't out yet). Obviously over time those figures can only go up assuming the books continue to sell. My books do require a fair bit of work and you could write a simpler book in less than 2000 hours; but to repeat they are relatively good sellers. 

I'd imagine the median author does not earn minimum wage. The lower figures there are slightly above that, but not by much! Of course even the higher figure is only a fraction of what I would be paid if I had continued working in a hedge fund...

Bear in mind I also do other things, mainly for free, which promote my books. That bumps the hourly rate down (and I have a few expenses like web hosting fees...). On the other hand, I have perhaps derived some other financial benefits from writing which don't show up in those figures. My hourly rate from consulting is many multiples of the figures above, and arguably I wouldn't have got most of that consulting work without writing the books.


Summary

Write a book! But don't do it for the money. If you have any more questions please comment below and I'll put the answers in the body of the post.

Friday, 4 September 2026

Not another one! My fifth book...

Well yes, I am pleased to announce that as of this week I completed final proof reading of my new book "The Art And Science of Trading"(AAST). It joins the list of my existing books with their  own acronyms: Systematic Trading (ST), Smart Portfolios (SP), Leveraged Trading (LT) and Advanced Futures Trading Strategies (AFTS).

Due to the inherent delays involved in global dead tree supply chains the book won't actually be officially published until 1st December, although if you pre-order now you will probably get your copy a little earlier. 

I also approved the cover art, which looks like this:



Briefly, what is this book about?

This is effectively four books at once (I know, cool trick right?!). Firstly, it effectively forms a counterpart to my third book Leveraged Trading (LT). LT is an 'introductory' book to trading properly with leveraged instruments; things like futures or spreadbets. Essentially, AAST is the delta-one counterpart to LT. It's an introductory level to trading properly without leverage - so where you can't take on bigger positions than your account value, nor can you go short. It covers the classic delta one instruments used by retail traders: shares, ETFs and ..... crypto (I'll address that particular block chain sized elephant in a moment).

Note: Yes I did cover shares and ETFs in 'Smart Portfolios' (book#2) but from an investment rather than a trading perspective.

Secondly, it's the most introductory book I've ever written, and aimed at more of a mass market (is that because I'm trying to educate as many people as possible, or is it because I want to sell a gazillion copies rather than modest five figures.... well a little of both). So there is a lot more hand holding than there is even in Leveraged Trading; plus more careful explanations of why you can't trust 'gurus', and I've  also stripped back my usual introductory trend trading strategy to the simplest possible rule set it can be without being dangerous (essentially using Occams razor to the point where you are about to cut yourself with it, but not quite). For example, the trend rule - which you can have for free as loyal readers of this blog - is 'has the price gone up or down'?

Thirdly, and this is in the title, I think there is a bunch of 'science' that all traders need to know about, even retail traders - nay, especially retail traders. And actually I go into far more detail about explaining this intuitively than I have in any of my previous books. Familiar concepts like proper robust backtesting, judging outcomes by distributional uncertainty, and of course my old mate the Kelly criteria are all in here. These are all explained in an accessible way from first principles.

Finally, and this is also in the title, it's about the art and science of trading. I came up with the idea of semi-automatic trading in my 1st book, and I used it again in my 3rd. So if you are one of those gifted people who can intuitively predict price direction better than a systematic method, that's lovely, but you should still do that within a systematic framework for position sizing and risk management. Essentially by putting a set of science based guard rails around your trading methods, you will make the most of a good method, and protect yourself from the worst excesses of a bad one. This also means someone using a crap 'systematic' method like <insert obscure japanese sounding charting method name here> won't lose too much money, and if they're lucky enough might even make some.

The relationship between my 5 books is explained quite well on this web page https://www.systematicmoney.org/which-book-should-i-buy where you can find this neat diagram:



A brief aside: Crypto. Rob-seriously?

Let me quote from page 25 of AAST:

I should state my own prejudices up front: I am not a fan of cryptocurrencies, which are used primarily for gambling and criminal activities such as money laundering, and which consume a great deal of electrical power, with obvious implications for the climate crisis. In an ideal world I would ignore them completely. Although I am retained as a research advisor for a crypto hedge fund, and I trade Bitcoin and Ethereum futures, I do not hold any crypto in my personal portfolio.

But the point of this book is to guide traders into using certain scientific rules to reduce their chances of losing money, and nobody needs those rules more than those trading crypto. The message of this book as it pertains to crypto can be summarised as ‘I would not do this stupid thing if I were you, but if you insist, this is the least stupid way to do it.’

(is this because I'm trying to educate as many crypto people as possible, or is it because putting crypto on the cover will increase the sales by a factor of a gazillion.... well a little of both)


Do I need to buy it?

If you're reading this blog, there's a good chance you tick all of these boxes:

  • I consider myself something of a financial expert, actually
  • I only trade leveraged instruments, like futures
  • I'm a fully systematic trader, not interested in this 'intuitive trading' sounds like woke nonsense to me.
  • I've already read your other books and I have a firm grasp on the concepts, thanks very much
So if you tick all of these boxes then you probably don't need to buy this book. Of course you may still want to, because:
  • You have already derived $x000's or even $x,000,000's of benefit from my existing books and blog at minimal cost, and chucking me another $x0 seems only fair
  • My writing style is so awesome that people will happily read my books for fun
  • It's probably worth being reminded of certain basic concepts and ideas
  • You never know, there could even be some deep insight within the book that even you haven't thought of before. As one reviewer said "Despite being an experienced market practitioner, this book really gave me new ideas when it comes to trading". Thanks Saeed, the next burger is on me!
  • You have a friend or relative who doesn't tick all these boxes, but has an interest in trading. And... Christmas is coming!
However if you are someone who ticks one or more of these boxes:
  • Is a relative beginner at this trading nonsense;
  • Is unfamiliar with, or struggled to understand, books like Leveraged Trading, Systematic Trading and Advanced Futures Trading Strategies;
  • Trades non leveraged instruments like ETFs, stocks or crypto;
  • Trades in a non systematic way
... then I'd suggest that you should seriously consider a purchase of AAST. The worst outcome would be that you'd read it, decided trading isn't as easy as you thought, and then decide not to trade. You'd be out the price of a book rather than losing hundreds or thousands of <insert local currency unit here>. 

Of course if you do decide to trade, then owning a copy of AAST will seriously improve your chances of successful trading. Naturally, actually reading and doing what it suggests will help even more.

Has anyone read this nonsense, and liked it?

Five people! And only three of them are mates of mine! Here are some nice things they wrote without me having to give them money (or got AI to write, I didn't ask):


Saeed Amen, Author of Trading Thalesians; Co founder Turnleaf Analytics (ex Lehmans FX, ex Thalesians)

I’ve always enjoyed Rob’s trading books, because they’re always very practical. This new book is useful both for novice and experienced traders. I like the way he creates a framework in the book for managing risk that is applicable to both discretionary and systematic traders. Crucially he takes you through the whole lifecycle of a trade, from position sizing to execution and the broader question of how to manage different assets in a portfolio. Despite being an experienced market practitioner, the book really gave me new ideas when it comes to trading.

Andreas F. Clenow, Chief Investment Officer and author of multiple financial bestsellers (his words!)

Rob Carver is an outlier among financial authors. He has managed billions at tier one institutions and he is a world class quant professional. Seeing his name on the cover of a book should be enough to buy it. I have all his previous books in my office and reference them often in my own work. This time, Rob brings his institutional perspective to tackle equities, ETFs, and crypto in the same structured and well-researched manner as his previous work. In particular, I enjoyed his ruthless analysis of crypto returns, day trading, and the separation of internet hype from the brutal reality of real-world, professional trading. I am clearing space on my office shelf for another book which I will read and reference many times, and so should you.


Alex Spiroglou, CFTe, Dip(TA) ATAA Semi-systematic macro trader

A highly insightful and practical read for anyone looking to improve their trading. Rob Carver cuts through the noise and shares a thoughtful approach grounded in experience, discipline and real-world market understanding. The book offers plenty to reflect on, whatever your trading style or experience level.


Tony Guida, Head of Quant Research AtonRa Partners

In a few words: I really liked it. It reads well and fast, and you got the ordering right. In my world almost all the effort goes into the opening signal and almost all the P&L comes from what surrounds it. Very few authors are willing to say that out loud, because "here is how to size a position" sells fewer books than "here is how to pick winners". The costs chapter and the trade management rules are what I would hand to a junior on day one. A few other things I liked. Chapter 12, on adjusting positions and stops when risk changes, is the chapter almost nobody writes and everybody needs. The forecast-based stop losses in 13 are the right way round: the stop follows the conviction rather than a round number on a chart. And I appreciated that the diversification section treat it as an operational problem, instrument substitution, and portfolio construction, not as a slogan about not putting eggs in one basket.

I should declare my bias. I would have happily read another two hundred page of formulas and python. But I am clearly not the main target here, and that is the point. Putting it in spreadsheets is what makes the rules usable by the people who need them, and the rules do not get worse for being written in Excel.

My humble endorsement: “A discretionary trader and a systematic PM can read this book and end up agreeing with each other, which almost never happens unless the building is on fire or bonuses are at stake. Carver's argument is that you can keep your intuition for choosing what to trade, provided everything about how you trade it follows rules. Thirty years of experience compressed into procedures that fit in a spreadsheet, with no equations and no black boxes. He has written something a beginner can act on and a professional cannot argue with.”


Sam Beatson, PhD, EMBA, FRSA Lecturer in Finance, Risk and Banking Nottingham University Business School and CEO, MarketNous

Robert Carver has managed to combine a rigorous approach with accessibility, without pretending that trading in markets is anything other than demanding and challenging. The Art and Science of Trading is the perfect primer to the wider Carver canon, but also stands strongly in its own right as a practical and intellectually grounded guide to trading.

One of the book’s most useful contributions is the distinction between the art of finding trades and the science of managing them. Carver gives intuition, judgement and experience a legitimate place in trade-finding, while making a persuasive case that position sizing, costs, risk and trade management demand much stricter, rules-based discipline.

He shares his expertise on the less glamorous but essential aspects of trading: randomness, overfitting, transaction costs and the difficulty of distinguishing genuine skill from good fortune. Rather than looking for shortcuts, the reader is encouraged to question apparently impressive results, understand why a strategy should work, and think carefully about whether an edge is likely to survive beyond the historical data in which it was discovered.

In characteristic Carver style, you’ll find answers grounded in evidence, scepticism about any easy path to market profits, and an abundance of practical lessons for new and experienced traders alike.”

Seems appropriate to say thank you

Yes, I do have a list of thank yous:
  • The panel of Elite Traders who helped me pierce my Anglocentric bubble and get a better understanding of the international landscape for retail traders: Alexey Chursanov, ‘Elder’, ‘Kernfusion’, Matthijs Vákár, Professor Paul Calluzzo, Goran Peretin, Dr Sebastian Schmidt, and Vikram Mundkur.
  • A couple of key crypto people from Twitter/X: Crunchster and Scott Phillips. They didn't know they were contributing to a book but their posts were very helpful in my research process.
  • My sister Vicki and my 'sister' Debbie who forced me to write their names into the book despite me insisting it wasn't a novel. This isn't really a thank you, it's documentary evidence I will need for the police report.
  • The expert reading panel: Burak Yenigun (of Stylus Digital) and Riccardo Ronco (of recently retired). This is an unpaid position requiring many hours of reading the first draft of my prose. Which is awful. I can barely read it myself. And the only reward is a signed copy and passive aggressive responses from me ignoring nearly all their comments. Why do they do it? To get this brief mention in a blog post only 50 people will read? I guess.
  • Various random people from my publisher Harriman house: Myles, Victoria, both Charlottes, Sally, Lucy and Suzanne
  • Editors: Comissioning - Craig Pearce, Copy - Dominic Fenn, Proof - Amy Webber (who also as assistant editor has assidously guided this book on it's journey from concept to physical copies). This is a paid position requiring many hours of reading the 2nd, 3rd, 4th..... 89th drafts of my prose. And you can't get AI to do it. Because AI would be like "This is great! Just needs more em-dashes and it would be perfect".
  • The people who live in my house with me (some or all of the time) and put up with all my nonsense.

Is that it then? No more books? <slightly pleading voice>

Ha! If only. No, I'm currently in the early stages of thinking about book#6 which will provisionally be  a relatively advanced book about backtesting. And I'll probably stick AI on the cover to get some more sales.


Note: for those that don't understand the 'not another one' it's a UK political reference to 'Brenda from Bristol' 

https://www.reuters.com/article/world/us/not-another-one-brenda-from-bristol-speaks-for-britons-sick-of-elections-idUSKBN17L1FX/

To see Brenda live, watch the first 5 seconds of this video:




Friday, 3 July 2026

Jumping back in the pool(ing): testing pooling by asset class and portfolio weight distance

This is post #10 in my 2026 series on portfolio optimisation. Time for a quick recap. I'm not going to revisit every post but instead summarise what I now think one should be doing when optimising forecast weights before costs (I haven't yet incorporated costs, nor thought about instrument weights).

(I also confirmed in my very first post it was better to estimate forecast then instrument weights, rather than doing them jointly).

That doesn't seem like much value for the thousands of words I've written, and it's also not a million miles from what I would have down without all this research. A few things haven't worked out: random based methods (bayesian and monte carlo) which don't account for the reduced predictability of real returns compared to synthetic data; formal structural breaks on estimates; grouping and pooling instruments according to forecast SR; shorter EWM windows for SR estimates; and shrinking weights rather than inputs. 

I should probably move on now to looking at costs, and instrument returns, but like a dog with a particularly tasty bone or a cat pulling on an especially interesting piece of string; I can't quite let go of the idea that we should be able to improve on pooling everything.


Prior art

Let's run through the options we potentially have for pooling:

  1. We could cluster things together that have similar characteristics, such as by asset class. 
  2. We could do it on an estimate by estimate basis. We could compare the distribution of returns for say carry10 on US10 year bonds, and on US2 year bonds; and say "Well these distributions aren't significantly different. Let's pool the returns together". 
  3. Or we could look at the estimates of SR across different rules. You could have a vector of the SR for carry10, carry20 and so on. And you'd look at that vector of estimates, and calculate <some measure of> distance between them, and if the distance is low enough, then you'd pool the returns for all the rules for those two instruments.  I covered this in my previous post in this series. 
  4. Or we could do it on portfolio weights. We could for example fit the weights for 2 year bonds, and for 10 year bonds, and then see if they were significantly different. We could then pool the returns if they were not that different. I have also looked at this before.
  5. We don't pool at all, and fit each instrument individually. That sounds terrifying, but remember we're shrinking with our fitting.
  6. We pool everything. So far that seems to the best option, and the one I've used in the past. 

Note that we also have the option of:

  • A pooling the returns before estimating the statistics and then the weights
  • B not pooling the returns, and then pooling the weights
I'm not keen on B because it produces 'over robustness' when combined with a shrinkage methodology. Basically we throw away too much information and end up too close to equal weights.

So returning to the numbered list:

  1. By asset classes - is untried, although it resembles what we used to at AHL when we were organised into asset class teams, each of which fitted their own strategies.
  2. Grouping per estimate: I have objections to in terms of computational time and statistical unpleastness, discussed in the previous post.
  3. Grouping per vector of estimates: I tried this in the previous post. It wasn't effective, and also produced weird undesirable groups.
  4. Grouping by weights: I have tried before in a limited test with some success.

So that leaves us with 1 and 4 as candidates, along with the standard options of #6 full pooling and #5 no pooling at all - fitting each instrument's forecast weights purely on it's own data:

  • Unpooled
  • All instruments pooled
  • Asset class pooled
  • Grouping by portfolio weights


By asset classes - method

This is pretty trivial; the eight asset classes in my system are:

  • Stock indices (58 instruments in my dataset including duplicates and expired instruments like Eurodollar to avoid survivorship bias)
  • Sector stocks (eg 'EU oil companies') 36 instruments
  • Vol 4
  • FX 43
  • Bonds and STIR 39
  • Energies 20
  • Agricultural 39
  • Metals 21 (includes two crypto futures)

So for a given portfolio we fit those instruments in the same asset class together.


Grouping by weights

Well this is easy, as I already did this here and under the heading "get instrument groupings" it tells us we can use k-means clustering and there is even some code there for me to copy and paste. An important difference between this and the grouping by SR vector is that correlations will also be taken into account, at least in an implicit way.

One open question that remains is whether the grouping is done on portfolio weights that have been derived using a shrinkage method, or on weights that haven't (just using naive mean variance). I felt it was better to use 'purer' weights which hadn't used shrinkage so we don't end up discarding useful differences.

As I did in my prior post in this series, let's run the grouping exercise on my entire portfolio. Partly for laughs, and partly to see if the grouping makes sense. How many groups/clusters should we use? Well there are 7 substantive asset classes, excluding vol:

Cluster 0, length 16

BTP3, CANOLA, EU-FOOD, FED, GBPCHF, GOLD_micro, HIGHYIELD, LIVECOW, OMX, R1000, SILVER, SP500_micro, US-INDUSTRY, WHEAT, YENEUR, ZAR

Ags: 3, Metals: 2, Equity: 3, FX: 3, Sector: 2, Bond: 3


Cluster 1, length 29

BRENT_W, CNH, COAL-GEORDIE, COCOA, COFFEE, COTTON, ETHER-micro, EU-AUTO, EU-DJ-TELECOM, EU-DJ-UTIL, EU-MEDIA, EU-REALESTATE, EU-TECH, FTSETAIWAN, GBP, HEATOIL, KOSPI_mini, MILK, MSCIEAFA, MSCISING, OATIES, OJ, RUBBER, SEK, SMI, SONIA3, US-DISCRETE, US2, VNKI

OilGas: 3, Ags: 7, Metals: 1, Equity: 5, FX: 3, Sector: 7, Vol: 1, Bond: 2


Cluster 2, length 20

CAD10, CH10, CHF, CHFJPY, COPPER-micro, CZK, FTSECHINAA, FTSEINDO, IRON, JGB, JGB-SGX-mini, JP-REALESTATE, MUMMY, NIKKEI, SGX, SOYBEAN_mini, SOYOIL, TOPIX, US-ENERGY, US-HEALTH

Ags: 2, Metals: 2, Equity: 6, FX: 3, Sector: 3, Bond: 4


Cluster 3, length 12

AUD_micro, EU-INSURE, FTSE100, FTSECHINAH, GASOIL, HANG_mini, HOUSE-US, NASDAQ_micro, NOK, NZD, US-STAPLES, US-TECH

Sector: 4, Equity: 4, FX: 3, OilGas: 1


Cluster 4, length 16

ALUMINIUM, AUDJPY, BITCOIN, BOBL, BONO, BUND, BUXL, CORN, DOW, GBPJPY, MILKDRY, OAT, RICE, ROBUSTA, SHATZ, STEEL

Ags: 4, Metals: 3, Equity: 1, FX: 2, Bond: 6


Cluster 5, length 79

BB3M, BBCOMM, BRE, BTP, BUTTER, CAD, CHEESE, CHINAA-CON, COAL, COCOA_LDN, COPPER_LME, COTTON2, CRUDE_ICE, CRUDE_W_micro, DJSTX-SMALL, DX, EU-BANKS, EU-CHEM, EU-CONSTRUCTION, EU-MID, EU-OIL, EU-TRAVEL, EURCAD, EURCHF, EURIBOR-ICE, EUROSTX, EUROSTX-SMALL, EUR_micro, FANG, FEEDCOW, FTSE250, GAS-PEN, GASOILINE, GAS_US_mini, GICS, GILT, HANGENT_mini, IBEX_mini, IG, INR, IRS, JPY, KOSDAQ, KR10, KR3, LEAD_LME, LEANHOG, LUMBER-new, MIB, MILKWET, MILLWHEAT, MSCIEMASIA, MSCITAIWAN, MSCIWORLD, MXP, NICKEL_LME, PALLAD, PLAT, REDWHEAT, SARONA, SGD, SMI-MID, SOFR, SOYMEAL, SP400, SPI200, SUGAR11, SUGAR16, SUGAR_WHITE, TIN_LME, TWD, US10, US20, US5, V2X, VIX_mini, WHEAT_ICE, WHEY, ZINC_LME

OilGas: 6, Ags: 18, Metals: 7, Equity: 16, FX: 12, Sector: 6, Vol: 2, Bond: 12


Cluster 6, length 32

AEX, BOVESPA, BRENT-LAST, CAC, CAD2, CAD5, CLP, DAX, EU-BASIC, EU-DIV30, EU-HEALTH, EU-HOUSE, EU-RETAIL, EUA, EURAUD, EURO600, FTSEVIET, GBPEUR, HANGTECH, KRWUSD_mini, MSCIASIA, PLN, RUSSELL, SWISSLEAD, US-FINANCE, US-MATERIAL, US-PROPERTY, US-REALESTATE, US-UTILS, US10U, US3, US30

OilGas: 2, Equity: 11, FX: 5, Sector: 9, Bond: 5

There doesn't seem much congruency with asset classes there. Is this "the data speaking to us", or are we just data mining with a very sharp spade? Let's find out.


Testing

In my older post, here, I did a rather simplistic 'one shot' test on a subset of my available instruments and forecast rules (albeit on a rolling out of sample basis). But I have a rather more exhaustive way of doing things I've been using in this series. 

I cycle through different lengths of in sample (5 years, 10 years, 20 years) and out of sample (1 year and 5 years) lengths of time. For shorter time periods that will allow me to subsample different historic periods. For speed and to get some alternative paths I'm not going to consider all the instruments. Instead I will randomly subsample 50 instruments randomly out of the 214 available. 

Then for a given set of returns I will eithier use fully pooled, asset class pooled, portfolio weight pooled, or unpooled returns. Then I will optimise for each instrument based on the relevant returns, using the shrinkage method with SR shrinkage of 0.5 and correlation of 0.75. Finally I will take the equally weighted across instruments portfolio SR for the 50 instruments, out of sample. 

In previous posts I've discussed a more honest way of backtesting, where we include the opposite of a given trading rule to avoid implicit fitting; and then only bring positive SR rules into the optimisation. All the results here will use that methodology exclusively.


5 years in sample, 1 year out of sample

You should hopefully recognise this format from before. Each row is a fitting option. The first column shows the median SR across the many, many runs of random resampling. The second column shows the t-test p-value from comparing the best option with the others. NaN means this is the best option. A low number in this column, say below 0.01 or 0.05, indicates that the best option is statistically significantly better than the other option.

                           SR  pvalue

unpooled                 0.046     0.0

all pooled               0.425     0.0

asset class pooled       0.557     NaN

weight distanced pooled  0.184     0.0

That is ... pleasing. The least robust method is worse. More robust methods do better. And we get a significant improvement from pooling within asset classes. OK the portfolio weight distancing isn't so good, but we haven't got huge amounts of data to form our portfolio weights with so maybe they are a little unstable.


5 years in sample, 5 years out of sample

                            SR  pvalue
unpooled                 0.418     0.0
all pooled               0.391     0.0
asset class pooled       0.731     NaN
weight distanced pooled  0.376     0.0

Unpooled does a little better here, but asset classes are still the way to go.

10 years in sample, 1 year out of sample

                            SR      pvalue
unpooled                 0.664     NaN
all pooled               0.417   0.000
asset class pooled       0.635   0.127
weight distanced pooled  0.415   0.000

OK interestingly unpooled is making a comeback, but it still isn't significantly better than asset class pooled.

10 years in sample, 5 years out of sample

                            SR  pvalue
unpooled                 0.855     0.0
all pooled               0.575     0.0
asset class pooled       1.028     NaN
weight distanced pooled  0.559     0.0

Asset class is again asserting it's dominance with unpooled a close second.

20 years in sample, 1 year out of sample

                            SR  pvalue
unpooled                 0.571     0.0
all pooled               0.469     0.0
asset class pooled       1.127     NaN
weight distanced pooled  0.410     0.0

OK this is getting a bit silly. I feel like the dad whose kid at sports day is winning everything, proud but also getting a little embarrassed. "Now come on jonny, let one of the other kids win the next one". 

Interestingly it does seem with more data that unpooled is the way to go for a second option.


20 years in sample, 5 years out of sample

                            SR  pvalue
unpooled                 0.251     0.0
all pooled               0.569     NaN
asset class pooled       0.551     0.0
weight distanced pooled  0.553     0.0

"Well done Jonny. Everyone knows you could have won it if you wanted but it's good to show good sportmanship"

So all pooled finally gets it's day in the sun albeit with a slim advantage over the other two pooled methods. Bear in mind only 65 instruments have sufficient history here; with only 18 having two distinct blocks of 25 years so there won't be much genuine variation if we choose 50. So this could be a fluke. Jonny will tell you that it is.


But Rob, What about averaging?

At this point, given the choice between the complexity of weight distancing, and the simplicity and efficiency of asset class pooling; I'm inclined to go with the latter. And it's what we were doing at AHL all those years ago (not because of empirical evidence but because it suited the organisational structure...).

However there is another option which I talked about in the original asset class pooling post, using a blend. Here we take an average of the portfolio weights selected with different methodologies. So that would be an average of:

  • Unpooled
  • All pooled
  • Asset class pooled
Blending weights in this way is a way to improve robustness. It's arguably the correct thing to do, since otherwise we'd be making an in sample choice of methodology - 'meta implicit fitting' if you will. One of my favourite research shops, Resolve asset management, are very keen on doing this. One potential downside is it might be producing 'over robustness' given we're using weights that have already had shrinkage. But let's find out.


5 years in sample, 1 year out of sample

Note these numbers won't be exactly the same as those above, since they're a different set of random experiments. They would eventually converge but it would take millions of runs.

And also, just for fun, I've added an extra column. I started off this series of posts talking about the importance of considering other points of the distribution but I've quietly dropped that and only been quoting the median. For balance then, I've added the 25% SR point as well as the median. The pvalue is as before.

                    SR median  SR 25%  pvalue
unpooled                0.025  -0.569     0.0
all pooled              0.475  -0.147     0.0
asset class pooled      0.620   0.045     0.0
average                 0.650  -0.067     NaN

Averaging is the winner - just - but asset class is better at the more conservative point.

5 years in sample, 5 years out of sample

                    SR median  SR 25%  pvalue
unpooled                0.428   0.164     0.0
all pooled              0.430   0.243     0.0
asset class pooled      0.771   0.537     NaN
average                 0.664   0.430     0.0

A clear win for asset class pooled here. Averaging suffers from it's association with the less performative unpooled / all pooled.

10 years in sample, 1 year out of sample

                    SR median  SR 25%  pvalue
unpooled                0.681   0.034     0.0
all pooled              0.452   0.067     0.0
asset class pooled      0.664   0.167     0.0
average                 0.935   0.256     NaN

This time averaging takes the win, helped by the good performance of unpooled.

10 years in sample, 5 years out of sample

                    SR median  SR 25%  pvalue
unpooled                0.887   0.641     0.0
all pooled              0.570   0.406     0.0
asset class pooled      1.066   0.833     NaN
average                 1.005   0.780     0.0

Asset class pooled is still the winner, but averaging gives a good job.

20 years in sample, 1 year out of sample

                    SR median  SR 25%  pvalue
unpooled                0.538  -0.209     0.0
all pooled              0.515   0.154     0.0
asset class pooled      1.167   0.539     NaN
average                 0.809   0.252     0.0

Asset class pooled by more of a margin now.

20 years in sample, 5 years out of sample

                   SR median  SR 25%  pvalue
unpooled                0.243   0.084     0.0
all pooled              0.531   0.414     NaN
asset class pooled      0.513   0.391     0.0
average                 0.461   0.355     0.0

As before 'all pooled' is the winner, whilst average is dragged down by the poor performance of unpooled. But as I said above, with these longer periods it's hard to know if it's just down to flukey instrument selection.

What to do...

There is enough evidence above to justify asset class pooling as the dominant choice. But equally, I don't think there is enough to discard averaging. And there is something so neat about averaging. We combine three quite disparate source of data together, so we're protected if one of them doesn't work out. It's robustness writ large! It can be justified without any in sample fitting - whereas one could argue that the selection of asset class pooling is an implicit in sample 'meta parameter' choice.

I think we're now (finally) ready to fit our forecast weights, and with costs. This is exciting for me, as whatever comes out I will be using as my new weights. This will be more of a 'literature review' since I've talked about optimising with costs in some detail and at some length before.

Monday, 29 June 2026

Rolling, rolling, rolling.... updating statistical estimates yes or no

 The mega blog post series on portfolio optimisation continues!

A couple of posts ago, here, I looked at using the idea of formal testing for structural breaks in parameter estimates. Important parameters like Sharpe Ratio (SR). Because stuff like this happens:


This is the pre-cost performance of the momentum4 rule on CORN. The formal test found a structural break in 1989.

It's fair to say the structural break stuff didn't work that well. But there may be a much easier way of dealing with the non stationarity of these estimates, and that's to use rolling estimates. For example, if you were to use a 10 year rolling estimate of SR then by the mid 1990s we would conclude that this was a money losing rule. We could also use a rolling estimate for correlation, though as these are stable enough over periods of five years or more this wouldn't affect things much.

Of course I wouldn't be so crude as to use a mere rolling window, instead I'd use an exponential window. As usual I'm going to specify this using the span parameter of the pandas ewm function. A 10 year span has a 3.5 year half life; i.e. the 10 year EWM is roughly equivalent (same halflife) to a 7 year simple moving average.


The test

Regular readers will know exactly what to expect here, but for those that aren't regular here is how I test this procedure to be as sure as possible there is no luck involved.

  • Select 10,20,30 or 40 years of in sample data (shorter periods won't make sense to apply an exponentially weighted [EW] estimation)
  • Select 1 or 5 years of out of sample data
  • Pick a random instrument, ensuring there is enough history available (between 11 and 45 years). We will only choose from instruments with sufficient history for the time required. 
  • Randomly pick N=9 forecasting rules from those available (the same as in previous posts)

Then for each of those sumsamples:

  • Cycle through using an exponentially weighted [EW] span of 5,10,20,30 years; and no span (use all available history). For shorter in sample periods the EW results using longer spans will be very similar to those without EW estimation.
  • Estimate SR using the EW span.
  • Estimate correlation using all the in sample data (we could use an EW span here, but correlations are sufficiently stable that it won't unduly affect results).
  • Use fixed shrinkage levels (estimated here): SR shrinkage 0.5, correlation 0.75 (since we'll always have at least five years of in sample data we don't need to worry about the higher levels of shrinkage required when we have insufficent data). The results won't be much different with any vaguely similar shrinkage; you could argue we'd need more shrinkage with shorter EW spans but I am not going to test this.
  • Run in sample optimisation and out of sample optimisation on all the options above

Finally once we have all our subsamples:

  • Get the median SR from the distribution of subsamples
  • Find the optimal EWM span with the higest median SR
  • Test to see if that optimum is significantly higher than the others

As I also did in my last post I'm going to see if the figures are different without any implicit fitting. To achieve this I include the opposite of a given trading rule as a candidate; and then when I come to do optimisation I pick the version that has a positive SR (there are no costs, so the SR will be identical with a negative sign).


10 years in sample, one year out of sample

We only have five optionts to consider so we can do this in a simple table.

         SR  pvalue
5 0.026 0.065
10 0.021 0.026
20 0.033 NaN
30 0.030 0.042
999999 0.017 0.131

Each row is a different EW span. '99999' means the entire in sample period was used. The next column is the out of sample Sharpe Ratio for each option. In the second column is the p-value for a test of the optimal option against the relevant option. NaN is the optimal option, and lower values (say below 0.05) mean the optimal option is significantly better than the alternatives. We can see that a 20 year span is the optimal, and it's a little better than the other alternatives but not significantly better than the entire in sample period.

Do the results differ when we don't preselect only the 'correct' rules?


SR pvalue
5 0.076 0.188
10 0.093 NaN
20 0.085 0.186
30 0.087 0.169
999999 0.083 0.236

Nothing is really significant there.


10 years in sample, five years out of sample


SR pvalue
5 0.201 0.009
10 0.215 NaN
20 0.214 0.078
30 0.211 0.277
999999 0.199 0.271

SR pvalue 5 0.093 0.000 10 0.112 NaN 20 0.104 0.339 30 0.104 0.466 999999 0.110 0.533

Here we do get better performance with anything more than 5 years.

20 years in sample, one year out of sample

          SR  pvalue
5 -0.154 0.892
10 -0.170 0.687
20 -0.163 0.610
30 -0.164 0.647
999999 -0.138 NaN


          SR  pvalue
5 -0.202 0.006
10 -0.135 0.011
20 -0.110 0.029
30 -0.097 0.059
999999 -0.055 NaN

Longer estimates are better.

20 years in sample, five years out of sample


SR pvalue
5 0.093 0.000
10 0.119 0.000
20 0.134 0.026
30 0.132 0.043
999999 0.149 NaN
          SR  pvalue
5 0.061 0.000
10 0.111 0.003
20 0.129 0.070
30 0.131 0.071
999999 0.140 NaN

Yes, longer estimates are better.


30 years in sample, one year out of sample


SR pvalue
5 -0.073 0.0
10 -0.078 0.0
20 -0.031 0.0
30 -0.005 0.0
999999 0.042 NaN

SR pvalue 5 -0.132 0.007 10 -0.152 0.000 20 -0.156 0.000 30 -0.104 0.000 999999 0.000 NaN


Same story, slightly different numbers.

30 years in sample, five years out of sample

          SR  pvalue
5 -0.038 0.0
10 -0.031 0.0
20 -0.017 0.0
30 -0.006 0.0
999999 0.008 NaN


SR pvalue
5 -0.050 0.001
10 -0.046 0.003
20 -0.038 0.003
30 -0.029 0.003
999999 -0.017 NaN


40 years in sample, one year out of sample


SR pvalue
5 -0.135 0.145
10 -0.113 0.023
20 -0.110 0.001
30 -0.090 NaN
999999 -0.150 0.947

Again, we basically want a very long estimate.
          SR  pvalue
5 -0.159 NaN
10 -0.224 0.044
20 -0.236 0.028
30 -0.238 0.072
999999 -0.254 0.061

That was a little unexpected.

40 years in sample, five years out of sample


SR pvalue
5 -0.049 0.0
10 -0.040 0.0
20 -0.029 0.0
30 -0.021 0.0

999999 -0.015     NaN    


SR pvalue
5 -0.097 0.000
10 -0.064 0.000
20 -0.016 0.006
30 -0.006 NaN
999999 -0.029 0.703


Conclusion

I'm a big believer in publishing (well blogging) research even if it doesn't result in a positive result. And certainly it looks like you don't really gain anything from using exponentially weighted estimates of Sharpe Ratios for optimisation, versus the simpler alternative of using all the data. Still there is that nagging feeling that we should at least have the option of dropping something that hasn't worked for a while which implies a very slow EWM. A 30 year EWM span has a 10.3 year halflife, the same as a 20 year or so SMA; whilst a 40 year EWM span is equivalent to a 28 year SMA. 



One of These Things (Is Not Like the Others). Or is it? Pooling rule p&l estimates across instruments.

 This is the eighth post in a series I'm writing on portfolio optimisation. I haven't done one of these for a few posts, so here is the story so far:

  • In the first post I showed that if you are optimising across forecasts from different trading rules and instruments, then you should first fit within; and then across, instruments. As I do anyway.
  • In my second post I ran some experiments with optimising with random data. The results showed a supreme indifference between joint winners: monte carlo and bootstrapping, and a shrinkage methodology with a tiny bit of SR shrinkage. 
  • For post three I showed that the predictability of sampling distribution of parameter estimates was much worse with real data than with random data.
  • Number four, saw me rerun post #2 with real data. A middle ground of some shrinkage was the winner across most time periods; unless the in sample period was too short.
  • Post number five was a twist on Bayesian shrinkage and an abject failure.
  • Number six was about clustering. It turns out clustering is good, though not staggeringly so. A cluster size of six was arbitrarily chosen as being reasonable enough.
  • The post whose number is seven was about structural breaks in estimates of SR. For forecast/instrument pairings these occur between 13% and half the time depending on the critical value used. However out of sample optimisation did not show a significant SR improvement if only history after a break was used for estimation.
This post has something in common with number seven. We know that we want more data for estimation. We can get more data with more frequent data (not helpful if you are trading slowly) or more history of data. For more history we only want history that is relevant. If the history occured before a structural break then we should throw it away (at least in theory - that didn't work so well in practice).

There is another way to get more data and that is in the cross section. For example, we could combine the p&l for the trading rule momentum16 across all the US government bond futures, or the entire fixed income sector.  Alternatively we could go the whole hog and combine all the p&l across every future (all this is ignoring costs, which are different for each instrument, and would have to be deducted ex-post this exercise). 

A key question however when doing this is 'are these things similar enough'. For example, should we use the same SR estimate for momentum16 across all instruments. Or can we say that a particular instrument 'just doesn't trend well'? Consider Cocoa, the stand out star of many trend following portfolios in 2024. Here is it's performance using the momentum16 trading rule:

Is it wise to assume that a particular instrument is poor at trending, just because it has been historically (or at least from 1980 to 2020)?

Note: this isn't the same as assuming a particular instrument is poor - that decision will come when we look at instrument weights.

Some of you might remember this plot from my third book, Leveraged Trading:

That shows the SR for that same trading rule, momentum16, with error bars across the data set used in the book. The error bars suggest that there aren't any SR that are statistically different from each other, so we should pool everything.

If I recalculate these numbers usign the 214 instruments in my current data set, excluding duplicates, then the estimated SR trading momentum16 varies across instruments from between -1.85 and 1.95. That range is, to be fair, larger than in the plot above.
 
If we test the SR difference between the samples of the worst and best instrument (Lead-LME and House-US FWIW) we do get a significant t-statistic (around 4 to 5, depending on whether we only test on the overlapping period or do an independent test of all the data from both instruments). So they are significantly different. It's even more impressive when you consider there are only 3 or 5 years of data used to make this evaluation (again eithier the overlapping or the entire time period). The p-value is around 0.003%. Much less than the p-value we would crudely expect to see by fluke with 214 instruments (which would be a little below 0.5%). 

It's also worth noting that this is quite a wide range of p&l for a trading rule: from -1.85 to 1.94 is a range of 3.8. For momentum64 it's from -1.0 to +1.35; and for carry10 it's from -0.86 to 1.46. The wider ranges of SR seem to be only present for the faster trend style rules; a range of 3.1 SR units for momentum4 (from -1.0 to +2.1 pre costs), 2.8 for breakout10, 3.3 for relmomentum10 and so on. Some of those more extreme figures are because some instruments don't have as much data (in the box plot above, they'd have wider boxes).

But could this just be luck? What kind of SR range would you expect across 214 random gaussian p&l streams with an underlying expected SR of 0.19 and say 4 years of data? The answer is about 2.68; with a 90% range of 2.44 to 3.11. Another way of looking at a distribution is the cross sectional standard deviation, across 214 random instruments the standard deviation of SR estimates with 4 years of data is around 0.5 (and that is much more stable than the range). 

Now, if we subsample random 4 year periods for each instrument across the actual performance of momentum16 we get much bigger numbers. The SR range is around 3.88, and the standard deviation comes in around 0.59. So we can see that the real data has around a fifth more variability than what we'd expect purely from randomness.

Those four year cross sectional standard deviations come in at similar values for all trading rules; the lowest is 0.53 (momentum64) and almost all are between 0.5 and 0.6 with one standout exception: a value of 0.866 for mrinasset1000 (a slow cross sectional mean reversion within asset classes). 

All this arseing around is just to confirm that there is indeed more cross sectional variability in SR estimates than luck would suggest. Which means it is possible that full pooling (use all data to estimate everything) approach might be beatable by another more selective pooling approach.


Some selective pooling approaches

There are a number of ways we could approach this exercise:

  1. We could cluster things together that have similarities, such as by asset class. I have done this in the past but it is slightly unsatisfactory to use a method which could have subjectivity and can't 'learn' from the data. Let's ignore that for now.
  2. We could do it on an estimate by estimate basis. We could compare the distribution of returns for say carry10 on US10 year bonds, and on US2 year bonds; and say "Well these distributions aren't significantly different. Let's pool the returns together". 
  3. Or we could look at the estimates of SR across different rules. You could have a vector of the SR for carry10, carry20 and so on. And you'd look at that vector of estimates, and calculate <some measure of> distance between them, and if the distance is low enough, then you'd pool the returns for all the rules for those two instruments.  
  4. Or we could do it on portfolio weights. We could for example fit the weights for 2 year bonds, and for 10 year bonds, and then see if they were significantly different. We could then pool the returns if they were not that different. In fact I have looked at this before*.
* Note: we could also take an average of the weights, but that risks 'over robustness' if the weights were already produced using some kind of shrinking technology; i.e. you would end up averaging the weights too much.

An advantage of the second approach is we don't need to worry if instruments have different sets of trading rules available to them. Another is that it's obvious what significantly different means - we can just run plain vanilla t-tests like we did with the previous post on structural breaks at some critical value (CV). A disadvantage is that we need to do a lot more computation (one set for every rule seperately); yet another is that because we are testing so many things the danger of finding false positives is greatly increased. The standard response to this is to reduce the CV but then we're likely to miss some real differences. Yes, the classic dilemma of statistical testing.

For the third and fourth approaches we're basically saying "is this instrument like this other instrument".  That radically reduces the set of comparisons we have to do (just comparing instruments with instruments). The disadvantage is that it's harder to compare instruments with different rules; though not impossible. If the rule sets are similar enough then we can do our comparisons with a zero weight to the missing rules; and then just add back the rules that aren't in the shared dataset. Then we have the calibration of significance. We can use random data, like I did above, to work out what the likelihood of a particular distance between estimates or weights happening by pure fluke. 

It goes get difficult however to incorporate missing or additional forecasts when we are comparing weights. But that's straightforward with the third method. If some rules are missing from the pooled returns, then we can just calculate the additional statistics we need using returns only for that instrument.

Note that all four approaches can incorporate different cost levels. We just do everything in pre-cost world, and then as a final step deduct costs from the gross returns before optimising a given instrument. Note we couldn't do that as easily if were averaging weights for the third approach.

As I have looked at using weights before, I'm going to look at SR based grouping in this post - approach #3. So to be clear what I am doing is:

"Look at the estimates of SR across different rules. You could have a vector of the SR for carry10, carry20 and so on. And you'd look at that vector of estimates, and calculate <some measure of> distance between them, and if the distance is low enough, then you'd pool the returns for all the rules for those two instruments."


Calibrating the threshold

This then is the sort of thing we are looking at:

               US10   US5  SP500
breakout10    -0.02  0.10  -0.43
breakout20     0.23  0.28  -0.08
breakout40     0.36  0.39   0.07
breakout80     0.35  0.38   0.25
breakout160    0.28  0.30   0.34
breakout320    0.30  0.41   0.37
relmomentum10  0.09  0.23  -0.15
relmomentum20 -0.02  0.11  -0.10
relmomentum40  0.12  0.13  -0.14
relmomentum80  0.17  0.26  -0.13
mrinasset1000 -0.06 -0.15  -0.49
carry10        0.51  0.50   0.10
carry30        0.53  0.50   0.10
carry60        0.53  0.48   0.12
carry125       0.54  0.49   0.18
assettrend2    0.02  0.03  -0.17
assettrend4    0.25  0.25  -0.17
assettrend8    0.41  0.40  -0.05
assettrend16   0.43  0.44   0.17
assettrend32   0.39  0.39   0.25
assettrend64   0.40  0.40   0.26
normmom2       0.05  0.14  -0.35
normmom4       0.25  0.30  -0.27
normmom8       0.39  0.38  -0.10
normmom16      0.42  0.42   0.08
normmom32      0.40  0.42   0.25
normmom64      0.37  0.43   0.32
momentum4      0.18  0.27  -0.23
momentum8      0.35  0.42  -0.02
momentum16     0.39  0.46   0.16
momentum32     0.35  0.42   0.30
momentum64     0.32  0.41   0.35
relcarry       0.04  0.20   0.14
skewabs365    -0.02 -0.12   0.24
skewabs180     0.17  0.02   0.32
skewrv365      0.29  0.22  -0.06
skewrv180      0.26  0.16   0.19
accel16        0.31  0.31  -0.11
accel32        0.22  0.28  -0.16
accel64        0.03  0.14  -0.04

That shows you the vector Sharpe Ratios for each trading rule for three different instruments. The question then is, should be pool the returns of US5 and US10? And what about SP500? Or are these vectors of SR distinctively different and we should not pool at all?

Just by eye the two bonds do look very similar. The S&P 500 not so much. A simple euclidian distance metric gives a distance of 0.07 between the two bonds; and around 0.31 between the equity and the bonds. Now this distance measure is crude. It doesn't take into account the length of data each asset has. A proper statistical test if the time periods were matched would also look at the correlation of the two  matched return distributions. But regular followers of this blog will know that I love crude. So let's run with this.

Note: The distance metric is just sqrt(average(w_i_1 - w_i_2)) for weights in rules i=1...N and for instruments 1 and 2.

How can we calibrate this distance measure? To put it another way, is 0.07 very low, and is 0.31 very high? Should we pool everything? Just the bonds?

Well, my bias is towards pooling. Before writing this blog post I've generally pooled everything without giving it a moments thought. So I would only be not pooling if there is a high chance that two instruments are distinctly different. That suggests my rule is to pool two instruments, unless their vector distance is above some critical value. In the simple example above, any critical value in the range 0.08 to 0.29 would imply pooling the two bonds, but would say not to pool the S&P. A critical value below 0.07 would result in no pooling. A value of 0.32 or above would imply pooling everything. 

How to find these critical values? Easy! I can set the critical value using random data at a level where we would pool unless there is a (say) 95% chance that the instruments are actually significantly different. We know that we typically have about 20 years of data. We know that the average trading rule on the typical instrument has a SR of around 0.15. If we generate 40 lots of random returns with that, and measure the SR, we'll get something like one of the columns above. Repeat that for another non existent instrument and we have two random 'instruments' we can calculate a weight for. Then we calculate the distance between those two random weights. Finally we rinse and repeat many times. We then get a distribution of weights. Voila:




We can certainly say that a distance of 0.31 is what we'd easily expect through random chance, whereas 0.07 is very unlikely to happen. You may be wondering how different that would be for say an instrument with just 5 years of data. Wonder no longer:


With less data and more variability in SR larger distances are more common. And what about the upper end with say 40 years of data (roughly what we have for the two bonds and S&P above):


There is less variability in outcomes with longer periods, so the distances are smaller. We're still not seeing a distance of 0.07 here though. It's incredibly unlikely to be a coincidence that the two bonds have roughly the same weights. At the other end of the spectrum, it's also pretty unlikely that the S&P and the two bonds are actually drawn from the same distribution; since 0.31 is at the right edge of the distribution of distances.

Now we should apply a pinch of salt correction to numbers from random data as we know from post two that real data doesn't behave like random data with a fixed SR, and shows more variability. So we would expect larger distances in real data than we see here, particularly for longer periods. For a given critical value calibrated using random data, it's likely that with actual data we will see more apparent significant differences, and therefore slightly less pooling going on.

The other thing to point out is that there are (N^2-N)/2 possible pairwise comparisons of weights; or for 214 instruments 23,000 or so. Where we to set our threshold for pooling at (say) 99% we'd expect to see over 200 apparent significant weight differences just by chance even if the instruments had no significant difference in true SR. 

Fortunately there isn't that much difference in the tails for the distribution of distances over different time periods from random data:
    
         1 year      5 years       10 years   20 years  30 years    40 years
95%       1.65         0.74          0.53      0.37      0.30         0.26
99%       1.81         0.80         0.57      0.40      0.33         0.28
99.9%     1.91         0.85          0.61      0.43      0.35         0.30

Note that using the bottom row would just barely still result in S&P 500 and the bonds getting seperated (distance 0.31 with 40 years or so of data); and with a little less history they would be pooled together. Despite the higher risk of false positives, my bias to pooling isn't so absurd that I think that should happen. Anyway, I'm going to use the top row, which implies:

We will pool instruments unless there is a 95% chance or greater that their SR vectors are significantly different. That will be the case if their SR vectors have distances greater than 1.65 (one year or less) up to 0.26 (40 years or less).

What if we have instruments with different amounts of history? Given our bias is towards pooling, I would always use a higher critical value for distance. For example, if we had one instrument with 5 years of returns and another with 40 years, I'd use the critical value for 5 years. That also means that instruments with less returns are more likely to be pooled when they first enter the data set. Which feels like the correct approach.


The pooling algo in full

OK so what we do is (for a given point in time as this will be on an in and out of sample basis):

  • estimate the SR for each rule on each instrument
  • for that vector of SR, work out the distance between that instrument and all other instruments
  • calculate the critical value for each pairing, using the lowest number of years available for one of the instruments.
  • assuming there is at least one pair where the distance is less than the critical value, find the pair with the smallest distance
  • combine the returns of those instruments together into a new psuedo pooled instrument
  • calculate the SR vector, and distances between this new pseudo instrument and all existing instruments (all the previously calculated distances between the remaining instruments will remain the same and don't need recalculating). Note that the number of years available for a pseudo instrument will be equal to the sum of the years on the individual instruments.
  • repeat until there are no distances less than the critical value (which means there is a less than 95% chance that their SR are significantly different).
We now have a mixture of pseudo instruments and possibly instruments. We use the pre-cost returns for each pool to optimise the appropriate portfolio weights. There is some additional logic around handling distinct and missing forecasts, and also costs, but for now let's keep things simple. 


Just for fun

Just for fun, let's run a single in sample test and see what gets pooled together in instrument space. This is akin to clustering exercises I have done before but there I just used underlying instrument returns.

This takes a while, and you may be surprised by some of the first pairs of instruments that are pooled together:

Pooling DistanceKeys(key1='SOFR', key2='EDOLLAR')   # both STIR
Pooling DistanceKeys(key1='US5', key2='US10')       # the example we have been using
Pooling DistanceKeys(key1='PLAT', key2='REDWHEAT')  # WTF!
Pooling DistanceKeys(key1='HEATOIL', key2='CHF')    # WATF?!
Pooling DistanceKeys(key1='GILT', key2='CAD10')     # both 10 year bonds fine
Pooling DistanceKeys(key1='ZAR', key2='DAX')        # WATFF?!?!?
...

Anyway once finished we end up with 54 pooled returns rather than 214 of our original distinct instruments. 

There are two huge groups that take in a big chunk of the instruments. Here is the first with 103 instruments:
['AUD_micro', 'BBCOMM', 'BOBL', 'BONO', 'BRE', 'BRENT_W', 'BTP', 'BTP3', 'BUND', 'BUXL', 'CAD', 'CAD10', 'CANOLA', 'CH10', 'CHEESE', 'CHF', 'COCOA', 'COCOA_LDN', 'COFFEE', 'COPPER-micro', 'CORN', 'COTTON', 'COTTON2', 'CRUDE_ICE', 'CRUDE_W_micro', 'DAX', 'DOW', 'DX', 'EDOLLAR', 'EU-BANKS', 'EU-DJ-UTIL', 'EURCHF', 'EUR_micro', 'FANG', 'FEEDCOW', 'FTSE250', 'FTSECHINAA', 'GAS-PEN', 'GASOIL', 'GASOILINE', 'GAS_US_mini', 'GBP', 'GICS', 'GILT', 'GOLD_micro', 'HANG_mini', 'HEATOIL', 'HIGHYIELD', 'IBEX_mini', 'IRS', 'JGB', 'JGB-SGX-mini', 'JPY', 'KOSPI_mini', 'KR3', 'LEANHOG', 'LIVECOW', 'LUMBER', 'MILLWHEAT', 'MSCISING', 'MXP', 'NASDAQ_micro', 'NIFTY', 'NIKKEI', 'OAT', 'OATIES', 'OJ', 'OMX', 'PALLAD', 'PLAT', 'PLN', 'R1000', 'RAPESEED', 'REDWHEAT', 'RICE', 'ROBUSTA', 'RUR', 'SGX', 'SHATZ', 'SILVER', 'SMI-MID', 'SOFR', 'SOYBEAN_mini', 'SOYMEAL', 'SOYOIL', 'SP400', 'SP500_micro', 'SUGAR11', 'SUGAR_WHITE', 'TOPIX', 'US-DISCRETE', 'US-HEALTH', 'US-TECH', 'US10', 'US10U', 'US2', 'US20', 'US30', 'US5', 'VIX_mini', 'WHEAT', 'YENEUR', 'ZAR']

Note that this does include both the S&P 500 and the US bond markets!

The second group of fifty instruments is mostly stock sectors, but not entirely:

['AEX', 'BOVESPA', 'CAC', 'CAD2', 'CAD5', 'CLP', 'CZK', 'DJSTX-SMALL', 'EU-AUTO', 'EU-BASIC', 'EU-CHEM', 'EU-CONSTRUCTION', 'EU-DIV30', 'EU-DJ-TELECOM', 'EU-FOOD', 'EU-HEALTH', 'EU-MID', 'EU-OIL', 'EU-REALESTATE', 'EU-RETAIL', 'EU-TECH', 'EU-TRAVEL', 'EURCAD', 'EURO600', 'EUROSTX', 'EUROSTX-SMALL', 'FTSE100', 'FTSECHINAH', 'GBPCHF', 'GBPEUR', 'IG', 'INR', 'MSCIASIA', 'MSCIEAFA', 'NICKEL_LME', 'NOK', 'NZD', 'RUSSELL', 'SEK', 'SMI', 'SPI200', 'US-ENERGY', 'US-FINANCE', 'US-INDUSTRY', 'US-MATERIAL', 'US-PROPERTY', 'US-REALESTATE', 'US-STAPLES', 'US-UTILS', 'V2X']

Again in terms of weirdness, the Canadian 10 year bond is in group 1 whilst everything else is in group 2. VIX is in group 1, and V2X in group 2. 

Next there are a few small groups, which mostly don't have any internal logic:

BRENT-LAST, USIRS5, USIRS10 (two out of three make sense)
MILK, WHEY, KR10, WHEAT_ICE (two out of four make sense)
FED, COAL-GEORDIE (nope, I got nothing)
IRON, ETHANOL
EURIBOR-ICE, COAL
SUGAR16/MILKDRY (the "what you shouldn't put in your coffee" group)

This leaves 46 instruments which can't be pooled with anything else:

['ALUMINIUM', 'AUDJPY', 'BB3M', 'BITCOIN', 'BUTTER', 'CHFJPY', 'CHINAA-CON', 'CNH', 'COPPER_LME', 'ETHER-micro', 'EU-HOUSE', 'EU-INSURE', 'EU-MEDIA', 'EUA', 'EURAUD', 'FTSEINDO', 'FTSETAIWAN', 'FTSEVIET', 'GBPJPY', 'HANGENT_mini', 'HANGTECH', 'HOUSE-US', 'JP-REALESTATE', 'KOSDAQ', 'KRWUSD_mini', 'LEAD_LME', 'LUMBER-new', 'MIB', 'MILKWET', 'MSCIEMASIA', 'MSCITAIWAN', 'MSCIWORLD', 'MUMMY', 'RUBBER', 'SARONA', 'SGD', 'SONIA3', 'STEEL', 'SWISSLEAD', 'TIN_LME', 'TWD', 'US3', 'USIRS2ERIS', 'USIRS5ERIS', 'VNKI', 'ZINC_LME']

Oh yes crypto people, Bitcoin and Ethereum are 'special'. As special as Tin and Rubber anyway. The furthest distance remaining after all that pooling is just under 0.31 which just exceeds the relevant critical value.

Evaluating the results

You should be used to the procedure by now if you've been following the blog posts. I will do the usual thing of cycling through different lengths of in sample (5 years, 10 years) and out of sample (1 year and 5 years) lengths of time. For shorter time periods that will allow me to subsample different historic periods. For speed and to get some alternative paths I'm not going to consider all the instruments. Instead I will randomly subsample 50 instruments randomly out of the 214 available. Note that the pool of available instruments will be smaller when I am using e.g. 15 years of in and out of sample data, which is why I'm not going to a 40 year in sample period as I've done before when investigating structural breaks.

Then for a given set of returns I will eithier use fully pooled, distance weight pooled, or unpooled returns. Then I will optimise for each instrument based on the relevant returns, using the shrinkage method with SR shrinkage of 0.5 and correlation of 0.75. Finally I will take the equally weighted across instruments portfolio SR for the 50 instruments, out of sample. Note this should be better than the average SR for each instrument. I could do better with some kind of instrument weight allocation, but that is for another day. I should still be able to pick up whether I am losing in lower diversification through pooling.


... with a twist

Basically everything I have done up until now includes implicit in sample fitting, because I'm only selecting from trading rules that actually work. This will inflate the backtest results, but until now at least won't have a serious effect on the calibrations I have been running. But with this step of looking at pooling I am worried that there will be rules that just don't work on some instruments. To try and alleviate that in sample fitting problem, I'm going to include the opposite of each trading rule as well as the original rule. Then at each optimisation we only choose the positive SR option. Note there are no trading costs at this stage of my research so the p&l of the opposite rule is exactly equal to -1* the 'correct' rule. 

Anyway on with the results.

5 years in sample, 1 year out of sample

               SR    pvalue
unpooled 0.320 0.0
all pooled 0.447 0.0
algo pooled 0.514 NaN

               SR    pvalue
unpooled -0.104 0.0
all pooled 0.391 NaN
algo pooled 0.016 0.0

The first table shows the results as I've been analysing up to now, with implicit fitting and only the 'correct' version of the trading rules included. In the second table I've allowed the possibility of the opposite rule to be included. Note the much lower performance that results; and a difference of opinion on whether we are better pooling everything or using the algo.


5 years in sample, 5 year out of sample

               SR    pvalue
unpooled 0.624 0.0
all pooled 0.431 0.0
algo pooled 0.657 NaN
               SR    pvalue
unpooled 0.339 0.0
all pooled 0.346 0.0
algo pooled 0.404 NaN
Once agin the SR are reduced by being more honest, but with longer out of sample the algo pooling method is now superior. 

10 years in sample, 1 year out of sample


SR pvalue
unpooled 0.862 NaN
all pooled 0.436 0.0
algo pooled 0.626 0.0
               SR    pvalue
unpooled 0.460 NaN
all pooled 0.304 0.0
algo pooled 0.248 0.0
The one thing we haven't got here is consistency... now not pooling at all is the correct thing to do!

10 years in sample, 5 years out of sample

               SR    pvalue
unpooled 0.683 0.0
all pooled 0.584 0.0
algo pooled 0.735 NaN

SR pvalue
unpooled 0.781 NaN
all pooled 0.491 0.0
algo pooled 0.650 0.0

A bit of an unusual case here since we do better on unpooled when including opposite rules, but it can happen just by luck. Anyway things really are inconsistent here...


Summary

Although the results above do seem quite messy, if we focus on the more honest figures that include opposite rules we can see a pattern if we look at the best method in each case:

5 year 1 year:  All pooled
5 year 5 year:  Algo pooled
10 year 1 year: Unpooled
10 year 5 year: Unpooled

Hence the more data we have, the more it seems we can allow each instrument to have it's own parameter estimates rather than sharing with other instruments.

Anyway, what to do? I am struggling here. I like more SR as much as the next guy, but I also have biases towards simplicity (Occam's razor), robustness and not changing things if I can avoid them. Sticking with what I currently do - pooling everything - is very tempting. It's simple, and it is also likely to be very robust. Not pooling at all is possibly even simpler; and with enough data history does seem to perform better. But it also worries me! Although we're ensuring robustness by using shrinkage, so maybe it's okay.

The Algo method is cool and fun, but definitely massively complicates matters. The method also doesn't produce 'nice' results. When I ran the original 'all instruments' grouping exercise, the long tail of instruments that don't fit elsewhere was slightly concerning. I had hoped to get groups that were congruent with asset classes or at least had some obvious logic, and I certainly didn't. This does suggest that the pooling by weights I have attempted before is worth a second look.

Alternatively I could use some simple heuristic like:
  • If an instrument has less than 5 years of data history, use pooled returns
  • If it has more than 25 years of history, use individual returns
  • With between 5 and 25 years of history, use weights that are an average of these; where the weight on pooled returns for N years of returns is (25-N)*0.05 and obviously the weight on . 
So there is another blog post to come at some point where I revisit the issue of pooling.

But for now we can put pooling by SR vector in the bin, the concept permanently damaged by the sharp edge of Occams razor (topical political reference there!).