k-NN Candlestick Pattern Search Extensions: More Data

This is a followup to the Mining for Three Day Candlestick Patterns post. If you haven’t read the original post, do so now because I’m not going to repeat the basic mechanics of the strategy. While the approach was somewhat fruitful, it also had some obvious problems: it only seems to work in bearish or high volatility market regimes, and it couldn’t produce good short signals. The main idea I had to resolve these issues was simply to get more data.

equity curves with without IBS

Original strategy using only SPY data. Note long stretches of flat results.

That is easier said than done. Could we use mutual funds or index values to extend the dataset backwards? No, because the daily high/low values are inaccurate. The only alternative we are left with is using data from other instruments. So I picked a broad selection of equity ETFs to include: EWY, EWD, EWC, EWQ, EWU, EWA, EWP, EWH, EWL, EFA, EPP, EWM, EWI, EWG, EWO, IWM, QQQ, EWS, EWT, and EWJ.

The selection was comprehensive and unoptimized. I think you could do some sort of walk-forward optimization that picks the best combination of securities to include in the data set. I’m not sure how much that would help.

The additional data worked fantastically well, resolving both problems. The number of opportunities to trade increased significantly, long signals work very nicely under all market conditions, and predicting negative returns works far better. There was also an unexpected benefit: far less time is needed before the forecasts become usable. In the original implementation I waited 2000 days before starting to use the forecasts. With the extended data set this can be cut to 500, thus letting the backtest cover a longer period.

Performance-wise there were no problems, as the Accord .NET k-d tree implementation that I use is very quick. Finding the nearest 75 points in a data set of approximately 100,000, in 11 dimensions, takes less than 2 milliseconds on my overclocked 2500K.

The settings used in the search are simple: the length of the patterns is 3 days, the 75 closest ones are used to construct a forecast by averaging their next-day returns, and distance is calculated as the sum of squared distances in every dimension. Trades are taken when the forecast is above/below a certain threshold. They are then passed through a filter which only allows long positions when IBS < 0.5 and short positions only when IBS > 0.5.

It should be noted that using traditional measures of “fit” does not work very well with pattern matching. Adding the above instruments actually increases the RMSE, despite significantly increasing the trading performance of the forecasts.

A look at forecasts vs realized next-day returns:

PatternFinderMultiInput (x-axes) vs next day returns (y-axies), when IBS < 0.5

PatternFinderMultiInput (x-axes) vs next day returns (y-axies), for IBS < 0.5 and forecast > 0

An important aspect to note is that even marginally positive forecasts work very well. For example, with the extended dataset, forecasts between 5 and 10 basis points resulted in an average 21 bp return the next day. On the other hand, using SPY data only, the return for those forecasts was just 5 basis points. What this means is that there are many more trades to take, which is what allows the strategy to do well in all market environments. Here’s the long-only equity curve:

Long position taken when IBS  5 basis points. $0.005 per share in commissions.

Long position taken when IBS < 0.5 and forecast > 5 basis points. $0.005 per share in commissions.

 

A couple of charts to analyze the sensitivity of the long-only strategy’s results to changes in inputs (IBS limit and minimum forecast limit):

sensitivity analysis

The additional data also has the benefit of making shorting possible. The equity curve doesn’t look as good, but it’s still a giant improvement over zero predictive ability on the short side:

multi input short only

Short position taken when IBS > 0.5 and forecast < -20 basis points. $0.005 per share in commissions.

 

Finally, the long and short strategies combined, along with the stats:

multi input long short

Long and short strategies above combined. $0.005 per share in commissions.

stats

 

The concept also seems to work for stocks. For example, I tested a long-only strategy on AAPL, using the same settings as above, both with and without the addition of MSFT data. The Microsoft data improved every aspect of the results, with surprisingly consistent performance over nearly 20 years:

AAPLMSFT

It would be interesting to try to apply this on a more massive scale, by increasing the data set to something like all S&P 500 stocks. Some technical restrictions prevent me from doing that right now, but I’ll come back to the idea in the future.

