Skip to content

Trading hours

Restrict new entries to a market session or a time window. Session filters use the bar's timestamp, so the same rule can be checked on historical data.

Trade within the session

symbol = "TCS"

def on_tick():
    if not in_session("NSE", between=("09:30", "15:00")):
        return
    if len(close) < 20:
        return
    if position.is_flat and close[0] > mean(close, 20):
        long(10)
    elif position.is_long and close[0] < mean(close, 20):
        close()

This narrows the NSE regular session to the 09:30–15:00 window. Returning outside the window also skips signal exits in this example. It does not automatically close an open position at the end of the window. Choose an explicit exit if you want to flatten before the close.

Choose a filter

Call Meaning
in_session("NSE") Eligible regular-session bars.
in_session("NYSE", between=("10:00", "15:00")) Narrow NYSE-local window.
after("10:00") Strictly after the market-local clock time.
before("14:30") Strictly before the market-local clock time.

Filters combine: the bar must satisfy all of them. in_session is available inside strategy functions without an import. Use HH:MM strings in validated drafts. The API also accepts skip_open/skip_close duration objects, but the current strategy import rules reject from datetime import timedelta (TS003); use these only when an approved environment supplies the duration values.

Timezones and boundaries

Windows are interpreted in the venue's local timezone. between includes both supplied endpoints, while regular sessions include the open and exclude the close. The session and narrower window must both permit the bar. Known lunch breaks and configured holidays are excluded. The built-in holiday tables are minimal, so do not treat them as a complete official calendar.

Unknown venue codes raise KeyError; use list_venues() to check supported names. venue_hours("NSE") returns the configured hours. Bars should have timezone-aware timestamps; a naive timestamp is treated as UTC when a market timezone is configured, otherwise legacy venue-local interpretation applies. Use aware timestamps to avoid that ambiguity.

Always-open venues

CRYPTO and FOREX have no regular open/close boundary in this helper. Use a UTC between window to restrict hours. skip_open or skip_close has no reference boundary and returns false for these venues.

in_session("FOREX", between=("13:00", "17:00"))

This helper's calendar does not establish broker availability or instrument support. See exact session functions.

Combine restrictions without losing exits

A session check is a Boolean condition. To restrict entries while continuing to evaluate signal exits, place the check on the entry branch:

symbol = "TCS"

def on_tick():
    if len(close) < 20:
        return
    average = mean(close, 20)
    if position.is_long and close[0] < average:
        close()
    elif position.is_flat and in_session("NSE", between=("10:00", "14:30")):
        if close[0] > average:
            long(10)

Here an exit can match outside the entry window, provided the runtime still dispatches that bar. An early return outside the session would skip both branches. Neither arrangement automatically flattens at the end of the window.

Check an exact clock or holiday

at("15:20") matches the current bar's market-local hour and minute. after("10:00") and before("14:30") are strict comparisons; equality does not satisfy them. An exact-time test needs a dispatched bar at that minute. A five-minute data grid does not contain every possible clock minute.

is_holiday("NSE", date) checks the configured calendar for a Python date. list_venues() returns supported venue codes, and venue_hours(code) exposes their configured hours. Unknown codes raise KeyError; spellings are not inferred from an instrument name.