| Overall Statistics |
|
Total Trades 26 Average Win 1.00% Average Loss -0.25% Compounding Annual Return 33.789% Drawdown 7.800% Expectancy 2.144 Net Profit 41.489% Sharpe Ratio 2.548 Loss Rate 38% Win Rate 62% Profit-Loss Ratio 4.03 Alpha 0.263 Beta 1.575 Annual Standard Deviation 0.116 Annual Variance 0.013 Information Ratio 2.377 Tracking Error 0.116 Treynor Ratio 0.187 Total Fees $26.50 |
from datetime import timedelta
import decimal as d
class ETFEmaCross(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2017,1,1)
self.SetEndDate(2017,12,29)
self.SetCash(25000)
# Tolerance to avoid bouncing
self.LongTolerance = .0020
self.ShortTolerance = .00015
self.etfs = [
self.AddEquity("SPY", Resolution.Minute).Symbol,
self.AddEquity("VXX", Resolution.Minute).Symbol,
self.AddEquity("VONE", Resolution.Minute).Symbol,
self.AddEquity("ILTB", Resolution.Minute).Symbol,
self.AddEquity("FNCL", Resolution.Minute).Symbol,
self.AddEquity("HYD", Resolution.Minute).Symbol,
self.AddEquity("IXUS", Resolution.Minute).Symbol,
self.AddEquity("ICVT", Resolution.Minute).Symbol,
self.AddEquity("QAI", Resolution.Minute).Symbol,
self.AddEquity("PICK", Resolution.Minute).Symbol,
self.AddEquity("QQQ", Resolution.Minute).Symbol
]
# add indicator dicts(to store an indicator per asset)
self.ema13 = {}
self.ema49 = {}
for symbol in self.etfs:
self.ema13[symbol] = self.EMA(symbol, 13, Resolution.Daily)
self.ema49[symbol] = self.EMA(symbol, 49, Resolution.Daily)
# Fire rebalance on open each day
self.AddEquity("SPY", Resolution.Minute)
self.Schedule.On(self.DateRules.EveryDay("SPY"),
self.TimeRules.AfterMarketOpen("SPY", 30),
Action(self.Rebalance))
# Charting is cool for debugging, but careful not to overdo it and run out of quota
self.charting_mode = False
if self.charting_mode:
stockPlot = Chart('Indicators')
# On the Trade Plotter Chart we want 3 series: trades and price:
for i, symbol in enumerate(self.etfs):
stockPlot.AddSeries(Series('%s'%str(symbol), SeriesType.Line, i)) #y axis label only
stockPlot.AddSeries(Series('%s_Price'%str(symbol), SeriesType.Line, i))
stockPlot.AddSeries(Series('%s_13'%str(symbol), SeriesType.Line, i))
stockPlot.AddSeries(Series('%s_49'%str(symbol), SeriesType.Line, i))
self.AddChart(stockPlot)
# warmup to prepare the indicators so they work on day 1(which are in daily mode, but algo steps in minute mode)
self.SetWarmUp(int(6.5*60*49))
def OnData(self, data):
# fires every minute
if self.IsWarmingUp: return
pass
def Rebalance(self):
self.winnerLength = []
# loop through universe
for symbol in self.etfs:
# Ensure the Indicators are ready and not returning 0.0
if self.ema13[symbol].IsReady and self.ema49[symbol].IsReady:
#self.winnerLength.append(1)
#Long
if self.ema13[symbol].Current.Value > self.ema49[symbol].Current.Value*d.Decimal(1+self.LongTolerance):
self.winnerLength.append(1)
if self.Portfolio[symbol].Quantity <= 0:
self.SetHoldings(symbol, 1./float(len(self.winnerLength)), tag="Long")
# Liquidate
elif self.ema13[symbol].Current.Value < self.ema49[symbol].Current.Value*d.Decimal(1+self.ShortTolerance):
if self.Portfolio[symbol].Quantity >= 0:
self.SetHoldings(symbol, 0/float(len(self.etfs)), tag="Short")
if self.charting_mode:
self.Plot('Indicators', '%s_Price'%str(symbol), self.Securities[symbol].Price)
self.Plot('Indicators', '%s_13'%str(symbol), self.ema13[symbol].Current.Value)
self.Plot('Indicators', '%s_49'%str(symbol), self.ema49[symbol].Current.Value)