Many, many, many years ago, I implemented a backtest engine in Python for my master’s degree… it’s an event-driven engine (they are slower than the vector-based engines but imho they are easier to write strategies for, understand and debug) with all blows and whistles, similar to the late Zipline (but with multi-asset capabilities). In fact, I tried most of the Python backtest engines that exist, and that’s why I prefer to use what I built over the years: I have 100% understanding of what’s happening and 100% control. I’m thinking about sharing it...
IMO, a big advantage of event driven engines is their readiness for production / actual trading with minimum code modification required. It would be great if you could share yours.
I'll probably do it in the near future. However, I'm currently swamped with work and need to find time to do it properly.
Yes, event-driven engines are more ready, I agree. Nevertheless, at least in my experience, the production code needs to be carefully adapted to the broker's API (I'm not sure about the word "minimum" :)). Otherwise, we might get slippage, partial fills, all kinds of bugs, etc...
It varies by stock and throughout time. That's one of the key insights.
Example: today, TSLA open with a gap down of -1.8% (after an amazing +21% gains yesterday). If you had bought it, you would be making +1.8% only today. Also today, ADP open with a gap down of -0.5%. If you had also bought it, you would also be making money. However, although -0.5% is a sufficiently large gap for ADP, it is NOT a sufficiently large gap for TSLA.
So how do you present test results if every stock is different? Do you run a test on every stock first to see how large a gap before a stock springs back later in the day?
In my experience there will not be enough volume at the gap open price for most of these fills. A significant portion of the largest gaps down traded when a thin order book on the buy side coincides with a naive market price sell order, so there may be only one trade marking the gap. I tried a related strategy a few years ago and learned this the hard way. It is more pronounced trading lower volume tickers, but persists even at the S&P 500 level.
In any case, I’m collecting trade by trade data for every stock in the S&P500 to compute exactly how much volume % is traded at or below the open price for each symbol. I wasn’t planning on writing about it because it is too much detail. But I can share it with you, just let me know if you are interested. Cheers!
Thanks for your perspective. That’s why I mentioned the results are totally dependent on the execution algorithm each one uses and the account size. I’m forward testing my algorithm, so far so good. If the results continue as good as I’m seeing so far, I’ll start live trading it pretty soon. Then we will have an answer if my particular implementation works. Cheers!
You may be waiting some time after the bell for a subset of opening prints, especially if there is a gap down. It might be asking too much to collect all prints, then order by vol to select your orders, then place orders. Maybe take a couple quarters of earnings to test before you take the next steps. Happy trading
Threshold with lower volatility. Ranking by % didn’t make sense to me because they are not directly comparable between stocks. Example (exaggerated to make the point):
- stock A opened with a 1% gap. Its vol is 2%;
- stock B opened with a 2% gap. Its vol is 20%.
To me, intuitively, A is a much better opportunity that B, although B’s gap % is absolutely wider than A’s.
But maybe I’m wrong. As it didn’t make sense to me I didn’t even look into it…
What backtesting library you are using?
Many, many, many years ago, I implemented a backtest engine in Python for my master’s degree… it’s an event-driven engine (they are slower than the vector-based engines but imho they are easier to write strategies for, understand and debug) with all blows and whistles, similar to the late Zipline (but with multi-asset capabilities). In fact, I tried most of the Python backtest engines that exist, and that’s why I prefer to use what I built over the years: I have 100% understanding of what’s happening and 100% control. I’m thinking about sharing it...
IMO, a big advantage of event driven engines is their readiness for production / actual trading with minimum code modification required. It would be great if you could share yours.
I'll probably do it in the near future. However, I'm currently swamped with work and need to find time to do it properly.
Yes, event-driven engines are more ready, I agree. Nevertheless, at least in my experience, the production code needs to be carefully adapted to the broker's API (I'm not sure about the word "minimum" :)). Otherwise, we might get slippage, partial fills, all kinds of bugs, etc...
how big of a gap down at open was the test?
It varies by stock and throughout time. That's one of the key insights.
Example: today, TSLA open with a gap down of -1.8% (after an amazing +21% gains yesterday). If you had bought it, you would be making +1.8% only today. Also today, ADP open with a gap down of -0.5%. If you had also bought it, you would also be making money. However, although -0.5% is a sufficiently large gap for ADP, it is NOT a sufficiently large gap for TSLA.
So how do you present test results if every stock is different? Do you run a test on every stock first to see how large a gap before a stock springs back later in the day?
Terrific article thanks, look forward to checking in on the results
In my experience there will not be enough volume at the gap open price for most of these fills. A significant portion of the largest gaps down traded when a thin order book on the buy side coincides with a naive market price sell order, so there may be only one trade marking the gap. I tried a related strategy a few years ago and learned this the hard way. It is more pronounced trading lower volume tickers, but persists even at the S&P 500 level.
In any case, I’m collecting trade by trade data for every stock in the S&P500 to compute exactly how much volume % is traded at or below the open price for each symbol. I wasn’t planning on writing about it because it is too much detail. But I can share it with you, just let me know if you are interested. Cheers!
Thanks for your perspective. That’s why I mentioned the results are totally dependent on the execution algorithm each one uses and the account size. I’m forward testing my algorithm, so far so good. If the results continue as good as I’m seeing so far, I’ll start live trading it pretty soon. Then we will have an answer if my particular implementation works. Cheers!
You may be waiting some time after the bell for a subset of opening prints, especially if there is a gap down. It might be asking too much to collect all prints, then order by vol to select your orders, then place orders. Maybe take a couple quarters of earnings to test before you take the next steps. Happy trading
That is the secret. The tradeoff I mentioned. It’s anything between milliseconds to 5 minutes :)
Great job! So you actually cannot try to replicate this as an EOD only strategy when you have to evaluate the open for the gap, right?
Thanks! Yes, you are right: this strategy hinges on evaluating the openings for the stocks in our tradable universe (S&P 500 constituents)
Did you try ranking by gap% to fill your slots or only use the threshold (Anything above the specified percent) with lowest volatility?
Threshold with lower volatility. Ranking by % didn’t make sense to me because they are not directly comparable between stocks. Example (exaggerated to make the point):
- stock A opened with a 1% gap. Its vol is 2%;
- stock B opened with a 2% gap. Its vol is 20%.
To me, intuitively, A is a much better opportunity that B, although B’s gap % is absolutely wider than A’s.
But maybe I’m wrong. As it didn’t make sense to me I didn’t even look into it…
How have the forward test results running? Would love a follow up! Also are you live trading it now ?
When you look at the separation of the returns by vol of the stocks, have you ensured that you haven’t got forward looking bias in the vol
Meaning on day t you will only know the vol of the stock based on close prices up to t-1 and not t itself
how big of a gap down in the test