Skip to content

Alexander-Panov/Arbitrage-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NG Futures Arbitrage Bot

Бот статистического арбитража фьючерсов на природный газ между Московской биржей (RTSX) и NYMEX (XNYM).

Создан в рамках туториала на Хабре: Как написать алготрейдинг-бота с помощью ИИ-агента

Торгует в рамках соревнования алгостратегий Finam Arena.


Как это работает

Стратегия эксплуатирует временное расхождение цен между идентичными по сроку фьючерсами на газ на двух биржах.

Спред = цена_RTSX − цена_XNYM
Z-score = (спред − mean) / std   [скользящее окно, 25 000 точек ≈ 30 дней M1]
Условие Действие
|z| > 2.0 Открыть позицию: купить недооценённый, продать переоценённый
|z| < 0.5 Закрыть позицию (конвергенция)
|z| > 3.5 Стоп-лосс

Рероллинг контрактов происходит автоматически за 5 торговых дней до экспирации — по расписанию из data/ng/ng_pairs_2026.json.

Архитектура

Finam gRPC (SubscribeQuote)
        │  real-time тики
        ▼
   Rolling deque ──► Z-score ──► Signal
   (2000 точек)                    │
                                   ▼
                          Arena REST API
                      POST /v1/accounts/{id}/orders
