Denys Rtveliashvili
ai

Python in Finance: Widely Used Despite Many Flaws

Introduction

Python is one of the most popular programming languages in the world. It is widely used for various applications: end-user applications, robotics, scripting, web servers, and A.I. just to name a few. It is easier to tell where Python is not used, and that would be more exotic niches like kernel drivers. Of course, it is also popular in quantitative finance. In fact, by this point, it has almost pushed out competition almost entirely and is used for quant research, trading algorithms, various tools, and so on.

But is it a good tool for the jobs one has to deal with in quantitative finance? I would say “no”, and there is no expectation that the situation is going to improve. The problems are inherent to the specifics of the language itself, as well as its popular infrastructure is unlikely going to be replaced by anything else.

Despite this, Python reigns supreme and there is no viable competition available.

Requirements of quantitative finance

There are several kinds of work in quantitative finance, and there is a bit of diversity depending on the kind of trading involved and the specific aspect of the work.

In general, one needs to deal with math-heavy matters during quantitative research, modelling, and backtesting.

Then there is algorithmic trading, which as a minimum would include execution, but would say (and I would say “must”) also include decision-making and basic risk controls.

Finally, trading would involve a suite of various tools which support operations, including the reconciliation of records and comprehensive risk controls.

Let us consider all three aspects in more detail.

Quantitative research, modelling, and backtesting

Research requires an ability to work with various data, mostly of time-series sort. The volume of data can be large.

When working with time-series data, it is important to be able to match two timestamped datasets in a way where for items in one of them the most recent data from another dataset is selected (as-of join).

The activity involves statistical analysis, so access to quality statistical libraries is important.

The ability to represent linear algebra operations and work with multidimensional data in a natural way is valuable.

The results occasionally need to be visualised, and it would help if that visualisation is intuitive and effortless.

The documentation often needs to include complex formulae, so support for standard notations like LaTeX is useful.

Decent support for time, date, timestamps, time deltas, and missing values is often important.

And finally, and this is important, there is a strong demand for flexibility and agility in trying new things out.

Support tools

The tools need to do various jobs, but mostly it is the creation of reports, moving data around / transforming the data.

The code is usually not complex but often needs to deal with many external systems and work with diverse data.

The data is often in a tabular or time-series form. It must be possible to represent operations on it with ease.

Reliability is more important than in research as many tools are meant to run automatically.

Algorithmic trading

Here it is assumed that algorithmic trading is running automatically and mostly autonomously. It is based on the results of quant research, modelling, and backtesting. Unlike the research environment, everything happens in real-time and while there is human oversight, people do not make decisions in every single case: the algorithm makes decisions independently, based on its model.

Reliability and precision are very important here, as human oversight happens only post-factum and on a fairly high level. Nobody babysits an algorithm.

Raw performance may also be important. This depends on the nature of the trading.

Documentation is important, but less so than in quant research. There is less demand for complex mathematics in comments.

The clarity of the algorithm’s code is very valuable. Quantitative parts of the code are hard to review at the best of times, but there is a higher chance of making a costly mistake if they are written poorly.

Python and its ecosystem

Python is known as a language that is easy to learn, full of libraries for anything you might need, and enjoys a large community behind it.

Let’s consider the strengths and weaknesses of different parts of Python’s ecosystem in the context of quantitative finance.

Pros and cons

… of the language

Pros:

Cons:

… of numpy

Numpy is a popular library which provides support for the efficient representation of arrays and operations on them. As of now, it is a de-facto standard. It underpins pandas and many other libraries. The reason why it is fast is that its storage is specialised for the data it works with, and various operations like matrix multiplication are implemented with the help of well-tuned libraries (rather than in Python itself). This makes a dramatic improvement when working with large data.

Pros:

Cons:

… of pandas

Pandas is a library which provides an implementation of tables (called DataFrame) and series (which can be seen as vectors with an associated index).

Pros:

Cons:

… of other libraries

Pros:

Cons:

… of Jupyter Notebook/Lab

Jupyter Notebook/Lab is irreplaceable for quant work in Python.

Pros:

Cons:

… of contributors

Pros:

Cons:

For example, years ago I spotted a bug in a library dealing with differences in sequences. One of its functions was called find_longest_match and its documentation said that it finds the longest matching block. However, it was not. In fact, the code was sometimes unable to find a match at all, even though it was clearly there.

When I filed a bug report, I was told that:

  1. It was not a bug.
  2. The code is looking for the longest interesting match.
  3. The bug is not in the code, it is in the documentation.

This was back in 2007. Now it is 2023, the documentation is still claiming that the code is looking for the longest match, and the bug is still there:

