- GuruFinance Insights
- Posts
- How I Evaluate a Trading Strategy Without Conventionally Backtesting It
How I Evaluate a Trading Strategy Without Conventionally Backtesting It
Let’s keep significance as high as possible!
The NEXT Trillion Dollar Company?
This company just signed a MASSIVE deal with Apple.
It gets their AI tech in Apple’s iPhones and iMacs until 2040!
But it goes beyond that.
The company is getting its tech into products by Nvidia, Google, and Samsung too.
Its AI tech is so crucial…
Nvidia is actually buying up the stock too.
They’ve invested more in this one company than any other… nearly $150 million.
Is this stock the next Nvidia… which has gone up 81,700% over the last 20 years?
Exciting News: Paid Subscriptions Have Launched! 🚀
On September 1, we officially rolled out our new paid subscription plans at GuruFinance Insights, offering you the chance to take your investing journey to the next level! Whether you're just starting or are a seasoned trader, these plans are packed with exclusive trading strategies, in-depth research paper analysis, ad-free content, monthly AMAsessions, coding tutorials for automating trading strategies, and much more.
Our three tailored plans—Starter Investor, Pro Trader, and Elite Investor—provide a range of valuable tools and personalized support to suit different needs and goals. Don’t miss this opportunity to get real-time trade alerts, access to masterclasses, one-on-one strategy consultations, and be part of our private community group. Click here to explore the plans and see how becoming a premium member can elevate your investment strategy!
Usually, when I stumble across a strategy, I implement it as a whole: entries, exits, risk management, fees, slippage, spread, and so on. So, we try to simulate how we would’ve potentially traded with the money we would’ve had. But often, besides all those other backtest assumptions, there is a substantial problem when doing this:
There are trades we couldn’t enter, but we would’ve entered.
This can be due to several reasons. For example,
there is not enough cash left to enter the position,
or we already have bought the symbol and don’t want to buy more, as our portfolio would be exposed to a higher risk regarding that one symbol.
By restricting us this way, we lose valuable trades that would’ve helped us evaluate the strategy. However, it highly depends on the strategy and the amount of signals it produces.
It cannot only affect the significance of the strategy’s performance, but it can also impact the entire backtest results. Here’s an example of a (very bad) long-only Bollinger Bands® mean reversion strategy on AAPL with 1,975 signals starting on
A) March 16, 2001
B) and one business day later on March 19, 2001:

A) Strategy starting on March 16, 2001. Annualized return of 35.66%. 105 trades. Image by author.
Fueled for Fortune
Wired's "rocket fuel of AI" label has Wall Street buzzing. Projections skyrocketing to $80 trillion, akin to 41 Amazons, signal a seismic shift. But here's the kicker: astute investors have a shot at riding the wave with a company primed for supremacy. Dive into The Motley Fool's exclusive report for your front-row seat.

B) Strategy starting on March 19, 2001. Annualized return of 38.72%. 108 trades. Image by author.
This is not the perfect example, but I hope you get the gist: We just started the backtest one business day later, and the overall annualized return has decreased by 3%. Some trades also differ from strategy A to B. We even had 1,975 signals, but only ~100 (~5%) have been used to enter trades. That’s the problem we’re dealing with.
Dealing With the Problem
Instead of simulating an entire market and the associated trading behavior, we take a look at the price development relative to the entry signal, which looks like this for the strategy above:

Mean and median price development of all signals of the Bollinger Bands strategy on AAPL. 10 days before and 20 days after signal. 1984 entry signals. Image by author.
The deep blue line represents the mean price development, the dashed line the median price development, and the filled area displays the standard deviation.
After the signal, the price slightly increases on average, suggesting that it is a good indicator, right? We can’t really say yet because AAPL had been quite a flying rocket during the past decades. Thus, any long-only strategy on AAPL would have been profitable anyhow. This is why we also need to compare this to a benchmark signal, meaning that every single day is a signal. I’ve added its mean price development as a red line to the plot:

