Securities

Market Hours

Introduction

The Exchangeexchange property of a Security object contains information about the exchange that lists the security, including its time zone and the trading days and hours. To get the exchange market hours, use the Exchange.Hoursexchange.hours property on a Security object.

// Get properties of the exchange that lists the security.
var securityExchangeHours = Securities["SPY"].Exchange.Hours;
# Get properties of the exchange that lists the security.
security_exchange_hours = self.securities["SPY"].exchange.hours

Market Status

To check if the exchange is open at a specific time, call the IsOpenis_open method.

// Check if the exchange is currently open.
var isOpenNow = securityExchangeHours.IsOpen(Time, extendedMarketHours: false);

// Check if the exchange is open at any point in time over a specific interval.
var isOpen = securityExchangeHours.IsOpen(Time, Time.AddDays(1), extendedMarketHours: false);
# Check if the exchange is currently open.
is_open_now = security_exchange_hours.is_open(self.time, extended_market_hours=False)

# Check if the exchange is open at any point in time over a specific interval.
is_open = security_exchange_hours.is_open(self.time, self.time + timedelta(days=1), extended_market_hours=False)

To check if the exchange is open on a specific date, call the IsDateOpenis_date_open method.

// Check if the exchange is open at some time today.
var isOpen = securityExchangeHours.IsDateOpen(Time, extendedMarketHours: true);
# Check if the exchange is open at some time today.
is_open = security_exchange_hours.is_date_open(self.time, extended_market_hours=True)

To get the next market open time, call the GetNextMarketOpenget_next_market_open method.

// Get the next market open time.
var marketOpenTime = securityExchangeHours.GetNextMarketOpen(Time, extendedMarketHours: false);
# Get the next market open time.
market_open_time = security_exchange_hours.get_next_market_open(self.time, extended_market_hours=False)

To get the next market close time, call the GetNextMarketCloseget_next_market_close method.

// Get the next market close time.
var marketCloseTime = securityExchangeHours.GetNextMarketClose(Time, extendedMarketHours: false);
# Get the next market close time.
market_close_time = security_exchange_hours.get_next_market_close(self.time, extended_market_hours=False)

To get the previous trading day, call the GetPreviousTradingDayget_previous_trading_day method.

// Get the previous trading day.
var day = securityExchangeHours.GetPreviousTradingDay(Time);
# Get the previous trading day.
day = security_exchange_hours.get_previous_trading_day(self.time)

To get the next trading day, call the GetNextTradingDayget_next_trading_day method.

// Get the next trading day.
var day = securityExchangeHours.GetNextTradingDay(Time);
# Get the next trading day.
day = security_exchange_hours.get_next_trading_day(self.time)

Extended Market Hours

By default, your security subscriptions only cover regular trading hours. To subscribe to pre and post-market trading hours for a specific asset, enable the extendedMarketHoursextended_market_hours argument when you create the security subscription.

AddEquity("SPY", extendedMarketHours: true);
self.add_equity("SPY", extended_market_hours=True)

You only receive extended market hours data if you create the subscription with minute, second, or tick resolution. If you create the subscription with daily or hourly resolution, the bars only reflect the regular trading hours.

Properties

The SecurityExchange object has the following attributes:

Examples

The follow examples demonstrate some common practices for trading with market hours data.

Example 1: Only Within 1 Hour Of Market Open And Close

Buying SPY shortly after market holidays or weekend breaks can be a profitable strategy. Historically, the market has tended to experience positive returns in the trading sessions immediately following extended market closures. This is often attributed to the release of pent-up demand and information during the downtime. By positioning into SPY at the open or within the first few trading hours after a holiday or weekend, investors may be able to capture this post-break bounce in the broader market.

public class MarketHourExampleAlgorithm : QCAlgorithm
{
    private Equity _spy;
        
    public override void Initialize()
    {
        SetStartDate(2024, 9, 1);
        SetEndDate(2024, 12, 31);
        _spy = AddEquity("SPY", Resolution.Hour);
    }

    public override void OnData(Slice slice)
    {
        // Check if the previous day is holiday
        if (_spy.Exchange.Hours.Holidays.Contains(Time.Date.AddDays(-1)))
        {
            // Buy if it is a holiday a day before
            SetHoldings(_spy.Symbol, 1);
        }
        else if (Portfolio[_spy.Symbol].Invested)
        {
            // Liquidate otherwise if any open position
            Liquidate(_spy.Symbol);
        }
    }
}
class MarketHourExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.spy = self.add_equity("SPY", Resolution.HOUR)

    def on_data(self, slice: Slice) -> None:
        # Check if the previous day is holiday
        previous_day = self.time.replace(hour=0, minute=0) - timedelta(1)
        if previous_day in self.spy.exchange.hours.holidays:
            # Buy if it is a holiday a day before
            self.set_holdings(self.spy.symbol, 1)
        elif self.portfolio[self.spy.symbol].invested:
            # Liquidate otherwise if any open position
            self.liquidate(self.spy.symbol)

