Logo hamster-bot
RU EN PT

Загрузка…

API и MCP

Управление ботом из скриптов, программ и ИИ-ассистентов

HTTP API для управления ботом и тестером: настройки, стратегии, API-ключи бирж, позиции и ордера, логи, запуск тестера и работа с его отчётами. Бот также работает как MCP-сервер — ИИ-ассистент может сам смотреть состояние бота, вести исследования в тестере и управлять стратегиями.

Адрес — тот же, что у веб-интерфейса: http://<хост>:<порт>. Порт задаётся полем port в settings_program.json.

Доступ Запросы и ответы Эндпоинты Тестер MCP для ИИ-ассистентов Коды ответов

Доступ

Токен API (рекомендуется)

Передавайте в каждом запросе заголовок Authorization: Bearer <api_token>:

curl -H "Authorization: Bearer <api_token>" http://127.0.0.1:5000/api/current/bots

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.

Cookie входа

Вместо токена можно передавать cookie hamster-bot-token, если вход через Telegram включён:

  1. POST /htmx/login/get-token — бот присылает одноразовый код в Telegram.
  2. POST /htmx/login/verify с формой token_enter=<код> — в ответе приходит заголовок Set-Cookie: hamster-bot-token=...
  3. Передавайте cookie в запросах: curl -b "hamster-bot-token=<значение>" ...

Cookie действует до 10 дней. Действует только последний вход: новый вход (в том числе из браузера) делает прежний cookie недействительным.

Запросы и ответы

  • Тело 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=, без него берётся первая.

Пример: создать стратегию из черновика со значениями по умолчанию.

curl -X POST http://127.0.0.1:5000/api/settings/strategy/draft \
  -H "Content-Type: application/json" \
  -d '{ "account": "main", "symbol": "BTCUSDT", "strategy": "zigzag", "time_frame": "1h" }'

Черновик ничего не сохраняет: поправьте полученный объект и отправьте его в POST /api/settings/strategy — стратегия сохранится и сразу запустится.

curl -X POST http://127.0.0.1:5000/api/bots/main/T4%20BTC/pause
{ "success": true, "name": "T4 BTC", "is_runing": false }

Эндпоинты

Под описанием эндпоинта — свёрнутый пример запроса и ответа.

Настройки

GET/api/settings/configГлобальный конфиг (settings_program.json). Токен Telegram-бота замаскирован: видны первые 4 символа. api_token замаскирован: видны последние 4 символа
Пример
{
  "name": "MyBot",
  "use_web": true,
  "port": 5000,
  "api_token": "••••••••••••b9c2",
  "telegram": {
    "bot_token": "1234************",
    "id_chat": 123456789
  }
}
POST/api/settings/configИзменить конфиг: передайте только меняющиеся поля, применяется сразу. Токен Telegram-бота и api_token здесь не меняются: эти поля в теле игнорируются
Пример

Запрос:

{ "name": "MyBot", "chart": { "count": 500 } }

Ответ:

{ "success": true }
POST/api/settings/api-token/regenerateВыпустить новый api_token, прежний сразу перестаёт действовать. Единственный ответ API, в котором токен виден целиком. Тело не нужно
Пример
{ "success": true, "api_token": "<новый токен>" }
GET/api/settings/hints/{kind}Описания полей настроек: settings, config_tester, settings_program. Параметры ?lang= (en, ru, pt), ?filter=
Пример

Запрос:

GET /api/settings/hints/config_tester?filter=parameter_mining,monte_carlo

Ответ — объект «путь поля через точку → описание»:

{
  "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..."
}

Стратегии

GET/api/settings/strategyВсе стратегии бота
Пример
[
  {
    "name": "T4 BTC",
    "is_runing": true,
    "exchange": { "name": "binance", "account": "main" },
    "basic": { "symbol": "BTCUSDT", "strategy": "zigzag", "time_frame": "1h" }
  }
]
GET/api/settings/strategy/{name}Одна стратегия по имени (без учёта регистра)
POST/api/settings/strategy/draftЧерновик со значениями по умолчанию для аккаунта, ничего не сохраняет
Пример

