Logo hamster-bot
RU EN PT

Carregando…

API e MCP

Controle o bot a partir de scripts, programas e assistentes de IA

API HTTP para gerenciar o bot e o testador: configurações, estratégias, chaves de API das corretoras, posições e ordens, logs, execução do testador e trabalho com os seus relatórios. O bot também funciona como servidor MCP — um assistente de IA pode consultar o estado do bot, fazer pesquisas no testador e gerenciar estratégias por conta própria.

O endereço é o mesmo da interface web: http://<host>:<porta>. A porta é definida no campo port do settings_program.json.

Acesso Requisições e respostas Endpoints Testador MCP para assistentes de IA Códigos de resposta

Acesso

Token de API (recomendado)

Envie em cada requisição o cabeçalho Authorization: Bearer <api_token>:

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

O bot cria o api_token sozinho na primeira execução e o guarda no settings_program.json. O token funciona de qualquer endereço e com qualquer valor de auth_telegram, e o login pelo navegador não o invalida.

É possível ver e copiar o token na interface web: «Configuração global», bloco «Token da API e do MCP». Lá também fica o botão «Emitir novo» — o token anterior deixa de valer na hora. Com o login pelo Telegram desativado, esse bloco funciona apenas na mesma máquina (127.0.0.1).

No editor de configuração, no log e na resposta de GET /api/settings/config o token fica mascarado (os 4 últimos caracteres ficam visíveis), e ele não pode ser alterado pelo editor nem por POST /api/settings/config. Novo token pela API: POST /api/settings/api-token/regenerate, resposta { "success": true, "api_token": "..." }.

⚠️ Guarde o token como uma senha: com ele tudo fica acessível, inclusive operações e as chaves das corretoras.

Sem token, na mesma máquina

Se o login pelo Telegram estiver desativado ("auth_telegram": false), requisições sem token são aceitas apenas da mesma máquina, pelo endereço 127.0.0.1 ou localhost:

curl http://127.0.0.1:5000/api/current/bots

De outros endereços sem token a API retorna 401. Com o login desativado, a interface web continua aberta a qualquer um que consiga se conectar à porta, por isso, num servidor com a porta aberta, mantenha o login ativado.

Requisições de páginas de outros sites

Um POST com cabeçalho Origin diferente do endereço do bot é recusado com 403 — é a proteção contra CSRF. curl, scripts e clientes MCP não enviam Origin, então isso não os afeta. Se o bot estiver atrás de um proxy reverso, o proxy deve repassar o cabeçalho Host original.

Cookie de login

Em vez do token, é possível enviar o cookie hamster-bot-token, se o login pelo Telegram estiver ativado:

  1. POST /htmx/login/get-token — o bot envia um código de uso único no Telegram.
  2. POST /htmx/login/verify com o formulário token_enter=<código> — a resposta traz o cabeçalho Set-Cookie: hamster-bot-token=...
  3. Envie o cookie nas requisições: curl -b "hamster-bot-token=<valor>" ...

O cookie vale por até 10 dias. Só o último login é válido: um novo login (inclusive pelo navegador) invalida o cookie anterior.

Requisições e respostas

  • O corpo das requisições POST é JSON em UTF-8 (Content-Type: application/json).
  • Nomes no caminho são codificados em URL: estratégia T4 BTC → /api/settings/strategy/T4%20BTC.
  • Configurações são enviadas e retornadas no mesmo formato dos arquivos JSON do bot.
  • Uma ação bem-sucedida retorna { "success": true, ... }, um erro retorna { "success": false, "error": "texto do erro" } com um código da tabela de códigos de resposta.
  • Um bot é identificado pela conta e pelo nome da estratégia: /{accountName}/{settingsName}. Se a estratégia opera vários pares, o parâmetro ?symbol= escolhe o par; sem ele, é usado o primeiro.

Exemplo: criar uma estratégia a partir de um rascunho com valores padrão.

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" }'

O rascunho não salva nada: ajuste o objeto retornado e envie-o para POST /api/settings/strategy — a estratégia é salva e inicia na hora.

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

Endpoints

Abaixo da descrição de cada endpoint há um exemplo recolhido de requisição e resposta.

Configurações

GET/api/settings/configConfiguração global (settings_program.json). O token do bot do Telegram vem mascarado: só os 4 primeiros caracteres ficam visíveis. O api_token vem mascarado: só os 4 últimos caracteres ficam visíveis
Exemplo
{
  "name": "MyBot",
  "use_web": true,
  "port": 5000,
  "api_token": "••••••••••••b9c2",
  "telegram": {
    "bot_token": "1234************",
    "id_chat": 123456789
  }
}
POST/api/settings/configAlterar a configuração: envie só os campos que mudam, aplicado na hora. O token do bot do Telegram e o api_token não mudam aqui: esses campos no corpo são ignorados
Exemplo

Requisição:

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

Resposta:

{ "success": true }
POST/api/settings/api-token/regenerateEmitir um novo api_token, o anterior deixa de valer na hora. É a única resposta da API em que o token aparece por inteiro. Não precisa de corpo
Exemplo
{ "success": true, "api_token": "<novo token>" }
GET/api/settings/hints/{kind}Descrições dos campos: settings, config_tester, settings_program. Parâmetros ?lang= (en, ru, pt), ?filter=
Exemplo

Requisição:

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

Resposta — objeto «caminho do campo com pontos → descrição»:

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

Estratégias

GET/api/settings/strategyTodas as estratégias do bot
Exemplo
[
  {
    "name": "T4 BTC",
    "is_runing": true,
    "exchange": { "name": "binance", "account": "main" },
    "basic": { "symbol": "BTCUSDT", "strategy": "zigzag", "time_frame": "1h" }
  }
]
GET/api/settings/strategy/{name}Uma estratégia pelo nome (sem diferenciar maiúsculas)
POST/api/settings/strategy/draftRascunho com valores padrão para a conta, não salva nada
Exemplo

Requisição:

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

Em vez de symbol pode-se enviar symbols: ["BTCUSDT", "ETHUSDT"] — estratégia com vários pares. time_frame (padrão 1h) e account_type são opcionais. A resposta é um objeto de estratégia.

POST/api/settings/strategyCriar ou alterar uma estratégia, as mudanças valem na hora. ?old_name= — renomear
Exemplo

Requisição (o corpo é um objeto de estratégia):

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

Resposta (created: true — a estratégia é nova):

{ "success": true, "name": "T4 BTC v2", "created": false }
POST/api/settings/strategy/{name}/copyCópia com novo nome, salva e iniciada
Exemplo

Requisição (new_symbol é opcional):

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

Resposta:

{ "success": true, "name": "T4 ETH" }
POST/api/settings/strategy/{name}/deleteExcluir a estratégia, ordens e posição não são tocadas. ?full=1 — antes cancela as ordens e fecha a posição
Exemplo

Requisição:

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

Resposta:

{ "success": true }

Se com full=1 não for possível cancelar as ordens ou fechar a posição, a estratégia fica pausada e não é excluída — a posição nunca fica sem gerenciamento.

Contas (chaves de API das corretoras)

GET/api/settings/accountsTodas as contas
Exemplo
[
  {
    "name": "main",
    "exchange": "binance",
    "api_key": "...",
    "api_secret": "...",
    "is_encrypted": true
  }
]
GET/api/settings/accounts/{name}Uma conta
GET/api/settings/accounts/{name}/symbolsPares disponíveis na corretora para a conta
Exemplo
["BTCUSDT", "ETHUSDT"]
POST/api/settings/accountsCriar ou alterar uma conta, as chaves são enviadas em texto aberto. ?old_name= — renomear
Exemplo

Requisição:

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

Resposta (applied — quantos bots em execução receberam a nova chave):

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

Com "is_encrypted": true o bot guarda as chaves criptografadas. api_key, api_secret, api_passphrase vazios mantêm os valores atuais na alteração; ao mudar is_encrypted, a chave e o segredo precisam ser enviados de novo.

