Hello all, 

Sorry for dumping the code as is instead of attaching the backtest. The backtest of another project keeps running instead.

Anyways, I'm trying to get familiar with stop market orders and I was wondering if someone would be able to help me with this:

I have a list of stocks as you can see, say:  tickers = ["SPY", "TLT", "BND"]

I want to create a dictionary for stop buys and stop sells, each containing tickers as keys, and can be executed and updated. I am trying to do this with these two dictionaries: self.stopbuys[symbol] and self.stopsells[symbol] , and initializing both with values of None for each ticker. And afterwards be able to update each for each ticker accordingly. Also, I am trying to track the time that each stop market order was FILLED with these two dictionaries: self.stopbuys_time and self.stopsells_time.

This did not execute: 

self.stopbuys[symbol] = self.StopMarketOrder(symbol, shares_to_buy, round(value.window3[0].High, 2)) 

but without assinging the variable to it, it works, like this:

self.StopMarketOrder(symbol, shares_to_buy, round(value.window3[0].High, 2)) 

I don't think the update is working either. Is there a better way of tracking stop market orders for a list of stocks? 

Also, would this be if statement execute on the day a new stop market is ASSIGNED or the day it is FILLED?

if (self.Time - self.stopbuys_time[symbol]).days == 0:
            #   do something

Thanks a bunch, I appreciate it.

 

Code:

class MyAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2019,1,1) self.SetCash(100000) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) tickers = ["SPY", "TLT", "BND"] # Creates empty dictionary to later hold daily Tradebar price rolling windows self.symbolData = {} # Creates empty dictionary to later hold stop buy values self.stopbuys = {} # Creates empty dictionary to later hold stop sell values self.stopsells = {} # Creates empty dictionary to later hold time of buy breakout occurrence self.stopbuys_time = {} # Creates empty dictionary to later hold time of sell breakout occurrence self.stopsells_time = {} for ticker in tickers: self.equity = self.AddEquity(ticker, Resolution.Hour) self.equity.SetDataNormalizationMode(DataNormalizationMode.Raw) self.equity.SetLeverage(1.0) #symbol_window = self.equity.Symbol symbol = self.equity.Symbol self.stopbuys[symbol] = None self.stopsells[symbol] = None self.stopbuys_time[symbol] = datetime.min self.stopsells_time[symbol] = datetime.min # Consolidator consolidator_daily = TradeBarConsolidator(timedelta(days = 1)) consolidator_daily.DataConsolidated += self.OnDailyData self.SubscriptionManager.AddConsolidator(symbol, consolidator_daily) self.symbolData[symbol] = SymbolData(self, symbol) self.SetWarmUp(1000) # Adding daily bar data to 3,2,1 etc.. rolling windows def OnDailyData(self, sender, bar): self.symbolData[bar.Symbol].window4.Add(bar) self.symbolData[bar.Symbol].window3.Add(bar) self.symbolData[bar.Symbol].window2.Add(bar) def OnData(self, data): for symbol, value in self.symbolData.items(): if not data.ContainsKey(symbol.Value): return for symbol, value in self.symbolData.items(): value.window4.Add(data[symbol.Value]) value.window3.Add(data[symbol.Value]) value.window2.Add(data[symbol.Value]) if self.IsWarmingUp: return for symbol, value in self.symbolData.items(): if not (value.window4.IsReady and value.window3.IsReady and value.window2.IsReady): return for symbol, value in self.symbolData.items(): shares_to_buy = 50 if value.window3[0].Close > value.window3[1].Close > value.window3[2].Close: if self.stopbuys[symbol] == None: #self.stopbuys[symbol] = self.StopMarketOrder(symbol, shares_to_buy, round(value.window3[0].High, 2)) self.StopMarketOrder(symbol, shares_to_buy, round(value.window3[0].High, 2)) else: updateSettings = UpdateOrderFields() updateSettings.StopPrice = round(value.window3[0].High, 2) updateSettings.Quantity = round(shares_to_buy) updateSettings.Tag = "Stop Buy Updated for {}".format(symbol) self.stopbuys[symbol].Update(updateSettings) else: if self.stopbuys[symbol] == None: #self.stopsells[symbol] = self.StopMarketOrder(symbol, -self.Portfolio[symbol].Quantity, round(value.window3[0].Low, 2)) self.StopMarketOrder(symbol, -self.Portfolio[symbol].Quantity, round(value.window3[0].Low, 2)) else: updateSettings = UpdateOrderFields() updateSettings.StopPrice = round(value.window3[0].Low, 2) updateSettings.Quantity = -self.Portfolio[symbol].Quantity updateSettings.Tag = "Stop Sell Updated for {}".format(symbol) self.stopsells[symbol].Update(updateSettings) # Is this the time a stop buy was entered or updated ? Or is it the time it was filled?? # How do we get the time a stopbuy was filled instead? # if (self.Time - self.stopbuys_time[symbol]).days == 0: # do something def OnOrderEvent(self, orderEvent): # Event when the order is filled. Debug log the order fill. :OrderEvent: #if OrderEvent.FillQuantity == 0: if orderEvent.Status != OrderStatus.Filled: return fetched = self.Transactions.GetOrderById(orderEvent.OrderId) self.Debug("{} was filled. Symbol: {}. Quantity: {}. Direction: {}" .format(str(fetched.Type), str(orderEvent.Symbol), str(orderEvent.FillQuantity), str(orderEvent.Direction))) if self.stopbuys[orderEvent.Symbol] is not None and self.stopbuys[orderEvent.Symbol].OrderId == orderEvent.OrderId: self.stopbuys_time[orderEvent.Symbol] = self.Time self.Debug(str(self.stopbuys_time[orderEvent.Symbol])) class SymbolData: def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.window4 = RollingWindow[TradeBar](4) self.window3 = RollingWindow[TradeBar](3) self.window2 = RollingWindow[TradeBar](2)