Запрос:

{ "account": "main", "symbol": "BTCUSDT", "strategy": "zigzag", "time_frame": "1h", "account_type": "UNIFIED" }

Вместо symbol можно передать symbols: ["BTCUSDT", "ETHUSDT"] — стратегия на несколько пар. time_frame (по умолчанию 1h) и account_type необязательны. Ответ — объект стратегии.

POST/api/settings/strategyСоздать или изменить стратегию, изменения сразу применяются. ?old_name= — переименовать
Пример

Запрос (тело — объект стратегии):

POST /api/settings/strategy?old_name=T4%20BTC

Ответ (created: true — стратегия новая):

{ "success": true, "name": "T4 BTC v2", "created": false }
POST/api/settings/strategy/{name}/copyКопия под новым именем, сохраняется и запускается
Пример

Запрос (new_symbol необязателен):

{ "new_name": "T4 ETH", "new_symbol": "ETHUSDT" }

Ответ:

{ "success": true, "name": "T4 ETH" }
POST/api/settings/strategy/{name}/deleteУдалить стратегию, ордера и позиция не трогаются. ?full=1 — сначала отменить ордера и закрыть позицию
Пример

Запрос:

POST /api/settings/strategy/T4%20BTC/delete?full=1

Ответ:

{ "success": true }

Если при full=1 отменить ордера или закрыть позицию не удалось, стратегия остаётся на паузе и не удаляется — позиция не останется без управления.

Аккаунты (API-ключи бирж)

GET/api/settings/accountsВсе аккаунты
Пример
[
  {
    "name": "main",
    "exchange": "binance",
    "api_key": "...",
    "api_secret": "...",
    "is_encrypted": true
  }
]
GET/api/settings/accounts/{name}Один аккаунт
GET/api/settings/accounts/{name}/symbolsПары, доступные на бирже для аккаунта
Пример
["BTCUSDT", "ETHUSDT"]
POST/api/settings/accountsСоздать или изменить аккаунт, ключи передаются открытым текстом. ?old_name= — переименовать
Пример

Запрос:

{ "name": "main", "exchange": "binance", "api_key": "...", "api_secret": "...", "is_encrypted": true, "open_positions_limiter": 0 }

Ответ (applied — сколько работающих ботов получили новый ключ):

{ "success": true, "name": "main", "applied": 3 }

При "is_encrypted": true бот хранит ключи зашифрованными. Пустые api_key, api_secret, api_passphrase при изменении оставляют текущие значения; при смене is_encrypted ключ и секрет нужно передать заново.

POST/api/settings/accounts/{name}/deleteУдалить аккаунт
GET/api/current/accounts/{name}/infoДанные аккаунта и ключа с биржи, обновляются раз в час (нужен запущенный бот на аккаунте)
Пример
{
  "name": "main",
  "exchange": "binance",
  "api_key": "abc1****",
  "account_type": "UNIFIED",
  "symbol": "BTCUSDT",
  "ok": true,
  "status": "OK",
  "warnings": [],
  "rows": [ { "name": "Permissions", "value": "..." } ],
  "updated_utc": "2026-10-25T12:00:00Z"
}
GET/api/current/accounts/{name}/balance-historyИстория баланса, ?max= — не больше стольких точек (по умолчанию 5000)
Пример
{
  "account": "main",
  "total": 12000,
  "points": [ { "time": 1761393600, "margin": 1234.5, "wallet": 1200.0, "positions": "..." } ]
}

time — Unix-время в секундах, total — сколько точек всего в истории.

POST/api/current/accounts/{name}/balance-history/compactСжать историю баланса сейчас по настройкам monitoring
Пример
{ "success": true, "message": "...", "points_before": 12000, "points_after": 3000, "bytes_before": 512000, "bytes_after": 128000 }

Боты

