Hello QuantConnect Community! We have a question, we are trying to do is choosing a universe of 10 companies, and consolidating the bars in bars of 30 minutes. Save the first bar from 9 to 9:30 and if the price is above the High of the first bar (opening bar) then it will buy. Then we create an trailing stop that closes the transactions (0.95 from the highest price) by selling if the price falls by 5% (0.95 of the high). The problem is that the trailing stop is not being executed, and is apparently consolidating only 2 tickers. I leave my code here, I hope you can help me!
class DynamicOptimizedContainmentField(QCAlgorithm):
def Initialize(self):
self.stopMarketTicket = None
self.stopMarketOrderFillTime = datetime.min
self.highestPrice = 0
self.SetStartDate(2021, 3, 26) # Set Start Date\
self.SetEndDate(2021, 4, 26)
self.SetCash(1000000) # Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Minute
self.AddUniverse(self.SelectCoarse)
self.UniverseSettings.Leverage = 2
self.symbols = {}
self.stopPrice = self.GetParameter("stop")
def SelectCoarse(self, coarse):
sortedCoarse = sorted(coarse, key=lambda c:c.DollarVolume, reverse=True)
return [c.Symbol for c in sortedCoarse][:10]
def OnSecuritiesChanged(self, changes):
for security in changes.AddedSecurities:
symbol = security.Symbol
if symbol not in self.symbols:
self.symbols[symbol] = SymbolData(self, symbol)
self.Schedule.On(self.DateRules.EveryDay(symbol), self.TimeRules.At(13,30), self.ClosePositions)
for security in changes.RemovedSecurities:
symbol = security.Symbol
if symbol in self.symbols:
symbolData = self.symbols.pop(symbol, None)
self.SubscriptionManager.RemoveConsolidator(symbol, symbolData.consolidator)
def OnData(self, data):
for symbol, symbol_data in self.symbols.items():
if symbol_data.openingBar is None: continue
if not data.Bars.ContainsKey(symbol):
continue
if data.Bars[symbol].Close > symbol_data.openingBar.High and not self.Securities[symbol].Invested:
quantity = self.CalculateOrderQuantity(symbol, 0.08) # orders 8% of portfolio
self.MarketOrder(symbol, quantity)
self.stopMarketTicket = self.StopMarketOrder(symbol, -self.Portfolio[symbol].Quantity, data[symbol].Close * 0.95)
continue
if self.Securities[symbol].Invested and data.Bars[symbol].Close > symbol_data.highestPrice:
self.highestPrice = self.Securities[symbol].Close
updateFields = UpdateOrderFields()
updateFields.StopPrice = self.highestPrice * 0.95
self.stopMarketTicket.Update(updateFields)
def OnOrderEvent(self, orderEvent):
if orderEvent.Status != OrderStatus.Filled:
self.symbols[orderEvent.Symbol].openingBar = None
return
if self.symbols[orderEvent.Symbol].stopMarketTicket is not None and self.symbols[orderEvent.Symbol].stopMarketTicket.OrderId == orderEvent.OrderId:
self.symbols[orderEvent.Symbol].stopMarketOrderFillTime = self.Time
def ClosePositions(self):
for symbolData in self.symbols.values():
symbolData.openingBar = None
self.Liquidate() # liquidate entire portfolio
def OnDataConsolidated(self, sender, bar):
self.Log(f"Bar at {self.Time} for {bar.Symbol}")
if bar.Time.hour == 9 and bar.Time.minute == 30:
self.symbols[bar.Symbol].openingBar = bar
class SymbolData:
def __init__(self, algorithm, symbol):
self.algorithm = algorithm
self.symbol = symbol
self.consolidator = TradeBarConsolidator(timedelta(minutes = 30))
self.consolidator.DataConsolidated += self.OnDataConsolidated
self.openingBar = None
algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
def OnDataConsolidated(self, sender, bar):
self.algorithm.Debug(f"Data Consolidatoed for {self.symbol} at {bar.EndTime} with bar: {bar}")