Overall Statistics Total Trades 57 Average Win 6.54% Average Loss -9.05% Compounding Annual Return 1.961% Drawdown 54.900% Expectancy 0.169 Net Profit 32.765% Sharpe Ratio 0.2 Loss Rate 32% Win Rate 68% Profit-Loss Ratio 0.72 Alpha -0.039 Beta 0.731 Annual Standard Deviation 0.16 Annual Variance 0.025 Information Ratio -0.635 Tracking Error 0.102 Treynor Ratio 0.044 Total Fees \$0.00
```#Several types of oil can be used (Brent, WTI, Dubai etc.) without big differences in results. The source paper for this anomaly uses Arab Light crude oil. Monthly oil
#returns are used in the regression equation as an independent variable and equity returns are used as a dependent variable. The model is re-estimated every month and
#observations of the last month are added. The investor determines whether the expected stock market return in a specific month (based on regression results and
#conditional on the oil price change in the previous month) is higher or lower than the risk-free rate. The investor is fully invested in the market portfolio if the expected
#return is higher (bull market); he invests in cash if the expected return is lower (bear market).

from datetime import datetime
import numpy as np
import pandas as pd
from collections import deque
import statsmodels.formula.api as sm

class Crude_Oil_Predicts_Equity_Returns(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2005, 1, 1)
self.SetEndDate(2019, 8, 1)
self.SetCash(100000)
self.data = {}

self.return_period = 21

# Monthly returns history
self.data[self.spx] = deque()
self.data[self.oil] = deque()

self.Schedule.On(self.DateRules.MonthStart(self.spx), self.TimeRules.AfterMarketOpen(self.spx), self.MonthStart)
self.Schedule.On(self.DateRules.MonthEnd(self.spx), self.TimeRules.BeforeMarketClose(self.spx), self.MonthEnd)

def MonthStart(self):
oil_closes = self.History(self.oil, self.return_period, Resolution.Daily)['settle']
oil_ret = self.Return(oil_closes)
self.data[self.oil].append(oil_ret)

if len(self.data[self.oil]) < 12: return

oil_monthly_returns = pd.Series([x for x in self.data[self.oil]])
spx_monthly_returns = pd.Series([x for x in self.data[self.spx]])
data_frame = pd.concat([spx_monthly_returns, oil_monthly_returns], axis = 1).dropna()
data_frame.columns = [ 'spx', 'oil' ]
model = sm.ols(formula = 'spx~oil', data = data_frame).fit()

# Simple Linear Regression
# Y = C + (M * X)
# Y = α + (β ∗ X)

# Multiple Linear Regression
# Y = C + (M1 * X1) + (M2 * X2) + …
# Y = α + (β ∗ X1) + (β ∗ X2) + ...

# Y = Dependent variable (output/outcome/prediction/estimation)
# C/α = Constant (Y-Intercept)
# M/β = Slope of the regression line (the effect that X has on Y)
# X = Independent variable (input variable used in the prediction of Y)

alpha = model.params
beta = model.params
X = oil_ret
Y = alpha + (beta * X)  # Expected SPX return

if Y > 0:
if not self.Portfolio[self.spx].Invested:
self.SetHoldings(self.spx, 1)
else:
self.Liquidate()

#self.Log(str(self.Time) + " Predicted: " + str(Y))
#self.Log(model.predict())
#self.Log(model.predict(Y))
#self.Log(model.summary())

def MonthEnd(self):
spx_closes = self.History(self.spx, self.return_period, Resolution.Daily)['settle']
spx_ret = self.Return(spx_closes)
self.data[self.spx].append(spx_ret)

def Return(self, history):
prices = np.array(history)
return (prices[-1] - prices) / prices

class QuandlFutures(PythonQuandl):
def __init__(self):
self.ValueColumnName = "Settle"```