| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -7.567 Tracking Error 0.098 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
class QuantumHorizontalRegulators(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 7, 1) # Set Start Date
self.SetEndDate(2020, 8, 31)
self.SetCash(333333) # Set Strategy Cash
self.scaning = False
self.lastToggle = None
self.needs_reset = False
self.backtestSymbolsPerDay = {}
self.current_universe = []
self.UniverseSettings.Resolution = Resolution.Daily
#self.AddUniverse("my-dropbox-universe", self.selector)
self.SetUniverseSelection(ScheduledUniverseSelectionModel(
self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday),
self.TimeRules.Every(timedelta(minutes = 15)),
self.SelectSymbols
))
self.AddAlpha(ShortSqueezeModel(self))
self.SetExecution(ImmediateExecutionModel())
self.SetPortfolioConstruction(AccumulativeInsightPortfolioConstructionModel(lambda time: None))
self.SetRiskManagement(MaximumUnrealizedProfitPercentPerSecurity(maximumUnrealizedProfitPercent = 0.1))
def SelectSymbols(self, dateTime):
# handle live mode file format
if self.LiveMode:
# fetch the file from dropbox
str = self.Download("https://www.dropbox.com/s/f1m6kxoi9iedina/Watchlist.csv?dl=1")
# if we have a file for today, return symbols, else leave universe unchanged
self.current_universe = str.split(',') if len(str) > 0 else self.current_universe
return self.current_universe
# backtest - first cache the entire file
if len(self.backtestSymbolsPerDay) == 0:
# No need for headers for authorization with dropbox, these two lines are for example purposes
#byteKey = base64.b64encode("UserName:Password".encode('ASCII'))
# The headers must be passed to the Download method as dictionary
#headers = { 'Authorization' : f'Basic ({byteKey.decode("ASCII")})' }
#str = self.Download("https://www.dropbox.com/s/f1m6kxoi9iedina/Watchlist.csv?dl=1", headers)
csv_data = self.Download("https://www.dropbox.com/s/f1m6kxoi9iedina/Watchlist.csv?dl=1")
for line in csv_data.splitlines():
data = line.split(',')
self.backtestSymbolsPerDay[data[0]] = data[1:]
index = dateTime.date().strftime("%Y%m%d")
if index in self.backtestSymbolsPerDay.keys():
tickers = self.backtestSymbolsPerDay[index]
self.current_universe = [Symbol.Create(ticker, SecurityType.Equity, Market.USA) for ticker in tickers]
return self.current_universe
class ShortSqueezeModel(AlphaModel):
symbolData = {}
def __init__(self, algo):
self.algo = algo
def Update(self, algorithm, slice):
return []
if algorithm.IsWarmingUp:
return []
# If it's the end of the day, update the yesterday close of each indicator
if not algorithm.Securities['my-dropbox-universe'].Exchange.ExchangeOpen:
for symbol in self.symbolData:
if symbol in slice.Bars:
self.symbolData[symbol].yest_close = slice.Bars[symbol].Close
insights = []
insight_seconds = 99999999999
# Create insights for symbols up at least 40% on the day
for symbol in self.symbolData:
# If already invested, continue to next symbol
if algorithm.Securities[symbol].Invested or symbol not in slice.Bars or self.symbolData[symbol].max.Samples == 0:
continue
# Calculate return sign yesterday's close
yest_close = self.symbolData[symbol].yest_close
close = slice[symbol].Close
ret = (close - yest_close) / yest_close
high_of_day_break = close > self.symbolData[symbol].max.Current.Value
if ret >= 0.4 and high_of_day_break: # Up 40% on the day & breaks high of day
hours = algorithm.Securities[symbol].Exchange.Hours
# 1-minute before the close
closeTime = hours.GetNextMarketClose(algorithm.Time, False) - timedelta(minutes=1)
insights.append(Insight.Price(symbol, closeTime, InsightDirection.Up))
# Update max indicator for all symbols
for symbol in self.symbolData:
if symbol in slice.Bars:
self.symbolData[symbol].max.Update(slice.Time, slice.Bars[symbol].High)
# Constantly updating 10% Trailing Stop Order
for symbol in self.symbolData:
if symbol in slice.Bars and algorithm.Securities[symbol].Invested and slice[symbol].Close <= 0.9*self.symbolData[symbol].max.Current.Value:
insights.append(Insight(symbol, timedelta(seconds=insight_seconds), InsightType.Price, InsightDirection.Flat))
return Insight.Group(insights)
def OnSecuritiesChanged(self, algorithm, changes):
if len(changes.AddedSecurities) > 0:
# Get history of symbols over lookback window
added_symbols = [x.Symbol for x in changes.AddedSecurities]
history = algorithm.History(added_symbols, 1, Resolution.Daily)
if history.empty:
return
history = history['close']
for added in changes.AddedSecurities:
# Save yesterday's close
closes = history.loc[[str(added.Symbol.ID)]].values
if len(closes) < 1:
continue
self.symbolData[added.Symbol] = SymbolData(closes[0], algorithm, added.Symbol)
for removed in changes.RemovedSecurities:
# Delete yesterday's close tracker
symbol_data = self.symbolData.pop(removed.Symbol, None)
if symbol_data:
symbol_data.dispose()
class SymbolData:
def __init__(self, yest_close, algo, symbol):
self.yest_close = yest_close
self.algo = algo
self.symbol = symbol
self.event = algo.Schedule.On(algo.DateRules.EveryDay(symbol), algo.TimeRules.AfterMarketOpen(symbol, 375), self.reset)
self.max = Maximum(45*60) # 45 minutes
def reset(self):
self.max.Reset()
def dispose(self):
self.algo.Schedule.Remove(self.event)
class MaximumUnrealizedProfitPercentPerSecurity(RiskManagementModel):
'''Provides an implementation of IRiskManagementModel that limits the unrealized profit per holding to the specified percentage'''
def __init__(self, maximumUnrealizedProfitPercent = 0.1):
'''Initializes a new instance of the MaximumUnrealizedProfitPercentPerSecurity class
Args:
maximumUnrealizedProfitPercent: The maximum percentage unrealized profit allowed for any single security holding, defaults to 5% drawdown per security'''
self.maximumUnrealizedProfitPercent = abs(maximumUnrealizedProfitPercent)
def ManageRisk(self, algorithm, targets):
'''Manages the algorithm's risk at each time step
Args:
algorithm: The algorithm instance
targets: The current portfolio targets to be assessed for risk'''
targets = []
for kvp in algorithm.Securities:
security = kvp.Value
if not security.Invested:
continue
pnl = security.Holdings.UnrealizedProfitPercent
if pnl > self.maximumUnrealizedProfitPercent:
### For debugging, add this to see when it is being called
algorithm.Log('Risk model triggered')
# liquidate
targets.append(PortfolioTarget(security.Symbol, 0))
return targets