Overall Statistics
Total Trades
296
Average Win
0.76%
Average Loss
-1.37%
Compounding Annual Return
0%
Drawdown
102.200%
Expectancy
-0.353
Net Profit
-102.239%
Sharpe Ratio
-0.478
Probabilistic Sharpe Ratio
0.000%
Loss Rate
58%
Win Rate
42%
Profit-Loss Ratio
0.55
Alpha
0
Beta
0
Annual Standard Deviation
2.087
Annual Variance
4.356
Information Ratio
-0.478
Tracking Error
2.087
Treynor Ratio
0
Total Fees
$388.88
Estimated Strategy Capacity
$0
Lowest Capacity Asset
KNCBTC E3
import decimal as d
import pandas as pd
from datetime import datetime, timedelta




# https://www.quantconnect.com/forum/discussion/2865/crypto-bollinger-band-strategy/p1
# https://www.factorresearch.com/research-quant-strategies-in-the-cryptocurrency-space
# https://www.quantconnect.com/tutorials/strategy-library/short-term-reversal-strategy-in-stocks
# https://www.quantconnect.com/tutorials/introduction-to-financial-python/rate-of-return,-mean-and-variance
# https://www.quantconnect.com/tutorials/strategy-library/forex-momentum


class Bitfinex_Crypto_ShortTerm_Momentum(QCAlgorithm):
    
    
    
    def __init__(self):
    # set the flag for rebalance
        self.reb = 1

    # Number of assets to long/short
        self.num_fine = 8
        
        
    

    def Initialize(self):

        self.SetStartDate(2019, 1, 1)  #Set Start Date
        self.SetEndDate(2021, 3, 31)    #Set End Date


        # Set Strategy Cash (USD)
        self.SetCash(10000)


        self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin)
        
        self.SetBenchmark('BTCUSD')


        tickers = ["LTCBTC", "ETHBTC", "ETCBTC", "ZECBTC", "XMRBTC",
                   "XRPBTC", "EOSBTC", "SANBTC", "OMGBTC",
                   "NEOBTC", "ETPBTC", "BTGBTC", "BATBTC",
                   "ZRXBTC", "TRXBTC", "DAIBTC",
                   "ANTBTC", "XLMBTC", "KNCBTC", "XTZBTC",
                   "BSVBTC"]


        for ticker in tickers:
            self.AddCrypto(ticker, Resolution.Daily)
        
        

        # Set warmup period
        self.SetWarmUp(timedelta(7))

        # Schedule the rebalance function to execute at the begining of each week
        self.Schedule.On(self.DateRules.WeekStart(), self.TimeRules.At(12, 0, 0), Action(self.rebalance))





    def OnData(self, data):
        # Beräkna 7d avkastning på samtliga valutor.
        # Gå lång på de 4 valutor som utvecklats bäst de senaste 7d.
        # Gå kort på de 4 valutor som utvecklats sämst de senaste 7d.
        
        # Ombalansera varje vecka.
        pass
        
        
        
        
        
    def rebalance(self):
        
        tickers = ["LTCBTC", "ETHBTC", "ETCBTC", "ZECBTC", "XMRBTC",
                   "XRPBTC", "EOSBTC", "SANBTC", "OMGBTC",
                   "NEOBTC", "ETPBTC", "BTGBTC", "BATBTC",
                   "ZRXBTC", "TRXBTC", "DAIBTC",
                   "ANTBTC", "XLMBTC", "KNCBTC", "XTZBTC",
                   "BSVBTC"]
        
        df = pd.DataFrame()

        #start = datetime(2018, 10, 1)
        #end = datetime(2018, 12, 31)
        
        # Gets historical data from the subscribed assets
       
        #h1 = self.History(self.Securities.Keys, start, end, Resolution.Daily)
        h1 = self.History(tickers, timedelta(30), Resolution.Daily)

        if h1.empty:
            self.Log("EMPTY dataframe!")
        
        
        # Resample to 1W timeframe.
        for i in tickers:
            df[i] = h1.loc[i]['close'].resample('W').mean().pct_change()
        
        # Sort the lastrow of dataframe       
        last_week = df.iloc[-1].sort_values(ascending=False)
        
        # Assign the assets to short/long       
        self.long = [last_week.index[0], last_week.index[1], last_week.index[2], last_week.index[3]]
        self.short = [last_week.index[-1], last_week.index[-2], last_week.index[-3], last_week.index[-4]]
       
       
        #if self.Portfolio.Invested != 0:
        
        
        # if this month the stock are not going to be long/short, liquidate it.
        long_short_list = self.long + self.short
        for i in self.Portfolio.Values:
            if (i.Invested) and (i not in long_short_list):
                self.Liquidate(i.Symbol)
                
                
        #else:
        #    self.Log("Not invested.")
        
        #self.Liquidate()
        
        
        # Assign each asset equally. Alternatively you can design your own portfolio construction method
        for i in self.long:
            self.SetHoldings(i, 0.9/self.num_fine)
        
        for i in self.short:
            self.SetHoldings(i, -0.9/self.num_fine)

        self.reb = 1




    def OnOrderEvent(self, orderEvent):
        self.Debug("{} {}".format(self.Time, orderEvent.ToString()))


    def OnEndOfAlgorithm(self):
        self.Log("{} - TotalPortfolioValue: {}".format(self.Time, self.Portfolio.TotalPortfolioValue))
        self.Log("{} - CashBook: {}".format(self.Time, self.Portfolio.CashBook))