| 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