Overall Statistics |
Total Trades 1026 Average Win 0.21% Average Loss -0.18% Compounding Annual Return -46.471% Drawdown 13.500% Expectancy -0.035 Net Profit -5.169% Sharpe Ratio -0.345 Probabilistic Sharpe Ratio 33.114% Loss Rate 56% Win Rate 44% Profit-Loss Ratio 1.19 Alpha -0.518 Beta 1.451 Annual Standard Deviation 0.31 Annual Variance 0.096 Information Ratio -1.335 Tracking Error 0.293 Treynor Ratio -0.074 Total Fees $1289.72 Estimated Strategy Capacity $8700000.00 Lowest Capacity Asset CURO WQ6CRD6VV1ID |
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] = SymbolData(self, x.Symbol) def OnData(self, data): SCTR = {} for symboldata in self.Data.values(): if symboldata.IsReady(): self.Debug(f'{symboldata.symbol}\'s SCTR = {symboldata.SCTR()} in {self.Time}') SCTR[symboldata.symbol] = symboldata.SCTR() [self.SetHoldings(symbol, sctr/sum(list(SCTR.values()))) for symbol, sctr in SCTR.items()] class SymbolData: def __init__(self, algo, symbol): self.symbol = symbol self.EMA200 = algo.EMA(symbol, 200, Resolution.Daily) self.EMA50 = algo.EMA(symbol, 50, Resolution.Daily) self.ROC125 = algo.ROC(symbol, 125, Resolution.Daily) self.ROC20 = algo.ROC(symbol, 20, Resolution.Daily) self.PPO = algo.PPO(symbol, 12, 26, MovingAverageType.Exponential, Resolution.Daily) self.RSI14 = algo.RSI(symbol, 14, MovingAverageType.Simple, Resolution.Daily) self.PPOWindow = RollingWindow[float](3) history = algo.History(symbol, 200, Resolution.Daily) for index, bar in history.loc[symbol].iterrows(): self.EMA200.Update(index, bar.close) self.EMA50.Update(index, bar.close) self.ROC125.Update(index, bar.close) self.ROC20.Update(index, bar.close) self.PPO.Update(index, bar.close) self.RSI14.Update(index, bar.close) self.PPOWindow.Add(self.PPO.Current.Value) 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