Found a bug that was confirmed by QC support, but wanted to make it known to the community as well. 

I submitted a short limit order on 10/03 at 9:15am EST (15 min before the market open) at a price of 10.58 (5% above the closing price the day before). On 10/03, the price opened at 13.89, hit a low of 11.35, and closed at 11.51. The short limit order should have filled at the open at 13.89, but instead filled at the low of 11.35. You can run the code below and I've printed out some Debug statements as proof.

Date: 2022-10-03 09:15:00; Submitted Sell Limit at 10.58

Date: 2022-10-04 00:00:00; FillPrice: 11.35 

Date: 2022-10-04 00:00:00; Open: 13.89; High: 15.51; Low:11.35; Close:11.51

  1. # region imports
  2. from AlgorithmImports import *
  3. # endregion
  4. class BackTestBug(QCAlgorithm):
  5. def Initialize(self):
  6. self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.SplitAdjusted
  7. self.SetStartDate(2022, 10, 1) # Set Start Date
  8. self.SetEndDate(2022, 10, 3)
  9. self.SetCash(100000) # Set Strategy Cash
  10. self.AddEquity("ATXI", Resolution.Daily)
  11. self.AddEquity("SPY", Resolution.Daily)
  12. self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", -15), self.FillOpenPositions)
  13. def FillOpenPositions(self):
  14. symbol = self.Symbol("ATXI")
  15. history = self.History(symbol, 1, Resolution.Daily)
  16. symbolHistory = history.loc[symbol]
  17. for bar in symbolHistory.itertuples():
  18. close = bar.close
  19. limitPrice = round(close * 1.05, 2)
  20. orderProperties = OrderProperties()
  21. orderProperties.TimeInForce = TimeInForce.GoodTilDate(self.Time + timedelta(hours=20))
  22. self.LimitOrder(symbol, -10, limitPrice, orderProperties=orderProperties)
  23. self.Debug("Date: {0}; Submitted Sell Limit at {1}".format(self.Time, limitPrice))
  24. def OnOrderEvent(self, orderEvent):
  25. order = self.Transactions.GetOrderById(orderEvent.OrderId)
  26. symbol = order.Symbol
  27. if order.Status == OrderStatus.Filled:
  28. fillPrice = orderEvent.FillPrice
  29. self.Debug("Date: {0}; FillPrice: {1}".format(self.Time, fillPrice))
  30. history = self.History(symbol, 1, Resolution.Daily).loc[symbol]
  31. for bar in history.itertuples():
  32. o = bar.open
  33. h = bar.high
  34. l = bar.low
  35. c = bar.close
  36. self.Debug("Date: {0}; Open: {1}; High: {2}; Low:{3}; Close:{4}".format(self.Time, o, h, l, c))
+ Expand

Author

Chetan Prabhu

November 2022