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)