As we have said before on this blog, TradersStudio was designed by real traders for real traders. This means that a lot of thought was put into making TradersStudio evaluate strategies correctly. A lot of backtesting platforms will make assumptions in their software that may make a system looks good on paper, but in reality the system isn’t effectively tradable in the real-world market. When designing a backtesting platform, there are certain considerations that must be made to make it mimic the markets as closely as possible given the data that we have. Limit orders are a prime example of this. Do we fill an order when the limit is touched or do we only fill if the limit is exceeded?. When we evaluate a trading strategy which uses limit orders it’s important that we understanding Limit orders and backtesting.
This may sound like a trivial problem but as we’ll see it isn’t. After all, let’s assume gold is trading at $1600 an ounce. You have a limit order to buy it but that does not guarantee that the order will be filled – even if it the ticker price touches the limit price. This is a big problem for backtesting platforms. Suppose we have a system that uses limit orders and one day decides that we should buy gold at $1600 with a minimum move of $0.10. Now, let’s further suppose that the low for the day is exactly $1600. Do we count the order as having been filled? Or do we assume that it wasn’t filled? The fact that the minimum move is so high prohibits us from saying conclusively one way or the other. Neither assumption will be 100% correct 100% of the time. In the live market, we simply don’t know if the order would have been filled or not. Depending on what we choose on the backend (i.e. should we fill at the limit price or only when the ticker price exceeds it) can change the outcome of a trading system.
You may be tempted to say that it cannot have that significant of an impact. After all how much can 10 cents influence a broad trading system? You’d be surprised. Consider the following system:
Dim X As BarArray
If High<>Low Then
If Type=0 Then
If Average(X,3,0) If Average(X,3,0)>.8 Then Sell("",1,High+2*getactiveminmove(),Limit,Day)
Here we have a very basic system that has one parameter “Type”. If Type is 0 then we use the “realistic” fill type whereby the price needs to exceed the limit price to be filled. If Type is any other number we use the “simple” fill type and the order is executed if we touch the limit price.
The results are astounding. We are using a big full size 250 per point S&P500 contract using 250 per point from 1/1/1998 to 6/24/2013. Using the simple trading algorithm, we see:
Total Net Profit: $30,175.00
Total # of trades 266
Percent Profitable 48.50%
Max intraday drawdown ($35,775.00)
Using the realistic algorithm we see:
Total Net Profit $14,975.00
Total # of trades 259
Percent Profitable 47.10%
Max intraday drawdown ($36,950.00)
You can also download the full report. Please note that this is not a tradable system! We did not deduct slippage and commission using this – we only tested the raw trades.
As we would expect, we execute more trades with our simple algorithm than the realistic one. However, using the assumption that the tick price must exceed the limit order reduces our profit in half! In the simple test we make $30k, but in the realistic test we only make $15k!
The assumption of when we fill the order is something you can customize within TradersStudio which gives you the ability to test your system under various market conditions. It’s important to remember that whatever system you build and trade should be robust enough to be able to handle either condition. In general, when designing TradersStudio, we aimed to most accurately simulate the real market. As such, if your system works well in TradersStudio and has been sufficiently optimized and tested, you can have confidence that it will work in real-life trading as well.