> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ziplime.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Расписание и ограничения

> Запуск функций в заданное время и применение правил управления рисками

Используйте функции по расписанию, если стратегия должна выполняться в определённое время, а не на каждом баре. Ограничения позволяют применять простые правила управления рисками до принятия заявок.

## Функции по расписанию

### `context.schedule_function(func, date_rule=None, time_rule=None, half_days=True, calendar=None)`

Регистрирует асинхронную функцию обратного вызова с той же сигнатурой, что и `handle_data`.

```python theme={null}
from ziplime.finance.execution import MarketOrder
from ziplime.utils.events import date_rules, time_rules


async def initialize(context):
    context.asset = await context.symbol("SBER")
    context.schedule_function(
        rebalance,
        date_rule=date_rules.week_start(),
        time_rule=time_rules.market_open(minutes=30),
    )


async def rebalance(context, data):
    await context.order_target_percent(context.asset, 1.0, style=MarketOrder())
```

В дневных симуляциях текущий планировщик игнорирует `time_rule`, потому что на одну сессию приходится только один бар. В минутных симуляциях важны и правило даты, и правило времени.

## Правила дат

Импортируйте их из `ziplime.utils.events` или `ziplime.api`.

```python theme={null}
from ziplime.utils.events import date_rules
```

| Правило                                 | Значение                           |
| --------------------------------------- | ---------------------------------- |
| `date_rules.every_day()`                | Каждый торговый день               |
| `date_rules.week_start(days_offset=0)`  | N-й торговый день каждой недели    |
| `date_rules.week_end(days_offset=0)`    | За N торговых дней до конца недели |
| `date_rules.month_start(days_offset=0)` | N-й торговый день каждого месяца   |
| `date_rules.month_end(days_offset=0)`   | За N торговых дней до конца месяца |

Примеры:

```python theme={null}
date_rules.every_day()
date_rules.week_start()
date_rules.week_end(days_offset=1)
date_rules.month_start(days_offset=2)
date_rules.month_end()
```

## Правила времени

```python theme={null}
from ziplime.utils.events import time_rules
```

| Правило                               | Значение                            |
| ------------------------------------- | ----------------------------------- |
| `time_rules.market_open(minutes=30)`  | Через 30 минут после открытия рынка |
| `time_rules.market_close(minutes=15)` | За 15 минут до закрытия рынка       |
| `time_rules.every_minute()`           | Каждую минуту в минутной симуляции  |

Смещение должно составлять от 1 минуты до 12 часов.

Примеры:

```python theme={null}
time_rules.market_open()
time_rules.market_open(hours=1)
time_rules.market_close(minutes=30)
```

## Торговые календари

Параметр `calendar` метода `schedule_function` принимает объект торгового календаря. Для российского контура обычно лучше не передавать его явно: тогда Ziplime использует календарь симуляции, настроенный для MOEX.

```python theme={null}
context.schedule_function(
    rebalance,
    date_rule=date_rules.month_end(),
    time_rule=time_rules.market_close(minutes=30),
)
```

Если запуск работает сразу с несколькими календарями, передайте в `calendar` объект, зарегистрированный в вашей среде. Не подменяйте его строкой MIC: тип параметра и доступные константы зависят от конфигурации среды.

## `before_trading_start` и функции по расписанию

Используйте `before_trading_start` для ежедневной подготовки, которую нужно завершить до выполнения торговой логики.

Функции по расписанию подходят для торговых действий в заданный момент сессии.

| Механизм               | Можно размещать заявки? | Асинхронный? | Типичное применение                                                                   |
| ---------------------- | ----------------------- | ------------ | ------------------------------------------------------------------------------------- |
| `before_trading_start` | Нет                     | Нет          | Подготовка набора инструментов, сброс дневного состояния, чтение результата пайплайна |
| Функция по расписанию  | Да                      | Да           | Ребалансировка, выход из позиций, снижение риска                                      |
| `handle_data`          | Да                      | Да           | Основная торговая логика на каждом баре                                               |

## Торговые ограничения

Ограничения обычно настраивают в `initialize`.

### Только длинные позиции

```python theme={null}
async def initialize(context):
    context.set_long_only()
```

### Максимальное кредитное плечо

```python theme={null}
async def initialize(context):
    context.set_max_leverage(1.5)
```

Параметр `run_simulation(..., max_leverage=...)` также регистрирует ограничение плеча.

### Максимальный размер позиции

```python theme={null}
async def initialize(context):
    context.set_max_position_size(
        asset=None,
        max_shares=10_000,
        max_notional=5_000_000,
    )
```

Для портфеля в RUB значение `max_notional` в примере равно 5 000 000 рублей. Передайте `asset`, чтобы ограничение действовало только для этого инструмента, или `asset=None`, чтобы применить его ко всем инструментам.

### Максимальный размер заявки

```python theme={null}
async def initialize(context):
    context.set_max_order_size(
        max_shares=5_000,
        max_notional=2_500_000,
    )
```

Денежное значение `max_notional` задаётся в валюте портфеля.

### Максимальное число заявок

```python theme={null}
async def initialize(context):
    context.set_max_order_count(10)
```

### Поведение при ошибке

Большинство ограничений по умолчанию принимает `on_error="fail"`. В зависимости от реализации ограничения значение `"fail"` вызывает исключение при нарушении правила. Используйте режимы без исключения только тогда, когда осознанно хотите лишь записывать нарушения в журнал или игнорировать их.

## Ограничения по инструментам

Метод `context.set_asset_restrictions(restrictions, on_error="fail")` регистрирует список запрещённых инструментов.

Классы ограничений доступны в `ziplime.finance.asset_restrictions` и через `ziplime.api`:

```python theme={null}
from ziplime.finance.asset_restrictions import StaticRestrictions


async def initialize(context):
    restricted = StaticRestrictions([context.restricted_asset])
    context.set_asset_restrictions(restricted)
```

## Политики отмены

Импортируйте их из `ziplime.finance.cancel_policy` или `ziplime.api`.

```python theme={null}
from ziplime.finance.cancel_policy import EODCancel, NeverCancel


async def initialize(context):
    context.set_cancel_policy(EODCancel(warn_on_cancel=True))
```

| Политика                         | Значение                                                    |
| -------------------------------- | ----------------------------------------------------------- |
| `EODCancel(warn_on_cancel=True)` | Отменять открытые заявки в конце сессии.                    |
| `NeverCancel()`                  | Оставлять заявки активными до исполнения или ручной отмены. |

## Настройка комиссии и проскальзывания

В бэктестах модели исполнения чаще всего настраиваются в `run_simulation(...)`:

```python theme={null}
from ziplime.finance.commission import PerDollar
from ziplime.finance.slippage.fixed_basis_points_slippage import FixedBasisPointsSlippage

result = await run_simulation(
    ...,
    equity_commission=PerDollar(cost=0.001),
    equity_slippage=FixedBasisPointsSlippage(basis_points=5.0, volume_limit=0.1),
)
```

`PerDollar` — неизменяемое имя класса API; модель применяется к денежному обороту в валюте расчётов среды, в российском контуре обычно в рублях.

Совместимые с Zipline методы `context.set_commission(...)` и `context.set_slippage(...)` доступны во время инициализации. Используйте их только тогда, когда конфигурация биржи и blotter рассчитана на модели уровня `context`. Для стандартного вызова `run_simulation` предпочтительнее явные параметры функции запуска.
