Overall Statistics |
Total Trades 239 Average Win 2.54% Average Loss -0.96% Compounding Annual Return 26.693% Drawdown 27.000% Expectancy 0.403 Net Profit 60.803% Sharpe Ratio 0.837 Probabilistic Sharpe Ratio 33.961% Loss Rate 61% Win Rate 39% Profit-Loss Ratio 2.63 Alpha 0.246 Beta -0.021 Annual Standard Deviation 0.26 Annual Variance 0.068 Information Ratio -1.803 Tracking Error 0.624 Treynor Ratio -10.406 Total Fees $0.00 Estimated Strategy Capacity $300000.00 Lowest Capacity Asset LTCUSD E3 |
class CreativeRedHornet(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 1) self.SetEndDate(2021, 1, 1) self.SetCash(100000) universe = ['BTCUSD', 'LTCUSD', 'ETHUSD', 'ETCUSD', 'RRTUSD', 'ZECUSD', 'XMRUSD', 'XRPUSD', 'EOSUSD', 'SANUSD', 'OMGUSD', 'NEOUSD', 'ETPUSD', 'BTGUSD', 'SNTUSD', 'BATUSD', 'FUNUSD', 'ZRXUSD', 'TRXUSD', 'REQUSD', 'LRCUSD', 'WAXUSD', 'DAIUSD', 'BFTUSD', 'ODEUSD', 'ANTUSD', 'XLMUSD', 'XVGUSD', 'MKRUSD', 'KNCUSD', 'LYMUSD', 'UTKUSD', 'VEEUSD', 'ESSUSD', 'IQXUSD', 'ZILUSD', 'BNTUSD', 'XRAUSD', 'VETUSD', 'GOTUSD', 'XTZUSD', 'MLNUSD', 'PNKUSD', 'DGBUSD', 'BSVUSD', 'ENJUSD', 'PAXUSD'] # add data for all tickers self.symbols = [ self.AddCrypto(ticker, Resolution.Daily, Market.Bitfinex).Symbol for ticker in universe ] self.SetBenchmark(self.symbols[0]) self.rsis = {} # add rsi for all symbols for symbol in self.symbols: self.rsis[symbol] = self.RSI(symbol, 14, MovingAverageType.Simple, Resolution.Daily) self.Settings.FreePortfolioValuePercentage = 0.05 self.maxPos = 5 # max number os positions to open at once self.rsiEntryThreshhold = 70 # enter position if rsi rises above this threshhold self.rsiExitThreshhold = 65 # exit position if rsi drops below this threshhold self.minVolume = 1000000 # filters out symbols with 30 day dollar volume less than this self.active = [] self.UniverseSelection() self.Schedule.On(self.DateRules.MonthStart(), self.TimeRules.At(12, 0), self.UniverseSelection) def UniverseSelection(self): # filters out symbols with too low 30 day avg daily dollar volume self.active = [] for symbol in self.symbols: hist = self.History(symbol, 30, Resolution.Daily) if "volume" in hist.columns and hist.loc[symbol]['volume'].mean() * hist.loc[symbol]['close'].mean() >= self.minVolume: self.active.append(symbol) self.Log("Universe: " + str([str(symbol) for symbol in self.active])) def OnData(self, data): for symbol in self.symbols: if not self.rsis[symbol].IsReady: return if self.Portfolio[symbol].Invested and symbol not in self.active: # liquidate symbols outside of active universe self.Liquidate(symbol, "Not enough volume") # number of open positions investedPos = len([x.Key for x in self.Portfolio if x.Value.Invested]) for symbol in self.active: rsi = self.rsis[symbol].Current.Value if self.Portfolio[symbol].Invested: if rsi < self.rsiExitThreshhold: self.Liquidate(symbol, "RSI below threshhold") investedPos -= 1 elif rsi > self.rsiEntryThreshhold and investedPos < self.maxPos: self.SetHoldings(symbol, 1 / (self.maxPos+1)) investedPos += 1