Overall Statistics |
Total Trades 438 Average Win 0.58% Average Loss -0.40% Compounding Annual Return -34.856% Drawdown 20.100% Expectancy 0.017 Net Profit -3.575% Sharpe Ratio -0.273 Probabilistic Sharpe Ratio 34.183% Loss Rate 58% Win Rate 42% Profit-Loss Ratio 1.44 Alpha -0.5 Beta 1.184 Annual Standard Deviation 0.601 Annual Variance 0.362 Information Ratio -0.752 Tracking Error 0.595 Treynor Ratio -0.139 Total Fees $1130.55 Estimated Strategy Capacity $25000000.00 Lowest Capacity Asset GME SC72NCBXXAHX |
class WellDressedSkyBlueSardine(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 12, 1) self.SetEndDate(2020, 12, 31) self.SetCash(100000) self.AddUniverse(self.CoarseFilter, self.FineFilter) self.UniverseSettings.Resolution = Resolution.Hour self.Data = {} def CoarseFilter(self, coarse): sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) return [x.Symbol for x in sortedByDollarVolume if x.Price > 10 and x.HasFundamentalData][:200] def FineFilter(self, fine): sortedByPE = sorted(fine, key=lambda x: x.MarketCap) return [x.Symbol for x in sortedByPE if x.MarketCap > 0][:10] def OnSecuritiesChanged(self, changes): # close positions in removed securities for x in changes.RemovedSecurities: self.Liquidate() if x.Symbol in self.Data: del self.Data[x.Symbol] # can't open positions here since data might not be added correctly yet for x in changes.AddedSecurities: self.Data[x.Symbol] = SCTR("SCTR",x.Symbol) self.RegisterIndicator(x.Symbol,self.Data[x.Symbol],Resolution.Daily) history = self.History(x.Symbol, 200, Resolution.Daily) if history.empty or 'close' not in history.columns: continue for bar in history.loc[x.Symbol, :].itertuples(): tradebar = TradeBar(bar.Index, x.Symbol, bar.open, bar.high, bar.low, bar.close, bar.volume) self.Data[x.Symbol].Update(tradebar) def OnData(self, data): SCTR = {} for symboldata in self.Data.values(): if symboldata.IsReady: self.Debug(f'{symboldata.symbol}\'s SCTR = {symboldata.Value} in {self.Time}') SCTR[symboldata.symbol] = symboldata.Value [self.SetHoldings(symbol, sctr/sum(list(SCTR.values()))) for symbol, sctr in SCTR.items()] class SCTR(PythonIndicator): def __init__(self, name,symbol): self.Name = name self.symbol = symbol self.Value = 0 self.EMA200 = ExponentialMovingAverage(200) self.EMA50 = ExponentialMovingAverage(50) self.ROC125 = RateOfChange(125) self.ROC20 = RateOfChange(20) self.PPO = PercentagePriceOscillator(12,26,MovingAverageType.Exponential) self.RSI14 = RelativeStrengthIndex(14) self.PPOWindow = RollingWindow[float](3) def Update(self, bar): self.EMA200.Update(bar.Time, bar.Close) self.EMA50.Update(bar.Time, bar.Close) self.ROC125.Update(bar.Time, bar.Close) self.ROC20.Update(bar.Time, bar.Close) self.PPO.Update(bar.Time, bar.Close) self.RSI14.Update(bar.Time, bar.Close) self.PPOWindow.Add(self.PPO.Current.Value) if self.isReady(): self.Value = self.SCTR() return True self.Value = 0 return False def SCTR(self): return self.EMA200.Current.Value*0.3 + self.EMA50.Current.Value*0.15 + self.ROC125.Current.Value*0.3 + self.ROC20.Current.Value*0.15 \ + (self.PPOWindow[0] - self.PPOWindow[2])/(3*self.PPOWindow[2]) *0.05 + self.RSI14.Current.Value*0.05 def isReady(self): return self.EMA200.IsReady and self.EMA50.IsReady \ and self.ROC125.IsReady and self.ROC20.IsReady\ and self.PPO.IsReady and self.RSI14.IsReady