Example 2: Pre-market Short Limit Order

A pre-market short limit order is a type of order placed before the regular trading session begins. It allows a trader to take a short position at a price higher than the current market price, with the intention of selling the position shortly after the market opens and profiting from the expected price decline. This strategy is often used by traders who anticipate a decline in the asset's value and want to capitalize on it.

public class MarketHourExampleAlgorithm : QCAlgorithm
{
    private Equity _spy;
        
    public override void Initialize()
    {
        SetStartDate(2024, 9, 1);
        SetEndDate(2024, 12, 31);
        // Add SPY data with extended market hours.
        _spy = AddEquity("SPY", extendedMarketHours: true);
    }

    public override void OnData(Slice slice)
    {
        if (!slice.QuoteBars.ContainsKey(_spy.Symbol)) return;
        // During pre-market hours, place an unmarketable limit order.
        if (!_spy.Invested &&
            IsBeforeMarketOpenExtendedHours(slice.Time) &&
            Transactions.GetOpenOrderTickets(_spy.Symbol).Count() == 0)
        {
            LimitOrder(_spy.Symbol, -10, _spy.BidPrice * 1.005m);
        }
        // Check if the normal market is opening and any position
        else if (_spy.Invested && _spy.Exchange.Hours.IsOpen(slice.Time, false))
        {
            Liquidate(_spy.Symbol);
        }
    }

    private bool IsBeforeMarketOpenExtendedHours(DateTime time)
    {
        return (
            // It's currently extended market hours.
            _spy.Exchange.Hours.IsOpen(time, true) &&
            // The next market open for regular trading hours is today.
            _spy.Exchange.Hours.GetNextMarketOpen(time, false).Day == time.Day
        );
    }
}
class MarketHourExampleAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        # Add SPY data with extended market hours.
        self._spy = self.add_equity("SPY", extended_market_hours=True)

    def on_data(self, slice: Slice) -> None:
        if self._spy.symbol not in slice.quote_bars:
            return
        # During pre-market hours, place an unmarketable limit order.
        if (not self._spy.invested and
            self._is_before_market_open_extended_hours(slice.time) and
            not list(self.transactions.get_open_order_tickets(self._spy.symbol))):
            self.limit_order(self._spy.symbol, -10, self._spy.bid_price * 1.005)
        # If we hold a position during regular trading hours, liquidate
        # it.
        elif (self._spy.invested and
            self._spy.exchange.hours.is_open(slice.time, False)):
            self.liquidate(self._spy.symbol)
        
    def _is_before_market_open_extended_hours(self, time: datetime) -> bool:
        return (
            # It's currently extended market hours.
            self._spy.exchange.hours.is_open(time, True) and
            # The next market open for regular trading hours is today.
            self._spy.exchange.hours.get_next_market_open(
                time, False
            ).day == time.day
        )

However, it is important to note that pre-market trading can be more volatile and riskier than regular trading, and the intended price may not be achieved on this strategy.

Example 3: Last Hour Trades

Establishing a scheduled trading event in the hour before market close can be an effective strategy. This allows the trader to analyze market conditions, identify potential trade opportunities, and prepare orders ahead of the close. By emitting their trading insights and planned actions to the market in this critical final hour, the trader can influence other market participants and potentially gain an edge.

public class MarketHourExampleAlgorithm : QCAlgorithm
{
    private Equity _spy;

    public override void Initialize()
    {
        SetStartDate(2024, 9, 1);
        SetEndDate(2024, 12, 31);
        _spy = AddEquity("SPY");

        // Set up a portfolio construction model to handle insights for trading
        SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel(Expiry.EndOfDay));

        // Set up a scheduled event on 1-hour before market close to open position
        Schedule.On(
            DateRules.EveryDay(_spy.Symbol),
            TimeRules.BeforeMarketClose(_spy.Symbol, 60),
            LastHourTrade
        );
    }

    private void LastHourTrade()
    {
        // Get the time of next market close
        var marketCloseTime = _spy.Exchange.Hours.GetNextMarketClose(Time, extendedMarketHours: false);
        // Emit an insight that expires 1 minutye before the next market close
        EmitInsights(Insight.Price(_spy.Symbol, marketCloseTime.AddMinutes(-1), InsightDirection.Up));
    }
}
class MarketHourExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.spy = self.add_equity("SPY")

        # Set up a portfolio construction model to handle insights for trading
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel(Expiry.END_OF_DAY))

        # Set up a scheduled event on 1-hour before market close to open position
        self.schedule.on(
            self.date_rules.every_day(self.spy.symbol),
            self.time_rules.before_market_close(self.spy.symbol, 60),
            self.last_hour_trade
        )

    def last_hour_trade(self) -> None:
        # Get the time of next market close
        market_close_time = self.spy.exchange.hours.get_next_market_close(self.time, extended_market_hours=False)
        # Emit an insight that expires 1 minutye before the next market close
        self.emit_insights(Insight.price(self.spy.symbol, market_close_time - timedelta(minutes=1), InsightDirection.UP))

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: