Overall Statistics
Total Trades
1659
Average Win
1.09%
Average Loss
-1.46%
Compounding Annual Return
415.292%
Drawdown
29.600%
Expectancy
0.438
Net Profit
15194.096%
Sharpe Ratio
2.154
Probabilistic Sharpe Ratio
99.795%
Loss Rate
18%
Win Rate
82%
Profit-Loss Ratio
0.75
Alpha
1.297
Beta
0.133
Annual Standard Deviation
0.609
Annual Variance
0.371
Information Ratio
1.96
Tracking Error
0.615
Treynor Ratio
9.883
Total Fees
$0.00
import numpy as np

class VentralResistanceRegulators(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 1, 1)  # Set Start Date
        self.SetCash(10000)  # Set Strategy Cash
        
        self.lookback = 500
        self.symbols = [
            "BTCUSD", 
            #"BSVUSD", 
            "ETHUSD",
            "LTCUSD",
            #"BCHUSD",
            #"EOSUSD",
            #"XRPUSD",
            #"DSHUSD",
        ]
        for i in self.symbols:
            self.AddCrypto(i, Resolution.Hour, Market.Bitfinex, AccountType.Margin)
            
        self.position = dict.fromkeys(self.symbols, 0)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), Action(self.rebalance))
        self.needs_rebalancing = False
        
    def OnData(self, data):
        
        hist = self.History(self.symbols, self.lookback, Resolution.Hour)
        self.Debug("Processing history of length %i" % len(hist))
        
        for symbol in self.symbols:
            if not symbol in hist.index:
                self.position[symbol] = 0.0
                continue
            mean_price = (hist.loc[symbol]['close']).iloc[-200:].mean()
            std_price = (hist.loc[symbol]['close']).iloc[-400:].std()
            price = (hist.loc[symbol]['close']).iloc[-1]
            if price < 1.0:
                continue
            
            upper = mean_price + 1.0 * std_price
            lower = mean_price - 6.0 * std_price
            
            vol = (hist.loc[symbol]['volume']).iloc[-1]
            mean_vol = (hist.loc[symbol]['volume']).mean()
            volume_aug = (vol / mean_vol) > 1.5
            
            exit_short = price > mean_price and self.position[symbol] < 0.0
            exit_long = price < mean_price and self.position[symbol] > 0.0
            
            if exit_short or exit_long:
                self.position[symbol] = 0
                self.needs_rebalancing = True
            if price > upper and volume_aug and self.position[symbol] != 1.0:
                self.position[symbol] = 1.0 
                self.needs_rebalancing = True
            elif price < lower and volume_aug and self.position[symbol] != -1.0:
                self.position[symbol] = -1.0
                self.needs_rebalancing = True

        if self.needs_rebalancing:
            self.rebalance()
            
            
    def rebalance(self):
        self.Debug("Rebalancing")
        w_sum = 0.2
        for symbol, w in self.position.items():
            w_sum += np.abs(w)
            if w == 0:
                self.Liquidate(symbol)
                
        targets_list = [
            PortfolioTarget(symbol, w/w_sum) 
            for symbol, w in self.position.items()
            if w != 0
        ]
        
        self.SetHoldings(targets_list)
        self.needs_rebalancing = False