← На главную
Guides· 6/28/2026· 5 мин чтения

Статистический арбитраж с нуля: как написать торгового бота на Z-score, если вы не программист

Научись строить ботов для статистического арбитража (Pairs Trading). Пошаговый гайд по Z-score, Mean Reversion и Python.

Статистический арбитраж с нуля: как написать торгового бота на Z-score, если вы не программист
AI-assisted, edited by a human reviewer

Если вы хотите получать доход от неэффективностей рынка, но не хотите тратить месяцы на изучение Python и квантовой математики, этот гайд для вас. Мы разберем, как построить бота для статистического арбитража (Pairs Trading) с помощью готовых API и современных AI-помощников, используя только логику.

***

Почему классический арбитраж уже не работает и что делать вместо этого

Классический арбитраж (купить А на бирже 1, продать А на бирже 2) — это ниша, которую давно захватили высокочастотные (HFT) алгоритмы. Найти разорившийся спред в микросекунды без колоссальных вычислительных мощностей практически невозможно.

Однако есть стратегия, которая позволяет обойти это ограничение: Статистический арбитраж (Pairs Trading).

Вместо того чтобы искать идеальную идентичную пару активов, мы ищем два актива, которые исторически очень тесно связаны (например, фьючерсы на газ на разных биржах или акции конкурентов из одного сектора). Наша задача — не ждать, пока они достигнут идеальной цены, а ждать, пока их отношение вернется к историческому среднему.

В этом и кроется ключ к стратегии: мы торгуем не ценами, а спредом (разницей) между ценами.

Что такое коинтеграция и как работает «невидимый поводок»

Для понимания, как это работает, нужно понять концепцию коинтеграции.

Представьте двух людей, которые всегда ходят вместе. Их пути могут отклоняться (это обычная корреляция), но они не могут уйти слишком далеко друг от друга — существует невидимая, физическая граница (как длина поводка). Эта граница и есть коинтеграция.

Если два актива коинтегрированы, их разница (спред) будет обладать свойством возврата к среднему (Mean Reversion). Это означает, что если спред резко расширится (один актив сильно вырастет относительно другого), математика с высокой вероятностью "вернет" его к историческому равновесию.

Задача бота: Поймать момент, когда спред слишком далеко отклонился от нормы, и зафиксировать прибыль, когда он возвращается обратно.

Главный инструмент: Z-score

Чтобы понять, насколько сильно спред отклонился от нормы, используется показатель Z-score.

Z-score — это нормализованная мера, которая показывает, на сколько стандартных отклонений текущее значение (спреда) отстоит от исторического среднего значения.

$$ Z = \frac{Спред_{текущий} - Mean_{спреда}}{Standard \ Deviation_{спреда}} $$

  • $Mean_{спреда}$: Среднее значение спреда за выбранный период (например, последние 30 дней).
  • $Standard \ Deviation_{спреда}$: Волатильность спреда (его «шум»).
  • $Z_{текущий}$: Вычисляется в реальном времени.

Правило принятия решений:

  • Если $|Z| > 2$ (например, $Z=2.5$), спред находится за пределами 95% исторического диапазона. Это сигнал на вход.
  • Когда $Z$ приближается к $0$, спред вернулся к историческому равновесию. Это сигнал на выход и фиксацию прибыли.

Пошаговый алгоритм: от теории к коду

Для написания бота вам потребуется доступ к API двух или более бирж и знание Python. Но если вы используете современные AI-агенты (вроде Claude Code или Cursor), вам останется только дать правильный промпт и проследить логику.

Шаг 1. Выбор и проверка пары (Самое важное)

Нельзя просто выбрать любые два актива. Они должны быть:

  1. Экономически связаны (например, нефть и бензин, акции конкурентов).
  2. Проверены на коинтеграцию.

На этом этапе вы можете использовать специализированные скринеры (например, те, что ищут пары по коинтеграции), чтобы получить начальный набор пар и подтвердить, что математически связь существует.

Шаг 2. Сбор и расчет исторических данных

Прежде чем бот начнет торговать, ему нужен «поводок» — исторические данные.

Действие: Загрузить дневные бары (OHLCV) для обоих активов ($A$ и $B$) за период, достаточно большой для расчета $Mean$ и $Standard \ Deviation$ (минимум 30 дней).

