Repository: nautechsystems/nautilus_trader
File: nautilus_trader/adapters/interactive_brokers/client/market_data.py (Python)

Code before:

        Parameters
        ----------
        bar_type_str : str
            The string representation of the bar type.
        bar : BarData
            The bar data received from Interactive Brokers.
        handle_revised_bars : bool
            Indicates whether revised bars should be handled or not.
        historical : bool | None, optional
            Indicates whether the bar data is historical. Defaults to False.

        Returns
        -------
        Bar | ``None``

        """
        previous_bar = self._bar_type_to_last_bar.get(bar_type_str)
        previous_ts = 0 if not previous_bar else int(previous_bar.date)
        current_ts = int(bar.date)

        if current_ts > previous_ts:
            is_new_bar = True
        elif current_ts == previous_ts:
            is_new_bar = False
        else:
            return None  # Out of sync

        self._bar_type_to_last_bar[bar_type_str] = bar
        bar_type: BarType = BarType.from_str(bar_type_str)
        ts_init = self._clock.timestamp_ns()

        if not handle_revised_bars:
            if previous_bar and is_new_bar:
                # New bar arrived - publish the previous (completed) bar immediately
                # and schedule completion timeout for the current bar
                await self._schedule_bar_completion_timeout(bar_type_str, bar)
                bar = previous_bar
            else:
                # First bar or same timestamp - schedule completion timeout
                # but don't publish yet (wait for bar period to complete)
                await self._schedule_bar_completion_timeout(bar_type_str, bar)
                return None  # Wait for bar period to complete

            if historical:
                ts_init = await self._ib_bar_to_ts_init(bar, bar_type)

                if ts_init >= self._clock.timestamp_ns():
                    return None  # The bar is incomplete

        # Process the bar

Review comment (refactor):
I think if `start` is not a `pd.Timestamp` then we should always suffix the units, like `start_ns`. The choice to use nanos depends on the abstraction level, generally passing around a `pd.Timestamp` is a little nicer unless it's passing into Cython territory.

Code after:
        self._bar_timeout_tasks[bar_type_str] = task

    async def _process_bar_data(
        self,
        bar_type_str: str,
        bar: BarData,
        handle_revised_bars: bool,
        historical: bool | None = False,
        start: int | None = None,
    ) -> Bar | None:
        """
        Process received bar data and convert it into NautilusTrader's Bar format. This
        method determines whether the bar is new or a revision of an existing bar and
        converts the bar data to the NautilusTrader's format.

        Parameters
        ----------
        bar_type_str : str
            The string representation of the bar type.
        bar : BarData
            The bar data received from Interactive Brokers.
        handle_revised_bars : bool
            Indicates whether revised bars should be handled or not.
        historical : bool | None, optional
            Indicates whether the bar data is historical. Defaults to False.
        start: int, optional
            The start time of a subscription in ns.

        Returns
        -------
        Bar | ``None``

        """
        previous_bar = self._bar_type_to_last_bar.get(bar_type_str)
        previous_ts = 0 if not previous_bar else int(previous_bar.date)
        current_ts = int(bar.date)

        if current_ts > previous_ts:
            is_new_bar = True
        elif current_ts == previous_ts:
            is_new_bar = False
        else:
            return None  # Out of sync

        self._bar_type_to_last_bar[bar_type_str] = bar
        bar_type: BarType = BarType.from_str(bar_type_str)
        bar_ts_init = await self._ib_bar_to_ts_init(bar, bar_type)

        if start and bar_ts_init < start:
            # Filtering bar out as it's historical data we don't want, see subscribe_historical_bars
            return None