When Selection Sours

One of the main traits that separates professional investors from the retail, I believe, is narrative tracking. Watching the quality of ones investment vehicles over time takes time and resources, access to data, and the ability to digest and act upon it. But knowing who the winners are in your portfolio and having the conviction to let them ride, as well as constantly cutting out the fat and realizing when you’ve made a mistake is what separates those who generate long term returns that beat the market.

I wondered how well an investment team comprised of college students managing a small fund performed at this task, so I set about analyzing my investment team’s historical portfolio.

Note, the discussion here gets a little tricky because the team does not disclose portfolio details or investment methodology, but I want to at least share my reasoning, methodology, insights, and next steps. But for privacy concerns, this may be a shorter post than I’d like.

When the team pitches a stock, it is either a “yes” or a ”no” to open a position vote based on a simple majority. If it is a tie it seems to usually become a no. As a member of the investment team for 2.5 years now, I have voted on tens of pitches and pitched about 7 names myself. For a long while, I have wanted to compare my investment intuition to the rest of the teams by comparing the returns of either portfolio. I suspected that the team was generally risk off, or that we were passing over the investments that would yield significant highs and lows. I had good reason to think this: as a student organization in the business school, the incentive is to learn and preserve our ability to invest (preserve capital). But I digress.

In my opinion, part of the learning experience (even the majority of it) is understanding where you have made mistakes in the past and not making them again. Or at least realizing when you have made a mistake or wasted a resource more quickly than preceding cases. An investment team cannot do this without a thorough understanding of past performance, so I set out to build something from which I could glean some insight.

Backtesting

I’ve wanted to back test trading strategies for a good while now, and this was (I thought) a great way to dive in. Not to mention to practice my Python, which is an underused and underdeveloped “skill” of mine. Back testing is essentially taking a strategy (say, buying and selling momentum or analyzing online sentiment) and seeing how it performs historically. The idea is to then take this model, tweak it and have it make money in real time as an algorithmic trading tool. This rarely works in execution, but I believe there is a lot of value in understanding how past trades worked in order to optimize for future returns, as well as in understanding how to fundamentally build these tools.

The backtesting library I settled on is Backtrader, an open-source library for backtesting stocks that has a lively community and plenty of features. I have used Quantopian (now gone) and Quantconnnect in the past (and plan to learn more of the latter), but found the gamified in-browser experience a bit constricting and to be honest, the learning curve a bit steeper than I’d like. These are great resources though and I plan to use Quantconnect’s academic trading strategy resources in the future.

My goal for this project was simple: Find out how every stock pitched by the team since the beginning of 2015 had performed in the investment timeline the pitch team had set, experiment with some basic risk management strategies, and analyze the results.

To do this, I first needed to scrape the investment team’s historical pitches for information on everything pitched since 2015 and learned an important lesson: in order to learn from past mistakes, data on previous actions needs to be organized and follow a set of basic requirements. Otherwise, a project like this would take immense time to set up or, more likely, would be impossible to do. Have a good system for evaluating any strategy in place by codifying actions.

Once I had this data on each name pitched, I was able to turn it into an array for my code to read so that I could spit out my performance analysis.

But first, I needed code.

First, the class for a basic buy and hold strategy, something like this

#Basic Buy and Hold
class Stoploss_0(bt.Strategy):
    params = (
        ('start_date', None),
        ('end_date', None),
        ('sizer', None),
        )

And a method that runs every loop that checks to see if the stock has yet been bought, and buys and sells it within a set range of dates that is passed through the object

def next(self):
        self.currdate = self.datas[0].datetime.datetime(0)
        #print(self.currdate)
        self.duration = len(self) - self.bar_executed + 1
        
        #print(self.getposition().size)
        if not(self.position) and self.i == 0:
            if self.within_range():
                self.buy()
                self.i = 1
        
        elif self.currdate >= self.p.end_date or self.currdate >= datetime.datetime(2020,12,25):
            self.close()

    def stop(self):
        self.close()

Then I built classes like this for stoplosses, trailing stoplosses, and momentum strategies where I check for moving average crossups to be my buy signal.

