Friday, 18 December 2015

pysystemtrade

There are already many python packages where you can back test trading strategies. Some of them also include a framework for automatic execution and complete position management.

I can't give an exhaustive list but I'll pick out:

- Quantopian's  zipline
- BT
- pythalesians
- pyalgotrade

There is a longer list here. 

Does the world really need another one? Well, probably not, but today I've released one anyway (this explains at least partly why it's been a month since my last post, since I've spent the last month writing it).

You can find pysystemtrade on github, here. This is version 0.0.1. It provides a basic backtesting enviroment that implements the 'staunch systems trader' example in my book. And it's GPL 3 open source.

However it's my intention that this will become a fully featured back tester that will include all the optimisation and calibration techniques that I've discussed here on the blog, and in my book. It will also, eventually, include a complete end to end system that can be used for fully automated futures trading with interactive brokers.

UPDATE 2026: The now much more mature pysystemtrade project is now hosted here and is maintained by Andy Geach. It is a full featured backtester and fully automated trading system which uses Interactive Brokers.

Why am I doing this?


Having said that this is probably a futile exercise, it's probably worth explaining why I've released this today.


My own code needs rewriting


I've been running with a trading system that I wrote in early 2014 for the best part of 21 months. Whilst it's been pretty stable, it isn't very pretty or extendable.  There are things I'd like to do with my system that I can't implement without having to do a massive refactoring; massive enough that a rewrite from the ground up would be better. Parts of it are over engineered; other parts too tightly coupled. I'd probably make different decisions about many parts of it with the experience I've had. I'd also like to move to python 3.

Oh yes pysystemtrade is in python 3; well 3.4. Didn't I mention that? Sorry...

So the job of rewriting this code has been on my back list for some time. Doing it in public will hopefully encourage me to finish the job.


I like to write my own stuff


A question I'm often asked is why I didn't write my original trading system as part of, or as an extension of, one of the libraries I mentioned above. It's equally valid to ask why I'm writing everything from scratch again.

I've worked with quite a few backtesting frameworks in my life. I've never been completely happy with frameworks that someone else has written. Whenever you use someone elses stuff there is an obvious benefit, but three costs. The first cost is the time penalty in understanding how to use the product. The second is the time spent in extending it to do what you want it to do.

Since I already know that 95% of the final code base isn't going to be back testing, but production implementation of a trading system, the benefits of using someone elses backtesting framework are mostly outweighed by these two costs.

Also as a linux user I get irritated when to use someone elses code I have to install a huge stack of python libraries first. That's why there are minimal dependencies for this.

The third cost is that you have to put up with the API that the developer has imposed. In particular I'm very choosy about how I spend my time at the command line developing systems on the fly (in my previous job I spent a lot of time moaning at technologists when they tried to create a trading system that was lovely and robust, but hard to use interactively. They got it right in the end).

Finally it's just more fun to write your own stuff; if you're a strange person like me.

By the way I know that there are many of you who also like to, and have, written your own stuff. So I'll try and keep the code relatively modular. When I drop my optimisation code into the project, it should be easy to remove it and tie it into your own system. Should you want to use a different broker, or different storage and data feeds, I'll make that as straightforward as I can.

Pro-bono publico

 
I've noticed that writing on this blog has involved writing quite a bit of code (and I keep getting requests to write some more). Whilst the original series of posts I wrote about using swigibpy is quite self contained; subsequently I seem to be putting together quite a little messy pile of code in the systematictradingexamples repo..

Rightly or wrongly I reckon it will be better for all concerned if I created a single project that held all the code I use to demonstrate techniques and points of interest. At some point I'll circle back and rewrite the examples in systematictradingexamples into this new project).