POST/api/settings/accounts/{name}/deleteExcluir a conta
GET/api/current/accounts/{name}/infoDados da conta e da chave na corretora, atualizados de hora em hora (exige um bot em execução na conta)
Exemplo
{
  "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-historyHistórico de saldo, ?max= — no máximo tantos pontos (padrão 5000)
Exemplo
{
  "account": "main",
  "total": 12000,
  "points": [ { "time": 1761393600, "margin": 1234.5, "wallet": 1200.0, "positions": "..." } ]
}

time — tempo Unix em segundos, total — quantos pontos o histórico tem no total.

POST/api/current/accounts/{name}/balance-history/compactCompactar o histórico de saldo agora conforme as configurações de monitoring
Exemplo
{ "success": true, "message": "...", "points_before": 12000, "points_after": 3000, "bytes_before": 512000, "bytes_after": 128000 }

Bots

GET/api/current/botsResumo de todos os bots: status, preço, posição, número de ordens, sincronização com a corretora
Exemplo
[
  {
    "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 — o bot está pausado. position: null — sem posição. orders — número de ordens abertas. sync_missed_cycles — quantos ciclos seguidos falharam ao obter dados da corretora.

GET/api/current/balancesSaldo da carteira e de margem por chave, spot e futuros separados. ?account=
Exemplo

Requisição:

GET /api/current/balances?account=main

Resposta:

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

No spot os dois valores são o saldo em USDT. O saldo vem dos bots em execução: uma conta sem bot em execução não aparece na lista.

GET/api/current/bots/{accountName}/{settingsName}/barsCandles do bot, ?limit= — últimos N (padrão 500)
Exemplo

Requisição:

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

A resposta é um array de candles com os campos Timestamp, Open, High, Low, Close, Volume e outros.

GET/api/current/ubots
/api/current/ubots/{accountName}/{settingsName}
Snapshot completo do estado. O formato pode mudar entre versões — para uma integração permanente use bots, positions, orders
POST/api/bots/pause-all
/api/bots/play-all
Pausar / iniciar todos os bots
Exemplo
{ "success": true, "count": 5 }
POST/api/bots/{accountName}/{settingsName}/pause
/api/bots/{accountName}/{settingsName}/play
Pausar / iniciar uma estratégia (numa estratégia com vários pares — todos os pares)
Exemplo

Requisição:

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

Resposta (para play — "is_runing": true):

{ "success": true, "name": "T4 BTC", "is_runing": false }
POST/api/bots/{accountName}/{settingsName}/send-chartEnviar o gráfico do bot para o Telegram
POST/api/bots/{accountName}/{settingsName}/send-positionEnviar um resumo para o Telegram: saldo, posição, PnL, ordens

Posições e ordens

GET/api/current/positionsPosições de todos os bots
Exemplo
[
  {
    "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/ordersOrdens abertas de todos os bots
Exemplo
[
  {
    "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/marketOrdem a mercado na conta. O par precisa ser operado por um dos bots dessa conta
Exemplo

Requisição (side — Buy ou Sell; size — volume em unidades da corretora):

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

Resposta:

{ "success": true, "order_id": "order-123" }
POST/api/positions/{accountName}/{settingsName}/closeFechar a posição do bot
Exemplo

Requisição:

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

Resposta:

{ "success": true }
POST/api/positions/{accountName}/close-allFechar todas as posições da conta
Exemplo
{ "success": true, "count": 3 }

count — quantas posições foram enviadas para fechamento.

POST/api/positions/{accountName}/reduceReduzir todas as posições da conta em percent (1–100)
Exemplo

Requisição:

{ "percent": 50 }

Resposta:

{ "success": true, "count": 3 }
POST/api/orders/{accountName}/{settingsName}/{orderId}/cancelCancelar uma ordem (comum ou stop)
Exemplo

Requisição:

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

Resposta:

{ "success": true }
POST/api/orders/{accountName}/cancel-allCancelar todas as ordens da conta
Exemplo
{ "success": true, "count": 2 }

count — em quantos bots as ordens foram canceladas.

POST/api/orders/cancel-allCancelar todas as ordens em todas as contas
Exemplo
{ "success": true, "count": 7 }

Sistema e logs

GET/api/system/statusVersão do programa, recursos do servidor, contadores de bots
Exemplo
{
  "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/shutdownEncerrar o programa (só com login pelo Telegram)
POST/api/system/updateIniciar a atualização do programa (veja auto_update_supported no status)
GET/api/logsÚltimas linhas do log geral (array de strings), ?tail=
GET/api/logs/errorsErros das últimas ?hours= horas (padrão 24, até 48), ?warnings=1 — com avisos
Exemplo
[
  {
    "level": "Error",
    "first_utc": "2026-10-25T08:00:00Z",
    "last_utc": "2026-10-25T12:00:00Z",
    "count": 3,
    "source": "T4 BTC",
    "message": "...",
    "exception": "..."
  }
]

Mensagens iguais são agrupadas, count — quantas vezes se repetiu.

GET/api/logs/filesArquivos de log, os mais recentes primeiro
Exemplo
[ { "name": "log_25-10-2026.log", "size": 102400, "modified_utc": "2026-10-25T12:00:00Z" } ]
GET/api/logs/files/{filename}Conteúdo do arquivo de log como texto, ?download=1 — baixar

Testador

GET/api/tester/statusEstado do testador: execuções, execuções únicas, download de dados
Exemplo
{
  "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 — busca de parâmetros, teste de estresse ou repetição por snapshot; status: Idle, Running, Completed ou Failed; runs_done / runs_total — quantas combinações já foram calculadas. wizard_runs — execuções únicas, as concluídas ficam visíveis por mais 5 minutos. download — download de dados históricos. settings_folder — pasta atual de configurações do testador.

GET POST/api/tester/configConfiguração do testador (config_tester.json): período, taxas, parâmetros de busca. POST — a configuração inteira
GET/api/tester/exchanges
/api/tester/exchanges/{exchange}/symbols
Corretoras com dados históricos e seus pares. Lista de pares vazia — a corretora está indisponível no momento
Exemplo
["bybit", "binance", ...]
GET/api/tester/settings
/api/tester/settings/{name}
Configurações de estratégias do testador na pasta atual
Exemplo
[ { "name": "T4 BTC", "exchange": "bybit", "symbol": "BTCUSDT", "symbols": null, "strategy": "zigzag", "time_frame": "1h" } ]
POST/api/tester/settings/draftRascunho de configuração, não salva nada
Exemplo

Requisição:

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

Em vez de symbol pode-se enviar symbols — vários pares. account_type é opcional. A resposta é um objeto de configuração.

POST/api/tester/settingsSalvar configuração, ?old_name= — renomear. Uma configuração existente com o mesmo nome não é sobrescrita
Exemplo
{ "success": true, "name": "T4 BTC" }
POST/api/tester/settings/{name}/copy
/api/tester/settings/{name}/delete
Copiar (inclusive para outra corretora ou par) / excluir
Exemplo

Requisição copy (new_exchange e new_symbol vazios mantêm os valores da configuração original):

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

Resposta:

{ "success": true, "name": "T4 BTC binance" }
GET POST/api/tester/settings-folderPasta atual de configurações do testador e troca de pasta ("" — pasta principal)
Exemplo

GET — resposta (settings — quantas configurações há na pasta):

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

POST — requisição:

{ "path": "2026-10" }

POST — resposta:

{ "success": true, "path": "2026-10" }
POST/api/tester/runBusca de parâmetros (parameter_mining)
Exemplo

Requisição (config é opcional — sem ele é usada a configuração salva do testador):

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

Resposta:

{ "success": true }
POST/api/tester/stressTeste de estresse: as mesmas configurações em condições de execução piores. Corpo e respostas como em /api/tester/run
POST/api/tester/wizard-runExecução única. Corpo como em /api/tester/run
Exemplo
{ "success": true, "run_id": "a1b2c3d4" }

O andamento fica em wizard_runs do status do testador pelo run_id, as métricas em wizard-results.

POST/api/tester/snapshot-runRepetir uma execução a partir de um arquivo snapshot (?root=&path=). O corpo é opcional: um snapshot alterado vale só para esta execução
Exemplo
POST /api/tester/snapshot-run?root=report&path=T4/run_snapshot_20261025.json
POST/api/tester/download-dataBaixar dados históricos para todas as configurações do testador
GET/api/tester/wizard-resultsResultados das execuções únicas, os mais recentes primeiro: métricas e caminhos dos relatórios
Exemplo
[
  {
    "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 — link para o relatório HTML no navegador. report_path — o mesmo relatório como caminho dentro de root=report. report_json_path — a versão JSON, se tiver sido gravada.

GET/api/tester/filesPastas do testador: ?root=report|data|runs&path=
Exemplo
{
  "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 — o arquivo pode ser executado via snapshot-run. editable: true — o arquivo pode ser alterado via files/save.

GET POST/api/tester/files/download
/api/tester/files/delete
/api/tester/files/content
/api/tester/files/save
Baixar, excluir, ler um snapshot, salvar JSON em runs (?root=&path=)
GET/api/tester/reports/summaryResumos de relatórios para comparação: métricas e curva de capital, ?r= pode se repetir
Exemplo

Requisição:

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

Resposta:

[
  {
    "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 e equity_v — tempo (Unix, segundos) e saldo dos pontos da curva de capital. summary: null — o relatório não tem resumo.

GET/api/tester/reports/jsonResultados detalhados de uma execução em JSON compacto: ?path=, ?sections=, ?trades_offset=, ?trades_limit=
Exemplo

Requisição:

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

Resposta:

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

Em trades: count — total de operações, net_pnl — resultado da operação descontadas as taxas, mae e mfe — pior e melhor resultado intermediário da operação (USDT), horários em UTC. Os campos v, created_utc e html_report sempre são retornados.

GET/api/tester/publish/filesArquivos de uma pasta de relatório que podem ser publicados no site, ?path=
Exemplo
[ { "name": "reports_history.csv", "size": 10240, "kind": "history" } ]

kind — history (histórico de execuções), snapshot (snapshot da execução) ou summary (relatório resumido).

POST/api/tester/publishEnviar os arquivos escolhidos para o site, a publicação aparece após moderação
Exemplo

Requisição (agree: true — concordância com os termos de publicação, obrigatório):

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

Resposta:

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

Testador via API

  • Todas as execuções rodam em segundo plano: a resposta vem na hora, o andamento e o resultado ficam em GET /api/tester/status.
  • Busca de parâmetros, teste de estresse e repetição por snapshot rodam um de cada vez. Execuções únicas podem rodar em paralelo. Enquanto os dados históricos são baixados o testador não inicia, e vice-versa — a resposta é 409.
  • Uma busca em andamento não pode ser interrompida, então verifique antes o número de combinações (ou defina monte_carlo — uma amostra aleatória).
  • Os resultados da busca vão para report/<name_comment>: reports_history.csv com as métricas de cada combinação, relatórios HTML e JSON, relatório resumido do otimizador. Dê a cada experimento o seu próprio name_comment.
  • O relatório JSON (report.enable_json_report) tem os mesmos números do relatório HTML, mas é dezenas de vezes menor: seções run, metrics, by_symbol, monthly, trades, curves, settings.

MCP para assistentes de IA

O bot funciona como servidor MCP (Model Context Protocol): um assistente de IA — Claude e outros clientes MCP — pode consultar o estado do bot, executar o testador e gerenciar estratégias por conta própria. As ferramentas MCP espelham a API e seguem as mesmas regras de acesso.

Ativação

O MCP vem desativado. Ative-o no settings_program.json:

{ "use_mcp": true }

A mudança vale na hora, sem reiniciar. Também pode ser feita pela API: POST /api/settings/config com o corpo { "use_mcp": true }. Enquanto o MCP está desativado, /mcp retorna 404.

Endereço: http://127.0.0.1:<porta>/mcp, transporte Streamable HTTP.

Conexão ao Claude Code

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

Ou no arquivo .mcp.json do projeto:

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

Outros clientes se conectam pelo mesmo endereço, se suportarem Streamable HTTP e cabeçalhos de requisição próprios.

Acesso e segurança

  • O acesso é igual ao da API (veja Acesso): cabeçalho Authorization: Bearer <api_token> de qualquer endereço; sem ele — cookie hamster-bot-token com o login ativado, ou apenas da mesma máquina com o login desativado. Caso contrário, /mcp retorna 401.
  • Para conectar de outra máquina, use o endereço do servidor no lugar de 127.0.0.1. O token é então enviado em texto aberto, por isso, pela internet, conecte-se por um proxy HTTPS ou um túnel SSH.
  • Ferramentas que operam na corretora, iniciam operações ou alteram dados de forma irreversível são marcadas como perigosas (destructiveHint) — o cliente pede confirmação antes de chamá-las: ordens a mercado, fechamento de posições, cancelamento de ordens, início de bots, salvar e excluir estratégias e chaves, alterar a configuração, encerrar e atualizar o programa.
  • A leitura do estado é marcada como segura (readOnlyHint).

Ferramentas

Configuraçõesget_config, update_config, get_field_hints
Estratégiaslist_strategies, get_strategy, draft_strategy, save_strategy, copy_strategy, delete_strategy
Contaslist_accounts, get_account, get_account_symbols, save_account, delete_account, get_account_info, get_balance_history, compact_balance_history
Botslist_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
Posições e ordenslist_positions, list_orders, market_order, close_position, close_all_positions, reduce_positions, cancel_order, cancel_account_orders, cancel_all_orders
Sistema e logsget_system_status, shutdown_program, update_program, get_log, get_errors, list_log_files, read_log_file
Testadortester_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

Um erro da API chega ao assistente como erro da ferramenta, com código e texto, por exemplo HTTP 404: {"success":false,"error":"Strategy not found"}. Respostas muito longas são cortadas em 200 000 caracteres. Para CSV longos, read_tester_file tem os parâmetros tail_lines e contains. Para comparar execuções use tester_report_summaries, para os detalhes de uma execução — read_tester_report.

Pesquisas no testador

O assistente pode pesquisar uma estratégia por conta própria. O testador trabalha com dados históricos e não opera na corretora. Um fluxo típico:

  1. get_field_hints — entender o significado dos campos das configurações da estratégia e do testador, incluindo a sintaxe de parameter_mining.
  2. draft_tester_settings, save_tester_settings — criar as configurações para a corretora, o par e o timeframe desejados.
  3. save_tester_config — definir período, taxas, parameter_mining e um novo name_comment; ativar report.enable_json_report.
  4. tester_download_data — baixar os candles e aguardar a conclusão em tester_status.
  5. tester_run_single ou tester_run_mining — testar uma combinação ou todas: resultados em tester_wizard_results ou <name_comment>/reports_history.csv.
  6. read_tester_report — analisar uma execução: totais por par, meses, operações.
  7. tester_report_summaries, tester_run_stress — comparar as melhores variantes e verificar a robustez (também walk_forward na configuração).

Exemplo de pedido ao assistente: «Encontre o comprimento do zigzag para BTCUSDT 1h na Bybit nos últimos três meses. Compare as melhores variantes pelo drawdown e verifique-as com um teste de estresse».

Códigos de resposta

200Sucesso
400Requisição inválida: corpo vazio, JSON inválido, campos obrigatórios ausentes
401Sem acesso: api_token inválido; cookie ausente, expirado ou substituído por um novo login; requisição sem token fora da mesma máquina
403Requisição de uma página de outro site (Origin diferente do endereço do bot)
404Não encontrado
409Conflito: testador ou download de dados já em andamento, nome ocupado, bot necessário não está em execução
500Erro interno ou erro da corretora
502O serviço externo recusou a requisição
503O programa ainda está iniciando