Overall Statistics Total Trades 73 Average Win 6.35% Average Loss -3.87% Compounding Annual Return 8.126% Drawdown 34.400% Expectancy 0.834 Net Profit 292.846% Sharpe Ratio 0.634 Probabilistic Sharpe Ratio 4.027% Loss Rate 31% Win Rate 69% Profit-Loss Ratio 1.64 Alpha 0.078 Beta -0.042 Annual Standard Deviation 0.116 Annual Variance 0.014 Information Ratio -0.117 Tracking Error 0.212 Treynor Ratio -1.749 Total Fees $664.90 Estimated Strategy Capacity$380000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X
# https://quantpedia.com/strategies/paired-switching/
#
# This strategy is very flexible. Investors could use stocks, funds, or ETFs as an investment vehicle. We show simple trading rules for a sample strategy
# from the source research paper. The investor uses two Vanguard funds as his investment vehicles – one equity fund (VFINX) and one government bond
# 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.months = 3

self.Schedule.On(self.DateRules.MonthStart(self.first), self.TimeRules.AfterMarketOpen(self.first), self.Rebalance)

def Rebalance(self):
if(self.months % 3 == 0):
if self.Securities.ContainsKey(self.first) and self.Securities.ContainsKey(self.second):
history_call = self.History([self.first, self.second], timedelta(days=90))
if not history_call.empty:
first_bars = history_call.loc[self.first.Value]
last_p1 = first_bars["close"].iloc[0]

second_bars = history_call.loc[self.second.Value]
last_p2 = second_bars["close"].iloc[0]

# Calculates performance of funds over the prior quarter.
first_performance = (float(self.Securities[self.first].Price) - float(last_p1)) / (float(self.Securities[self.first].Price))
second_performance = (float(self.Securities[self.second].Price) - float(last_p2)) / (float(self.Securities[self.second].Price))

# Buys the fund that has the higher return during the period.
if(first_performance > second_performance):
if(self.Securities[self.second].Invested):
self.Liquidate(self.second)
self.SetHoldings(self.first, 1)
else:
if(self.Securities[self.first].Invested):
self.Liquidate(self.first)
self.SetHoldings(self.second, 1)

self.months += 1