Algorithm and Portfolio Stats: 05/13/2024 - 05/17/2024

Algorithm performance has remained poor this week, hence our decision to temporarily pull it. We’re using this time to prepare more advanced reporting on our long term portfolio, as well as evaluating the reasons behind the algorithm’s poor live performance. I’ll note that all of our systems currently in live testing had Sharpe ratios above 2.0 in backtests. Given our main system’s consistent failure as of late, it’s significantly misaligned with our back test results. Our working theory is no longer that it’s a bad period for the signal itself, but that our live engine is some way flawed. That is to say: our back test results aren’t aligned with our live results, because our live engine isn’t exactly matching the decision-making processes of our back tester.

I’ve been doing deep dives into our recent trades for much of this week, individually checking them against back tests, and I’ve found a few incongruities between our live engine and our testing system. I suspect that these are the reason for our system’s recent under-performance. So far, the incongruities are:

  • Early Stop-Outs. This is a bug we’ve seen before in our live system, and that I believed had been fixed previously. To summarize this bug, I need to elaborate on how our system uses stop losses. In our live engine, a trade follows these steps:

    • The signal is observed. The algorithm takes a short or long position. For this example, we’ll assume a long position.

    • The algorithm is allowed to set a “Permanent Stop Loss”. This is a stop loss that cannot be changed, and remains the same until the position is exited. Our current algorithm does not use permanent stop losses, but previous ones have.

    • The algorithm is also allowed to set a “Dynamic Stop Loss”. This works identically to a regular stop loss, but the system can raise and lower it at the end of each 5m candle. Note that the position will be exited as soon as the price dips below either stop loss

    • The system can also set “Permanent Exit” and/or “Dynamic Exit” levels - these work the same as stop losses, but in reverse. Our current algorithm doesn’t incorporate these.

    • Then, our system watches each 5m candle. If, during the candle, the price breaks through either exit or either stop loss, the system signals an exit at that price. Otherwise, if we’re still holding at the end of the candle, the system may choose to exit there, depending on its technical outlook (if you see an exit notification, with the label “Reason For Exit: Unfavorable Technical Signals”, this is what’s happening there). If we still don’t exit at the end of that candle, the system may update its dynamic stop loss and dynamic exit, if it has them.

    This problem is occurring during that last bullet point. That is, our dynamic stop loss is being applied too early. Rather than only applying the new dynamic stop for the next candle, the system is sometimes misremembering when it last updated it. As a result, it will update to a new dynamic stop loss at the end of the candle, and then signal an exit if it previously hit said price during that candle.

    Since this algorithm uses the Tenkan-Sen level as its dynamic stop loss, this should, on paper, be a minor difference. In fact, if you were using the Tenkan-Sen level as a trailing stop, and watching live, this is arguably closer to how you would end up trading it. But regardless, this isn’t how it works in the back tests, so it’s a flaw that must be corrected. This has led to us being stopped out of positions in live trading earlier than we would have in those same trades in a back test setting.

    This is a problem which can compound, building up live losses faster. This is because, on occasion, we’ve seen a trade get stopped out early, and take a re-entry which it shouldn’t have even been eligible for.

  • Inconsistent Stop Loss Rules. This was a bug in our back test engine which, as of writing, has been fixed. To summarize it, our back tester assumed that, when we first entered a trade, we had no dynamic stop loss until the first 5m candle elapsed. This isn’t consistent with our live engine, which implements its dynamic stops immediately upon entry. When I’m confident we’ve made as many repairs to our systems as are needed, I’ll do a new batch of back tests with and without this change. This is technically something we can use in the live engine, in that we can prevent it from implementing dynamic stops until a candle elapses, if it’s found to improve performance.

  • Inconsistent Historic Data. A few of the databases we’ve been using are somewhat incomplete. This appears to have been my mistake, and to be localized mostly to the last month or so. This mostly takes the form of certain inter-market candles missing, but since the Tenkan-Sen and Kijun-Sen lines use a fixed number of candles in each of their look backs, even 1 missing candle from our records creates a problem. For example, the Kijun-Sen line uses the last 26 candles in its calculation. If our database excludes even 1 of those candles, we can end up with a different line, and thus trades that don’t match up between back tests and live implementations. This should be easy, albeit time-consuming, to fix.

I want to apologize again for the recent under-performance of the algorithm. My hope is that, after rectifying these discrepancies, performance will closer match up with our stronger back test results.

Additionally, we’re working on more advanced reporting of our portfolio, as well as experimenting with new quantitative methods of organizing it. The more advanced reporting will include total revenue breakdowns, international exposures, as well as highlighting some of the more correlated tickers within it. As for the quantitative methods, we’re experimenting with utilizing Markowitz-style allocations. We’ll give more updates on this as we get them.

We feel that our portfolios will be closer-aligned with many of our user’s investment goals. As such, in a few weeks time, we’re going to be pushing these more as a main pillar. Whereas our portfolio is designed to consistently beat SPY, our algorithm is zero-beta. That is, it’s designed to consistently provide returns, independent of the market’s performance. We can modify our algorithm to increase its market beta, but given that it only invests in a given ticker for a short period of time (unlike our portfolio, which holds its constituents for a week straight), it’s unlikely we can break a 1.0 market beta with it. As such, we see a lot of value in our portfolio, especially for investors looking for “Invest in the market, but better”.

Speaking of our portfolio:

Our portfolio is on another winning week! We’re up 1.69%, relative to SPY’s 1.32%. As is common, tech was our big kingmaker for the week. If you were deep in tech, you probably had a very strong week. If you were light or even short on it, you probably missed out.

As such, it should be no surprise that we’re remaining deep in tech this week. It’s our single biggest sector allocation, taking up more than double or portfolio, when compared to our next heaviest sector. It’s also our most over-exposed sector going into this week, with Industrials, Healthcare, and Consumer Discretionary also being over-exposures. We’re also long the market as a whole, citing recent SPY momentum.

As always, our portfolio for this week is below. Tickers with allocations below 0.5% are excluded, for brevity.

That’s all I have for you tonight. As always, thank you for reading - and happy trading!

Previous
Previous

HaiKhuu Weekly Preview

Next
Next

HaiKhuu Weekly Recap & Analysis