That's amazing, certainly worth further looking into this one. It's great that you also included delisted stocks in the backtest :). I would love to repeat this backtest and got couple questions
1) universe you're testing it against?
2) in the article you mentioned using normalized distance "surfing" of SMA10, SMA20. Is it like: dist_to_ma10 = abs(current_close - ma10) / ma10 then if dist_to_ma10 < threshold we go on to measuring the consolidation (below)
3) is there a constrain on the consolidation? Say if we define the normalized_range = (box_top - box_bottom)/box_top, the November SOUN has a range of range of 22%
4) I see that you mentioned allocating 0.5% of portfolio per trade, is there also a limit for the maximum number of position? If there are more than one stock breaking out, which one will we choose to buy first?
To do it without constraint, do you mean that we go long if (normalized_distance_10<normalized_distance_20), and (sma_distance_ratio_pct <ADR%) and (close>previous_N_high)? Note: I'm trying with 20 days high.
I learned a lot about backtesting from Marwood Research and Enlightened Stock Trading. Also the podcast Better System Trader. In terms of Python backtesting it was a lot of trial and error and didn't really learn it somewhere..
Great effort! I suspect having the initial stop at 1ATR stopped you out too much. Did your test include position sizing based on risk? If so, how did the algorithm size and what was the new stop percentage?
Yes position size is based on risk. I did tighter stops but at the end of the day risk adjusted returns were kind of the same. I risked 0.5% of the account per trade in the above backtest.
Nice strategy and results! Just to check - did you use opening range highs (intraday data) to determine the entries? Or were the entries based on daily OHLC data?
Nicely written, one thing you should check is to ensure that the ROC ranking is done for the day before your trade day. Otherwise, you risk incorporating lookahead bias into your trading.
You probably have already done so but note to some who may forget this...
This is an attempt to create a system out of his blog post. Systems are strict and rule based, and will have tough time competing with discretionary traders like Qullamaggie. That been said, not that:
1. He trades a combination of 3 (probably more) trading set ups. Next post I will combine 3 of his setups to achieve around 65% CAGR and maybe 1 or 2 down years.
2. His DD % is much higher than what I allowed (I think). I aimed for 20% max DD. If you allow 40% the results will more than double.
3. He lost quite a lot in 2022 so thinking a system can have 0 negative years is not very realistic.
In his chat with traders interview, I think he mentioned he only trades in selective time periods. So if you could incorporate a regime filter or similar (without over fitting), it could filter out the bad trades and hopefully increase your risk adjusted return metrics. But the hard part with this is not overfitting.
not really, trying to keep this very simple. I'm not aiming for 300% years, I don't think it's sustainable systematically. I will probably be smarter on the disc. side when I start trading this live
1. Try year to date performance as the strength filter
2. Only take setups where a stock's sector (etf) is a top performer year to date
3. Do the results meaningfully change if you use 2/4/6/8/10 month performance rather than 1/3/6/12?
4. Do the results meaningfully change if you limit the universe to Russell 1000 versus Russell 3000?
5. Rank performance over time relative to volatility over that time period to avoid stocks that are choppy
6. The 140 EMA seems like a pretty overfitted market bullihs/bearish indicator, probably simpler to use month to date red/green rather than something so backwards looking. Or, is SPY above it's year/quarter/month VWAP.
I don't know if you've gleaned the trend, but in general I think a study on what are current candles doing (month/quarter/year) doing rather than more backwards looking rolling periods might be a worthwhile study.
* regarding the 140 EMA, it's not optimized it's the first value I use. I sometimes use 100, sometimes 200 and sometimes 140 in my backtests - there's nothing to the specific number, just a very simple trend filter.
* What do you mean what current candles are doing?
5. Would be "% gain / realized volatility". Volatility doesn't change too much so you can probably use a 2-3 month rolling lookback. I often look at year/quarter/month to date performance versus 63 day realized volatility (you can also use ADR rather than realized vol, but it doesn't acknowledge gaps).
Current candle is simply the most recent day/week/month/quarter/year, aka day/week/month/quarter/year to date. So, say, it would have been pretty handy knowing that in 2022 the year was bright red (close < open) on most indicies/sectors except for Energy. Or, recently, equal weight being green from day 1 of November '24 throughout the whole month, but then red on day 1 of December, which the whole month being red, etc etc.
Love the effort that you have put into it! Great job!
One question about the SOUN trade: Your system bought on Nov 7th. Why did it not buy already on Oct 28th? Conditions look similar
It actually did but stopped out. I cherry picked the best one in SOUN ;)
I was suspecting this but wanted to confirm 😊 your win rate % is around 30% to 35% ?
32%
Nice work Niv ! 2025, 35% 2 months in ? Might be setting up for an epic year, maybe even the best compared to the backtested results.
Breakout traders I know are making a killing this year
That's amazing, certainly worth further looking into this one. It's great that you also included delisted stocks in the backtest :). I would love to repeat this backtest and got couple questions
1) universe you're testing it against?
2) in the article you mentioned using normalized distance "surfing" of SMA10, SMA20. Is it like: dist_to_ma10 = abs(current_close - ma10) / ma10 then if dist_to_ma10 < threshold we go on to measuring the consolidation (below)
3) is there a constrain on the consolidation? Say if we define the normalized_range = (box_top - box_bottom)/box_top, the November SOUN has a range of range of 22%
4) I see that you mentioned allocating 0.5% of portfolio per trade, is there also a limit for the maximum number of position? If there are more than one stock breaking out, which one will we choose to buy first?
1. All US stocks - listed and delisted
2. It means that I divide the % distance from MAs by ADR %
3. No constraint, that's the point of normalizing. A range of 22% on 20% ADR is not like on 1% ADR stock.
4. I did 1.5x leverage so 150% of the balance. The choosing is random there is no ranking system.
Thanks for your respond Niv, I get (1), (4). As for 2 and 3. I want to confirm my understanding. If we define
1) %distance := dist_to_ma10 = abs(close- ma10) / ma10
2) normalized distance = %distance/ADR% (I use ADR% 5 days) computed for sma10, sma20
3) sma_distance_ratio_pct = abs(ma10 - ma20) / ma20
To do it without constraint, do you mean that we go long if (normalized_distance_10<normalized_distance_20), and (sma_distance_ratio_pct <ADR%) and (close>previous_N_high)? Note: I'm trying with 20 days high.
Awesome work ! How did u learn to backtest so well ? Do u recommend ressources ?
I learned a lot about backtesting from Marwood Research and Enlightened Stock Trading. Also the podcast Better System Trader. In terms of Python backtesting it was a lot of trial and error and didn't really learn it somewhere..
Great effort! I suspect having the initial stop at 1ATR stopped you out too much. Did your test include position sizing based on risk? If so, how did the algorithm size and what was the new stop percentage?
Yes position size is based on risk. I did tighter stops but at the end of the day risk adjusted returns were kind of the same. I risked 0.5% of the account per trade in the above backtest.
Nice strategy and results! Just to check - did you use opening range highs (intraday data) to determine the entries? Or were the entries based on daily OHLC data?
The entries are based on OHLC data
Nicely written, one thing you should check is to ensure that the ROC ranking is done for the day before your trade day. Otherwise, you risk incorporating lookahead bias into your trading.
You probably have already done so but note to some who may forget this...
Yes its looking backwards
Would you mind sending me the details you referenced in the post please?
For which stock?
Something is wrong in the setup or process. Qullamaggie makes 300-500% a year but your process even has negative years ???
This is an attempt to create a system out of his blog post. Systems are strict and rule based, and will have tough time competing with discretionary traders like Qullamaggie. That been said, not that:
1. He trades a combination of 3 (probably more) trading set ups. Next post I will combine 3 of his setups to achieve around 65% CAGR and maybe 1 or 2 down years.
2. His DD % is much higher than what I allowed (I think). I aimed for 20% max DD. If you allow 40% the results will more than double.
3. He lost quite a lot in 2022 so thinking a system can have 0 negative years is not very realistic.
In his chat with traders interview, I think he mentioned he only trades in selective time periods. So if you could incorporate a regime filter or similar (without over fitting), it could filter out the bad trades and hopefully increase your risk adjusted return metrics. But the hard part with this is not overfitting.
Oh I see you do have a basic regime filter in this backrest. Have you considered adding more indicators/features to your regime filtering methodology?
not really, trying to keep this very simple. I'm not aiming for 300% years, I don't think it's sustainable systematically. I will probably be smarter on the disc. side when I start trading this live
Couple of thoughts:
1. Try year to date performance as the strength filter
2. Only take setups where a stock's sector (etf) is a top performer year to date
3. Do the results meaningfully change if you use 2/4/6/8/10 month performance rather than 1/3/6/12?
4. Do the results meaningfully change if you limit the universe to Russell 1000 versus Russell 3000?
5. Rank performance over time relative to volatility over that time period to avoid stocks that are choppy
6. The 140 EMA seems like a pretty overfitted market bullihs/bearish indicator, probably simpler to use month to date red/green rather than something so backwards looking. Or, is SPY above it's year/quarter/month VWAP.
I don't know if you've gleaned the trend, but in general I think a study on what are current candles doing (month/quarter/year) doing rather than more backwards looking rolling periods might be a worthwhile study.
Love your work!
Great thoughts thanks!
* Can you elaborate on 5?
* regarding the 140 EMA, it's not optimized it's the first value I use. I sometimes use 100, sometimes 200 and sometimes 140 in my backtests - there's nothing to the specific number, just a very simple trend filter.
* What do you mean what current candles are doing?
5. Would be "% gain / realized volatility". Volatility doesn't change too much so you can probably use a 2-3 month rolling lookback. I often look at year/quarter/month to date performance versus 63 day realized volatility (you can also use ADR rather than realized vol, but it doesn't acknowledge gaps).
Current candle is simply the most recent day/week/month/quarter/year, aka day/week/month/quarter/year to date. So, say, it would have been pretty handy knowing that in 2022 the year was bright red (close < open) on most indicies/sectors except for Energy. Or, recently, equal weight being green from day 1 of November '24 throughout the whole month, but then red on day 1 of December, which the whole month being red, etc etc.
https://www.tradingview.com/x/byjTn76U/