Comments (12)

  • k-NN Candlestick Pattern Search Extensions: Combining Forecasts : QUSMA says:

    […] probably final, followup to the Mining for Three Day Candlestick Patterns post. Previously, we improved performance by adding more data to the search. In this post we’ll try to improve the system further by combining multiple […]

  • Sam says:

    Excellent work as always, I appreciate your effort.

    – It seems like by introducing data from other markets, you’d be “muddying” it for any one instrument in particular. The AAPL+MSFT case makes sense since they’re in the same sector, but the fact it works across all those others is very interesting.
    – What are your technical limitations?
    – How, exactly, are you adjusting for volatility?
    – Newb question: Do any of Sharpe, Sortino, MAR, take into account the time you are actually in market and exposed to risk?
    – Would you actually trade this?

    • qusma says:

      >- It seems like by introducing data from other markets, you’d be “muddying” it for any one instrument in particular. The AAPL+MSFT case makes sense since they’re in the same sector, but the fact it works across all those others is very interesting.

      I don’t really know how much of a factor the sector is, I haven’t done any more extensive tests…it could be the case that these things just generalize really well.

      >- What are your technical limitations?

      The data handling capabilities of my platform are really primitive, I’m working on making them better though.

      >- How, exactly, are you adjusting for volatility?

      When adding the data points, I divide the next-day return by the 10-day realized volatility. Then when I form the forecast I multiply the average by the “current” 10-day realized volatility.

      >- Newb question: Do any of Sharpe, Sortino, MAR, take into account the time you are actually in market and exposed to risk?

      Nope.

      >- Would you actually trade this?

      Sure, why not?

  • Itayda says:

    Great work !!! very interesting,
    Assuming the number of nearest neighbors, 75, is a decent number
    The only issue I can see here is figuring out the forecast threshold you would use,
    If you would like to try this method on many stocks, you will probably come up with
    some logic to do that, which is dynamic for each stock, did you consider using a
    sort of volatility for that ?

    • qusma says:

      I think the most robust way of choosing k is through cross-validation (in backtesting that has to be done in a walk-forward manner, of course). It becomes less relevant when you use an ensemble, of course.

      • Itayda says:

        I totally agree, getting the right K is in the machine learning domain,

        I was referring to the threshold above or below it you open positions, that probably should not be a fixed number if you would like to try out this method on many instruments, this is an issue in the trading domain, did you think about using the volatility of the instrument for determining the threshold ?

        • qusma says:

          Oh, I’m sorry I misread your comment. I haven’t tried changing the threshold using volatility, but instead what I have tried is changing the forecast using volatility. If you check out the follow-up post on combining multiple models, I include some which instead of simply forecasting returns, forecast returns adjusted for 10-day realized volatility instead. The results are pretty good.

          • Itayda says:

            I assume that you divide the future 1 day return by the 10 day volatility, then use that number as the target of the features and insert both to the KD tree, afterwards you will get a list of volatility adjusted returns for the K NN’s, average it and then multiply the result by the current 10 day volatility and use that number as the forecast for the next day return, am I correct ?

            Anyhow, I think you will still need a threshold to filter trades (pre IBS filter),
            and that threshold should vary according to the stock, determining it correctly might be the difference between a 50%+ win rate and a 60%+
            win rate which is very very significant in case of this kind of short term trading.

            Just my 2 cents…

  • ViK says:

    Hi, This is a great and very creative research work. Thank you for sharing this.
    I have some stupid questions.
    Do you trade only SPY when introduce more Data(ETF) or Trade every ETF ?
    Assuming you trade more than SPY.
    What if there are 5~10 different ETF launch Long signal in the same day ? If take all signal to Long we will have large exposure due to High correlation. Isn’t it too risky? Do you just take all signal to trade?
    Thank you.

    • qusma says:

      The tests above use SPY only. Of course in the real world you’d want to use as many instruments as possible.

      The issue of picking which instruments to trade when you have multiple signals, and with what sort of position sizing is extremely complicated and challenging obviously…optimally you’d have a framework to figure out that stuff automatically, taking into account your desired risk levels, correlations, etc.

  • The QUSMA Data Management System Is Now Open Source says:

    […] k-NN Candlestick Pattern Search Extensions: More Data […]


Leave a Reply

Your email address will not be published. Required fields are marked *