Overall Statistics |
Total Trades 315 Average Win 0.14% Average Loss -0.15% Compounding Annual Return 4.264% Drawdown 3.000% Expectancy 0.018 Net Profit 0.977% Sharpe Ratio 0.441 Probabilistic Sharpe Ratio 38.423% Loss Rate 47% Win Rate 53% Profit-Loss Ratio 0.94 Alpha 0.019 Beta 0.037 Annual Standard Deviation 0.089 Annual Variance 0.008 Information Ratio -3.906 Tracking Error 0.13 Treynor Ratio 1.07 Total Fees $342.06 |
class EMAMomentumUniverse(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 7) self.SetEndDate(2019, 4, 1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction) self.averages = { } def CoarseSelectionFunction(self, universe): selected = [] universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True) universe = [c for c in universe if c.Price > 10][:100] for coarse in universe: symbol = coarse.Symbol if symbol not in self.averages: # 1. Call history to get an array of 200 days of history data history = self.History(symbol, 200, Resolution.Daily) #2. Adjust SelectionData to pass in the history result self.averages[symbol] = SelectionData(history) self.averages[symbol].update(self.Time, coarse.AdjustedPrice) if self.averages[symbol].is_ready() and self.averages[symbol].fast > self.averages[symbol].slow: selected.append(symbol) return selected[:10] def OnSecuritiesChanged(self, changes): for security in changes.RemovedSecurities: self.Liquidate(security.Symbol) for security in changes.AddedSecurities: self.SetHoldings(security.Symbol, 0.10) class SelectionData(): #3. Update the constructor to accept a history array def __init__(self, history): self.slow = ExponentialMovingAverage(200) self.fast = ExponentialMovingAverage(50) self.keltner = KeltnerChannels(10, 2, MovingAverageType.Simple) #4. Loop over the history data and update the indicatorsc for bar in history.itertuples(): tradeBar = TradeBar(bar.Index[1], bar.Index[0], bar.open, bar.high, bar.low, bar.close, bar.volume, timedelta(1)) self.fast.Update(bar.Index[1], bar.close) self.slow.Update(bar.Index[1], bar.close) self.keltner.Update(tradeBar) def is_ready(self): return self.slow.IsReady and self.fast.IsReady and self.keltner.IsReady def update(self, time, price): self.fast.Update(time, price) self.slow.Update(time, price)