Encouraging people to trade properly is a bit of a mission of mine. If this project helps one person who would otherwise be using some overfitted 'robot' trader tied to an expensive broker, then it will be worth it (though I'd hope for a better return on my time).


Sorry - no support


I had one big concern about releasing my code open source. Not that I would give away any deep secrets; as you will know if you've been paying attention I don't believe in secret sauce.

I also have the natural embaressment of showing people my code, especially given I am not by any means a professional programmer. So be nice, or I'll pull it all from the repo :-)

No I was concerned, based on my experience with the code I've already released, that answering emails of the 'this doesn't work' type will eventually take all my time. For this reason I've decided (a) this project will be thoroughly documented and will have some tests, and (b) I won't be committing to to help you with any problems. Here's what I say in the README file:

"This is an open source project, designed for people who are already comfortable using and writing python code, are capable of installing the dependencies, and who want a head start on implementing a system of their own. I do not have the time to provide support. Of course I am very happy if you get in touch with me on any of the following topics:

  • Confusing error messages
  • Missing or misleading documentation
  • Suggestions for extra features
However I can't guarantee that I will reply immediately, or at all. If you need that level of support then you are better off with another project.
I'll try and incorporate any feedback into the code, but this is a part time venture for me, and it will be competing with my other interests (writing books, blogging and research). But if you occasionally check github you will hopefully find it gradually improving. Offers to contribute will of course be gratefully accepted."

Look guys let me make it clear. You're getting the benefit of my distilled wisdom for free (though some of you have shelled out up to $60 for my book, for which I thank you from the bottom of my heart); something my former employer used to pay quite a lot of money for. But becoming an unpaid technical support monkey for a bunch of strangers (and a few old friends and colleague) on the internet isn't my idea of fun. I'll make an effort to release stable code, write a few tests, and document it properly, but then you're on your own.

Also this is open source. I know for a fact that at least half the people reading this blog are better programmers than I. If you find a bug or want to improve the code in some way, then please feel free to offer to do it (and thanks to those of you who have offered, or have already done so).


A very quick demo


There is a long demo, and an even longer user guide, in the repo so I don't need to repeat them here. Instead here is how you'd simulate the system in chapter 15 of my book, in three lines:


from systems.provided.futures_chapter15.basesystem import futures_system
from matplotlib.pyplot import show

system = futures_system()

system.accounts.portfolio().sharpe()
system.accounts.portfolio().curve().plot()
show()


The account curve for the system in chapter 15 of my book. Sharpe Ratio 0.48

Seasons greetings to one and all


This will be my last post for the year. I hit a high water mark in my trading account yesterday so I'm in a good mood. So please feel free to enjoy the warm feelings I am currently transmitting into this keyboard, have a good holiday, and see you next year.


Wednesday, 18 November 2015

Random data: Random wanderings in portfolio optimisation

Everyone knows that the usual naive method of portfolio optimisation is, well, a bit rubbish. This isn't because the method is flawed, but it relies on the inputs being 100% accurate, or to put it another way we need to know precisely what the mean, volatility and correlation of future returns are going to be. But most peoples crystal balls are somewhat foggy.

Fortunately there are a few methods we can use to deal with this problem. Some of these are straightforward; like the handcrafted method I describe in my book. Others such as bootstrapping and shrinkage are more complicated. On any particular set of asset price history one method or another may perform better. It's even possible that just by fluke the simplest naive method will do best.

I believe that to get a good grasp of which portfolio optimisation is best you need to use random data; and I'll do exactly that in this post.

This is the third and final post in a series on using random data. The first, which is worth reading before this one, can be found here. The second post is optional reading. You may also want to read this post which shows some optimisation with real data and explains some of the concepts here in more detail.


Optimisation 101


I'm using straightforward Markowitz optimisation. We maximise the Sharpe Ratio of a portfolio, over some portfolio weights, given the expected mean, standard deviation, and correlation of returns.

Because I'm optimising the weights of trading systems I constrain weights to be positive, and to sum to 100%. I can also assume that my systems have the same expected volatility of returns, so all I need is the mean (or Sharpe Ratio) and correlation. Finally I don't expect to see negative correlations which makes the problem more stable.

The 'one period' or naive method is to take all past returns and estimate Sharpe Ratios and correlations; and then plug these estimates into the model. The flaw of this method is it ignores the huge uncertainty in the estimates.

Method two - bootstrapping - involves repeating our optimisation many times over different parts of our data, taking the resulting weights, and averaging them out. So the weights are the average of many optimisations, rather than one optimisation on the average of all data.

The logic for bootstrapping is simple. I believe that the past is a good guide to the future; but I don't know which part of the past will be repeated. To hedge my bets I assume there is an equal chance of seeing any particular historical period. So it's logical to use an average of the portfolios which did best over all previous periods.

Shrinkage is a Bayesian method which involves taking the estimated Sharpe Ratios and correlation, and then "shrinking" them towards a "prior". There are numerous ways to do this, but I'm going to use a relatively simple variation. "Shrinking" involves taking a weighted average of the estimated correlation matrix (or mean vector) and the prior; the weighting on the "prior" is the shrinkage factor. For "priors" I'm going to use the "zero information" priors - equal Sharpe Ratios, and identical correlations.

By the way the nemesis of all optimisations, the very simplest method of equal weights, is equivalent to using the shrinkage method of a shrinkage factor of 100%. It should also be obvious that using 0% shrinkage is the same as a naive optimisation.

Handcrafting is a simple robust method I describe in chapter four of my book. We estimate correlations, and then use a lookup table to determine what weights to use. I'm going to use the extended table which is here.

 * There is an extension in my book to the hand crafted method which incorporates estimated Sharpe Ratios; but to keep life simple I won't be discussing it here.


The analysis



I'm going to use the technique I described in the first post in this series for producing random returns for 3 assets. I'm going to use three because it will make the results more tractable and intuitive. It also means I can use the handcrafted method without creating a complex grouping algorithim. The general results will still apply with more assets.

The portfolio I'm going to generate data from has identical Sharpes (in expectation), and correlations of 0.8, 0, 0. So it's very similar to the portfolio of two equity indicies and one bond index I consider in this post.

Note that the set of correlations is deliberately different (mostly) from the set used by the handcrafted method, just to ensure there is no favouritism here.

The usual caveat about random data applies here. The expected sharpe ratio, volatility and correlation of returns in this random world is fixed; but in reality it varies a lot. Nevertheless I think we can still draw some useful conclusions by using random data. Be warned though that non robust methods (such as the classic naive method) will do even worse in the real world than they do here.
All my testing will be done on out of sample windows*. So I'll use data in the past to estimate sharpe ratio and correlations, coming up with some weights, and then run those weights for a year to see how the portfolio behaves. The amount of history you have is critical, particularly with this stylised example where there is a fixed data generation process to be 'discovered'.

I ran tests with available asset price histories of 1 year, 5 years, 10 years and 20 years for the in sample period, with 1 year for the out of sample period.

* this term is explained more in chapter three of my book, and in this post.

To keep things simple I'll just be using the average out of sample sharpe ratio as my measure of how successful a given method is. Just for fun I'll also measure the average degradation of Sharpe ratio for the optimised weights between in sample, and out of sample.

I'm going to going to basically compare the four methods against each other, and see which does best on at out of sample basis. Actually I'm going to compare 18 (!) methods- hand-crafted and bootstrapping; plus shrinkage with a shrinkage factor of 0% (which is equivalent to the naive method), 33%, 66% and 100% (which is equivalent to equal weighting); note because I allow different shrinkage factors on the mean and correlation that adds up to 16 possibilities.



Results


All these graphs have the same format. The x axis shows which of the 18 methods are used. Note the abbreviations: H/C is handcrafted (which is also the benchmark), BS is bootstrapped and Sab implies shrinkage of a on asset Sharpe Ratios and b on correlations; where 0,3,6 and 1 represent 0%, 33%, 66% and 100%. Naturally S00 is the naive method and S11 is equal weights. The y axis shows eithier the average out of sample SR versus a benchmark (S00), or the average degradation from in sample to out of sample (negative means returns got worse).

I plot the methods with shrinkage for the mean increasing as we go to the right (S11 - equal weights, BS and HC are on the extreme right; the naive portfolio S00 on the extreme left).

Naturally because this is random data I've generated a number of series of asset returns for each set of asset sharpe ratios and correlations; and the results are averaged over those.

There is some (messy) code here.

One year

The results above are from using just one year of data. Adding shrinkage to correlations seems to make things slightly worse, but shrinking the means improves things. The handcrafted method does best, with bootstrapping coming in second. The scale is a little misleading; going from the worst to the best method is an improvement in SR from around 0.53 to 0.68.


Unsurprisingly without sufficient shrinkage on the means there is massive degradation in the Sharpe Ratio going from in sample to out of sample. Look at S00 the naive method. Out of sample it has an average SR of 0.58; in sample it is 0.78 higher than this, at 1.36! Using a non robust optimisation method over such a short period of data is going to give you seriously .


Five years










Ten years


 

Twenty years


With twenty years of data the naive method is doing a little better. Shrinking the correlations definitely penalises performance  - we now have enough data to be confident that the correlations are significant. However there is still a benefit from shrinking the means; even completely away. The advantage of handcrafting and bootstrapping has been whittled away, but they are still amongst the best methods.

There is still a degradation in performance going out of sample, but it is much smaller than before.


Postscript


To an extent these results are a function of the underlying portfolio. If we ran these tests with a portfolio that had significant mean differences then shrinking the mean wouldn't be such a good idea. Here for example are the results with the same correlations as before, but Sharpe Ratios of [0.0, 0.5, 1.0].

First one year:



Now after twenty years:

Here the optimal shrinkage for the mean seems to be between 33% and 66%.
Handcrafting, which in the simple form here does not account for differences in sharpe ratios, doesn't do as well as bootstrapping which does. It also loses out once the shrinkage methods have enough data to use the difference in Sharpe ratios properly.

However we don't know in advance what kind of portfolio we have... and significant differences in correlations are more common than statistically different Sharpe Ratios.

Conclusion


I naturally have a soft spot for my preferred method of bootstrapping and handcrafting. Shrinking can be a good alternative, but it's hard to get the shrinkage factor correct. In general you need to shrink mean estimates more than correlations, and shrink more when you have less data history. Using insufficient shrinkage; or none at all with the naive method, will also lead to massive degradation from in sample to out of sample returns.

This was the final post in a series on using random data.

First post: Introducing random data
Second post: Does equity curve trading work?

Monday, 16 November 2015

David Versus Goliath

Just a quick post today. As most of you know until a couple of years ago I worked for a large systematic hedge fund. Now I manage my own money. I'm doing similar things (systematically trading futures, with a holding period averaging a few weeks, and a variety of trading rules with a trend following bias).

An interesting question, which I'm often asked, is can a little guy like me compete with a giant behemoth of a fund? Should we little guys just give up? After all surely a huge fund has a number of advantages over a one person "business" like mine. Or does it? Let's weigh up the pros and cons of size.

That's me on the right. In a manner of speaking. (researchcenter.paloaltonetworks.com)


Advantages of big over small


Here are what I see as the key advantages that a large fund has over a small trader (or a small fund for that matter). I've listed them in order of importance - most important first.


Wider set of markets traded


A larger fund can trade a much wider set of instruments; 100 - 300 versus the 40 or so futures markets that I trade. Diversification is the only free lunch in finance, and diversification across instruments rather than trading strategies is much more powerful since the correlations are lower.

I estimate that I should be able to get a sharpe ratio around 30% higher if I could trade 300 instruments rather than 40.

Why can large funds trade more markets? I can think of three reasons:


Higher FUM


The main reason why large funds can invest in more markets is because they are ... large (this is the level of deep intellectual analysis you have come to expect from this blog). If you are a tiny investor with just a few thousand dollars in capital then in the futures trading world at least you're going to trade even a low risk market like the German Shatz future. To trade something like the japanese government bond future, which has a nominal size over a million bucks, you need to have a pretty substantial account size (assuming you don't want it to be a huge chunk of your portfolio risk allocation). 