import difflib
text1 = "a" + "b"*210
text2 = "b"*210 + "c"
m = difflib.SequenceMatcher(None, text1, text2)
(_, _, l) = m.find_longest_match(0, len(text1), 0, len(text2))
print("Text #1: ", text1)
print("Text #2: ", text2)
print("Longest match: ", l)

other notable weaknesses

For the idea of a timestamp you can use:

  1. A floating point number, which would normally mean “seconds since UNIX Epoch”.
  2. numpy’s datetime64
  3. pandas’ Timestamp
  4. datetime’s datetime

They are not equivalent, conversions between them are awkward, and important matters like time zones are sometimes handled differently depending on which version of a library you are using.

Speaking of timezones, there are datetime’s tzinfo and timezone, as well as pytz.

There are also datetime’s date and time with a mostly obvious meaning. But let’s not stare at the abyss for now.

The idea of a time difference can be represented too:

  1. A floating point number, which would usually mean “time difference in seconds”.
  2. numpy’s timedelta64
  3. pandas’ Timedelta
  4. datetime’s tiemdelta

Again, conversions between them are not as obvious as one might want and there are differences between the representations.

Alternatives

R

R is a very flexible and expressive language which was designed for statisticians. I have to admit, I like it.

Pros:

As an example, you can run a linear regression in both Python and R, but R will give you much more diagnostics, helping you to understand whether your regression is reasonably trustworthy. Python would not.

regression_results <- lm(heart_disease ~ biking + smoking, data = medical_data)

Here, the data is taken from a table medical_data, where heart_disease, biking, and smoking are columns. Linear regression is fitted, where heart_disease is a predicted value while biking and smoking are feature variables.

A %*% inv(B) %*% t(C)

In my humble opinion, this is easier to read than its equivalent in Python:

np.matmul(np.matmul(A, np.linalg.inv(B)), C.T)

Cons:

C# / Java / C++

These three languages are quite different, but I am grouping them here regardless. All three have a similar syntax and have inspired each other over decades.

Pros:

Cons:

Overall, Java, C++, and C# are quite good for many things, but they would be a terrible choice for research, modelling, and backtesting.

APL derivatives

APL is one of the oldest languages where the central datatype is the multidimensional array. It also makes use of a set of unusual symbols, which may have put off many people from using it.

Multiple implementations and derivatives of APL exist, such as q and J.

Pros:

Cons:

life  {1  . 3 4 = +/ + ¯1 0 1 ∘. ¯1 0 1 ¨ }  ⍝ Conway's Game of Life

While APL derivatives may look interesting in a theoretical sense, it is hard to see why would someone use these for research, modelling, actual trading, or tools. There is no obvious and strong-enough edge over other languages.

Wolfram Mathematica and MATLAB

Wolfram Mathematica and MathWorks MATLAB are commercial products which can be used for modelling, research, trading, and the creation of tools. They also have a wide range of libraries/toolkits available, which covers many problem domains.

Pros:

Cons:

Overall, it seems that both may be fairly good for research and modelling, being as scientific as R while also being more polished. It is harder to see why would someone want to use them for algo trading or tools.

Conclusion

Python is not a perfect language for quantitative finance. Its lack of decent support for missing values makes it hard to work with partially unavailable data. Messy and poor support for time-related data does not help and sometimes actively causes problems. It is easy to write code quickly but the code would tend to be fragile, which is bad for algo trading. The available libraries were mostly created with programmers rather than scientists/statisticians/engineers in mind, which has an impact on the quality.

Nevertheless, Python is widely used. It is a result of many factors:

  1. Python and most of its ecosystem are free to use.
  2. There is a large number of people who know Python.
  3. There is a hope that models and signals created during research can be moved into trading with no modifications. Sometimes this works, although often it does not.
  4. Many believe that it is good to have just one language which is used for everything.

The best approach in your case depends on the kind of trading you are doing.

My view is that in most cases a single language won’t be enough to cover everything. Well… Perhaps OCaml can, although it is hard to see how can research be done in it. So I would rather bet on specialisation:

  1. Pick the best language for your research and modelling, so that discovery of signals and market inefficiencies would be as quick as possible. Python may be an OK choice here, but it is worth considering the alternatives as well.
  2. Pick the best language for your algo trading, so that you would be competitive in actual trading while also bearing in mind that safety is important.
  3. Establish a process by which you can implement your trading algorithm and signals, backtest them, and confirm that the results of backtesting match the numbers seen in research. Yes, that would likely mean two independent backtesting systems running off the same data.
  4. Implement your tools in whatever is easiest.

The classic combination is Python for research and Java / C# / C++ for algo trading. I am sure it can work well when properly implemented. Although I am sceptical of C++, especially when it is chosen in order to minimise latencies. But that is a story for another post.

Happy trading!