GET/api/current/botsСводка по всем ботам: статус, цена, позиция, число ордеров, синхронизация с биржей
Пример
[
  {
    "account": "main",
    "exchange": "binance",
    "strategy": "T4 BTC",
    "strategy_code": "zigzag",
    "symbol": "BTCUSDT",
    "time_frame": "1h",
    "is_runing": true,
    "is_live": true,
    "status_text": "...",
    "last_price": 65500.0,
    "last_bar_time": "2026-10-25T12:00:00",
    "last_sync_utc": "2026-10-25T12:00:05Z",
    "sync_missed_cycles": 0,
    "position": { "side": "Buy", "size": 0.01, "entry_price": 65000.0, "cost": 650.0, "unrealized_pnl": 5.0 },
    "orders": 2
  }
]

is_runing: false — бот на паузе. position: null — позиции нет. orders — число открытых ордеров. sync_missed_cycles — сколько циклов подряд не удалось получить данные с биржи.

GET/api/current/balancesБаланс кошелька и маржи по ключам, отдельно спот и фьючерсы. ?account=
Пример

Запрос:

GET /api/current/balances?account=main

Ответ:

[
  { "account": "main", "exchange": "bybit", "type": "futures", "wallet": 1234.56, "margin": 1180.20 },
  { "account": "main", "exchange": "bybit", "type": "spot", "wallet": 500.00, "margin": 500.00 }
]

Для спота оба значения — баланс в USDT. Баланс берётся у запущенных ботов: аккаунт без запущенного бота в список не попадает.

GET/api/current/bots/{accountName}/{settingsName}/barsСвечи бота, ?limit= — последние N (по умолчанию 500)
Пример

Запрос:

GET /api/current/bots/main/T4%20BTC/bars?limit=100

Ответ — массив свечей с полями Timestamp, Open, High, Low, Close, Volume и др.

GET/api/current/ubots
/api/current/ubots/{accountName}/{settingsName}
Полный снимок состояния. Формат может меняться между версиями — для постоянной интеграции используйте bots, positions, orders
POST/api/bots/pause-all
/api/bots/play-all
Пауза / запуск всех ботов
Пример
{ "success": true, "count": 5 }
POST/api/bots/{accountName}/{settingsName}/pause
/api/bots/{accountName}/{settingsName}/play
Пауза / запуск стратегии (для стратегии на несколько пар — все её пары)
Пример

Запрос:

POST /api/bots/main/T4%20BTC/pause

Ответ (для play — "is_runing": true):

{ "success": true, "name": "T4 BTC", "is_runing": false }
POST/api/bots/{accountName}/{settingsName}/send-chartОтправить график бота в Telegram
POST/api/bots/{accountName}/{settingsName}/send-positionОтправить в Telegram сводку: баланс, позиция, PnL, ордера

Позиции и ордера

GET/api/current/positionsПозиции всех ботов
Пример
[
  {
    "account": "main",
    "exchange": "binance",
    "strategy": "T4 BTC",
    "symbol": "BTCUSDT",
    "position": {
      "Symbol": "BTCUSDT",
      "Side": "Buy",
      "Size": 0.01,
      "EntryPrice": 65000.0,
      "Cost": 650.0,
      "UnrealizedPnl": 12.5,
      "Leverage": 10,
      "Cross": false
    }
  },
  {
    "account": "sub1",
    "exchange": "binance",
    "strategy": "T3 ETH",
    "symbol": "ETHUSDT",
    "position": null
  }
]
GET/api/current/ordersОткрытые ордера всех ботов
Пример
[
  {
    "account": "main",
    "exchange": "binance",
    "strategy": "T4 BTC",
    "symbol": "BTCUSDT",
    "order": {
      "Id": "order-123",
      "client_id": "cl-456",
      "Market": "BTCUSDT",
      "Side": "Buy",
      "Type": "Limit",
      "Status": "New",
      "Size": 0.01,
      "filledSize": 0.0,
      "remainingSize": 0.01,
      "Price": 64000.0,
      "TriggerPrice": null,
      "ReduceOnly": false
    }
  }
]
POST/api/trading/marketРыночный ордер на аккаунте. Пара должна торговаться одним из ботов этого аккаунта
Пример

