HTTP API для управления ботом и тестером: настройки, стратегии, API-ключи бирж, позиции и ордера, логи, запуск тестера и работа с его отчётами. Адрес — тот же, что у веб-интерфейса: http://<хост>:<порт>, порт задаётся полем port в settings_program.json.
api_token бот создаёт сам при первом запуске и хранит в settings_program.json. Токен работает с любого адреса и при любом значении auth_telegram, и вход из браузера его не сбрасывает. Храните токен как пароль: с ним доступно всё, включая торговлю и ключи бирж.
Посмотреть и скопировать токен можно в веб-интерфейсе: «Глобальная конфигурация», блок «Токен API и MCP». Там же кнопка «Выпустить новый»; прежний токен сразу перестаёт действовать. При выключенном входе через Telegram этот блок работает только с этой же машины (127.0.0.1). В редакторе конфига, в логе и в ответе GET /api/settings/config токен скрыт (видны последние 4 символа), а через редактор и POST /api/settings/config его изменить нельзя.
Новый токен через API: POST /api/settings/api-token/regenerate, ответ { "success": true, "api_token": "..." }.
Если вход через Telegram выключен ("auth_telegram": false), запросы без токена принимаются только с этой же машины по адресу 127.0.0.1 или localhost:
curl http://127.0.0.1:5000/api/current/bots
С других адресов без токена API отвечает 401. Веб-интерфейс при выключенном входе по-прежнему открыт любому, кто может подключиться к порту, поэтому на сервере с открытым портом оставляйте вход включённым.
Запросы со страниц других сайтов (POST с заголовком Origin, не совпадающим с адресом бота) отклоняются с кодом 403 — это защита от CSRF. curl, скрипты и MCP-клиенты заголовок Origin не отправляют, их это не касается. Если бот стоит за обратным прокси, прокси должен передавать исходный заголовок Host.
Тело POST-запросов — JSON в кодировке UTF-8 (Content-Type: application/json).
Имена в пути URL-кодируются: стратегия T4 BTC → /api/settings/strategy/T4%20BTC.
Настройки и конфиги передаются и возвращаются в том же виде, что и в JSON-файлах бота.
Успешное действие возвращает { "success": true, ... }.
Ошибка возвращает { "success": false, "error": "текст ошибки" } с кодом из таблицы Коды ответов.
Бот определяется аккаунтом и именем стратегии: /{accountName}/{settingsName}. Если стратегия торгует несколькими парами, нужную пару выбирает параметр ?symbol=. Без него берётся первая.
Изменяет глобальный конфиг и сразу применяет его. Передавайте только поля, которые меняются, — остальные останутся как были. Токен Telegram-бота, api_token и tester_data_dir здесь не меняются: эти поля в теле игнорируются.
Описания полей настроек — те же подсказки, что показывает редактор настроек. {kind}:
settings — настройки стратегий (бота и тестера), для всех стратегий сразу;
config_tester — конфиг тестера, включая parameter_mining, walk_forward и столбцы reports_history.csv;
settings_program — глобальный конфиг.
Параметры:
?lang= — en (по умолчанию), ru или pt;
?filter= — только поля, в пути которых есть одна из подстрок через запятую, например ?filter=zigzag,close_by_margin.
200 Ответ
объект «путь поля через точку → описание»:
{
"parameter_mining": "List of parameters to mine. Each has a name (parameter path) and either a start/end/step range or a values list...",
"monte_carlo": "Mining limit: if there are more combinations than this number, a random sample of this size is used..."
}
sections — секции, которые читает стратегия; секции из ignored_sections она не читает. Общие секции (basic, options, filter, exchange) в списках не указаны.
position_filter — стратегия учитывает filter; поля filter.<имя>.* действуют, только когда filter.<имя>.use = true.
conditional_fields — поля, которые действуют только при условии. * в конце — все поля с этим началом.
notes — поля, которые влияют на результат только в крайних случаях (перебор по ним часто даёт одинаковые строки).
tester_ignores — поля, которых тестер не моделирует.
shared_fields — поля секции, которые читают и другие стратегии.
Поле без правила считается действующим. Те же правила дают предупреждения warnings при сохранении настроек и запуске тестера.
Черновик стратегии со значениями по умолчанию для выбранного аккаунта. Ничего не сохраняет: поправьте результат и отправьте в POST /api/settings/strategy.
Создаёт или изменяет стратегию. Тело — объект стратегии, как в GET /api/settings/strategy/{name}. Изменения сразу применяются к работающим ботам, новая стратегия сразу запускается.
?old_name= — переименовать стратегию old_name в имя из тела.
Создаёт стратегию бота из проверенной настройки тестера. Настройка копируется как есть; exchange.name и exchange.account берутся от аккаунта. По умолчанию стратегия создаётся на паузе (is_runing: false): бот её загружает, но не торгует, пока её не запустят (play).
Удаляет стратегию и останавливает её ботов. Ордера и позиция на бирже при этом не трогаются.
?full=1 — полное удаление: стратегия ставится на паузу, все её ордера отменяются, позиция закрывается, и только потом стратегия удаляется. Если отменить ордера или закрыть позицию не удалось, стратегия остаётся на паузе и не удаляется — позиция не останется без управления.
Как правильно отключить стратегию. Позиция и ордера на паузе остаются на бирже без управления стратегией (её стопов, тейков и выходов), поэтому их нельзя бросать. Порядок:
пауза;
снять ордера;
закрыть позицию;
удалить настройку.
?full=1 делает именно это: после паузы ждёт завершения текущего цикла бота, чтобы он не успел выставить новый ордер. Вручную — тот же порядок, и паузу пропускать нельзя: работающий бот выставит ордера заново сразу после отмены.
Запрос
POST /api/settings/strategy/T4%20BTC/delete?full=1
200 Ответ
{ "success": true }
Ошибки
404не найдена
409для full=1 стратегия должна быть запущена
500не удалось отменить ордера, закрыть позицию или удалить стратегию
Создаёт или изменяет аккаунт. Изменения сразу применяются к работающим ботам.
?old_name= — переименовать аккаунт old_name в имя из тела.
Ключи передаются открытым текстом. При "is_encrypted": true бот хранит их зашифрованными. Пустые api_key, api_secret, api_passphrase при изменении оставляют текущие значения; при смене is_encrypted ключ и секрет нужно передать заново.
is_runing: false — бот на паузе. position: null — позиции нет. orders — число открытых ордеров. sync_missed_cycles — сколько циклов подряд не удалось получить данные с биржи.
wallet — баланс кошелька, margin — маржинальный баланс, как их отдаёт биржа. Для спота оба значения — баланс в USDT. Баланс берётся у запущенных ботов: аккаунт без запущенного бота в список не попадает.
Полный снимок состояния всех ботов. Набор полей подробный и может меняться между версиями — для постоянной интеграции используйте GET /api/current/bots, /api/current/positions и /api/current/orders.
Ставит стратегию на паузу (для стратегии на несколько пар — все её пары): она перестаёт выставлять ордера. Открытая позиция и ордера остаются на бирже без управления стратегией — после паузы либо снова запустите её, либо снимите ордера и закройте позицию (см. удаление).
Удаляет стратегию бота и убирает бота из работы. Ордера и позиция на бирже не снимаются и остаются без управления. Для безопасного отключения используйте POST /api/settings/strategy/{name}/delete?full=1.
Версия программы, ресурсы сервера и счётчики. Поля pid, exe_path, working_directory, port (порт, на который пришёл запрос) и started_utc однозначно определяют экземпляр процесса: по ним внешний скрипт отличает несколько запущенных ботов и замечает перезапуск (меняются pid и started_utc).
Завершает программу. Доступно только при входе через Telegram. Сама программа не запустится: перезапуск процесса делает внешний супервизор (служба, systemd, скрипт). Проверить, что супервизор поднимает бота через 61 секунду после остановки (RestartSec=61, run_service.cmd), можно скриптом tools/check-shutdown-restart.ps1 (останавливает работающий бот). Инструмента restart_program нет. Он обычно и не нужен: изменения стратегий, аккаунтов и настроек через API применяются к работающим ботам сразу. Обновление с перезапуском — POST /api/system/update. После перезапуска убедитесь по pid и started_utc из /api/system/status, что поднялся новый процесс. Перед остановкой проверьте, что нет прогона тестера: он прервётся, а очередь не сохраняется.
200 Ответ
{ "success": true } — программа завершится через полсекунды
Ошибки за последние ?hours= часов (по умолчанию 24, не больше 48). ?warnings=1 — вместе с предупреждениями. Если Telegram не настроен (telegram.id_chat = 0), сообщения не отправляются и ошибок «chat not found» нет: в лог один раз за запуск пишется предупреждение Telegram chat is not set. Ошибка «chat not found» при заданном чате означает неверный id чата или токен. Повторы уже сгруппированы: одинаковые сообщения одного источника объединены в одну запись, count — сколько раз повторилось за всё хранимое окно (до 48 часов, с запуска программы), first_utc и last_utc — первое и последнее появление. Записи идут от свежих к старым.
?since= — время UTC (например 2026-11-02T06:00:00Z; без часового пояса считается UTC): вернутся только записи, повторявшиеся после него. Для проверки «что нового с прошлого раза» передайте самый поздний last_utc из предыдущего ответа. Если first_utc записи раньше since, это старая ошибка, которая случилась снова, а count остаётся общим. Неверная дата — 400.
Тестер прогоняет стратегии на исторических данных. Перебор параметров, стресс-тест и повтор по snapshot выполняются по одному. Одиночные прогоны можно запускать параллельно. Пока загружаются исторические данные, тестер не запускается, и наоборот — в этих случаях ответ 409.
Все запуски работают в фоне: ответ приходит сразу, ход и результат — в GET /api/tester/status.
run — перебор параметров, стресс-тест или повтор по snapshot. status: Idle, Running, Completed или Failed; runs_done / runs_total — сколько комбинаций параметров посчитано. report_folders — папки результатов текущего или последнего прогона внутри root=report; result_files — итоговые файлы, уже записанные в них с начала прогона: reports_history.csv, сводный HTML (report_optimizer_*, stress_test_*, walk_forward_*) и snapshot.
queue — запуски полного режима, ждущие своей очереди (?queue=1): queue_id, position, message, queued_utc.
wizard_runs — одиночные прогоны. Завершённые видны ещё час. Метрики (stats) здесь не передаются — они в /api/tester/wizard-runs/{run_id}. У прогонов пакета, ещё не начатых, status: "Queued".
batches — пакеты одиночных прогонов: batch_id, done из total.
Какие исторические данные уже скачаны: ?exchange= (обязательно), ?symbols=A,B (без него — все скачанные пары биржи), ?start=&end= — период для проверки.
gap_days — дни без данных между первым и последним. period есть только при start и end. Учитываются только скачанные файлы: недостающее докачивает сам прогон (UpdateData) или download-data.
Ошибки
400биржа не поддерживается или задан только один из start / end
Все запросы к настройкам тестера, запуски и загрузка данных принимают папку настроек: ?folder= в адресе или поле folder в теле запуска. Это путь внутри tester/settings_strategy, "" — основная папка. Без folder используется папка, выбранная в интерфейсе (POST /api/tester/settings-folder). Это общее состояние: его может сменить пользователь или параллельная задача, поэтому скриптам и ассистентам лучше всегда передавать folder.
У настройки могут быть необязательные поля tags (список меток) и owner (автор, например "MCP"). По ним настройки отбираются в списке и удаляются разом.
Сохраняет настройку тестера. Тело — объект настройки. ?old_name= — переименовать настройку old_name. Существующая настройка с тем же именем не перезаписывается. ?folder= — папка. ?owner_default= — значение owner, если в настройке его нет (MCP передаёт MCP).
warnings — изменённые (не как по умолчанию) поля, которые ни на что не влияют: секция другой стратегии (одна строка на секцию), поле другого zz.type, выключенный включатель use_*, basic.leverage (тестер плечо не моделирует) — см. /api/settings/schema. null — замечаний нет. Сохранение предупреждения не отменяют.
То же поле warnings есть в ответе копирования настройки, а у импорта — warnings по имени каждой настройки.
Копирует настройку тестера в той же папке (?folder=), при желании — на другую биржу или пару. ?owner_default= — как у сохранения. Скопировать в другую папку — copy-to-folder.
Какие настройки копировать — names (имена или маски), mask ("*" — все), tag, owner; фильтры сочетаются, нужен хотя бы один. on_conflict — что делать, если имя в папке назначения уже есть: skip (по умолчанию), replace или error (ничего не копировать).
config необязателен: без него используется сохранённый конфиг тестера.
overrides — правки настроек только на этот запуск; файлы настроек не меняются. Правила применяются по порядку. match — имя или маска (по умолчанию все), tag — только настройки с этим тегом. set заменяет значения, mul умножает числа (целое поле остаётся целым), cap_pct после них ограничивает basic.balance_percentage_long и _short этих настроек — множитель размера с потолком на пару: { "match": "T_*", "mul": { "basic.balance_percentage_long": 2, "basic.balance_percentage_short": 2 }, "cap_pct": 10 }. exclude: true убирает настройки из запуска. Поля — пути через точку, как в объекте настройки. Если поля нет ни в одной подходящей настройке, это ошибка (обычно опечатка); если его нет только у части, эти настройки перечислены в not_applied. Правки записываются в comment прогона и попадают в отчёт и snapshot.
Что можно перебирать. Любую настройку бота (settings[*].zz.depth, settings[T_*].basic.use_short, settings[NAME].…), любое поле конфига тестера (config_tester.…), settings_program.… и аккаунта. Для чисел достаточно start/end/step, для остальных (текст, логические) задаётся values.
Скрининг пар. Файл настроек на каждую пару не нужен: берётся одна настройка-шаблон, а символ перебирается как обычный параметр. Список пар — из tester_exchange_symbols:
Вместе с другими параметрами (например, settings[*].zz.depth) получается сетка на каждую пару. Символ попадает в столбец reports_history.csv, так что сводку «пара → медиана по сетке» считают по этому файлу (read_tester_file с columns). Данные для всех перебираемых пар скачивает tester_download_data. Число комбинаций равно произведению длин списков значений: ограничивайте его monte_carlo.
Тестер прогоняет все комбинации значений из parameter_mining; если задан monte_carlo, то случайную выборку такого размера. Заранее проверяйте число комбинаций; остановить запущенный перебор — POST /api/tester/stop с full: true. Ход — в run ответа GET /api/tester/status (runs_done из runs_total).
Результаты попадают в папку report с именем, равным name_comment конфига тестера (недопустимые в имени файла символы заменяются на _). Ответ на запуск возвращает её в report_folders; при включённом walk_forward там же вторая папка <name_comment>_WF_OOS с прогонами вне выборки. Чтобы эксперименты не смешивались, давайте каждому свой name_comment. В папке:
reports_history.csv — по строке на комбинацию: метрики (TotalPnLPercent, MaxDrawdownPercent, ProfitFactor, WinRate, TradingVolume, …), Strategies (имена настроек прогона через |), RunTag и столбец со значением каждого перебираемого параметра. При single_mode в каждой строке одна настройка, блоки комбинаций идут по имени настройки;
HTML-отчёт каждой комбинации (если включён report.enable_html_report) и его JSON-версия (если включён report.enable_json_report); RunTag комбинации есть в имени файла;
run_snapshot_<name_comment>_<время>.json — точные настройки и конфиг запуска, см. snapshot-run.
periods — перебор на нескольких периодах: [["2026-02-01","2026-05-01"], ["2026-05-01","2026-08-01"]]. Каждый период — отдельный полный прогон в папку <name_comment>_<начало>_<конец>; они идут друг за другом через очередь. Ответ — { "success": true, "periods": [ { "start", "end", "report_folders", "queued", "queue_id", "position" } ], ... }. Сравнить периоды — /api/tester/mining-robustness.
Предупреждения запуска. Ответ на запуск содержит warnings (null — замечаний нет):
параметр parameter_mining, которого нет ни в настройках, ни в конфигах (опечатка: он не применится);
перебираемое поле, которое подходящие настройки не читают (ignored by all N matching settings: все комбинации дадут одинаковый результат) или читают не все; условия по полям, которые сами перебираются, не проверяются;
заметка о поле, которое влияет только в крайних случаях (zz.zz6_risk_max);
поле из overrides, которое настройка не читает.
Предупреждения запуск не отменяют.
Одиночные прогоны и пакеты пишут эти предупреждения и в итоги прогона (warnings у wizard-runs/{run_id}), пакет — ещё и в общий warnings с префиксом runs[i] <имя>. Запуск по snapshot проверяется так же.
Портфельный перебор. Без single_mode все настройки идут вместе в каждой комбинации. Параметр с именем settings[ИМЯ].путь меняет одну настройку, а settings[T_*].путь — все настройки по маске имени; остальной набор остаётся как есть. Сравнивайте строки по портфельным MaxDrawdownPercent и UlcerIndex (включите reports_history.ulcer_index).
sides — стороны торговли на этот запуск: long (только лонг), short (только шорт), split (каждая настройка дважды — <имя> [long] и <имя> [short]; при single_mode стороны майнятся отдельно) или both (как в настройках).
?queue=1 — если тестер занят другим полным прогоном или загрузкой данных, запуск встаёт в очередь, а не получает 409. Ответ тогда — { "success": true, "queued": true, "queue_id": "63a8e791", "position": 1, ... }; запуск начнётся сам, очередь видна в queue ответа GET /api/tester/status, отменить ещё не начатый — POST /api/tester/queue/{queue_id}/cancel.
Ошибки
400настройка не найдена, неверный config, overrides или sides
404папка не найдена
409тестер уже работает или загружаются данные (без ?queue=1)
Стресс-тест: те же настройки в ухудшенных условиях исполнения. Тело, ?queue=1 и ответы — как у /api/tester/run, кроме periods (не поддерживается). Результаты — в папке <name_comment>_STRESS (report_folders ответа): строки сценариев в reports_history.csv и сравнение с базой в stress_test_*.html.
Дождаться прогона и получить его метрики и пути к отчётам — GET /api/tester/wizard-runs/{run_id}?wait=. Ход всех прогонов — в wizard_runs ответа GET /api/tester/status.
Пакет одиночных прогонов: несколько наборов, каждый на нескольких периодах, через одну очередь с ограничением параллельности. Так сравнивают варианты и проверяют вариант на нескольких периодах одним запросом.
Поля набора — как в теле /api/tester/run (settings, folder, config, overrides, sides) плюс name и свои periods. Чего нет в наборе, берётся из пакета. Каждый набор идёт на каждом периоде отдельным прогоном; без periods — на периоде конфига. parallel — сколько прогонов одновременно (по умолчанию 2; каждый держит свои данные в памяти). Ошибка в любом наборе отклоняет весь пакет.
Пакет и итоги каждого прогона. ?wait= — сколько секунд (до 240) ждать завершения всего пакета.
Длинный пакет (десятки прогонов) в полном виде не помещается в ответ (MCP режет его на 200 000 символов, и JSON становится невалидным), поэтому есть сокращение и страницы. Те же параметры у POST /api/tester/wizard-batch:
Параметр
Описание
compact=1
у каждого прогона только name, start, end, run_id, status, run_params, key и пути отчёта (message только у упавших). Без summary, stats, warnings, applied
offset, limit
страница списка runs; limit=0 — только счётчики. В ответе offset, returned и has_more (есть следующая страница: offset + returned). done, total, failed всегда по всему пакету
Если полный ответ длиннее 150 000 символов, он заменяется компактным автоматически (compact: true в ответе); страницы offset/limit при этом сохраняются.
key есть в каждом прогоне, в том числе в полном ответе: главные метрики в одном виде, из summary JSON-отчёта, а если отчёта нет, из итоговых stats: pnl, pnl_percent, max_drawdown_percent, max_drawdown_worst_percent (только при JSON-отчёте), trades, volume, fees, profit_factor (только при JSON-отчёте). Вызывать reports/json на каждый прогон ради них не нужно.
summary — как раздел summaryJSON-отчёта; он есть, если включён report.enable_json_report, иначе вместо него stats. Строки прогонов пакета попадают и в reports_history.csv папки name_comment (столбцы StartDate, EndDate, Strategies). Пакеты хранятся час.
Ошибки
404пакета нет: неверный batch_id, прошло больше часа или программа перезапускалась
batch_id — все прогоны пакета: ещё не начатые не стартуют;
full: true — текущий полный прогон: перебор, стресс-тест, walk-forward, snapshot;
clear_queue: true — ещё и убрать из очереди не начатые полные прогоны.
Идущий прогон останавливается на следующей свече. Прерванный прогон не пишет ни отчёт, ни строку reports_history: результат за часть периода ввёл бы в заблуждение. У полного прогона строки уже посчитанных комбинаций остаются; в параллельном режиме дочерние процессы завершаются. Статусы: полный прогон — Stopped в run ответа /api/tester/status, одиночный — Cancelled в wizard-runs/{run_id}. Загрузку исторических данных этот запрос не останавливает.
status — Running, Completed или Failed; Running после wait значит, что время ожидания вышло, — запросите снова. report_path и report_json_path — пути внутри root=report, null, если отчёт не записан. snapshot_path — snapshot прогона: точные настройки и конфиг, с которыми он шёл. warnings — пропущенные настройки, нехватка данных и причина, по которой нет отчёта. Если не запустилась ни одна настройка, прогон завершается со status: "Failed" и причиной в message. Завершённые прогоны хранятся час (до перезапуска программы).
Ошибки
404прогона нет: неверный run_id, прошло больше часа или программа перезапускалась
Повторяет прогон по snapshot-файлу. Каждый запуск сохраняет snapshot рядом с отчётом — run_snapshot_<name_comment>_<время>.json с разделами settings (настройки всех стратегий), tester_config и program_config. Токены (api_token, telegram.bot_token) в snapshot не записываются. Запуск по snapshot — полный режим: один за раз, как перебор. Файл выбирается параметрами ?root=&path=, как в файлах тестера.
Тело необязательно: можно передать изменённый snapshot — изменения действуют только на этот запуск, файл не меняется. То же в интерфейсе: Тестер, вкладка «Результаты (файлы)», кнопка «Запустить» рядом со snapshot открывает его в редакторе, и правки идут только в этот запуск.
Запрос
POST /api/tester/snapshot-run?root=report&path=T4/run_snapshot_20261025.json
?queue=1 — встать в очередь, если тестер занят, как у /api/tester/run.
Загружает исторические данные для всех настроек папки (?folder=). Ход и итог — в download ответа GET /api/tester/status.
Параметр
Описание
start
Начало периода, например 2026-05-01. По умолчанию StartDate конфига тестера минус WarmupDays
end
Конец периода. По умолчанию текущий момент (UTC). EndDate сохранённого конфига не используется, поэтому для докачки свежих дней конфиг менять не нужно
200 Ответ
{ "success": true }
После окончания download.message кратко пишет, по какой день данные есть на диске, а download.result содержит по каждой паре first_day, last_day (последний день со свечами) и days:
"download": {
"active": false, "status": "Completed", "message": "Data on disk ends at 2026-10-31..2026-10-31 (last day with candles)",
"result": { "requested_start": null, "requested_end": null,
"pairs": [ { "symbol": "BTCUSDT", "exchange": "bybit", "first_day": "2025-10-01", "last_day": "2026-10-31", "days": 396 } ] }
}
Свечи закрытого дня источник публикует с задержкой (обычно после 06:00 UTC): до этого last_day остаётся на день раньше, загрузку нужно повторить позже. Пара без данных получает first_day/last_day = null.
Ошибки
400start или end не дата, либо start не раньше end
Результаты одиночных прогонов, свежие первыми. Новый прогон того же набора настроек заменяет его прежнюю запись; результат конкретного прогона — в /api/tester/wizard-runs/{run_id}.
chartUrl — ссылка на HTML-отчёт для браузера. report_path — тот же отчёт как путь внутри root=report, для файлов тестера и /api/tester/reports/summary. report_json_path — его JSON-версия; поле есть, только если она записана.
Содержимое папки тестера. ?root= — report (отчёты, по умолчанию), data (исторические данные: tester/data или папка из tester_data_dir в settings_program.json) или runs (наборы для повторных прогонов); ?path= — путь внутри неё. ?contains= — только имена с этим текстом, ?offset= и ?limit= — часть списка. Сначала идут папки по имени, затем файлы, свежие первыми; total — сколько всего элементов подходит.
Сохраняет JSON-файл в runs (?root=runs&path=): изменяет существующий или создаёт новый. Тело — новое содержимое файла. Если у существующего файла в теле нет раздела settings, он берётся из текущего файла. Новый файл должен быть полным snapshot: непустой settings и tester_config.
Так готовят прогон для пользователя: в интерфейсе (Тестер, вкладка «Результаты (файлы)», папка runs) у каждого такого файла есть кнопки «Запустить» и «Изменить». При use_runs в конфиге тестера полный прогон из командной строки (--run-tester) запускает все .json из runs.
200 Ответ
{ "success": true, "created": false }
Ошибки
400пустое тело, неверный JSON или новый файл без settings / tester_config
Подробные результаты одного прогона в компактном JSON. Те же числа, что в HTML-отчёте, но файл в десятки раз меньше: несколько десятков килобайт вместо мегабайтов.
Тестер пишет <отчёт>.json рядом с HTML-отчётом, если в конфиге тестера включено report.enable_json_report (по умолчанию выключено). JSON пишется и при выключенном report.enable_html_report: так большой перебор идёт быстрее и всё равно сохраняет детали каждой комбинации.
Параметры:
?path= — путь отчёта в report: файл .json или его .html (например, report_path из wizard-results);
?sections= — только эти разделы через запятую, например ?sections=summary или ?sections=metrics,by_symbol;
?trades_offset= и ?trades_limit= — часть сделок.
Разделы:
Раздел
Содержимое
summary
сводка на 1–2 КБ: PnL, просадки (в том числе нереализованная и худшая из трёх, как MaxDrawdownPercent в reports_history.csv), Ulcer Index, profit factor, Sharpe, CAGR, сделки, win rate, комиссии, средняя и максимальная позиция, худший месяц, доходность по месяцам. Считается при чтении из run, metrics и monthly, поэтому есть и у старых отчётов
run
name_comment, comment, run_tag, run_params (значения перебираемых параметров), период, биржи, стратегии и пары. Что запуск дописал в comment текстом ([overrides: …], [sides: …]), лежит отдельными полями, разбирать comment регуляркой не нужно: overrides (массив правил как в запросе, без обрезки, в comment он обрезается до 300 символов), sides, а также откуда прогон: batch_id и name (имя набора) для tester_run_batch и tester_run_single с periods, run_id для прогонов мастера. Если значения нет, поле null. Запуски из интерфейса эти поля не заполняют, повтор по snapshot берёт их из snapshot
metrics
вся таблица статистики HTML-отчёта по блокам: PnL, баланс, доходность по месяцам, сделки, исполнения, Buy & Hold, риск и экспозиция, Sharpe, Sortino, CAGR, Calmar, Ulcer Index…
by_symbol
итоги по каждой паре: сделки, win rate, profit factor, PnL, лучшая и худшая сделка, просадка, Buy & Hold, комиссии, объём, размер позиции
monthly
доходность по месяцам, %: { "2025-09": -4.15 }
trades
сделки (от открытия позиции до полного закрытия или переворота), отсортированные по времени закрытия, — columns и rows
curves
кривые баланса (equity) и открытых позиций (open_positions_total, _long, _short), до 500 точек; t — Unix-время в секундах, v — значения
daily
значения на конец каждого календарного дня периода, без пропусков: days, equity (Margin-баланс), position (открытая позиция, USDT); strategies — стратегии (настройки) с парами, кодом, типом (trend / counter-trend) и тегами; pnl и position_by_strategy — по массиву на стратегию в том же порядке: накопленный с начала отчёта вклад в баланс и позиция. Пишется при report.json_daily (включено по умолчанию). Для больших наборов раздел большой — сводку по нему даёт /api/tester/reports/portfolio
settings
полные настройки стратегий прогона
Поля v (версия формата), created_utc и html_report (имя HTML-отчёта или null) возвращаются всегда.
Запрос
GET /api/tester/reports/json?path=T4/T4_run_001_of_001_BTCUSDT_1h_ee8c3c2e.html§ions=by_symbol,trades&trades_limit=2
В trades: count — число всех сделок, net_pnl — результат сделки за вычетом комиссий, mae и mfe — худший и лучший промежуточный результат сделки (USDT), время — UTC.
Портфельная аналитика прогона по разделу daily его JSON-отчёта. Стратегии собираются в группы, по группам считается всё, что ниже.
Параметры:
?path= — JSON-отчёт (или его .html) в report;
?group_by= — type (по умолчанию: T — трендовые, CT — контртрендовые, по коду стратегии), tag (первый тег настройки) или strategy (каждая настройка — своя группа);
?groups={"T":"T_*","CT":"CT_*"} — группы по маскам имён вместо group_by; настройки без совпадения попадают в other;
?worst_days= — сколько худших дней каждой группы брать (по умолчанию 10);
?curves=0, ?leave_one_out=0 — не считать эти разделы.
worst_week — худшие 7 дней подряд для портфеля и PnL каждой группы в них;
worst_days — для каждой группы её худшие дни: её PnL, PnL портфеля и PnL остальных групп в эти же дни; offset_percent — какую долю убытка отыграла другая группа (меньше нуля — добавила убыток);
leave_one_out — максимальная просадка и Ulcer портфеля без каждой стратегии и без каждой группы: drawdown_added больше нуля — стратегия добавляет просадку, меньше нуля — снижает её (хеджирует). Заменяет отдельный прогон набора без каждой стратегии;
curves — дневные кривые без пропусков: баланс, позиция, накопленный PnL и позиция каждой группы.
Все величины — по значениям на конец дня: просадки здесь меньше внутридневных из metrics, а leave_one_out приближённый — без влияния стратегий друг на друга через маржу и лимиты позиций.
Ошибки
400у отчёта нет раздела daily (нужны report.enable_json_report и report.json_daily; у старых отчётов его нет) или неверные group_by / groups
Устойчивость перебора на нескольких периодах: одна и та же сетка parameter_mining, прогнанная на каждом периоде в свою папку (periods у /api/tester/run).
Параметры:
?folders=a,b — папки в report, по периоду в каждой;
?metric= — столбец reports_history.csv, по умолчанию TotalPnLPercent; столбцы просадки, риска и UlcerIndex — чем меньше, тем лучше;
?base={"settings[*].zz.depth": 12} — исходная точка для сравнения;
?top= — сколько комбинаций показать на каждую настройку (по умолчанию 10).
Комбинации сопоставляются по значениям параметров и столбцу Strategies (при single_mode у каждой настройки свой рейтинг). На каждом периоде считается плато — среднее метрики по комбинации и её соседям на сетке (как в разделе устойчивости отчёта оптимизатора). Рейтинг — по среднему плато периодов, затем по худшему периоду.
best_by_period — лучшая точка каждого периода и её место в общем рейтинге: низкое место значит, что точка подогнана под свой период. beats_base — комбинация не хуже базовой ни на одном периоде.
Ошибки
400меньше двух папок, нет столбца метрики или слишком мало комбинаций для соседей
Отправляет файл отчёта тестера в Telegram — в чат уведомлений тестера (telegram.id_chat конфига программы, туда же приходят итоги переборов). Отправить можно только файл из report (.html, .json, .csv, .png, .txt, до 50 МБ); к торговле и чатам стратегий доступа нет. Подпись — Tester report: <путь> и caption.
Запрос
{ "path": "T4/T4_BTCUSDT_20261025.html", "caption": "Лучший вариант по просадке" }