Overall Statistics
Total Trades
9
Average Win
62.73%
Average Loss
-4.68%
Compounding Annual Return
11.890%
Drawdown
18.600%
Expectancy
6.201
Net Profit
119.621%
Sharpe Ratio
0.726
Probabilistic Sharpe Ratio
16.876%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
13.40
Alpha
0.002
Beta
0.907
Annual Standard Deviation
0.122
Annual Variance
0.015
Information Ratio
-0.17
Tracking Error
0.039
Treynor Ratio
0.098
Total Fees
$41.38
Estimated Strategy Capacity
$680000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
# region imports
from AlgorithmImports import *
# endregion

class CrudeOilPredictsEqeuityReturns(QCAlgorithm):
    
    def Initialize(self):
        # Set the cash we'd like to use for our backtest
        self.SetCash(100000)

        # Start and end dates for the backtest.
        self.SetStartDate(2010, 1, 1)
        self.SetEndDate(2017, 1, 1)

        # Add assets we'd like to incorporate into our portfolio
        self.spy = self.AddEquity("spy", Resolution.Daily).Symbol
        self.oil =self.AddData(NasdaqDataLink, "OPEC/ORB").Symbol
        self.tbill = self.AddData(NasdaqDataLink, "USTREASURY/BILLRATES").Symbol
        
        # Amount of time in look-back period
        self.regPeriod = timedelta(days=2*365)
        
        # Event is triggered every month
        self.Schedule.On(self.DateRules.MonthStart(self.spy), self.TimeRules.At(0, 0), self.MonthlyReg)
   
    def MonthlyReg(self):
        # Get historical data
        hist = self.History([self.oil, self.spy], self.regPeriod, Resolution.Daily)
        oilSeries = hist.loc[self.oil]['value'].resample('m').last()
        spySeries = hist.loc[self.spy]['close'].resample('m').last()
        index = sorted(set(oilSeries.index).intersection(spySeries.index))
        oilSeries = oilSeries[index]
        spySeries = spySeries[index]
        rf = float(self.Securities[self.tbill].Price)/12.0

        # Regression analysis and prediction
        x = np.array(oilSeries)
        x = (np.diff(x)/x[:-1])
        y = np.array(spySeries)
        y = (np.diff(y)/y[:-1])
        A = np.vstack([x[:-1],np.ones(len(x[:-1]))]).T
        beta, alpha = np.linalg.lstsq(A,y[1:])[0]
        yPred = alpha + x[-1]*beta

        # Make investment decisions based on regression result
        if yPred > rf:
            self.SetHoldings(self.spy, 1)
        else:
            self.Liquidate(self.spy)
        
        # Use the following comments to have better understanding of the regression
        # r, p = pearsonr(x[:-1],y[1:])
        # self.Log("Risk free rate {0}".format(rf))
        # self.Log("Beta {0}, Alpha {1}, P-value {2}".format(beta, alpha,p))
        # self.Log("YPred {0}".format(yPred))