In building trading systems, one notices patterns in how they are designing things. After you’ve built a couple, you start to see that they generally fall into certain classes based on time frequency and usage of data. Much of the infrastructure between systems feels the same, although getting the details right is always a little bit hard to do right from the start.
In computer science classes, one often encounters hard problems– designing efficient algorithms, writing something as concisely as possible, or solving a problem with only simple tools like bitwise operations. However there is another class of hard problems which one may unknowingly discuss in a class like “Software Engineering” but not directly encounter. Designing architectures is another category of hard problems which appear all the time in real-world software engineering but are missed by classes because it’s infeasible to actually code a large scale system in a semester and because most students don’t work well with fresh unpolished specifications. Design patterns are a way of coping with complexity and avoiding the tangles that can result from myopic coding. Besides just guiding the architecture …
In building trading systems, one notices patterns in how they are designing things. After you’ve built a couple, you start to see that they generally fall into certain classes based on time frequency and usage of data. Much of the infrastructure between systems feels the same, although getting the details right is always a little bit hard to do right from the start.
In computer science classes, one often encounters hard problems– designing efficient algorithms, writing something as concisely as possible, or solving a problem with only simple tools like bitwise operations. However there is another class of hard problems which one may unknowingly discuss in a class like “Software Engineering” but not directly encounter. Designing architectures is another category of hard problems which appear all the time in real-world software engineering but are missed by classes because it’s infeasible to actually code a large scale system in a semester and because most students don’t work well with fresh unpolished specifications. Design patterns are a way of coping with complexity and avoiding the tangles that can result from myopic coding. Besides just guiding the architecture designer’s thought process, we can often construct re-usable meta-frameworks and tools to speed future development.
Generally, the developer’s wisdom/learning curve follows these four steps, where you have to do each step 3-5 times to move on to the next:
prototype –> full system –> intuit patterns –> extract frameworks
But let’s just jump ahead to the patterns.
Batch
Batch based systems are like the tree bagging and SVM systems I mentioned earlier. Typically once per day or even less frequently, you run a script to download some historical data, run another script to re-optimize a model based on that updated data, and finally output signals, typically to a file to be imported into the execution software and submitted, after a quick sanity check.
Oops, let’s rewrite that as psuedocode to make it feel more actionable–
_| Batch(Pattern)
1|_ download some historical data
2|_ re-optimize a model
3|_ if conditions met:
4|__ output buy signals
5|__ import into execution software
6|__ sanity check and submit
Batch systems are the most amenable to machine learning in terms of developer friendliness, but lower frequency systems unfortunately have less data to work with. For this kind of system, data is typically stored in a matrix where each row is a day of observations of all the interesting variables on a historical date.
Scheduled
I bring up schedule based systems second although they’re more challenging to design than event driven systems because they are more intuitive based on human experience and more similar to TradeStation, OpenQuant, and other retail platforms which people are probably familiar with. People are used to being driven by clocks rather than purely by unanticipatable external events and impulses.
Let’s go straight to code here, it’s clearer–
_| Scheduled(Pattern)
1|_ turn on data stream
2|_ at time of day x:
3|__ calculate indicators
4|__ if conditions met:
5|___ submit order
One often designs according to this pattern when automating a strategy which is currently being traded discretionarily. It might also arise in a case where you want to trade at the `close’, but to implement it you have to check signals and place trades 10 minutes before, for example.
Event Driven
Event driven systems are the most powerful and flexible because they get closest to the raw data. Power and flexibility generally lead to more tedious code — think C++ vs. Excel. `High Frequency Trading’, as seen on TV, is generally event-driven.
The common patterns here are generally in seamlessly indexing by time and by message number, handling stored data and indicators, and code efficiency. Execution and position tracking also become more complex when signals can change before executed trades are even confirmed.
In some sense though, these systems are the most fun to write because they don’t impose structural constraints.
_| Event(Pattern)
1|_ register data stream listener
2|_ turn on data stream
3|_ listener (on new data event):
4|__ calculate indicators
5|__ if conditions met:
6|___ submit order
Augmented Intelligence
GETCO, the world’s current top high frequency group, generally follows this pattern, and was the inspiration for its inclusion. Here the parts that humans are good at are delegated to humans, and the parts that a computer is good at are delegated to the computer. Humans are good at analyzing world events, understanding what time of day things will happen and what to watch out for, and developing a general feel for a certain day’s market. The computer is good at reacting on a microsecond basis and following parameters precisely and unemotionally. Basically a human is inserted as an intermediary between `the world’ and the automated trading system because there are a lot of common sense things a human knows about the world which turn out to be really hard to get a computer to understand.
squishy chaotic world –> human –> computer –> market
The human turns on or off the model whenever they feel like it. There are all kinds of models (I list some possibilities here rather than previously because this is a relatively novel design pattern): A momentum model that is turned on a few minutes before earnings announcements and then turned off a few minutes after; a mean reversion algorithm that is activated on days that seem dull and don’t have any major news scheduled; a general market making model that’s run all the time except in extreme circumstances; a triple-witching-day model; etc.
Some are designed to run for minutes, some all day. Some hold for milliseconds, some for hours. Asset class and breadth are similarly unrestricted.
Each model is unique, but they also have parameters, so they are optimizable to changing conditions.
_| AugInt(Pattern)
1|_ have a feeling # human
2|_ set parameters # human
3|_ [other design pattern system here] # computer
I think GETCO’s design pattern is really interesting, although most of my thoughts on it are purely speculation.