(I talk about this problem in chapter twelve of my book)



Access to OTC markets


Institutions can trade over the counter markets, whilst retail investors are mostly limited to exchange traded (excluding the wild west of retail FX trading of course). Large funds can afford to employ large numbers of people in back and middle offices who can worry about painful things like ISDA agreements.


Dave's office after he mentioned in passing that he might want to trade Credit Derivatives some day. (gettyimages)


Also they can employ execution traders who understand how to trade the markets, and who can ring brokers and banks and say "Hi I'm calling from NAME OF LARGE FUND and I'd like to trade credit derivatives". Within minutes a team of salespeople will be round your fund salivating at the prospect of being your business partner. If I called brokers and banks I might get lucky and find someone I used to work with to buy me lunch, but I won't get a trading agreement set up any time soon.



Manpower for data cleaning


Even running a systematic, fully automated, fund requires some work. I spend a few minutes each month for every instrument I trade dealing with bad prices and deciding when to roll. If I were to trade a couple of hundred futures, then my workload would be enormous - perhaps a week a month.

With a technical futures system however this workload is still within the scope of an individual trader (as long as they aren't as lazy as I am). However if you were trading long-short equities, with a larger universe of instruments than in futures, and more types of fundamental data, then having more a few more people would be good.


Better execution


For a given size of trade larger funds should get better execution - lower slippage between the mid price and the fill price.

* Clearly large funds will do larger trades - I'll talk about this later in the post.

Large funds can invest in researching smart execution algos, much more sophisticated than the simpler stuff I do. However more importantly they can employ experienced execution traders to execute trades manually. In certain markets these guys will do much better than an algo (of course in certain OTC markets an algo won't be any good anyway, since there are no automated trading mechanisms).

I could execute my own trades manually if I wasn't so idle (and there's no way I'd get up early enough to trade Korea...), but I wouldn't do as good a job as a good execution guy would.


Note that the benefits of smarter execution are more powerful once you are doing larger trades; so all this category does is allow large funds to partially overcome one of their main disadvantages.

Lower commissions


Institutional investors pay lower commissions than retail investors do. This is pure market pricing power being exercised. If I'm trading billions of futures contracts a year I'm going to get a better deal than if I'm trading thousands.

I expect to pay around 30bp of my fund value in commissions; I'd expect to be able to halve that or better if I was a large fund. Adding 15bp to performance isn't going to change the world, but every little helps.

Economics of scale and specialisation



Having more people means you can have specialists. I'm an okay programmer, not a bad trader, I know a bit of economics, and I'm vaguely okay at statistical analysis. I've managed to teach myself the bare minimum of accounting to properly analyse my p&l. The point is I have to do all this stuff myself. I'm not even playing to my strengths; if I had a full time programmer working for me I'd be able to focus on developing better trading rules.

(I'm not moaning by the way, I enjoy dabbling in programming and having full control of the whole process).

However a large fund can hire people to do each of these functions seperately. They can afford to hire top notch programmers, excellent execution traders, super statisticians and brilliant economists; as well as all the other people you need to run an institutional fund.

This will add something to performance, but not a vast amount (except in specialist areas like high frequency trading where the difference between profits and losses is having someone who knows how to build a low latency trading system). It's hard to quantify how much exactly.


Large team of researchers


Related to the previous point most people assume the main advantage of a large fund is that they have a huge team of really smart people refining and developing models. Personally I'm less confident this is the case. I believe that a suite of relatively simple, well known, trading models will get you 95% or more of the performance of a more sophisticated complex set of trading rules (at least at the trading frequency I usually occupy).

So I believe one relatively stupid person (myself) can do almost as well as a team of very smart people. But maybe I'm being stupid.


Advantages of small over big


What is David's sling in this story, or if you prefer what can a small trader do that a large fund can't? Again I've listed these in order of importance, key point first.


More diversified signals


Large funds have investors, often themselves large institutions like pension funds. Large institutional investors buy funds not just because they think they are going to do well, but because they have a certain style such as trend following. To an extent this is rational because it's very hard to predict performance; but putting together a series of funds which are diversified across styles is an excellent way of constructing a portfolio.

What this means in practice is that funds might not be able to make as much in absolute return as they could in theory. If investors want to buy a trend following fund, but the optimal allocation to trend following is only 40%, then the fund will under perform someone who can put 60% into other trading rules even if the set of rules they haven't isn't quite as good.
 


No fees

If you invest in a fund you have to pay fees. If you invest or trade your own money, they you don't. Depending on how you value the opportunity cost of your own time, and how much time you spend on trading, this may or may not make sense. But it's certainly true that you'll get a higher absolute return from not having to pay fees.

No institutional pressure


The biggest mistake when trading a systematic system is to meddle. As an individual trader it's not easy to avoid meddling, but I usually manage to do so as I can't face the work involved. However I do believe that institutional pressures lead to models changing and frequent overrides.

Lower execution slippage


Smaller traders do smaller trades (for a given average holding period and leverage). If your trading size is always less than what is available at the inside spread then the most you should have to pay is half the spread.

However as I noted above large funds can employ resources to reduce the size of this effect.


Conclusion


I would say that a large fund has the edge, but it's perhaps closer than you might think, and the advantages they have aren't necessarily those you'd expect to be the most important.

As it happens after my first year of trading I was being beaten by my former employer, AHL - a large fund,  with a Sharpe of 4.0 vs my paltry 2.8 (okay it was a good year all round - this is about 3 times the long average SR I'd expect to see!).

So far this year (where both the large funds and myself haven't been doing quite as well) has been closer - and just for fun I'll update this comparision in April 2016.