In the main, I initiate Backtrader’s engine Cerebro in order to add my data feeds (my stock tickers), which contains classes that pull in and format the Yahoo finance historical data I have for each ticker as well as Backtrader’s library and the classes I have written (strategies).

It looks something like this:

cerebro = bt.Cerebro()

# Set data parameters and add to Cerebro
    data = bt.feeds.YahooFinanceCSVData(
        dataname=''.join(('C:/Users/carso/OneDrive/Documents/Python Scripts/Dec_2020/stockData/',symbol[0],'.csv')),
        fromdate=datetime.datetime(2015, 1, 1),
        todate=datetime.datetime(2020, 12, 24),
        )   

I then loop through my array of tickers using whatever strategy I implement on Cerebro. The array of arrays looks something like this:

etc…

Each index containing name, position size, buy date, and sell date. I can also set the sell date within Cerebro for examining how the portfolio fares in different market environments (e.g. without the COVID crash).

Then I write all my data to a .csv for post-processing (I am an excel queen).

Results

Shown below are the rankings of the results I found, from best performance to worse. No portfolio beat SPY over the 6 years. I have work to do..

Charted, the entire portfolio (everything ever pitched) returns paint an obvious picture:

The team likely hasn’t gotten much better at picking things to pick, the market has just picked up lots of steam as multiple expansion becomes the name of the game.

And the No-Portfolio looks like this:

Looks like the team has gotten better at passing over some of the higher returning names, unfortunately.

I can’t display the Yes-Portfolio for privacy, but I note one final thing from my results here – while the team’s average is lower than the OT-Portfolio (everything ever pitched), the standard deviation on returns is significantly lower (a factor of 3). This is entirely what we expect given the team’s incentives here: preservation of capital (granted, while it is slowly eaten away by the inflation in the overall equity market).

Insights

  • The Team seems to select against variability (and likely volatility) and not for returns. It votes “yes” seemingly almost at random, slightly less than 50% of the time (49.2%). The portfolio of everything we have pitched (since 2015), the OT-Portfolio, does better than almost every other strategy I tested.
  • The best portfolio, interestingly, is the portfolio of “Nos” or the Anti-portfolio. Notably, this is distinctly because of the best top 3 names in the history. If one removes these names, the Anti-portfolio performs significantly worse than our Yes-Portfolio.
    • I suspect the Anti-Portfolio returns would be even better with a stoploss/sell order strategy calibrated to some appropriate risk appetite, but have not tested this.
  • The risk/timing strategies I tested did not work. Strategies that attempt to limit losses appear too sensitive and buying upwards momentum at the 10/30 EMA day cross seems to perform about as well as the Yes-Portfolio historically
  • Without risk mitigation, the Equal Weightings typically perform better than slightly random allocations. These random allocations are the allocations each pitch team designates for their stock, which I presume are attempts to manage risk appetite/get a yes vote for your team. They don’t seem to work from a risk management perspective, but more importantly, they don’t seem to matter much at all.

Takeaways

  • The team should be keeping track of what the yes/no voting spread for each pitch is. This is just more data to learn from and echoes what I wrote earlier about codifying actions for better understanding of strategies. I suspect that the very divided names are the riskier picks and could be great targets for revisiting at a lower price point after some drawdown or setting a stoploss. The voting spread could also be used for allocation calibration if it seems to be indicative of something like variability, say giving more weight to a strong “yes” vote.
  • We should think of creative ways to limit downside/keep the portfolio exposed to significant upside. We take a few losses down -30% and more, and even greater losses in the No-portfolio. I believe the team could be more risk-on if we did a better job of portfolio tracking and assessing where the company is on the timeline/catalysts that the original pitch team perceived. It’s not a rule of thumb to sell at -35% drawdown as I show, but I imagine that qualitative assessments done more rigorously than we currently do could a lot to expose us to better upside. This point gets at the core of my research here: portfolio tracking, updating your thesis and where you were right/wrong is an absolutely crucial component of risk management and exposing yourself to upside.
    • Far DTE Call options are also a thought here, because the convexity is nice, but I don’t think that the fund has the risk appetite to buy calls on even 25% of the companies we pitch, though it might be something to consider. I did not look into how quickly after pitch dates stock prices typically appreciated/depreciated. More on this step below
  • The team seems to have generated alpha (or returns against the overall market) during the 2020 drawdown. That’s pretty cool.

