Overall Statistics
Total Trades
106
Average Win
8.42%
Average Loss
-2.68%
Compounding Annual Return
101.697%
Drawdown
35.300%
Expectancy
1.625
Net Profit
1105.092%
Sharpe Ratio
2.771
Probabilistic Sharpe Ratio
92.655%
Loss Rate
37%
Win Rate
63%
Profit-Loss Ratio
3.14
Alpha
1.146
Beta
0.543
Annual Standard Deviation
0.444
Annual Variance
0.197
Information Ratio
2.447
Tracking Error
0.44
Treynor Ratio
2.264
Total Fees
$144.95
# https://seekingalpha.com/article/4299701-leveraged-etfs-for-long-term-investing
# Momentum addaped verision of:
# https://www.quantconnect.com/forum/discussion/7708/using-levered-etfs-in-ira-10-years-24-cagr-1-56-sharpe/p1
# with some extra symbols.

import pandas as pd
import numpy as np

class MultidimensionalTransdimensionalPrism(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 1, 1)  # Set Start Date
        self.SetCash(10000)  # Set Strategy Cash
        #self.SetEndDate(2020, 7, 16)
        
        # create a dictionary to store momentum indicators for all symbols 
        self.data = {}
        self.rsi = {}
        self.momp = {}
        
        #MOM period
        period = 21*4
        #rsi period
        period2 = 10
        #MOMP period
        period3 = 44
        
        
        self.symbols = ["TQQQ", "UBT", "TECL","UGLD","TYD"]
        self.SetRiskManagement(TrailingStopRiskManagementModel(0.25))
        
        # warm up the MOM indicator
        self.SetWarmUp(period)
        for symbol in self.symbols:
            self.AddEquity(symbol, Resolution.Hour)
            self.data[symbol] = self.MOM(symbol, period, Resolution.Hour)
            
        for symbol in self.symbols:
            self.rsi[symbol] = self.RSI(symbol, period2, Resolution.Daily)
            
        for symbol in self.symbols:
            self.momp[symbol] = self.MOMP(symbol, period3, Resolution.Daily)     

        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), \
                 self.TimeRules.At(15, 30), \
                 self.Rebalance)
                
    def OnData(self, data):
        pass        
    def Rebalance(self):
        if self.IsWarmingUp: return
        
        #pd = panda data series for mom (not used)
        #top3 = pd.Series(self.data).sort_values(ascending = False)[:3]
        
        #self.Log(str(top3.index))
        #self.Log(str(pd.Series(self.data)))
        #self.Log(str(self.data))
        
        
        top3 = pd.Series(self.momp).sort_values(ascending = False)[:3]
        #momptop3 = pd.Series(self.momp).sort_values(ascending = False)[:3]
        
        #self.Log(str(momptop3.index))
        #self.Log(str(pd.Series(self.momp)))
        #self.Log(str(self.momp))
        
        #self.Plot("Stock", "TQQQ", self.Securities["TQQQ"].Price)
        #self.Plot("Stock", "UBT", self.Securities["UBT"].Price)
        #self.Plot("Stock", "TECL", self.Securities["TECL"].Price)
        #self.Plot("Stock", "UGLD", self.Securities["UGLD"].Price)
        #self.Plot("Stock", "TYD", self.Securities["TYD"].Price)
        
        #self.Plot("Momentum", "TQQQ", self.data["TQQQ"].Current.Value)
        #self.Plot("Momentum", "UBT", self.data["UBT"].Current.Value)
        #self.Plot("Momentum", "TECL", self.data["TECL"].Current.Value)
        #self.Plot("Momentum", "UGLD", self.data["UGLD"].Current.Value)
        #self.Plot("Momentum", "TYD", self.data["TYD"].Current.Value)
        
        #self.Plot("RSI", "TQQQ", self.rsi["TQQQ"].Current.Value)
        #self.Plot("RSI", "UBT", self.rsi["UBT"].Current.Value)
        #self.Plot("RSI", "TECL", self.rsi["TECL"].Current.Value)
        #self.Plot("RSI", "UGLD", self.rsi["UGLD"].Current.Value)
        #self.Plot("RSI", "TYD", self.rsi["TYD"].Current.Value)
        
        #self.Log(str(self.rsi))
        
        for kvp in self.Portfolio:
            #self.Log(f"\nkvp: {type(kvp)}\nkvp.Key: {type(kvp.Key)}\nkvp.Value: {type(kvp.Value)}")
            security_hold = kvp.Value
            #self.Log(str(kvp.Value))
            #self.Log(str(security_hold.Symbol.Value)) #shows all the securities in the libary
            #self.Log(str(security_hold.Invested)) #shows all the securities in the libary invested or not invested as True or False
            # liquidate the security which is no longer in the top3 momentum list
            
            if security_hold.Invested and (security_hold.Symbol.Value not in top3.index):
                self.Liquidate(security_hold.Symbol) # presumably liquidates those symbols held but not in the top3.index
                
        
        added_symbols = []        
        for symbol in top3.index:
            if not self.Portfolio[symbol].Invested:
                added_symbols.append(symbol)
        for added in added_symbols:
            self.SetHoldings(added, 1/len(added_symbols))