С чего начать
Как создать сессию
Каждая симуляция идет в рамках сессии. Чтобы ее начать, достаточно указать, какой отрезок истории проиграть.
startSlot/endSlot: с какого по какой слот проигрывать историю. Оба крайних слота входят в симуляцию.signerFilter(необязательно): адреса, чьи транзакции нужно убрать из истории. Например, чтобы исключить сделки своего бота и посмотреть, как рынок жил бы без них.disconnectTimeoutSecs(необязательно): если соединение оборвется, сессия не закроется сразу, а подождет переподключения. Здесь задается, сколько ждать: до 900 секунд, то есть 15 минут.
Для запроса нужен API-ключ: его передают в заголовке X-API-Key.
{
"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-соединение должно оставаться открытым. Если его закрыть, сессия завершится, а все состояние аккаунтов будет удалено: начинать придется заново.
Как получить данные аккаунтов
С сессией можно работать как с обычной нодой Solana: она поддерживает стандартные методы JSON-RPC и подписки по адресу /backtest/<session_id>. Среди них:
для чтения данных:
getAccountInfo,getBalance,getMultipleAccountsдля подписки на изменения:
accountSubscribe,programSubscribe,signatureSubscribe
Полный список поддерживаемых подписок есть в разделе Справочник API.
Как отправить свои транзакции
В симуляцию можно добавить собственные транзакции. Есть два способа, и разница между ними в том, когда транзакция исполнится.
Через RPC: Транзакция отправляется стандартным методом Solana
sendTransactionи исполняется сразу, в текущем слоте, после исторических транзакций блока.Через WebSocket.
Транзакции в кодировке base64 передаются вместе с запросом
continue. Они исполняются одним пакетом, после чего симуляция переходит к следующему слоту.Проще говоря: RPC подходит, чтобы действовать внутри текущего слота, а
continue, чтобы отправить транзакции и сразу двигаться дальше.
Порядок исполнения внутри слота:
Исторические транзакции блока
Транзакции, отправленные через
sendTransactionТранзакции из пакета в запросе
continue
Как управлять симуляцией
Симуляция начинается со startSlot и дальше сама не двигается: к следующему слоту она переходит только по запросу continue. Так после каждого шага можно спокойно изучить состояние сети.
Что можно передать в continue:
advanceCount: сколько слотов пройти, прежде чем снова остановиться. По умолчанию 1.transactions: свои транзакции для исполнения.modifyAccountStates: изменения состояния аккаунтов, которые применятся до исполнения.
{
"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: можно переходить к следующему слоту.
Повторное подключение к сессии
Если соединение случайно оборвалось, сессию не нужно создавать заново: достаточно снова подключиться к ней, пока не истекло время ожидания. Это время задается параметром disconnectTimeoutSecs при создании сессии.
Сервер хранит события подписок WebSocket за последние 100 слотов. Поэтому события, пропущенные во время обрыва, не потеряются, если с того момента прошло не больше 100 слотов.
{
"method": "attachBacktestSession",
"params": {
"sessionId": "<session_id>",
"lastSequence": 42
}
}Параметр lastSequence необязательный. В нем указывается номер последнего полученного события, и тогда сервер пришлет только то, что было после него. Если параметр не указать, сервер заново пришлет все сохраненные события.
На что обратить внимание при тестировании стратегий
Чтобы симуляция всегда стартовала одинаково, программы стоит загрузить заранее через
preloadProgramsи дождаться статусаprogramAccountsLoaded. Только после этого отправлять первыйcontinue.Чтобы быстрее проверять варианты, можно проходить несколько слотов за один шаг: для этого
advanceCountзадается больше 1. Уведомления о каждом слоте при этом все равно приходят.Проверка подписей отключена, поэтому транзакцию можно отправить от имени любого аккаунта, даже без его ключа. Это удобно, например, чтобы смоделировать действия крупного участника рынка.
Последнее обновление