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 -1.164 Tracking Error 0.147 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
#THIS WORKS DO NOT TOUCH class TheSqueezeUniverseSelection(QCAlgorithm): def __init__(self, algorithm, period = 20): self.algorithm = algorithm self.period = period self.indicators = {} def SelectCoarse(self, coarse): filtered = [] coarseSelection = [x for x in coarse if x.HasFundamentalData and x.DollarVolume < 1000000] #universe = [x.Symbol for x in coarseSelection[:10]] for x in coarseSelection: if x.Symbol not in self.indicators: self.indicators[x.Symbol] = self.SelectionData(x.Symbol, self.period) indicators = self.indicators.get(x.Symbol) #indicators have no attribute price if indicators.Update(x.Time, x.AdjustedPrice) and indicators.BollingerUpper > indicators.BollingerLower: filtered.append(indicators) universe = [x.Symbol for x in filtered] return universe class SelectionData: def __init__(self, symbol, period): self.Symbol = symbol self.bollinger = BollingerBands(period, 2, MovingAverageType.Simple) @property def BollingerUpper(self): return float(self.bollinger.UpperBand.Current.Value) @property def BollingerLower(self): return float(self.bollinger.LowerBand.Current.Value) def Update(self, time, value): return self.bollinger.Update(time, value)
class TheSqueezeUniverseSelection(QCAlgorithm): def __init__(self, algorithm, period = 20): self.algorithm = algorithm self.period = period self.indicators = {} def CoarseSelectionFunction(self, universe): selected = [] universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True) universe = [c for c in universe if c.Price > 10][:100] for coarse in universe: symbol = coarse.Symbol if symbol not in self.indicators: # 1. Call history to get an array of 200 days of history data history = self.History(symbol, 200, Resolution.Daily) #2. Adjust SelectionData to pass in the history result self.indicators[symbol] = SelectionData(history, self.period) self.indicators[symbol].update(self.Time, coarse.AdjustedPrice) if self.indicators[symbol].is_ready() and \ indicators.BollingerUpper < indicators.KelterUpper and \ indicators.BollingerLower > indicators.KelterLower: selected.append(symbol) return selected[:10] class SelectionData(): #3. Update the constructor to accept a history array def __init__(self, history, period): self.bollinger = BollingerBands(period, 2, MovingAverageType.Simple) self.keltner = KeltnerChannels(period, 1.5, MovingAverageType.Simple) #4. Loop over the history data and update the indicatorsc for bar in history.itertuples(): tradeBar = TradeBar(bar.Index[1], bar.Index[0], bar.open, bar.high, bar.low, bar.close, bar.volume, timedelta(1)) self.bollinger.Update(bar.Index[1], bar.close) self.keltner.Update(tradeBar) @property def BollingerUpper(self): return float(self.bollinger.UpperBand.Current.Value) @property def BollingerLower(self): return float(self.bollinger.LowerBand.Current.Value) @property def KeltnerUpper(self): return float(self.keltner.UpperBand.Current.Value) @property def KeltnerLower(self): return float(self.keltner.LowerBand.Current.Value) def is_ready(self): return self.bollinger.IsReady and self.keltner.IsReady def update(self, time, value): return self.bollinger.Update(time, value)
from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Universe import TheSqueezeUniverseSelection class UglySkyBlueRhinoceros(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 2, 15) # Set Start Date self.SetEndDate(2021, 4, 1) self.SetCash(100000) # Set Strategy Cash # self.AddEquity("SPY", Resolution.Minute) self.SetExecution(ImmediateExecutionModel()) self.CustomUniverseSelectionModel = TheSqueezeUniverseSelection(self) self.AddUniverse(self.CustomUniverseSelectionModel.SelectCoarse) def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' # if not self.Portfolio.Invested: # self.SetHoldings("SPY", 1)
class TheSqueezeUniverseSelection(QCAlgorithm): def __init__(self, algorithm, period = 20): self.algorithm = algorithm self.period = period self.indicators = {} def SelectCoarse(self, coarse): filtered = [] coarseSelection = [x for x in coarse if x.HasFundamentalData and x.DollarVolume < 1000000] #universe = [x.Symbol for x in coarseSelection[:10]] for x in coarseSelection: symbol = x.Symbol if symbol not in self.indicators: history = self.History(symbol, 30, Resolution.Daily) self.indicators[symbol] = SelectionData(history, self.period) indicators = self.indicators.get(symbol) indicators.update(self.Time, symbol.AdjustedPrice) if indicators.is_ready() and \ indicators.BollingerUpper < indicators.KelterUpper and \ indicators.BollingerLower > indicators.KelterLower: filtered.append(indicators) #if indicators.update(symbol.Time, symbol.AdjustedPrice) and \ #indicators.BollingerUpper < indicators.KelterUpper and \ #indicators.BollingerLower > indicators.KelterLower: #filtered.append(indicators) universe = filtered self.Log(universe) return universe class SelectionData(): def __init__(self, history, period): self.bollinger = BollingerBands(period, 2, MovingAverageType.Simple) self.keltner = KeltnerChannels(period, 1.5, MovingAverageType.Simple) for bar in history.itertuples(): tradeBar = TradeBar(bar.Index[1], bar.Index[0], bar.open, bar.high, bar.low, bar.close, bar.volume, timedelta(1)) self.bollinger.Update(bar.Index[1], bar.close) self.keltner.Update(tradeBar) @property def BollingerUpper(self): return float(self.bollinger.UpperBand.Current.Value) @property def BollingerLower(self): return float(self.bollinger.LowerBand.Current.Value) @property def KeltnerUpper(self): return float(self.keltner.UpperBand.Current.Value) @property def KeltnerLower(self): return float(self.keltner.LowerBand.Current.Value) def is_ready(self): return self.bollinger.IsReady and self.keltner.IsReady def update(self, time, value): return self.bollinger.Update(time, value) # Your New Python File