Overall Statistics |
Total Trades 60 Average Win 0.86% Average Loss -0.36% Compounding Annual Return 114.331% Drawdown 1.600% Expectancy 1.174 Net Profit 13.351% Sharpe Ratio 6.373 Probabilistic Sharpe Ratio 99.237% Loss Rate 36% Win Rate 64% Profit-Loss Ratio 2.38 Alpha 0.922 Beta -0.029 Annual Standard Deviation 0.141 Annual Variance 0.02 Information Ratio 0.504 Tracking Error 0.193 Treynor Ratio -30.991 Total Fees $108.93 Estimated Strategy Capacity $64000000.00 Lowest Capacity Asset TWLO WBMIXML35O4L |
class WellDressedSkyBlueSardine(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 1) self.SetEndDate(2019, 3, 1) self.SetCash(100000) self.rebalanceTime = datetime.min self.activeStocks = set() self.AddUniverse(self.CoarseFilter) self.UniverseSettings.Resolution = Resolution.Daily self.universe = set() self.portfolioTargets = [] self.indicators = {} self.EMA_Period_Fast = 20 self.EMA_Period_Slow = 50 #self.closeWindows = {} def CoarseFilter(self, coarse): # Rebalancing time if self.Time <= self.rebalanceTime: return self.Universe.Unchanged self.rebalanceTime = self.Time + timedelta(1) sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) self.universe = [x.Symbol for x in sortedByDollarVolume if x.Price > 10 and x.HasFundamentalData][:10] return self.universe def OnSecuritiesChanged(self, changes): # close positions in removed securities for x in changes.RemovedSecurities: self.Liquidate(x.Symbol) for security in changes.AddedSecurities: self.indicators[security.Symbol] = SymbolData(security.Symbol, self, self.EMA_Period_Fast, self.EMA_Period_Slow) def OnData(self, data): for symbol in self.universe: if not data.ContainsKey(symbol): continue if data[symbol] is None: continue if not symbol in self.indicators: continue if symbol in data.Bars: self.indicators[symbol].close_window.Add(data.Bars[symbol].Close) #------------------------------------------------------- if not (self.indicators[symbol].fast_ema_window.IsReady and self.indicators[symbol].slow_ema_window.IsReady): continue #return if (not self.Portfolio[symbol].Invested):# and (self.Portfolio.MarginRemaining > 0.9*self.percentagebuy*self.Portfolio.TotalPortfolioValue): if (self.indicators[symbol].fast_ema_window[1] >= self.indicators[symbol].slow_ema_window[2]): self.SetHoldings(symbol, 0.2) self.Debug("buying " + str(symbol.Value) + " for " + str(data[symbol].Price)) #self.Debug("Close Window is: " + str(self.indicators[symbol].closeWindow[0])) if self.indicators[symbol].fast_ema_window[1] <= self.indicators[symbol].slow_ema_window[1] and (self.indicators[symbol].fast_ema_window[4] > self.indicators[symbol].slow_ema_window[4]): invested = [ x.Symbol.Value for x in self.Portfolio.Values if x.Invested ] self.Debug("invested: " + str(invested)) self.Liquidate(symbol) #------------------------------------------------------- class SymbolData(object): rolling_window_length = 5 def __init__(self, symbol, context, fast_ema_period, slow_ema_period): self.symbol = symbol self.fast_ema_period = fast_ema_period self.slow_ema_period = slow_ema_period self.fast_ema = context.EMA(symbol, self.fast_ema_period, Resolution.Daily) self.slow_ema = context.EMA(symbol, self.slow_ema_period, Resolution.Daily) self.fast_ema_window = RollingWindow[float](self.rolling_window_length) self.slow_ema_window = RollingWindow[float](self.rolling_window_length) #self.daily_rw = RollingWindow[TradeBar](4) self.closeWindow = RollingWindow[float](4) #self.closeWindow = RollingWindow[float](4) self.close_window = RollingWindow[float](4) #self.closeWindows[symbol] = RollingWindow[float](4) # Warm up EMA indicators history = context.History([symbol], slow_ema_period + self.rolling_window_length, Resolution.Daily) for time, row in history.loc[symbol].iterrows(): self.fast_ema.Update(time, row["close"]) self.slow_ema.Update(time, row["close"]) self.close_window.Add(row["close"]) # Warm up rolling windows if self.fast_ema.IsReady: self.fast_ema_window.Add(self.fast_ema.Current.Value) if self.slow_ema.IsReady: self.slow_ema_window.Add(self.slow_ema.Current.Value) # if self.closeWindow.IsReady: # self.closeWindow.Add(time, row["close"]) #def CloseUpdated(self, sender, bar): '''Event holder to update the close Rolling Window values''' # self.closeWindow.Add(bar.Close) def get_fast_EMA(self): return self.fast_ema.Current.Value def get_slow_EMA(self): return self.slow_ema.Current.Value