Overall Statistics |
Total Trades 954 Average Win 4.00% Average Loss -0.83% Compounding Annual Return 118.472% Drawdown 24.700% Expectancy 0.629 Net Profit 865.148% Sharpe Ratio 2.094 Probabilistic Sharpe Ratio 86.932% Loss Rate 72% Win Rate 28% Profit-Loss Ratio 4.80 Alpha 0.338 Beta 0.399 Annual Standard Deviation 0.395 Annual Variance 0.156 Information Ratio -0.842 Tracking Error 0.475 Treynor Ratio 2.075 Total Fees $2349860.46 Estimated Strategy Capacity $450000.00 Lowest Capacity Asset ETHUSD E3 |
# Multi-asset, 4 Hour multi-indicators crypto portfolio with risk management # ---------------------------------------------------------------------------------- CRYPTOS = ['BTCUSD', 'LTCUSD', 'ETHUSD']; LEV = 1; MA_1 = 120; MA_2 = 12; RSIUP = 70; RSIDOWN = 30; a = RSIUP - RSIDOWN; b = RSIUP - a; c = ((RSIUP + 10) - (RSIDOWN - 10 )) / 100; d = (RSIUP + 10) - c * 100; # ---------------------------------------------------------------------------------- class UpgradedApricotPony(QCAlgorithm): def Initialize(self): #Grunddaten für Indikator self.SetStartDate(2019, 1, 1) self.SetEndDate(2021, 11, 24) self.SetCash(1000000) self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin) self.SetTimeZone("Europe/Berlin") self.profit_percentage = 0.3 self.loss_percentage = -0.1 self.pairs = [Pair(self, ticker) for ticker in CRYPTOS] self.SetWarmUp(5*24*(MA_1 + MA_2), Resolution.Hour) def OnData(self, data): for pair in self.pairs: if self.IsWarmingUp: return symbol = pair.symbol price = self.Securities[symbol].Price rsi = pair.rsi.Current.Value rsi_ema = pair.rsi_ema.Current.Value diff = rsi_ema - rsi nma = pair.nma.Current.Value nma_ema = pair.nma_ema.Current.Value bbr = (self.Securities[symbol].Price - pair.bb.LowerBand.Current.Value) / (pair.bb.UpperBand.Current.Value - pair.bb.LowerBand.Current.Value) if (pair.bb.UpperBand.Current.Value - pair.bb.LowerBand.Current.Value) > 0 else 0 bbnorm = (a * bbr + b) sto = pair.sto.Current.Value sto_stochd = (c * pair.sto.StochK.Current.Value + d) if not self.Portfolio[symbol].Invested: if self.Securities[symbol].Close > nma and pair.rsi.Current.Value > pair.rsi_ema.Current.Value and bbnorm > pair.rsi.Current.Value and pair.rsi.Current.Value > sto_stochd: quantity = (self.Portfolio.Cash * LEV/len(self.pairs))/ self.Securities[symbol].Price self.MarketOrder(symbol, quantity) elif self.Securities[symbol].Close < nma: self.Liquidate(symbol) profit = self.Portfolio[symbol].UnrealizedProfitPercent if self.Portfolio[symbol].Invested: if self.Portfolio[symbol].IsLong: if profit > self.profit_percentage: self.Liquidate(symbol, "Take Profit reached") elif profit < self.loss_percentage: self.Liquidate(symbol, "Stop Price reached") class Pair: def __init__(self, algorithm, ticker): self.symbol = algorithm.AddCrypto(ticker, Resolution.Hour, Market.Bitfinex).Symbol algorithm.consolidator = TradeBarConsolidator(timedelta(hours = 4)) # RSI over EMA self.rsi = RelativeStrengthIndex(14) algorithm.RegisterIndicator(self.symbol, self.rsi, algorithm.consolidator) self.rsi_ema = IndicatorExtensions.EMA(self.rsi, 13) # New Moving Average ema_1 = ExponentialMovingAverage(MA_1) algorithm.RegisterIndicator(self.symbol, ema_1, algorithm.consolidator, Field.High) ema_2 = ExponentialMovingAverage(MA_2) algorithm.RegisterIndicator(self.symbol, ema_2, algorithm.consolidator, Field.Low) self.nma = IndicatorExtensions.Over(IndicatorExtensions.Plus(ema_1, ema_2), 2) self.nma_ema = IndicatorExtensions.Of(ExponentialMovingAverage(MA_2), self.nma) # Bollinger Bands self.bb = BollingerBands(20, 2) algorithm.RegisterIndicator(self.symbol, self.bb, algorithm.consolidator) # Stochastic self.sto = Stochastic(14, 5, 1) algorithm.RegisterIndicator(self.symbol, self.sto, algorithm.consolidator)