---
title: "Scheduled Events"
description: "Scheduled Events let you trigger code to run at specific times of day, regardless of your algorithm's data subscriptions."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/scheduled-events
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/scheduled-events.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/26%20Scheduled%20Events
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# Scheduled Events

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Scheduled Events

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

Scheduled Events let you trigger code to run at specific times of day, regardless of your algorithm's data subscriptions. It's easier and more reliable to execute time-based events with Scheduled Events than checking the current algorithm time in the `on_data` event handler.

## Create Scheduled Events

To create a Scheduled Event, call the `schedule.on` method. The method expects a `DateRules` object, a `TimeRules` object, and a function to execute. The following examples demonstrate some common Scheduled Events.

### Schedule Events Before Market Open

You may want to train a model or fetch historical data before the market opens. The following example demonstrates how to set a Scheduled Event for 10 minutes before the market opens.

```python
def initialize(self):
    # Call the _before_market_open method 10 minutes before open every day SPY is trading.
    self.schedule.on(
        self.date_rules.every_day('SPY'),
        self.time_rules.before_market_open('SPY', 10),
        self._before_market_open
    )
```

### Schedule Events on the Last Trading Day of the Week

You may want to rebalance your portfolio on the last trading day of each week and factor in market holidays. The following example demonstrates how to set a Scheduled Event for the last trading day of each week 30 minutes before the market closes.

```python
def initialize(self):
# Call the _rebalance method 30 minutes before the end of the SPY trading week.
    self.schedule.on(
        self.date_rules.week_end('SPY'),
        self.time_rules.before_market_close('SPY', 30),
        self._rebalance
    )
```

### Schedule Events on Regular Intervals Throughout the Trading Day

You may want to perform some action on a regular interval through each trading day. The following example demonstrates how to set a Scheduled Event for every 30 minutes through the trading day for SPY.

```python
def initialize(self):
    # Every day SPY is trading, call the '_some_action' method every 30 minutes.
    self.schedule.on(
        self.date_rules.every_day('SPY'),
        self.time_rules.every(timedelta(minutes=30)),
        self._some_action
    )
```

## Date Rules

The following table describes the supported `DateRules`:

