| Overall Statistics |
|
Total Trades 2406 Average Win 0.58% Average Loss -0.63% Compounding Annual Return 6.619% Drawdown 24.900% Expectancy 0.049 Net Profit 37.823% Sharpe Ratio 0.396 Probabilistic Sharpe Ratio 6.521% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 0.92 Alpha 0.084 Beta -0.093 Annual Standard Deviation 0.181 Annual Variance 0.033 Information Ratio -0.239 Tracking Error 0.24 Treynor Ratio -0.773 Total Fees $0.00 Estimated Strategy Capacity $15000000.00 Lowest Capacity Asset ABBV VCY032R250MD |
class EMAMomentumUniverse(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 7)
self.SetEndDate(2015, 1, 7)
self.SetCash(100000)
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverse(self.CoarseSelectionFunction)
self.averages = { }
self.rebalanceTime = datetime.min
self.RSImin = 30
self.RSImax = 40
self.activeStocks = set()
self.portfolioTargets = []
self.selected = []
def CoarseSelectionFunction(self, universe):
if self.Time <= self.rebalanceTime:
return self.Universe.Unchanged
self.selected = []
universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True)
universe = [c for c in universe if c.Price > 10][:2000]
for coarse in universe:
symbol = coarse.Symbol
history = self.History(symbol, 11, Resolution.Daily)
self.averages[symbol] = SelectionData(history)
self.averages[symbol].update(self.Time, coarse.AdjustedPrice)
if int(self.averages[symbol].rsi.Current.Value) < self.RSImax and int(self.averages[symbol].rsi.Current.Value) > self.RSImin:
self.Debug(int(self.averages[symbol].rsi.Current.Value))
self.selected.append(symbol)
self.rebalanceTime = self.Time + timedelta(5)
return self.selected[:5]
def OnSecuritiesChanged(self, changes):
# close positions in removed securities
for x in changes.RemovedSecurities:
self.Liquidate(x.Symbol)
if x.Symbol in self.activeStocks:
self.activeStocks.remove(x.Symbol)
# can't open positions here since data might not be added correctly yet
for x in changes.AddedSecurities:
self.Securities[x.Symbol].FeeModel = ConstantFeeModel(0)
self.activeStocks.add(x.Symbol)
# adjust targets if universe has changed
self.portfolioTargets = [PortfolioTarget(symbol, 1/len(self.activeStocks))
for symbol in self.activeStocks]
def OnData(self, data):
if self.portfolioTargets == []:
return
for symbol in self.activeStocks:
if symbol not in data:
return
for symbol in self.portfolioTargets:
self.Debug(symbol)
self.SetHoldings(self.portfolioTargets)
self.portfolioTargets = []
class SelectionData():
#3. Update the constructor to accept a history array
def __init__(self, history):
#self.slow = ExponentialMovingAverage(200)
#self.fast = ExponentialMovingAverage(50)
self.rsi = RelativeStrengthIndex(10)
#self.macd = MovingAverageConvergenceDivergence(12, 26, 9)
#4. Loop over the history data and update the indicators
for data in history.itertuples():
time = data.Index[1]
close = data.close
#self.fast.Update(time, close)
#self.slow.Update(time, close)
self.rsi.Update(time, close)
#self.macd.Update(time, close)
def is_ready(self):
return self.rsi.IsReady
#and self.slow.IsReady and self.fast.IsReady and self.macd.IsReady
def update(self, time, price):
#self.fast.Update(time, price)
#self.slow.Update(time, price)
self.rsi.Update(time, price)
#self.macd.Update(time, price)