Same plot as above, but including the benchmark. Image by author.
As you can see, our signal isn’t better than buying AAPL every single day.
I also added the ability to pass commissions to the function, which lowers the overall price development (and entry price) by a given amount. For the following plot, I’ve set the overall commissions to 0.005 (0.5%), but for the rest of this article, I’ll set them to 0 so that we can focus solely on the signal without having to care about more assumptions.

Same plot as above, but including the commisions. Image by author.
As you can see, all the blue stuff moved down by 0.5%. I know this is kept a bit too easy but you can change it on your own if you want to. As already said, we’ll focus on the pure signal without commissions from now on.
Example Time!
Let’s have a look at some examplary signals:
1) RSI(10) Crossing Below 40 (NVDA)
signal = (talib.RSI(adj_close, timeperiod=10) <= 40) \
& (talib.RSI(shift_nb(adj_close, 1), timeperiod=10) > 40)
This strategy on the daily timeframe produced 26 signals, which is a rather small number to conclude that it really is significantly ““better”” than the benchmark, as the following plot might suggest:

Price development of 26 signals of a RSI crossover strategy on NVDA. 50 days before and 100 days after signal. Image by author.
2) Close Price Increases 3 Times in a Row (MSFT)
signal = (adj_close > shift_nb(adj_close, 1)) \
& (shift_nb(adj_close, 1) > (shift_nb(adj_close, 2)))
You can clearly see the 3-day increase before the signal, which — expectedly — has no effect on a better future performance:

Price development of 1,501 signals of a strategy looking if MSFT increases 3 days in a row. 50 days before and 100 days after signal. Image by author.
It’s fun to make these plots. However, there’s a new problem. Maybe, you’ve already spotted it.
The New Problem
It’s our x-axis: We plot the price development over constant time. It’d be helpful if we had a strategy that just closes each position after x days, but that’s rarely the case. Many strategies utilize take profits, stop losses, trailing stops, or other techniques to close a trade.
So, instead of assuming a fixed timeout, we now need to extend our strategy by adding exit signals. For this article, we stick to a simple ATR-based take profit and stop loss. I used it in a lot of other previous stories, but to those of you who don’t know it, it’s pretty simple:
stop_loss = close[i] - atr14[i] * sl_atr_factor
take_profit = close[i] + atr14[i] * sl_atr_factor * rrr
The factor sl_atr_factor just scales the range between stop loss and take profit, whilse the rrr (Risk Reward Ratio) determines how much we are willing to risk, i.e., it scales up/down the take profit in proportion to the risk.
How Do We Plot the Price Development Now?
Well, we just take the average trade duration and adjust every trade’s price development to this average trade duration by using linear interpolation if needed. That’s already the entire magic.
Given the previous strategy (price increasing 3 days in a row) with a sl_atr_factor of 2 and an rrr of 1.5 and extended with an RSI below 30, the plot looks like this:
signal = (adj_close > shift_nb(adj_close, 1)) \
& (shift_nb(adj_close, 1) > (shift_nb(adj_close, 2))) \
& (talib.RSI(shift_nb(adj_close, 1), timeperiod=10) < 30)

Price development of 24 trades on the strategy on MSFT. All trades have been interpolated to 22 days (average trade duration). sl_atr_factor=2, rrr=1.5. Image by author.
You can read the plot as follows: Every trade has been created at 0 and closed at 22 no matter the real trade duration. This is what the linear interpolation was for. I removed the price development before the signal since this isn’t relevant. Apparently, we should’ve closed each trade a bit earlier because of the small valley around 18. We can easily control this by decreasing the sl_atr_factor. Let’s try a sl_atr_factor of 1.8:

Price development of 24 trades on the strategy on MSFT. All trades have been interpolated to 22 days (average trade duration). sl_atr_factor=1.8, rrr=1.5. Image by author.
Nice! Looks even better now with the maximum at the end (at 14) for both median and mean! So, the plot demonstrates that the strategy supposedly outperforms the benchmark, but again, be careful; we’ve only 24 trades! So, this needs to be tested further.
I leave this and playing with the code up to you. Code is below.
Happy trading, everyone :)