In my algorithm I ran into to the problem that all my MarketOnOpenOrders are filled one day later as they should be. For simplicity reasons I recreated the problem in a far simplified algorithm. I am aware that the effects of this simplified algorithm could be achieved easier in many places, however I wanted to stay as close as possible to my original algorithm (e.g. keep a coarse and fine universe selection). Nevertheless I would like to ask that answers concentrate on the problem with the belated fill of the MarketOnOpenOrder.

The simplified algorithm is:

# region imports
from AlgorithmImports import *
# endregion
import datetime as dt


class Test(QCAlgorithm):

    def Initialize(self):
        
        self.SetStartDate(2023, 11, 7)
        self.SetEndDate(2023, 11, 11)
        self.SetCash(100000)

        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)

        self.AddEquity('SPY', Resolution.Daily)
        self.Schedule.On(self.DateRules.EveryDay('SPY'),  self.TimeRules.AfterMarketOpen('SPY', -10), self.__BeforeOpen)
        self.RemoveSecurity('SPY')

        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.__SelectCoarse, self.__SelectFine)

        self.count = 0


    def OnEndOfAlgorithm(self):
        self.AddEquity('MSFT', Resolution.Daily)
        BarList = self.History[TradeBar](self.Symbol('MSFT'), dt.datetime(2023,11,7), self.Time, Resolution.Daily)
        for bar in BarList:
            self.Debug('{:s}: Open = {:.4f}'.format(bar.Time.strftime('%m-%d-%Y %H:%M'), bar.Open))


    def __BeforeOpen(self):
        for sym in self.ActiveSecurities.Keys:
            if self.count == 0:
                self. count += 1
                self.Debug('{:s}: MarketOnOpenOrder for 100 shares of {:s}'.format(self.Time.strftime('%m-%d-%Y %H:%M'), sym.Value))
                ticket = self.MarketOnOpenOrder(sym, 100)
            
   
    def OnOrderEvent(self, orderEvent: OrderEvent):
        self.Debug('{:s} OnOrdrEvent: Symbol={:s}, filled={:.2f} for ${:.4f} per share'.format(self.Time.strftime('%m-%d-%Y %H:%M'), orderEvent.Symbol.Value, orderEvent.FillQuantity, orderEvent.FillPrice))


    def __SelectCoarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        if self.count == 0:
            C = [c.Symbol for c in coarse if c.Symbol.Value == 'MSFT']
        else:
            C = []
        return C


    def __SelectFine(self, fine: List[FineFundamental]) -> List[Symbol]:
        List = [f.Symbol for f in fine]
        
        return List


The debug output is:

11-07-2023 09:20: MarketOnOpenOrder for 100 shares of MSFT
11-07-2023 09:20 OnOrdrEvent: Symbol=MSFT, filled=0.00 for $0.0000 per share
11-09-2023 00:00 OnOrdrEvent: Symbol=MSFT, filled=100.00 for $361.2668 per share

11-07-2023 00:00: Open = 358.5722
11-08-2023 00:00: Open = 361.2668
11-09-2023 00:00: Open = 361.4165
11-10-2023 00:00: Open = 360.7578

Lets go through the timeline of this algorithm to see where the error occurs:

  • on 11/7 at 00:00 a universe of ['MSFT'] is defined
  • on 11/7 at 9:20 a Market on open order is issued
  • on 11/9 at at 00:00 the order is filled with the open price from 8/11


My question is:

Shouldn't the order be filled with the open price of 11/7 since it was issued before the open on 11/7? I understand that due to the daily resolution, it would be reported as filled on 11/8 at 00:00 when the full candle for 11/7 is available. But instead it is filled with the open price of 11/8 and reported as filled on 11/9 at 00:00.

Thank you for any kind of help, because that really confuses me.

Thanks,
     Markus