Overall Statistics
Total Trades
9
Average Win
34.51%
Average Loss
-6.51%
Compounding Annual Return
11.926%
Drawdown
22.500%
Expectancy
3.727
Net Profit
120.186%
Sharpe Ratio
0.716
Loss Rate
25%
Win Rate
75%
Profit-Loss Ratio
5.30
Alpha
0.007
Beta
0.851
Annual Standard Deviation
0.118
Annual Variance
0.014
Information Ratio
-0.125
Tracking Error
0.049
Treynor Ratio
0.1
Total Fees
$44.52
from datetime import datetime

from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data import *
from QuantConnect.Indicators import *
from QuantConnect.Orders import *
from QuantConnect.Securities import *
from QuantConnect.Python import PythonData
import decimal
import numpy as np
from scipy.stats import pearsonr

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.oil = self.AddEquity("oil", Resolution.Daily).Symbol
        self.spy = self.AddEquity("spy", Resolution.Daily).Symbol
        self.AddData(TBill, "tbill")
        self.tbill = self.Securities["tbill"].Symbol
        # We may also use imported data from Quandl by using the following comments
        # self.AddData(Oil, "oil")
        # self.oil = self.Securities["oil"].Symbol
		
		# Number of month in look-back peroid, Number of days in a month 
        self.regPeriod = 24
        self.daysInMonth = 21
        
        # Event is triggered every month
        self.Schedule.On(self.DateRules.MonthStart(self.spy), self.TimeRules.AfterMarketOpen(self.spy),Action(self.MonthlyReg))
   
    def MonthlyReg(self):
    	# Get historical data
		oilHist = self.History(self.oil, self.regPeriod*self.daysInMonth, Resolution.Daily)
		spyHist = self.History(self.spy, self.regPeriod*self.daysInMonth, Resolution.Daily)
		oilSeries = [float(x.Close) for x in oilHist][self.daysInMonth-1:self.regPeriod*self.daysInMonth:self.daysInMonth]
		spySeries = [float(x.Close) for x in spyHist][self.daysInMonth-1:self.regPeriod*self.daysInMonth:self.daysInMonth]
		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))
		
    def OnData(self,data):
    	pass

class TBill(PythonData):
	
    def GetSource(self, config, date, isLiveMode):
    	# Get the data source from Quandl
    	# Ascending order of the data file is essential!
        return SubscriptionDataSource("https://www.quandl.com/api/v3/datasets/USTREASURY/BILLRATES.csv?api_key=zxb6rfszSQW5-SLkaj3t&order=asc", SubscriptionTransportMedium.RemoteFile)
    
    def Reader(self, config, line, date, isLiveMode):
        tbill = TBill()
        tbill.Symbol = config.Symbol
        
        # Example Line Format:
        # Date      4 Wk Bank Discount Rate   
        # 2017-06-01 		0.8    
        if not (line.strip() and line[0].isdigit()): return None
        
        # Parse the file based on how it is organized
        try:
            data = line.split(',')
            value = float(data[1])*0.01
            value = decimal.Decimal(value)
            if value == 0: return None
            tbill.Time = datetime.strptime(data[0], "%Y-%m-%d")
            tbill.Value = value
            tbill["Close"] = float(value)
            return tbill;
        except ValueError:
            return None

# We may also use imported data from Quandl by using the following comments
# class Oil(PythonData):
#     def GetSource(self, config, date, isLiveMode):
#         return SubscriptionDataSource("https://www.quandl.com/api/v3/datasets/OPEC/ORB.csv?order=asc", SubscriptionTransportMedium.RemoteFile)
#     def Reader(self, config, line, date, isLiveMode):
#         oil = Oil()
#         oil.Symbol = config.Symbol
#         if not (line.strip() and line[0].isdigit()): return None
#         try:
#             data = line.split(',')
#             value = float(data[1])
#             value = decimal.Decimal(value)
#             if value == 0: return None
#             oil.Time = datetime.strptime(data[0], "%Y-%m-%d")
#             oil.Value = value
#             oil["Close"] = float(value)
#             return oil;
#         except ValueError:
#             return None