| 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))