Overall Statistics
Total Orders
48
Average Win
8.38%
Average Loss
-2.31%
Compounding Annual Return
10.201%
Drawdown
19.600%
Expectancy
2.622
Start Equity
100000
End Equity
365358.52
Net Profit
265.359%
Sharpe Ratio
0.587
Sortino Ratio
0.583
Probabilistic Sharpe Ratio
16.492%
Loss Rate
22%
Win Rate
78%
Profit-Loss Ratio
3.63
Alpha
0.038
Beta
0.299
Annual Standard Deviation
0.092
Annual Variance
0.008
Information Ratio
0.014
Tracking Error
0.134
Treynor Ratio
0.181
Total Fees
$486.67
Estimated Strategy Capacity
$2300000.00
Lowest Capacity Asset
AGG SSC0EI5J2F6T
Portfolio Turnover
0.96%
#region imports
from AlgorithmImports import *
#endregion


class PairedSwitching(QCAlgorithm):
    
    def initialize(self):
        self.set_start_date(2005,3,15)
        self.set_end_date(2018,7,15)
        self.set_cash(100000)
        #we select two etfs that are negatively correlated; equity and bond etfs
        self._first = self.add_equity("SPY",Resolution.MINUTE)
        self._second = self.add_equity("AGG",Resolution.MINUTE)
        self._months = -1
        #monthly scheduled event but rebalancing will run on quarterly basis
        self.schedule.on(self.date_rules.month_start("SPY"), self.time_rules.after_market_open("SPY", 1), self._rebalance)

    def _rebalance(self):
        self._months +=1
        if(self._months%3==0):
            #retrieves prices from 90 days ago
            history_call = self.history(self.securities.keys(), 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.set_holdings(self._first.symbol,1)
                else:
                    if(self.securities[self._first.symbol].invested):
                        self.liquidate(self._first.symbol)
                    self.set_holdings(self._second.symbol,1)