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 -0.906 Tracking Error 0.21 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
class DancingTanHorse(QCAlgorithm): def Initialize(self): self.SetStartDate(2019,1,1) # Set Start Date self.SetEndDate(2021,1,1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Daily #self.AddUniverse(self.CoarseSelection) self.longSymbols = [] self.shortSymbols = [] self.entryPrices = {} self.stopMarketTicket = {} self.indicators = {} stockPlot = Chart("Long Positions") stockPlot.AddSeries(Series("Longs", SeriesType.Bar, 0)) self.AddChart(stockPlot) stockPlot = Chart("Short Positions") stockPlot.AddSeries(Series("Shorts", SeriesType.Bar, 0)) self.AddChart(stockPlot) self.AddEquity("SPY", Resolution.Daily) self.SetBenchmark("SPY") self.Schedule.On(self.DateRules.EveryDay("SPY"), \ self.TimeRules.At(10, 00), \ self.EveryMarketOpen) self.maxPositions = 5 self.numOfCoarse = 6 * self.maxPositions self.stopLoss = 0.10 # def CoarseSelection(self, coarse): # selectedByDollarVolume = sorted([x for x in coarse if x.Price > 1 and x.HasFundamentalData], key = lambda x: x.DollarVolume, reverse = True) # universe = [x for x in selectedByDollarVolume] # squeeze = {} # for cf in universe: # symbol = cf.Symbol # if symbol not in self.indicators: # self.indicators[symbol] = SymbolData(algorithm, symbol) # # Updates the SymbolData object with current EOD price # indicators = self.indicators[symbol] # #indicators.update(cf.EndTime, cf.AdjustedPrice) # if self.indicators[symbol].is_ready() and \ # self.indicators[symbol].bollinger.UpperBand.Current.Value < self.indicators[symbol].keltner.UpperBand.Current.Value and \ # self.indicators[symbol].bollinger.LowerBand.Current.Value > self.indicators[symbol].keltner.LowerBand.Current.Value: # squeeze.append(symbol) # # Sorts the values of the dict: we want those with least difference between the bollinger bands # squeeze.sort(key=lambda x: x.Scale, reverse=False) # for x in squeeze[:self.numOfCoarse]: # self.Log('symbol: ' + str(x.symbol.Value) + ' scale: ' + str(x.scale)) # # we need to return only the symbol objects # return [ x.symbol for x in values[:self.numOfCoarse]] #this event fires whenever we have changes to our universe def OnSecuritiesChanged(self, changes): pass def EveryMarketOpen(self): pass class SymbolData: def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.bollinger = BollingerBands(20, 2, MovingAverageType.Simple) self.keltner = KeltnerChannels(20, 1.5, MovingAverageType.Simple) history = algorithm.History(symbol, 20, Resolution.Daily) for bar in history.itertuples(): tradeBar = TradeBar(bar.time - timedelta(1), symbol, bar.open, bar.high, bar.low, bar.close, bar.volume, timedelta(1)) self.bollinger.Update(bar.time, bar.close) self.keltner.Update(tradeBar) def Scale(self): return (self.bollinger.UpperBand.Current.Value - self.bollinger.LowerBand.Current.Value) def is_ready(self): return self.bollinger.IsReady and self.keltner.IsReady
# ctrl + / to comment # class DancingTanHorse(QCAlgorithm): # def Initialize(self): # self.SetStartDate(2019,1,1) # Set Start Date # self.SetEndDate(2021,1,1) # self.SetCash(100000) # self.UniverseSettings.Resolution = Resolution.Daily # self.AddUniverse(self.CoarseSelection) # self.longSymbols = [] # self.shortSymbols = [] # self.entryPrices = {} # self.stopMarketTicket = {} # self.indicators = {} # stockPlot = Chart("Long Positions") # stockPlot.AddSeries(Series("Longs", SeriesType.Bar, 0)) # self.AddChart(stockPlot) # stockPlot = Chart("Short Positions") # stockPlot.AddSeries(Series("Shorts", SeriesType.Bar, 0)) # self.AddChart(stockPlot) # self.AddEquity("SPY", Resolution.Daily) # self.SetBenchmark("SPY") # self.Schedule.On(self.DateRules.EveryDay("SPY"), \ # self.TimeRules.At(10, 00), \ # self.EveryMarketOpen) # self.maxPositions = 5 # self.numOfCoarse = 6 * self.maxPositions # self.stopLoss = 0.10 # def CoarseSelection(self, coarse): # selectedByDollarVolume = sorted([x for x in coarse if x.Price > 1 and x.HasFundamentalData], # key = lambda x: x.DollarVolume, reverse = True) # universe = [x for x in selectedByDollarVolume] # selectedSqueeze = [] # for coarse in universe: # symbol = coarse.Symbol # if symbol not in self.indicators: # # 1. Call history to get an array of 20 days of history data # history = self.History(symbol, 21, Resolution.Daily) # #2. Adjust SelectionData to pass in the history result # self.indicators[symbol] = SymbolData(history) # self.indicators[symbol].update(self.Time, coarse.AdjustedPrice) # if self.indicators[symbol].is_ready() and \ # self.indicators[symbol].bollinger.UpperBand.Current.Value < self.indicators[symbol].keltner.UpperBand.Current.Value and \ # self.indicators[symbol].bollinger.LowerBand.Current.Value > self.indicators[symbol].keltner.LowerBand.Current.Value: # selectedSqueeze.append(symbol) # #to sort by distance between bollinger bands look at the EmaCrossUniverseSelectionAlgorithm.py # def EveryMarketOpen(self): # pass # def OnOrderEvent(self, orderEvent): # pass # 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 # ''' # pass # # if not self.Portfolio.Invested: # # self.SetHoldings("SPY", 1) # class SymbolData(): # #3. Update the constructor to accept a history array # def __init__(self, history): # self.bollinger = BollingerBands(20, 2, MovingAverageType.Simple) # self.keltner = KeltnerChannels(20, 1.5, MovingAverageType.Simple) # self.volatility = 0 # #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) # def is_ready(self): # return self.bollinger.IsReady and self.keltner.IsReady # def update(self, time, value): # return self.bollinger.Update(time, value) # @property # def ScaledDelta(self): # return (self.bollinger.UpperBand.Current.Value - self.bollinger.LowerBand.Current.Value) # # Your New Python File