The programming language Python was conceived of and designed to be easy to write with (as opposed to its competitor at the time, Perl - as we obliquely noted in a previous blog). As such, it would be nice if we could write algos in it. Read on to find out more.
Please note that nothing in this blog is investment advice. You must do your own research and due diligence before making any investment or trading decision.
TL;DR - we’re going to show you how to do the stuff of this article - sign-up for that Webinar here:
The case for trading
Why buy things you don’t need? Why buy things that don’t even give you any pleasure? It can only be that they will later allow you to fulfill some need or be pleasant in some way. You buy them now because, if you wait until that later time they won’t be available or will cost too much.
Financial assets are placeholders for those things you will want or need later. You buy them now with the expectation that their value will rise along with the things you might want later.
Asset prices don’t always rise. They fluctuate based on many factors. If you can buy them at a relative low price you make a better return - it might be worth waiting for this low. A relative high price may occur before you had intended to sell: it may be worth selling early. Buying and selling based on price expectation in this way is trading.
You should only engage in trading if you know better than others what prices are low and high and when they will occur. How can you do this? You need to learn about it. There are many market analysis techniques. These can lead you to a strategy. That is an articulation of why and when you buy and sell.
If you are serious about using a strategy to trade you should write it down - in careful detail. Your strategy’s specifications of when to buy and sell are its signals. Your strategy should make clear how much of the asset to buy on each signal. This will depend on your total assets and your risk appetite.
You are likely to execute your strategy via a web interface. A web interface can be accessed programmatically using the Hypertext Transport Protocol (HTTP). Trading venues also often provide APIs to facilitate trading programmatically. HTTP and most APIs are available in Python.
Down to business
It’s not that straightforward. You have to authenticate. You have to make sure the market prices that precipitate your signals are correct. You have to be sure your orders get to the market. If you’re a software developer all this is expected. The challenge can be enjoyable. If you’re not a developer or your focus is financial you can use services that handle these details. One such service is profitview.net, my company. We’ll use it for the rest of this article.
ProfitView provides an event driven interface. That is, all the important market events that occur unpredictably cause particular functions to be called. The user can then provide implementations for these functions - that do whatever they want (presumably their strategy). The code can be completely general - though there’s some limitations on memory, disk and CPU.
Let’s do a mean-reversion strategy. Mean-reversion is a statistical property that asset prices tend to obey: they fluctuate about a mean. When prices move away from the mean, they’ll likely then go back towards it. So you buy when below the mean and sell when above it. That’s it. Let’s try it. First we need the mean. We’ll just accumulate trades, add them up and divide by how many we got (we won’t bother with volume):
class Strategy: LOOKBACK = 50 class Trading(Link): def __init__(self): super().__init__() self.prices =  self.mean = 0.0 self.elements = 0 def trade_update(self, src, sym, data): self.prices.append(newPrice := data["price"]) if self.elements < Strategy.LOOKBACK: # Until we have enough data for the mean self.mean = (self.elements*self.mean + newPrice)/(self.elements + 1) else: # Adjust mean - it's a moving average self.mean += (newPrice - self.prices)/self.elements self.prices = self.prices[1:]
Give me a sign
What does it mean to go away from the mean? It’s about volatility, which we measure using standard deviation. ProfitView provides the “TA-Lib” library for this calculation with stddev. The number of multiples of stddev that a price is away from the mean we’ll call the “standard reversion”. That’s what constitues a Signal in this simplistic case. So we add:
import talib ... REVERSION = 2.5 VENUE = 'BitMEX' SIZE = 100 ... stddev = talib.STDDEV(np.array(r.prices)) stdReversion = Strategy.REVERSION*stddev
and then we trade on that:
if newPrice > self.mean + stdReversion: # Upper extreme - Sell! self.create_market_order(Strategy.VENUE, sym, "Sell", Strategy.SIZE) if newPrice < self.mean - stdReversion: # Lower extreme - Buy! self.create_market_order(Strategy.VENUE, sym, "Buy", Strategy.SIZE)
That’s all there is to it really! (we would want to throttle the trades; probably use limit orders etc and incorporate our knowledge of volume - these are left as an exercise for the reader). You can find the working code in our Github.