Introduction
What is it?
Section titled “What is it?”The Backtester is a suite of tools designed for rapid prototyping and testing of systematic trading strategies. It can run simple event studies to quantify market “edges” all the way to full blown multi-currency, multi-timeframe, multi-strategy portfolio simulations. Written in C#, it can be called from any .NET language. It can also serve as a general toolbox underlying many market related applications.
Design philosophy
Section titled “Design philosophy”Many backtesters, particularly those written in R or Python, are often vector-based. For example, you might have an array containing a discrete signal (e.g. +1, 0, -1 for long, flat or short respectively) or a continuous variable (a z-score for example). This array can then be multiplied against market returns to calculate trading strategy performance. Vector-based simulations run extremely fast.
Another common architecture is event driven. Here you write code that responds to events like the market opening, a trade being printed, or the completion of a bar. An event driven approach mimics the real world and is particularly useful for real-time trading; however, it can sometimes be tedious for research where you typically want to iterate as fast as possible without worrying about how you might actually deploy a model in production. An event driven backtester typically requires data to be added at the completion of each new interval (e.g. the close of each new bar) and then recalculating indicators. A vector based backtester on the other hand can calculate an indicator across the full dataset in a single call.
The backtester employs a hybrid approach. Indicators are calculated in advance at the start of the simulation. Then the backtester steps through the data by date, calling various events. This approach allows for simplicity, while at the same time allowing you to respond to events like you would in real-time (e.g. opening or closing a position). The Backtester is also designed to hide as much complexity as possible to speed strategy development while still allowing the user access to low-level classes and functionality for fine-grained control if and when needed.
So what does a strategy look like in practice?
A simple moving average strategy
Section titled “A simple moving average strategy”class SimpleSma : Strategy{ protected override void OnStrategyStart() { Col1 = Sma(Close, 50); Col2 = Sma(Close, 200); }
protected override void OnBarClose() { if (Col1.Last > Col2.Last) { Buy(); } else { Sell(); } }}After a cursory glance at this code, even if you are not a C# expert, you can probably guess this is a long-only simple moving average strategy. The Strategy class abstracts away a lot of the details so you can focus on trading logic without having to worry about indicator calculations, lining up dates, or keeping track of entries and exits.