Запрос (side — Buy или Sell; size — объём в единицах биржи):

{ "account": "main", "symbol": "BTCUSDT", "side": "Buy", "size": 0.01 }

Ответ:

{ "success": true, "order_id": "order-123" }
POST/api/positions/{accountName}/{settingsName}/closeЗакрыть позицию бота
Пример

Запрос:

POST /api/positions/main/T4%20BTC/close

Ответ:

{ "success": true }
POST/api/positions/{accountName}/close-allЗакрыть все позиции аккаунта
Пример
{ "success": true, "count": 3 }

count — сколько позиций отправлено на закрытие.

POST/api/positions/{accountName}/reduceСократить все позиции аккаунта на percent (1–100)
Пример

Запрос:

{ "percent": 50 }

Ответ:

{ "success": true, "count": 3 }
POST/api/orders/{accountName}/{settingsName}/{orderId}/cancelОтменить один ордер (обычный или стоп-ордер)
Пример

Запрос:

POST /api/orders/main/T4%20BTC/order-123/cancel

Ответ:

{ "success": true }
POST/api/orders/{accountName}/cancel-allОтменить все ордера аккаунта
Пример
{ "success": true, "count": 2 }

count — у скольких ботов отменены ордера.

POST/api/orders/cancel-allОтменить все ордера на всех аккаунтах
Пример
{ "success": true, "count": 7 }

Система и логи

GET/api/system/statusВерсия программы, ресурсы сервера, счётчики ботов
Пример
{
  "program": "hamster-bot",
  "version": "2026/10/23",
  "name": "MyBot",
  "type": "bot",
  "os": "Linux 6.1",
  "architecture": "X64",
  "machine": "srv1",
  "runtime": ".NET 8.0",
  "processors": 4,
  "uptime_sec": 86400,
  "cpu_percent": 12.5,
  "memory_total_bytes": 8589934592,
  "memory_available_bytes": 4294967296,
  "process_memory_bytes": 314572800,
  "disk": "/",
  "disk_total_bytes": 107374182400,
  "disk_free_bytes": 53687091200,
  "accounts": 2,
  "strategies": 5,
  "bots": 6,
  "bots_running": 5,
  "auto_update_supported": true
}
POST/api/system/shutdownЗавершить программу (только при входе через Telegram)
POST/api/system/updateЗапустить обновление программы (см. auto_update_supported в статусе)
GET/api/logsПоследние строки общего лога (массив строк), ?tail=
GET/api/logs/errorsОшибки за ?hours= часов (по умолчанию 24, до 48), ?warnings=1 — с предупреждениями
Пример
[
  {
    "level": "Error",
    "first_utc": "2026-10-25T08:00:00Z",
    "last_utc": "2026-10-25T12:00:00Z",
    "count": 3,
    "source": "T4 BTC",
    "message": "...",
    "exception": "..."
  }
]

Одинаковые сообщения объединены, count — сколько раз повторилось.

GET/api/logs/filesФайлы логов, свежие первыми
Пример
[ { "name": "log_25-10-2026.log", "size": 102400, "modified_utc": "2026-10-25T12:00:00Z" } ]
GET/api/logs/files/{filename}Содержимое файла лога как текст, ?download=1 — скачать

Тестер

