For the complete documentation index, see llms.txt. This page is also available as Markdown.

С чего начать

1

Как создать сессию

Каждая симуляция идет в рамках сессии. Чтобы ее начать, достаточно указать, какой отрезок истории проиграть.

  • startSlot / endSlot: с какого по какой слот проигрывать историю. Оба крайних слота входят в симуляцию.

  • signerFilter (необязательно): адреса, чьи транзакции нужно убрать из истории. Например, чтобы исключить сделки своего бота и посмотреть, как рынок жил бы без них.

  • disconnectTimeoutSecs (необязательно): если соединение оборвется, сессия не закроется сразу, а подождет переподключения. Здесь задается, сколько ждать: до 900 секунд, то есть 15 минут.

Для запроса нужен API-ключ: его передают в заголовке X-API-Key.

// via websocket to `ws(s)://<host>/backtest`
{
  "method": "createBacktestSession",
  "params": {
    "startSlot": 123456,
    "endSlot": 234567,
    "signerFilter": ["addr..."],
    "disconnectTimeoutSecs": 30
  }
}

После создания сессии сервер присылает два сообщения по порядку. Сначала slotNotification со стартовым слотом: симуляция встала на начало выбранного отрезка. Затем readyForContinue: сессия готова, можно двигаться дальше.

Вместе с сессией приходит и ее собственный RPC-адрес. Все дальнейшие запросы к этой сессии отправляются туда.

{
  "method": "sessionCreated",
  "params": {
    "sessionId": "<session_id>",
    "rpcEndpoint": "/backtest/<session_id>"
  }
}

Пока идет сессия, WebSocket-соединение должно оставаться открытым. Если его закрыть, сессия завершится, а все состояние аккаунтов будет удалено: начинать придется заново.

2

Как получить данные аккаунтов

С сессией можно работать как с обычной нодой Solana: она поддерживает стандартные методы JSON-RPC и подписки по адресу /backtest/<session_id>. Среди них:

  • для чтения данных: getAccountInfo, getBalance, getMultipleAccounts

  • для подписки на изменения: accountSubscribe, programSubscribe, signatureSubscribe

Полный список поддерживаемых подписок есть в разделе Справочник API.

3

Как отправить свои транзакции

В симуляцию можно добавить собственные транзакции. Есть два способа, и разница между ними в том, когда транзакция исполнится.

  • Через RPC: Транзакция отправляется стандартным методом Solana sendTransaction и исполняется сразу, в текущем слоте, после исторических транзакций блока.

  • Через WebSocket.

    • Транзакции в кодировке base64 передаются вместе с запросом continue. Они исполняются одним пакетом, после чего симуляция переходит к следующему слоту.

    • Проще говоря: RPC подходит, чтобы действовать внутри текущего слота, а continue, чтобы отправить транзакции и сразу двигаться дальше.

Порядок исполнения внутри слота:

  1. Исторические транзакции блока

  2. Транзакции, отправленные через sendTransaction

  3. Транзакции из пакета в запросе continue

4

Как управлять симуляцией

Симуляция начинается со startSlot и дальше сама не двигается: к следующему слоту она переходит только по запросу continue. Так после каждого шага можно спокойно изучить состояние сети.

Что можно передать в continue:

  • advanceCount: сколько слотов пройти, прежде чем снова остановиться. По умолчанию 1.

  • transactions: свои транзакции для исполнения.

  • modifyAccountStates: изменения состояния аккаунтов, которые применятся до исполнения.

// via websocket to `/backtest/<session_id>`
{
  "method": "continue",
  "params": {
    "advanceCount": 1,
    "transactions": ["<base64_encoded_transaction>"],
    "modifyAccountStates": {
      "addr...": {
        "data": {
          "data": "<base64_bytes>",
          "encoding": "base64"
        },
        "executable": false,
        "lamports": 33594,
        "owner": "11111111111111111111111111111111",
        "space": 80
      }
    }
  }
}

Пока выполняется continue, сервер присылает сообщения status: по ним видно, на каком этапе сейчас симуляция. Например:

  • preparingBundle: собирается пакет транзакций

  • decodedTransactions: транзакции расшифрованы

  • appliedAccountModifications: изменения аккаунтов применены

  • executedBlockTransactions: транзакции блока исполнены

  • programAccountsLoaded: аккаунты программ загружены

Когда все готово, приходит readyForContinue: можно переходить к следующему слоту.

5

Повторное подключение к сессии

Если соединение случайно оборвалось, сессию не нужно создавать заново: достаточно снова подключиться к ней, пока не истекло время ожидания. Это время задается параметром disconnectTimeoutSecs при создании сессии.

Сервер хранит события подписок WebSocket за последние 100 слотов. Поэтому события, пропущенные во время обрыва, не потеряются, если с того момента прошло не больше 100 слотов.

// via websocket to `/backtest`
{
  "method": "attachBacktestSession",
  "params": {
    "sessionId": "<session_id>",
    "lastSequence": 42
  }
}

Параметр lastSequence необязательный. В нем указывается номер последнего полученного события, и тогда сервер пришлет только то, что было после него. Если параметр не указать, сервер заново пришлет все сохраненные события.

6

Как завершить сессию

// via websocket to `/backtest/<session_id>`
{
  "method": "closeBacktestSession"
}

В ответ сервер пришлет success и удалит сессию. Вернуться к ней после этого уже не получится.

На что обратить внимание при тестировании стратегий

  • Чтобы симуляция всегда стартовала одинаково, программы стоит загрузить заранее через preloadPrograms и дождаться статуса programAccountsLoaded. Только после этого отправлять первый continue.

  • Чтобы быстрее проверять варианты, можно проходить несколько слотов за один шаг: для этого advanceCount задается больше 1. Уведомления о каждом слоте при этом все равно приходят.

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

Последнее обновление