| Member | Description |
| --- | --- |
| `self.date_rules.set_default_time_zone(time_zone: DateTimeZone)` | Sets the time zone for the `DateRules` object used in all methods in this table. The default time zone is the [algorithm time zone](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md#12-Set-Time-Zone). |
| `self.date_rules.on(year: int, month: int, day: int)` | Trigger an event on a specific date. |
| `self.date_rules.on(dates: list[datetime])` | Trigger an event on specific dates. |
| `self.date_rules.every_day()` | Trigger an event all seven days of the week. |
| `self.date_rules.every_day(symbol: Symbol, extended_market_hours: bool = False)` | Trigger an event every day a specific symbol is trading. |
| `self.date_rules.every(days: list[DayOfWeek])` | Trigger an event on specific days throughout the week. To view the `DayOfWeek` enum members, see [DayOfWeek Enum](https://docs.microsoft.com/en-us/dotnet/api/system.dayofweek) in the .NET documentation. |
| `self.date_rules.month_start(days_offset: int = 0)` | Trigger an event on the first day of each month plus an offset. |
| `self.date_rules.month_start(symbol: Symbol, daysOffset: int = 0)` | Trigger an event on the first tradable date of each month for a specific symbol plus an offset. |
| `self.date_rules.month_end(days_offset: int = 0)` | Trigger an event on the last day of each month minus an offset. |
| `self.date_rules.month_end(symbol: Symbol, daysOffset: int = 0)` | Trigger an event on the last tradable date of each month for a specific symbol minus an offset. |
| `self.date_rules.week_start(days_offset: int = 0)` | Trigger an event on the first day of each week plus an offset. |
| `self.date_rules.week_start(symbol: Symbol, days_offset: int = 0)` | Trigger an event on the first tradable date of each week for a specific symbol plus an offset. |
| `self.date_rules.week_end(days_offset: int = 0)` | Trigger an event on the last day of each week minus an offset. |
| `self.date_rules.week_end(symbol: Symbol, days_offset: int = 0)` | Trigger an event on the last tradable date of each week for a specific symbol minus an offset. |
| `self.date_rules.quarter_start(days_offset: int = 0)` | Trigger an event on the first day of each quarter plus an offset. |
| `self.date_rules.quarter_start(symbol: Symbol, days_offset: int = 0)` | Trigger an event on the first tradable date of each quarter for a specific symbol plus an offset. |
| `self.date_rules.quarter_end(days_offset: int = 0)` | Trigger an event on the last day of each quarter minus an offset. |
| `self.date_rules.quarter_end(symbol: Symbol, days_offset: int = 0)` | Trigger an event on the last tradable date of each quarter for a specific symbol minus an offset. |
| `self.date_rules.year_start(days_offset: int = 0)` | Trigger an event on the first day of each year plus an offset. |
| `self.date_rules.year_start(symbol: Symbol, days_offset: int = 0)` | Trigger an event on the first tradable date of each year for a specific symbol plus an offset. |
| `self.date_rules.year_end(days_offset: int = 0)` | Trigger an event on the last day of each year minus an offset. |
| `self.date_rules.year_end(symbol: Symbol, days_offset: int = 0)` | Trigger an event on the last tradable date of each year for a specific symbol minus an offset. |
| `self.date_rules.today` | Trigger an event once today. |
| `self.date_rules.tomorrow` | Trigger an event once tomorrow. |

To define custom date rules, create a `FuncDateRule` object. The `FuncDateRule` constructor expects a `name` argument of type `str` and a `get_dates_function` argument of type `Callable[[datetime, datetime], list[datetime]]`. The `get_dates_function` function receives the start and end dates of the algorithm and returns a list of dates for the date rule. In live trading, the end date is 12/31/2025. The following example demonstrates how to define a date rule that represents the 10th day of each month:

```python
# Create a date rule that specifies the 10th day of each month.
date_rule = FuncDateRule(
    name="10th_day_of_the_month",
    get_dates_function=lambda start, end: [
        datetime(year, month, 10)
        for year in range(start.year, end.year) for month in range(1,12)
    ]
)
```

Some date rules require a Symbol. However, they accept a string representation of the Symbol as well. If your algorithm doesn't [add the security](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/requesting-data.md#02-Add-Assets), it assumes the string refers to a [US Equity](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/us-equity.md) Symbol. For example, if you use the `self.date_rules.every_day('ES')` method, it assumes that 'ES' refers to a US Equity. To create a Symbol without adding a security to your algorithm, call the `Symbol.create` method.

```python
symbol = Symbol.create('ES', SecurityType.FUTURE, Market.CME)
```

## Time Rules

The following table describes the supported `TimeRules`:

| Member | Description |
| --- | --- |
| `self.time_rules.set_default_time_zone(time_zone: DateTimeZone)` | Sets the time zone for the `TimeRules` object used in all methods in this table, except when a different time zone is given. The default time zone is the [algorithm time zone](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md#12-Set-Time-Zone). |
| `self.time_rules.before_market_open(symbol: Symbol, minutes_before_open: float = 0, extended_market_open: bool = False)` | Trigger an event a few minutes before market open for a specific symbol (default is 0). This rule doesn't work for Crypto securities or custom data. |
| `self.time_rules.after_market_open(symbol: Symbol, minutes_after_open: float = 0, extended_market_open: bool = False)` | Trigger an event a few minutes after market open for a specific symbol (default is 0). This rule doesn't work for Crypto securities or custom data. |
| `self.time_rules.before_market_close(symbol: Symbol, minutes_before_close: float = 0, extended_market_open: bool = False)` | Trigger an event a few minutes before market close for a specific symbol (default is 0). This rule doesn't work for Crypto securities or custom data. |
| `self.time_rules.after_market_close(symbol: Symbol, minutes_after_close: float = 0, extended_market_open: bool = False)` | Trigger an event a few minutes after market close for a specific symbol (default is 0). This rule doesn't work for Crypto securities or custom data. |
| `self.time_rules.every(interval: timedelta)` | Trigger an event every period interval starting at midnight. This time rule triggers every period, regardless of whether or not the market is open. |
| `self.time_rules.now` | Trigger an event at the current time of day. |
| `self.time_rules.midnight` | Trigger an event at midnight. |
| `self.time_rules.noon` | Trigger an event at noon. |
| `self.time_rules.at(hour: int, minute: int, second: int = 0)` | Trigger an event at a specific time of day (e.g. 13:10). |
| `self.time_rules.at(hour: int, minute: int, second: int, time_zone: DateTimeZone)` | Trigger an event at a specific time of day in the given [https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/time-zones.md](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/time-zones.md)time zone (e.g. 13:10 UTC). |

To define custom time rules, create a `FuncTimeRule` object. The `FuncTimeRule` constructor expects a `name` argument of type `str` and a `create_utc_event_times_function` argument of type `Callable[[list[datetime]], list[datetime]]`. The function receives the list of dates from the date rule and then returns a list of `datetime` that define the time rule.

```python
time_rule = FuncTimeRule(
    name="CustomTimeRule",
    create_utc_event_times_function=lambda dates: [d + timedelta(hours=10) for d in dates]
)
```

Some time rules require a Symbol. However, they accept a string representation of the Symbol as well. If your algorithm doesn't [add the security](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/requesting-data.md#02-Add-Assets), it assumes the string refers to a [US Equity](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/us-equity.md) Symbol. For example, if you use the `self.time_rules.before_market_open('ES', 15)` method, it assumes that 'ES' refers to a US Equity. To create a Symbol without adding a security to your algorithm, call the `Symbol.create` method.

```python
symbol = Symbol.create('ES', SecurityType.FUTURE, Market.CME)
```

## Remove Scheduled Events

If you no longer need a Scheduled Event in your algorithm, remove it so your algorithm doesn't execute unnecessary functions. To remove a Scheduled Event, save a reference to the Scheduled Event when you create it and then call the `remove` method to remove it.

```python
def initialize(self):
    # Remove a scheduled event by keeping a copy of the object on creation.
    self.scheduled_event = self.schedule.on(
        self.date_rules.every_day('SPY'),
        self.time_rules.after_market_open('SPY', 10),
        self._ten_minutes_after_open)

# Remove the scheduled event using the object reference in any method
self.schedule.remove(self.scheduled_event)
```

## Common Errors

Common errors with Scheduled Events include [stale fills](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/trade-fills/key-concepts.md#06-Stale-Fills) and execution timeouts.

### Stale Fills

A common error is to subscribe to daily resolution data and set a Scheduled Event intraday to place trades. If you trade intraday with daily data, you get stale fills.

Another common error is to set a Scheduled Event to trade immediately after the market open on illiquid securities. Illiquid securities can have no trades for the first few minutes after the market open. If you trade during this time, you get stale fills.

### Execution Timeouts

If your Scheduled Event takes longer than 10 minutes to execute, your algorithm will timeout. To increase the amount of time that your Scheduled Event can run, replace your Scheduled Event with a [training session](https://www.quantconnect.com/docs/v2/writing-algorithms/machine-learning/training-models.md).

### Invoking the Callback Method

Make sure to not accidentally invote the event handler method by adding trailing braces `()`. Use `self._event_handler_func`, not `self._event_handler_func()`.

## Execution Sequence

The algorithm manager calls events in the following order:

1. Scheduled Events
2. [Consolidation event handlers](https://www.quantconnect.com/docs/v2/writing-algorithms/consolidating-data/getting-started.md)
3. `on_data` event handler

This event flow is important to note. For instance, if your consolidation handlers or `on_data` event handler appends data to a `RollingWindow` and you use that `RollingWindow` in your Scheduled Event, when the Scheduled Event executes, the `RollingWindow` won't contain the most recent data.

## Live Trading Considerations

In live trading, Scheduled Events execute in a parallel thread based on a real-time clock. If you set a Scheduled Event to fire at 10:00 AM, it executes at exactly 10:00 AM. In backtesting, Scheduled Events are part of the main algorithm manager loop, so they may not execute exactly when you set them. For example, if your algorithm subscribes to minute resolution US Equity data with regular trading hours and you set a Scheduled Event to occur at 2:00 AM, your Scheduled Event will execute at 9:31 AM when the next bar is fed into your algorithm.

The difference between live trading and backtesting is important to note because it can affect your algorithm's behavior. There are two common scenarios to consider.

### Execution Timing and Backtest Timeouts

Take the following scenario:

- You set Scheduled Events for 2:00 AM, 3:00 AM, and 4:00 AM each day.
- Each Scheduled Event takes eight minutes to execute.
- Your algorithm only subscribes to US Equity securities without extended market hours (9:30 AM - 4:00 PM).

In this scenario, the Scheduled Events each fire at the correct time and execute without error in live trading. In backtesting, all of the Scheduled Events execute at 9:31 AM when your algorithm receives the first bar of the trading day. Since all the Scheduled Events take eight minutes to execute, the algorithm tries to execute all the Scheduled Events but reaches the 10-minute timeout and the backtest stops execution.

### Live Data Delays

In backtests, your algorithm receives data at perfect timing. If you request minute resolution data, your algorithm receives the bars at the top of each minute. In live trading, bars have a slight delay, so you may receive them milliseconds after the top of each minute. Take the following scenario:

- You subscribe to minute resolution data
- You set a Scheduled Event for 10:00 AM
- The Scheduled Event checks the current asset price

In live trading, the Scheduled Event executes at exactly 10:00 AM but your algorithm may receive the 9:59-10:00 AM bar at 10:00:00.01 AM. Therefore, when you check the price in the Scheduled Event, the price from the 9:58-9:59 AM bar is the latest price. In backtesting, the Scheduled Event gets the price from the 9:59-10:00 AM bar since your algorithm receives the bar at perfect timing.

## Examples

```python
def initialize(self):
    # Schedule an event to fire at a specific date/time using inline callback function.
    self.schedule.on(self.date_rules.on(2013, 10, 7),
                    self.time_rules.at(13, 0),
                    lambda: self.log(f"SpecificTime: Fired at : {self.time}"))

    # Schedule an event to fire every trading day for a security at 13:00:00 UTC.
    self.schedule.on(self.date_rules.every_day("SPY"),
                    self.time_rules.at(13, 0, 0, TimeZones.UTC),
                    lambda: self.log(f"EveryDay.SPY SpecificTime: Fired at: {self.time}"))

    # Schedule an event to fire every trading day for a security - 10 minutes before SPY's market open.
    self.schedule.on(self.date_rules.every_day("SPY"),
                    self.time_rules.before_market_open("SPY", 10),
                    lambda: self.log(f"EveryDay.SPY 10 min before open: Fired at: {self.time}"))

    # Schedule an event to fire every trading day for a security - 10 minutes after SPY's market open.
    self.schedule.on(self.date_rules.every_day("SPY"),
                    self.time_rules.after_market_open("SPY", 10),
                    lambda: self.log(f"EveryDay.SPY 10 min after open: Fired at: {self.time}"))

    # Schedule an event to fire every trading day for a security - 10 minutes before SPY's market close.
    self.schedule.on(self.date_rules.every_day("SPY"),
                    self.time_rules.before_market_close("SPY", 10),
                    lambda: self.log(f"EveryDay.SPY 10 min before close: Fired at: {self.time}"))

    # Schedule an event to fire every trading day for a security - 10 minutes after SPY's market close.
    self.schedule.on(self.date_rules.every_day("SPY"),
                    self.time_rules.after_market_close("SPY", 10),
                    lambda: self.log(f"EveryDay.SPY 10 min after close: Fired at: {self.time}"))

    # Schedule an event to fire on certain days of the week
    self.schedule.on(self.date_rules.every(DayOfWeek.MONDAY, DayOfWeek.FRIDAY),
                    self.time_rules.at(12, 0),
                    lambda: self.log(f"Mon/Fri at 12pm: Fired at: {self.time}"))

    # Schedule an event to fire once today at when this method is called (now)
    self.schedule.on(self.date_rules.today,
                    self.time_rules.now,
                    lambda: self.log(f"Now: Fired at: {self.time}"))

    # Schedule an event to fire once tomorrow at midnight
    self.schedule.on(self.date_rules.tomorrow,
                    self.time_rules.midnight,
                    lambda: self.log(f"Tomorrow at midnight: Fired at: {self.time}"))

    # Schedule an event to fire once today at noon
    self.schedule.on(self.date_rules.today,
                    self.time_rules.noon,
                    lambda: self.log(f"Today at noon: Fired at: {self.time}"))

    # Scan a method every ten minutes, every day.
    self.schedule.on(self.date_rules.every_day(),
                    self.time_rules.every(timedelta(minutes=10)),
                    self._liquidate_unrealized_losses)

    # Schedule an event to fire at the beginning of the month.
    # The symbol is optional but if specified, it will fire the first trading day
    # for that symbol of the month. Otherwise, it will fire on the first day of the month.
    self.schedule.on(self.date_rules.month_start("SPY"),
                    self.time_rules.after_market_open("SPY"),
                    self._rebalancing_code)

    # Schedule an event to fire at the end of the month, the symbol is optional.
    # If specified, it will fire the last trading day for that symbol of the month.
    # Otherwise, it will fire on the last day of the month.
    self.schedule.on(self.date_rules.month_end("SPY"),
                    self.time_rules.before_market_close("SPY"),
                    self._rebalancing_code)

    # Schedule an event to fire at the beginning of the week, the symbol is optional.
    # If specified, it will fire the first trading day for that symbol of the week.
    # Otherwise, it will fire on the first day of the week.
    self.schedule.on(self.date_rules.week_start("SPY"),
                    self.time_rules.after_market_open("SPY", 5),
                    self._rebalancing_code)

    # Schedule an event to fire at the end of the week, the symbol is optional.
    # If specified, it will fire the last trading day for that symbol of the week.
    # Otherwise, it will fire on the last day of the week.
    self.schedule.on(self.date_rules.week_end("SPY"),
                    self.time_rules.before_market_close("SPY", 5),
                    self._rebalancing_code)

    # Schedule an event to fire at the beginning of the quarter, the symbol is optional.
    # If specified, it will fire the first trading day for that symbol of the quarter.
    # Otherwise, it will fire on the first day of the quarter.
    self.schedule.on(self.date_rules.quarter_start("SPY"),
                    self.time_rules.after_market_open("SPY"),
                    self._rebalancing_code)

    # Schedule an event to fire at the end of the quarter, the symbol is optional.
    # If specified, it will fire the last trading day for that symbol of the quarter.
    # Otherwise, it will fire on the last day of the quarter.
    self.schedule.on(self.date_rules.quarter_end("SPY"),
                    self.time_rules.before_market_close("SPY"),
                    self._rebalancing_code)

# The following methods from examples above should be defined in the algorithm body.
def _liquidate_unrealized_losses(self) -> None:
    ''' if we have over 1000 dollars in unrealized losses, liquidate'''
    if self.portfolio.total_unrealized_profit < -1000:
        self.log(f"Liquidated due to unrealized losses at: {self.time}")
        self.liquidate()

def _rebalancing_code(self) -> None:
    ''' Good spot for rebalancing code?'''
    pass
```

**Demonstration Algorithm**

- [ScheduledEventsAlgorithm.py](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/ScheduledEventsAlgorithm.py) (Python)