Логика (Python pseudo-code): ```python

Предположим, что API уже загрузил данные A и B за 30 дней

data_A = api.get_bars(ticker_A, days=30) data_B = api.get_bars(ticker_B, days=30)

1. Рассчитываем спред (разницу цен)

data['Spread'] = data_A['Close'] - data_B['Close']

2. Вычисляем статистику

mean_spread = np.mean(data['Spread']) std_dev_spread = np.std(data['Spread']) ```

Шаг 3. Мониторинг и принятие торгового решения (Real-time)

Бот должен работать в цикле, постоянно подписываясь на реальные котировки (SubscribeQuote).

Действие: На каждом тике пересчитывать $Z_{текущий}$ и сравнивать его с заданными порогами.

Логика (Python pseudo-code): ```python def check_z_score(current_spread, mean_spread, std_dev_spread): # Рассчитываем Z-score z_score = (current_spread - mean_spread) / std_dev_spread return z_score

--- Цикл мониторинга ---

while True: # 1. Получаем текущий спред current_spread = api.subscribe_quote_spread(ticker_A, ticker_B) z_score = check_z_score(current_spread, mean_spread, std_dev_spread)

print(f"Текущий Z-score: {z_score:.2f}")

# 2. Проверка условий входа (Entry) if z_score >= 2.0: # Спред слишком дорогой (A >> B) -> Продаем A, Покупаем B api.execute_trade(action="SELL", ticker=ticker_A, size=1) api.execute_trade(action="BUY", ticker=ticker_B, size=1) print("Вход: Спред слишком высок. Открываем короткую позицию на A и длинную на B.")

elif z_score <= -2.0: # Спред слишком дешевый (B >> A) -> Покупаем A, Продаем B api.execute_trade(action="BUY", ticker=ticker_A, size=1) api.execute_trade(action="SELL", ticker=ticker_B, size=1) print("Вход: Спред слишком низок. Открываем длинную позицию на A и короткую на B.")

# 3. Проверка условий выхода (Exit) elif abs(z_score) < 0.5: # Спред вернулся к равновесию (Z близко к 0) api.close_all_positions() print("Выход: Спред вернулся к среднему. Закрытие позиций и фиксация прибыли.") ```

Шаг 4. Жизненно важный риск-менеджмент

Самая большая ошибка новичков — игнорировать риски. В трейдинге, как и в жизни, случаются форс-мажоры.

Главный риск: Расхождение (Divergence). Если в фундаменте одного из активов происходит катастрофа (например, эмбарго или смена законодательства), коинтеграция может быть разорвана. Спред перестает быть "поводком" и начинает уходить в бесконечность. В этом случае бот продолжит покупать/продавать, пока не достигнет критического убытка.

Меры защиты:

  1. Стоп-лосс по спреду: Не используйте стоп-лосс по цене. Установите критический уровень $Z_{stop}$ (например, $|Z| > 3.5$). Если спред продолжает движение в одном направлении, независимо от того, как мы вошли, бот должен немедленно закрыться с убытком.
  2. Контроль коинтеграции: Регулярно проверяйте, что связь между активами не ослабла.

Подводные камни и что попробовать дальше

Где ломается бот?

  1. Изменение режима рынка: Стратегия Mean Reversion работает отлично в боковом, "зажатом" рынке. В условиях сильного тренда (когда один актив растет, а другой остается на месте) спред может просто продолжать уходить в бесконечность, и бот будет терять деньги.
  2. Слишком частые сделки: Если вы используете слишком маленький период для расчета $Mean$ (например, 5 дней), бот будет слишком чувствителен к "шуму" и будет генерировать много ложных сигналов.
  3. Игнорирование комиссий: При расчете прибыли всегда учитывайте комиссию и проскальзывание (slippage). Они могут "съесть" всю вашу потенциальную прибыль.

Что попробовать дальше?

  • Динамический $Z$-score: Вместо фиксированного $Mean$ и $Std \ Deviation$, используйте скользящие средние (Moving Average) и скользящее стандартное отклонение. Это позволит боту адаптироваться к меняющейся волатильности.
  • Множественные пары: Вместо торговли одной парой, постройте систему, которая одновременно отслеживает 5–10 коинтегрированных пар и открывает сделку на той паре, где сигнал самый сильный.

Источники

By: PLai AI