The strategy invests in Vanguard funds VFINX or VUSTX based on quarterly performance, holding the better-performing fund for one quarter and repeating, leveraging momentum and negative asset class correlation.

I. STRATEGY IN A NUTSHELL

Invest quarterly in the better-performing fund between VFINX (equity) and VUSTX (government bonds), exploiting negative correlation and short-term momentum; rebalance every quarter.

II. ECONOMIC RATIONALE

Returns benefit from negative correlation between assets; accurate quarterly momentum timing enhances portfolio performance compared to static allocation.

III. SOURCE PAPER

Paired-Switching for Tactical Portfolio Allocation [Click to Open PDF]

Akhilesh Maewal; Joel Bock

<Abstract>

Paired-switching refers to investing in one of a pair of negatively correlated equities/ETFs/Funds and periodic switching of the position on the basis of either the relative performance of the two equities/ETFs/Funds over a period immediately prior to the switching or some other criterion. It is based upon the idea that if the returns of two equities are negatively correlated, the overlapping of the periods during which the equities individually yield returns greater than their mean values will be infrequent. Consequently, if the criterion for switching is even minimally accurate in its ability to identify the boundaries of such periods, there is a possibility of improving the performance of the portfolio consisting of the two equities over the portfolio wherein the two equities are statically weighted on the basis of traditional methods such as, for example, variance minimization. In this paper we present some results that indicate that some very simple criteria for paired-switching can lead to lower volatility without any significant penalty in terms of lower returns.

IV. BACKTEST PERFORMANCE

Annualised Return11.3%
Volatility9.3%
Beta0.016
Sharpe Ratio0.78
Sortino Ratio-0.379
Maximum DrawdownN/A
Win Rate51%

V. FULL PYTHON CODE

from AlgorithmImports import *
# fund (VUSTX). These two funds have a negative correlation as they are proxies for two negatively correlated asset classes. The investor looks at the
# performance of the two funds over the prior quarter and buys the fund that has a higher return during the ranking period. The position is held for one 
# quarter (the investment period). At the end of the investment period, the cycle is repeated.
class PairedSwitching(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2004, 1, 1)
        self.SetCash(100000)
        
        self.first_symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
        self.second_symbol = self.AddEquity("AGG", Resolution.Daily).Symbol
        self.recent_month = -1
    def OnData(self, data):
        if self.Time.month == self.recent_month:
            return
        self.recent_month = self.Time.month
        
        if(self.recent_month % 3 == 0):
            if self.first_symbol in data and self.second_symbol in data:
                history_call = self.History([self.first_symbol, self.second_symbol], timedelta(days=90))
                if not history_call.empty:
                    first_bars = history_call.loc[self.first_symbol.Value]
                    last_p1 = first_bars["close"].iloc[0]
    
                    second_bars = history_call.loc[self.second_symbol.Value]
                    last_p2 = second_bars["close"].iloc[0]
    
                    # Calculates performance of funds over the prior quarter.
                    first_performance = (float(self.Securities[self.first_symbol].Price) - float(last_p1)) / (float(self.Securities[self.first_symbol].Price))
                    second_performance = (float(self.Securities[self.second_symbol].Price) - float(last_p2)) / (float(self.Securities[self.second_symbol].Price))
                    
                    # Buys the fund that has the higher return during the period.
                    if(first_performance > second_performance):
                        if(self.Securities[self.second_symbol].Invested):
                            self.Liquidate(self.second_symbol)
                        self.SetHoldings(self.first_symbol, 1)
                    else:
                        if(self.Securities[self.first_symbol].Invested):
                            self.Liquidate(self.first_symbol)
                        self.SetHoldings(self.second_symbol, 1)

VI. Backtest Performance

Leave a Reply

Discover more from Quant Buffet

Subscribe now to keep reading and get access to the full archive.

Continue reading