GET/api/tester/statusСостояние тестера: прогоны, одиночные прогоны, загрузка данных
Пример
{
  "run": {
    "active": true,
    "status": "Running",
    "started_utc": "2026-10-25T12:00:00Z",
    "finished_utc": null,
    "message": "API mining run",
    "runs_done": 40,
    "runs_total": 120,
    "current_bar": 5000,
    "total_bars": 20000,
    "parallel": false
  },
  "wizard_runs": [
    {
      "run_id": "a1b2c3d4",
      "strategies": ["T4 BTC"],
      "status": "Completed",
      "started_utc": "2026-10-25T11:00:00Z",
      "finished_utc": "2026-10-25T11:02:00Z",
      "current_bar": 20000,
      "total_bars": 20000,
      "message": "Completed: 1 strategies."
    }
  ],
  "download": { "active": false, "status": "Idle", "started_utc": null, "finished_utc": null, "message": "" },
  "settings_folder": ""
}

run — перебор параметров, стресс-тест или повтор по snapshot; status: Idle, Running, Completed или Failed; runs_done / runs_total — сколько комбинаций посчитано. wizard_runs — одиночные прогоны, завершённые видны ещё 5 минут. download — загрузка исторических данных. settings_folder — текущая папка настроек тестера.

GET POST/api/tester/configКонфиг тестера (config_tester.json): период, комиссии, параметры перебора. POST — конфиг целиком
GET/api/tester/exchanges
/api/tester/exchanges/{exchange}/symbols
Биржи с историческими данными и их пары. Пустой список пар — биржа сейчас недоступна
Пример
["bybit", "binance", ...]
GET/api/tester/settings
/api/tester/settings/{name}
Настройки стратегий тестера в текущей папке
Пример
[ { "name": "T4 BTC", "exchange": "bybit", "symbol": "BTCUSDT", "symbols": null, "strategy": "zigzag", "time_frame": "1h" } ]
POST/api/tester/settings/draftЧерновик настройки, ничего не сохраняет
Пример

Запрос:

{ "exchange": "bybit", "symbol": "BTCUSDT", "strategy": "zigzag", "time_frame": "1h" }

Вместо symbol можно передать symbols — несколько пар. account_type необязателен. Ответ — объект настройки.

POST/api/tester/settingsСохранить настройку, ?old_name= — переименовать. Существующая с тем же именем не перезаписывается
Пример
{ "success": true, "name": "T4 BTC" }
POST/api/tester/settings/{name}/copy
/api/tester/settings/{name}/delete
Копировать (можно на другую биржу или пару) / удалить
Пример

Запрос copy (пустые new_exchange и new_symbol оставляют значения исходной настройки):

{ "new_name": "T4 BTC binance", "new_exchange": "binance", "new_symbol": "" }

Ответ:

{ "success": true, "name": "T4 BTC binance" }
GET POST/api/tester/settings-folderТекущая папка настроек тестера и выбор другой ("" — основная папка)
Пример

GET — ответ (settings — сколько настроек в папке):

{ "path": "", "folders": [ { "name": "2026-10", "settings": 12 } ] }

POST — запрос:

{ "path": "2026-10" }

POST — ответ:

{ "success": true, "path": "2026-10" }
POST/api/tester/runПеребор параметров (parameter_mining)
Пример

Запрос (config необязателен — без него используется сохранённый конфиг тестера):

{ "settings": ["T4 BTC", "T4 ETH"], "config": { ... } }

Ответ:

{ "success": true }
POST/api/tester/stressСтресс-тест: те же настройки в ухудшенных условиях исполнения. Тело и ответы — как у /api/tester/run
POST/api/tester/wizard-runОдиночный прогон. Тело — как у /api/tester/run
Пример
{ "success": true, "run_id": "a1b2c3d4" }

Ход прогона — в wizard_runs статуса тестера по run_id, метрики — в wizard-results.

