Overall Statistics
Total Trades
1728
Average Win
1.15%
Average Loss
-1.11%
Compounding Annual Return
2.796%
Drawdown
11.200%
Expectancy
0.027
Net Profit
17.868%
Sharpe Ratio
0.323
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
1.04
Alpha
0.025
Beta
0.032
Annual Standard Deviation
0.08
Annual Variance
0.006
Information Ratio
-0.027
Tracking Error
0.225
Treynor Ratio
0.802
Total Fees
$9679.23
import numpy as np

class BasicTemplateAlgorithm(QCAlgorithm):

	def Initialize(self):
		self.SetCash(25000)
		self.SetStartDate(2006,4,26)
		self.SetEndDate(2012,4,9)
		
		self.ewa = self.AddEquity('EWA',Resolution.Minute).Symbol
		self.ewc = self.AddEquity('EWC',Resolution.Minute).Symbol
		
		#specify variables

		self.delta = 0.0001
		self.vw = self.delta/(1-self.delta)*np.eye(2)
		self.ve = 0.001
		
		self.beta = np.zeros(2)
		self.P = np.zeros((2,2))
		self.R = None
		
		self.pos = None
		self.day = None

	def OnData(self, data):
		time = str(data.Time).split(' ')[1]
		day = str(data.Time).split(' ')[0].split('-')[2]
		if time.split(':')[0] != '15' or time.split(':')[1] not in ['55','56','57','58','59','60']:
			return
		
		if self.day is not None and self.day == day:
			return
		
		
		x = np.asarray([float(data[self.ewa].Close),1.0]).reshape((1,2))
		y = float(data[self.ewc].Close)
		
		if self.R is not None:
			self.R = self.P + self.vw
		else:
			self.R = np.zeros((2,2))
			
		yhat = x.dot(self.beta)
		
		Q = x.dot(self.R).dot(x.T)+self.ve
		threshold = np.sqrt(Q)
		error = y - yhat
		Kalman = self.R.dot(x.T)/Q
		self.beta = self.beta + Kalman.flatten()*error
		self.P = self.R - Kalman*x.dot(self.R)
		
		if self.pos is None:
			if error < -threshold:
				quantity = float(self.Portfolio.Cash)/float(data[self.ewa].Close)
				self.Buy(self.ewc,1000)
				self.Sell(self.ewa,1000*self.beta[0])
				self.pos = 'long'
				self.day = day
				
			elif error > threshold:
				quantity = float(self.Portfolio.Cash)/float(data[self.ewa].Close)
				self.Sell(self.ewc,1000)
				self.Buy(self.ewa,1000*self.beta[0])
				self.pos = 'short'
				self.day = day
				
		else:
			if self.pos == 'long' and error > -threshold:
				self.Liquidate()
				self.day = day
				self.pos = None
			elif self.pos == 'short' and error < threshold:
				self.Liquidate()
				self.day = day
				self.pos = None