Next Steps

Obviously, expanding into better risk management strategies is an attractive next step, particularly testing the Yes and No portfolios against a spectrum of stoplosses. Right now, I’ve only tested the original portfolio with all of the pitches against stoplosses, but it is entirely possible that protecting the Yes portfolio, which seems low in variability, from large drawdowns could be very successful. In addition, my code needs the added functionality of handling short selling for the stoplosses, something that backtrader doesn’t seem to handle super easily (I haven’t spent much time on this, admittedly).

Another thought is expanding our risk/reward by waiting for drawdowns to buy-in to the pitched price. A key component of this is understanding how the stocks tend to move after they are pitched, possibly even the yes category vs the no category. Do the yes’s tend to drop right after we buy them? How long does it take for a missed “no” to pick up momentum on average after the pitch date? With this understanding, we could identify if there are typically better entry points, as it is entirely likely that pitches get brainstormed biased by momentum stocks on the internet. This would also allow assessment of the viability of buying call contracts: if the stock typically runs up close to pitch date, long dated contracts could be closed before theta (time-decay) eats up too much of the extrinsic value of the contract.

I’m not sure how to backtest the success of this without buying options data, but LEAP calls could be a great option for lowering the risk of some of the riskier trades while keeping the team exposed to upside. Short strangles could also do the trick here, especially for the no-votes or the stocks that tend to move a lot near pitch date (if that seems to be the case); this is a rather expensive strategy but the payoff is likely significant.

Finally, I suspect that the team is doing a poor job of selling at the correct time due to general lack of portfolio tracking (there it is again). The easiest thing to do next would be to simply sell at the highest point or at some set percent gain for each name and compare this to the other strategies. Letting the stock run for the anticipated timeline might work well, but in several cases it is obvious that it can even lead to losses.

On the COVID-19 Downturn

One of my friends asked how the results fared if the overall market downturn from COVID were ignored: it was an unexpected regime shift in the markets, after all.

The results of testing the portfolios immediately prior to and at the bottom of the COVID-19 related US equities crash turns my analysis on its head.

Though there is still no beating the S&P, the Yes-portfolio returns significantly better than the OT-portfolio and the Anti-Portfolio. On an order of 14% and 27% respectively. Even more notable is that the variability is flipped on its head – the Yes-Portfolio appears to be much more variable than either of the two. It seems the team, prior to the crash, was doing exactly right exposing itself to upside and limiting losses.

This is still true if we look at the analysis done ending on Feb. 19, 2020, the day the market peaked. The Yes-Portfolio still outperforms both OT and Anti by similar margins, though it is beat by the S&P significantly more (hence the alpha we generated during the crash). The same story for variability carries here, and it is even more significant!

It is apparent from this further analysis that 2020 was for the team, like many others, an idiosyncratic year of trading and that only in 2020 (Post COVID market V recovery) did the successful strategy of stock selection turn on its head. I don’t think that this is any reason to change strategy course, though the new market environment could be pervasive for years and 2020 is indicative of a sub-par selection strategy for years to come.

Since the pre-crash results show the team doing almost exactly what I had prescribed on the exposure to upside front, I think the only systemic change that should be considered is limiting the variability of returns by following original timelines and thesis tracking to mitigate & cut losses.

In sum, when investing in individual names, track your thesis/models and watch out for drawdowns. Make sure there is rigor in what you record of pitches and track your performance overtime like your life depends on it. Take risks but know when to hop off the train. Investing is all about risk management.

One response to “When Selection Sours”

  1. Lueron Young Erickson Avatar
    Lueron Young Erickson

    Risky business! Just read your blog. Always impressed with you. Mimi

    Like

Leave a comment

Design a site like this with WordPress.com
Get started