POST/api/tester/snapshot-runПовтор прогона по snapshot-файлу (?root=&path=). Тело необязательно: изменённый snapshot действует только на этот запуск
Пример
POST /api/tester/snapshot-run?root=report&path=T4/run_snapshot_20261025.json
POST/api/tester/download-dataЗагрузить исторические данные для всех настроек тестера
GET/api/tester/wizard-resultsРезультаты одиночных прогонов, свежие первыми: метрики и пути к отчётам
Пример
[
  {
    "runId": "a82c93c5",
    "timestamp": "2026-10-25T05:26:50Z",
    "strategies": ["T4 BTC"],
    "stats": {
      "InitialBalance": 10000.0, "FinalBalance": 9581.25, "TotalPnL": -418.75, "TotalPnLPercent": -4.19,
      "TotalTrades": 23, "WinRate": 13.04, "MaxDrawdown": 527.89, "MaxDrawdownPercent": 5.26, "TotalFees": 22.2
    },
    "chartUrl": "/tester-report/T4/T4_run_001_of_001_BTCUSDT_1h_ee8c3c2e.html",
    "report_path": "T4/T4_run_001_of_001_BTCUSDT_1h_ee8c3c2e.html",
    "report_json_path": "T4/T4_run_001_of_001_BTCUSDT_1h_ee8c3c2e.json",
    "period": "2025-09-01 .. 2025-09-20",
    "elapsed": "00:00:07"
  }
]

chartUrl — ссылка на HTML-отчёт для браузера. report_path — тот же отчёт как путь внутри root=report. report_json_path — его JSON-версия, если она записана.

GET/api/tester/filesПапки тестера: ?root=report|data|runs&path=
Пример
{
  "root": "report",
  "path": "T4",
  "items": [
    { "name": "old", "is_dir": true, "size": 204800, "modified_utc": "2026-10-20T10:00:00Z", "snapshot": false, "editable": false },
    { "name": "run_snapshot_20261025.json", "is_dir": false, "size": 51200, "modified_utc": "2026-10-25T12:00:00Z", "snapshot": true, "editable": false }
  ]
}

snapshot: true — файл можно запустить через snapshot-run. editable: true — файл можно изменить через files/save.

GET POST/api/tester/files/download
/api/tester/files/delete
/api/tester/files/content
/api/tester/files/save
Скачать, удалить, прочитать snapshot, сохранить JSON в runs (?root=&path=)
GET/api/tester/reports/summaryСводки отчётов для сравнения: метрики и кривая доходности, ?r= можно повторять
Пример

Запрос:

GET /api/tester/reports/summary?r=T4/report.html&r=T4_STRESS/report.html

Ответ:

[
  {
    "report": "T4/report.html",
    "created": "2026-10-25T12:00:00Z",
    "summary": {
      "name_comment": "T4",
      "start": "2025-01-01T00:00:00",
      "end": "2026-01-01T00:00:00",
      "symbols": ["BTCUSDT"],
      "metrics": { "TotalPnLPercent": 42.1, "MaxDrawdownPercent": 12.3, "ProfitFactor": 1.8, "WinRate": 55.0, "TotalTrades": 120 },
      "equity_t": [1735689600],
      "equity_v": [1000.0]
    }
  }
]

equity_t и equity_v — время (Unix, секунды) и баланс точек кривой доходности. summary: null — у отчёта нет сводки.

GET/api/tester/reports/jsonПодробные результаты прогона в компактном JSON: ?path=, ?sections=, ?trades_offset=, ?trades_limit=
Пример

Запрос:

GET /api/tester/reports/json?path=T4/T4_run_001_of_001_BTCUSDT_1h_ee8c3c2e.html&sections=by_symbol,trades&trades_limit=2

Ответ:

{
  "v": 1,
  "created_utc": "2026-10-25T05:45:34Z",
  "html_report": "T4_run_001_of_001_BTCUSDT_1h_ee8c3c2e.html",
  "by_symbol": [
    { "symbol": "BTCUSDT", "strategy": "zigzag", "trades": 23, "win_rate": 13.04, "profit_factor": 0.395, "pnl": -390.14,
      "best_trade": 160.02, "worst_trade": -57.7, "max_drawdown_incl_unrealized": -483.2, "buy_hold_percent": 6.81,
      "fee": 22.2, "volume": 221995.16, "position_avg_percent": 49.31, "position_max_percent": 50.72 }
  ],
  "trades": {
    "count": 23,
    "columns": ["symbol", "side", "open", "close", "holding_hours", "fills", "net_pnl", "mae", "mfe"],
    "rows": [
      ["BTCUSDT", "short", "2025-09-01 00:04", "2025-09-01 07:54", 7.83, 2, -57.6968, -57.6968, 38.8311],
      ["BTCUSDT", "long", "2025-09-01 07:54", "2025-09-01 20:45", 12.85, 2, -46.2855, -50.7967, 26.7293]
    ],
    "offset": 0
  }
}

В trades: count — число всех сделок, net_pnl — результат сделки за вычетом комиссий, mae и mfe — худший и лучший промежуточный результат сделки (USDT), время — UTC. Поля v, created_utc и html_report возвращаются всегда.

GET/api/tester/publish/filesФайлы папки отчёта, которые можно опубликовать на сайт, ?path=
Пример
[ { "name": "reports_history.csv", "size": 10240, "kind": "history" } ]

kind — history (история прогонов), snapshot (snapshot прогона) или summary (сводный отчёт).

POST/api/tester/publishОтправить выбранные файлы на сайт, публикация появляется после модерации
Пример

Запрос (agree: true — согласие с условиями публикации, обязательно):

{ "path": "T4", "files": ["reports_history.csv"], "contact": "@telegram", "comment": "...", "agree": true }

Ответ:

{ "success": true, "sent": ["reports_history.csv"] }

Тестер через API

  • Все запуски работают в фоне: ответ приходит сразу, ход и результат — в GET /api/tester/status.
  • Перебор параметров, стресс-тест и повтор по snapshot выполняются по одному. Одиночные прогоны можно запускать параллельно. Пока загружаются исторические данные, тестер не запускается, и наоборот — ответ 409.
  • Запущенный перебор нельзя остановить, поэтому заранее проверяйте число комбинаций (или задайте monte_carlo — случайную выборку).
  • Результаты перебора — в папке report/<name_comment>: reports_history.csv с метриками каждой комбинации, HTML- и JSON-отчёты, сводный отчёт оптимизатора. Давайте каждому эксперименту свой name_comment.
  • JSON-отчёт (report.enable_json_report) содержит те же числа, что HTML-отчёт, но в десятки раз меньше: разделы run, metrics, by_symbol, monthly, trades, curves, settings.

MCP для ИИ-ассистентов

Бот работает как MCP-сервер (Model Context Protocol): ИИ-ассистент — Claude и другие клиенты MCP — может сам смотреть состояние бота, запускать тестер и управлять стратегиями. Инструменты MCP повторяют API и подчиняются тем же правилам доступа.

Включение

По умолчанию MCP выключен. Включите его в settings_program.json:

{ "use_mcp": true }

Изменение действует сразу, перезапуск не нужен. Можно и через API: POST /api/settings/config с телом { "use_mcp": true }. Пока MCP выключен, /mcp отвечает 404.

Адрес: http://127.0.0.1:<порт>/mcp, транспорт Streamable HTTP.

Подключение к Claude Code

claude mcp add --transport http hamster-bot http://127.0.0.1:5000/mcp --header "Authorization: Bearer <api_token>"

Или в файле .mcp.json проекта:

{
  "mcpServers": {
    "hamster-bot": {
      "type": "http",
      "url": "http://127.0.0.1:5000/mcp",
      "headers": { "Authorization": "Bearer <api_token>" }
    }
  }
}

Другие клиенты подключаются по тому же адресу, если поддерживают Streamable HTTP и свои заголовки запроса.

Доступ и безопасность

  • Доступ — как у API (см. Доступ): заголовок Authorization: Bearer <api_token> с любого адреса; без него — cookie hamster-bot-token при включённом входе или только с этой же машины при выключенном. Иначе /mcp отвечает 401.
  • Для подключения с другой машины укажите вместо 127.0.0.1 адрес сервера. Токен при этом передаётся открытым текстом, поэтому через интернет подключайтесь через HTTPS-прокси или SSH-туннель.
  • Инструменты, которые торгуют на бирже, запускают торговлю или необратимо меняют данные, помечены как опасные (destructiveHint) — клиент запрашивает подтверждение перед их вызовом: рыночные ордера, закрытие позиций, отмена ордеров, запуск ботов, сохранение и удаление стратегий и ключей, изменение конфига, выключение и обновление программы.
  • Чтение состояния помечено как безопасное (readOnlyHint).

Инструменты

Настройкиget_config, update_config, get_field_hints
Стратегииlist_strategies, get_strategy, draft_strategy, save_strategy, copy_strategy, delete_strategy
Аккаунтыlist_accounts, get_account, get_account_symbols, save_account, delete_account, get_account_info, get_balance_history, compact_balance_history
Ботыlist_bots, get_balances, get_bot_bars, get_bot_state, pause_all_bots, play_all_bots, pause_bot, play_bot, send_chart_to_telegram, send_position_to_telegram
Позиции и ордераlist_positions, list_orders, market_order, close_position, close_all_positions, reduce_positions, cancel_order, cancel_account_orders, cancel_all_orders
Система и логиget_system_status, shutdown_program, update_program, get_log, get_errors, list_log_files, read_log_file
Тестерtester_status, get_tester_config, save_tester_config, tester_exchanges, tester_exchange_symbols, list_tester_settings, get_tester_settings, draft_tester_settings, save_tester_settings, copy_tester_settings, delete_tester_settings, get_tester_settings_folder, set_tester_settings_folder, tester_run_mining, tester_run_stress, tester_run_single, tester_run_snapshot, tester_download_data, tester_wizard_results, list_tester_files, read_tester_file, save_tester_file, delete_tester_file, tester_report_summaries, read_tester_report, tester_publish_files, tester_publish

Ошибка API возвращается ассистенту как ошибка инструмента с кодом и текстом, например HTTP 404: {"success":false,"error":"Strategy not found"}. Очень длинные ответы обрезаются до 200 000 символов. У read_tester_file для длинных CSV есть параметры tail_lines и contains. Для сравнения прогонов лучше tester_report_summaries, для подробностей одного прогона — read_tester_report.

Исследования в тестере

Ассистент может сам вести исследование стратегии. Тестер работает на исторических данных и с биржей не торгует. Типичный порядок:

  1. get_field_hints — узнать смысл полей настроек стратегии и конфига тестера, в том числе синтаксис parameter_mining.
  2. draft_tester_settings, save_tester_settings — создать настройки для нужной биржи, пары и таймфрейма.
  3. save_tester_config — задать период, комиссии, parameter_mining и новый name_comment; включить report.enable_json_report.
  4. tester_download_data — загрузить свечи и дождаться окончания в tester_status.
  5. tester_run_single или tester_run_mining — проверить одну комбинацию или перебрать все: результаты в tester_wizard_results или <name_comment>/reports_history.csv.
  6. read_tester_report — разобрать прогон: итоги по парам, месяцы, сделки.
  7. tester_report_summaries, tester_run_stress — сравнить лучшие варианты и проверить их устойчивость (а также walk_forward в конфиге).

Пример запроса к ассистенту: «Подбери длину зигзага для BTCUSDT 1h на бирже Bybit за последние три месяца. Сравни лучшие варианты по просадке и проверь их стресс-тестом».

Коды ответов

200Успех
400Неверный запрос: пустое тело, неверный JSON, не заполнены обязательные поля
401Нет доступа: неверный api_token; cookie отсутствует, устарел или заменён новым входом; запрос без токена не с этой же машины
403Запрос со страницы другого сайта (Origin не совпадает с адресом бота)
404Не найдено
409Конфликт: тестер или загрузка данных уже работают, имя занято, нет нужного запущенного бота
500Внутренняя ошибка или ошибка биржи
502Внешний сервис не принял запрос
503Программа ещё запускается