Компонент Назначение
main.py Стратегия: z-score, сигналы, рероллинг, P&L
arena.py REST-клиент Finam Arena с авто-обновлением JWT
scripts/download_ng_history.py Загрузка M1-истории из Finam API
scripts/backtest.py Бэктест на исторических M1-данных
data/ng/ng_pairs_2026.json Календарь контрактов RTSX ↔ XNYM на 2026 год
data/ng/contracts/*_m1.csv Поконтрактные M1-данные; пополняются ежедневно из живого стрима

Установка и запуск

1. Скопируй .env.example в .env и заполни:

cp .env.example .env
# Finam Trade API — для gRPC котировок
FINAM_API_KEY=your_finam_api_key_here

# Finam Arena — для исполнения ордеров
ARENA_API_TOKEN=your_arena_api_token_here
ARENA_ACCOUNT_ID=1000000

2. Загрузи исторические данные (один раз):

uv run python scripts/download_ng_history.py

3. (Опционально) Запусти бэктест:

uv run python scripts/backtest.py
uv run python scripts/backtest.py --start 2026-06-01 --end 2026-06-22
uv run python scripts/backtest.py --start 2026-06-01 --end 2026-06-22 --json signals.json

4. Запусти стратегию:

uv run python main.py

Запускать из директории arbitrage/. Celery не нужен — standalone async процесс.


Параметры стратегии

Все параметры — константы в начале main.py:

Параметр Значение Описание
DEPOSIT 1 000 000 RUB База для расчёта размера позиции
Z_OPEN 2.0 Порог открытия
Z_CLOSE 0.5 Порог закрытия (конвергенция)
Z_STOP 3.5 Стоп-лосс
SPREAD_WINDOW 25 000 Размер скользящего окна (точек, ~30 дней M1)
WARMUP_MIN_POINTS 30 Минимум точек для начала торговли
LOOKBACK_DAYS 30 Дней истории для прогрева при старте
SAMPLE_SEC 5 Интервал между оценками сигнала (сек)
STALE_QUOTE_SEC 30 Макс. возраст котировки (сек)
ROLL_DAYS_BEFORE 5 Торговых дней до экспирации для рероллинга
COMM_RTSX / COMM_XNYM 0.001% / 0.1% Комиссия по биржам

Пример вывода

2026-06-19 10:15:32  INFO     NG Arbitrage starting
                              Deposit=1,000,000  Z_open=2.0  Z_close=0.5  Z_stop=3.5
                              Quotes: Finam gRPC  |  Orders: Arena REST (account=1000001)
2026-06-19 10:15:33  INFO     Active pair  NGM6@RTSX ↔ NGN26@XNYM
2026-06-19 10:15:33  INFO     Warmup loaded: 1847 spread samples from last 30 days
2026-06-19 10:15:33  INFO     Subscribing quotes: ['NGM6@RTSX', 'NGN26@XNYM']

2026-06-19 11:03:17  INFO     ┌─ OPEN  SHORT_SPREAD  SELL NGM6@RTSX / BUY NGN26@XNYM  z=+2.143  qty=48
2026-06-19 11:03:17  INFO     Arena  SIDE_SELL    NGM6@RTSX         ×48  price=4.3120  comm=0.0021
2026-06-19 11:03:17  INFO     Arena  SIDE_BUY     NGN26@XNYM        ×48  price=4.2980  comm=2.0630
2026-06-19 11:03:17  INFO     │  RTSX=4.3120  XNYM=4.2980  spread=0.0140
2026-06-19 11:03:17  INFO     │  capital=413280.00  entry_comm=2.0651

2026-06-19 14:22:51  INFO     └─ CLOSE [CONVERGE]  z=+0.312
2026-06-19 14:22:51  INFO        SHORT_SPREAD  held=3:19:34
2026-06-19 14:22:51  INFO        RTSX 4.3120→4.2940  XNYM 4.2980→4.2770
2026-06-19 14:22:51  INFO        spread 0.0140→0.0170
2026-06-19 14:22:51  INFO        gross=+0.0144  comm=4.1302  net=-4.1158  trade_ret=-0.0100%
2026-06-19 14:22:51  INFO        ═══ total_pnl=-4.1158  total_ret=-0.0010%  trades=1 (W0/L1)

Создано с помощью ИИ-агента

Стратегия написана с использованием Claude Code и finam-skill — расширения для работы с Finam Trade API из Claude Code — по следующим промптам.

Промпт 1 — поиск символов и загрузка исторических данных

Стратегия арбитража фьючерсов на природный газ между российской и американской биржой.
Текущая пара: NGM6@RTSX (Мосбиржа) и NGN26@XNYM (NYMEX) — оба активны в июне 2026.

Используя finam skill, найди тикеры фьючерсов за весь 2026 год (январь–декабрь) на
обеих биржах. Тикеры имеют закономерности в названиях:
- Для российской биржи (RTSX): поле name имеет вид NG-{n}.26, где n — номер месяца
- Для американской (XNYM): тикер имеет вид NG*26, где * — буква, обозначающая месяц

Сопоставь контракты в пары по месяцам экспирации. Правило маппинга неизвестно заранее —
выведи его самостоятельно на основе данного примера и дат экспирации контрактов из API.

По контрактам, чья дата экспирации уже прошла на момент запуска скрипта, выгрузи
исторические минутные данные за период активной торговли каждого контракта.

Склей данные всех контрактов каждой биржи в одну непрерывную временну́ю серию —
отдельный файл для RTSX и отдельный для XNYM. В каждом файле должна быть колонка
contract с тикером источника. Сохрани в data/ng/.

Промпт 2 — написание стратегии

/trade-api
Используй @old/ng_pair_grpc_min_capital.py как референс архитектуры.

Стратегия арбитража фьючерсов на природный газ между российской и американской биржой:
NGM6@RTSX (Мосбиржа) и NGN26@XNYM (NYMEX) (июнь).
Нужно предусмотреть рероллинг на другой месяц после даты экспирации. Для этого используй
маппинг по месяцам в @data/ng/ng_pairs_2026.json.
Размер депозита: 1 млн рублей. Не принимай во внимание валюты и лотность. Торгуй
насколько позволяет капитал. Цены приведены к одной базе.

Z-score: засей deque(2000) из последних 30 дней CSV, добавляй каждый сэмпл в реальном
времени. Сэмплируй раз в 5 сек. Пропускай сэмпл если котировка любой ноги старше 30 сек.

Сигналы:
- Открывай позицию если |z| > 2: покупай недооценённый, продавай переоценённый
- Закрывай позицию если |z| < 0.5 (конвергенция)
- Стоп-лосс: закрывай если |z| > 3.5

P&L считай через спред: (spread_exit - spread_entry) * pos_dir * qty.
Трекай wins/losses отдельно. База для % — реально задействованный капитал.
Транслируй сделки в консоль вместе с рассчитанной доходностью и общей доходностью.

Комиссия: RTSX 0.001%, XNYM 0.1% от суммы ордера.
Используй SubscribeQuote (gRPC) для котировок в реальном времени.
Реконнект при обрыве, SIGINT/SIGTERM → финальная сводка.
Ежедневно аппендь M1-бары (агрегированные из тиков) в CSV.
Загрузка ключей из .env.
Рероллинг: за 5 торговых дней до экспирации автоматически переходи на следующий месяц.

Используй данные из @data/ng/ng_rtsx_m1_continuous.csv и
@data/ng/ng_xnym_m1_continuous.csv для расчёта исторического z-score за последние 30 дней.

Промпт 3 — подключение Finam Arena

Реализуй открытие и закрытие сделок через платформу соревнований алгостратегий Finam Arena.
Вот документация: https://arena.finam.ru/docs
Вынеси функции в отдельный файл.

About

Natural gas futures statistical arbitrage bot (RTSX ↔ XNYM) — z-score mean-reversion with automatic contract rollover. Quotes via Finam gRPC, execution via Finam Arena.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages