Skip to content

trading_agent.risk.exchange_hours

Decides whether an exchange is open for new orders at a given moment.

With trading_window = "exchange_hours", each exchange's own regular session applies: NSE and BSE equities and derivatives 09:15 to 15:30, currency derivatives 09:00 to 17:00, and MCX 09:00 to 23:30, or 23:55 while the United States is not on daylight saving time, because MCX's evening follows US trading hours. A fixed "HH:MM-HH:MM" window applies the same hours to every exchange. Weekends are closed. With a market calendar, exchange holidays are closed too, a commodity holiday that closes only the morning or evening session narrows the hours, and a special session such as Muhurat trading opens the exchange for its own hours, even on a weekend or holiday.

Typical usage example:

hours = ExchangeHours() is_open, reason = hours.is_open('nse', 'nse_equities', moment, 'exchange_hours')

ExchangeHours

ExchangeHours(calendar=None)

The trading sessions of the Indian exchanges.

Creates the checker.

Parameters:

Name Type Description Default
calendar MarketCalendar | None

The exchanges' holidays and special sessions, or None to know weekends only.

None
Source code in src/trading_agent/risk/exchange_hours.py
def __init__(
    self,
    calendar: market_calendar_module.MarketCalendar | None = None,
):
    """Creates the checker.

    Args:
        calendar (market_calendar_module.MarketCalendar | None): The exchanges' holidays and special sessions, or None to know weekends only.
    """
    self._calendar = calendar

is_open

is_open(exchange, segment, moment, trading_window)

Says whether new orders are allowed for an instrument at a moment.

Parameters:

Name Type Description Default
exchange str

The exchange, such as nse, bse or mcx.

required
segment str

UBI's segment, used to tell currency derivatives apart.

required
moment datetime

The moment, with a time zone.

required
trading_window str

"exchange_hours", or "HH:MM-HH:MM" in India time.

required

Returns:

Type Description
tuple[bool, str]

Whether it is open, and the session that applies, for messages.

Source code in src/trading_agent/risk/exchange_hours.py
def is_open(
    self,
    exchange: str,
    segment: str,
    moment: datetime.datetime,
    trading_window: str,
) -> tuple[bool, str]:
    """Says whether new orders are allowed for an instrument at a moment.

    Args:
        exchange (str): The exchange, such as nse, bse or mcx.
        segment (str): UBI's segment, used to tell currency derivatives apart.
        moment (datetime.datetime): The moment, with a time zone.
        trading_window (str): "exchange_hours", or "HH:MM-HH:MM" in India time.

    Returns:
        tuple[bool, str]: Whether it is open, and the session that applies, for messages.
    """
    local = moment.astimezone(_INDIA)
    special = self._special_session(exchange, segment, local)
    if special is not None:
        special_text = f'the {special.name} session, {special.opens:%H:%M}-{special.closes:%H:%M} India time'
        if special.opens <= local.time() < special.closes:
            return True, special_text
        return (
            False,
            f'it is {local:%H:%M} India time; today has only {special_text}',
        )
    start, end = self._session(exchange, segment, local, trading_window)
    session_text = f'{start:%H:%M}-{end:%H:%M} India time on weekdays'
    if local.weekday() >= _SATURDAY:
        return False, f'it is a weekend; the session is {session_text}'
    closure = self._closure(exchange, segment, local)
    if closure is not None:
        if closure.closed == 'all':
            return (
                False,
                f'it is an exchange holiday ({closure.name}); the session is {session_text}',
            )
        if closure.closed == 'morning':
            start = max(start, _COMMODITY_SPLIT)
        if closure.closed == 'evening':
            end = min(end, _COMMODITY_SPLIT)
        session_text = f'{start:%H:%M}-{end:%H:%M} India time today, because of {closure.name}'
    if not start <= local.time() < end:
        return (
            False,
            f'it is {local:%H:%M} India time; the session is {session_text}',
        )
    return True, session_text