Overall Statistics Total Trades 126 Average Win 3.44% Average Loss -2.91% Compounding Annual Return 0.443% Drawdown 3.900% Expectancy 0.057 Net Profit 4.517% Sharpe Ratio 0.196 Probabilistic Sharpe Ratio 0.249% Loss Rate 52% Win Rate 48% Profit-Loss Ratio 1.18 Alpha 0.004 Beta -0.003 Annual Standard Deviation 0.02 Annual Variance 0 Information Ratio -0.853 Tracking Error 0.135 Treynor Ratio -1.384 Total Fees \$605.78
from sklearn.linear_model import LinearRegression
import numpy as np

closes_by_symbol = {}

def Initialize(self):

self.SetStartDate(2010,1,1)
self.SetEndDate(2020,1,1)
self.SetCash(100000)

self.threshold = 1.
self.numdays = 250  # set the length of training period

for symbol in [self.x_symbol, self.y_symbol]:
history = self.History(symbol, self.numdays, Resolution.Daily)
self.closes_by_symbol[symbol] = history.loc[symbol].close.values \
if not history.empty else np.array([])

def OnData(self, data):

for symbol in self.closes_by_symbol.keys():
if not data.Bars.ContainsKey(symbol):
return

for symbol, closes in self.closes_by_symbol.items():
self.closes_by_symbol[symbol] = np.append(closes, data[symbol].Close)[-self.numdays:]

log_close_x = np.log(self.closes_by_symbol[self.x_symbol])
log_close_y = np.log(self.closes_by_symbol[self.y_symbol])

x_holdings = self.Portfolio[self.x_symbol]

if x_holdings.Invested:
if x_holdings.IsShort and spread[-1] <= mean or \
self.Liquidate()
else:
if beta < 1:
x_weight = 0.5
y_weight = 0.5 / beta
else:
x_weight = 0.5 / beta
y_weight = 0.5

if spread[-1] < mean - self.threshold * std:
self.SetHoldings(self.y_symbol, -y_weight)
self.SetHoldings(self.x_symbol, x_weight)
if spread[-1] > mean + self.threshold * std:
self.SetHoldings(self.x_symbol, -x_weight)
self.SetHoldings(self.y_symbol, y_weight)

scale = 10000
self.Plot("Spread", "Top", (mean + self.threshold * std) * scale)
self.Plot("Spread", "Bottom", (mean - self.threshold * std) * scale)
self.Plot("State", "Value", np.sign(x_holdings.Quantity))

def regr(self, x, y):
regr = LinearRegression()
x_constant = np.column_stack([np.ones(len(x)), x])
regr.fit(x_constant, y)
beta = regr.coef_[1]
alpha = regr.intercept_
spread = y - x*beta - alpha
return spread, beta