Teste de estratégias de trading em dados históricos
Backtest de portfólio confiável. Nível de pesquisa quant
hamster-bot/tester - uma ferramenta avançada para testar sistemas de trading em dados históricos.
Recursos do backtester:
- Teste de portfólio. Várias estratégias de tipos diferentes, em pares e timeframes diferentes, ao mesmo tempo — em um único saldo compartilhado. Dá para ver como as estratégias convivem na mesma conta: carga total do depósito, drawdown geral, sobreposição de posições.
- O mesmo código de produção. O backtest roda o mesmo código com que o bot opera em tempo real: estratégias, serviço de posições, limitador de posições, opções da conta. Nada de reescrever a lógica para o testador.
- Simulação honesta dentro da vela. A estratégia é chamada a cada mudança da vela em formação. Trailing stops, reposicionamento de ordens e saídas dentro da vela funcionam como no trading real.
- Custos realistas. Taxas de maker/taker, slippage e atraso de ordens a mercado e stop, funding, execução de ordens limitadas limitada pelo volume da vela.
- Os dados são baixados automaticamente. BYBIT, BINANCE, MEXC e outras — para qualquer período histórico. Também é possível usar seus próprios dados em CSV.
- Relatório interativo detalhado. Curva de equity, mapa de calor do retorno mensal, gráficos de operações de cada par e mais de 50 métricas: Sharpe, Sortino, Calmar, CAGR, Recovery Factor, sequências de ganhos/perdas, carga do depósito etc. Verificação de sobreajuste. Monte Carlo sobre as operações, PnL sem as melhores operações e sem o melhor par, top-5 drawdowns com duração e tempo de recuperação, MAE/MFE de cada operação, resultado por hora, dia da semana e regime de mercado, distância até a liquidação.
- Otimizador de parâmetros. Varredura de quaisquer configurações do bot, das estratégias, da conta e do próprio testador. Execuções paralelas em todos os núcleos, amostragem Monte Carlo para espaços de parâmetros enormes, seleção de portfólio de pares sem repetição. Resultados — em uma tabela resumo e em mapas de calor / 3D surface.
- Verificação de robustez. Walk-forward (otimização em uma parte do histórico, verificação em outra), mapa de platô dos parâmetros, teste de estresse em um clique, comparação de várias execuções e resultado por regime de mercado (alta, queda, lateral, volatilidade).
- Testa sua própria lógica complexa, que não pode ser testada com precisão por soluções prontas de terceiros sem gambiarras.
Implementado como um conector separado
para uma "exchange" (um objeto mock que substitui a exchange). Assim é possível testar
todo o código já escrito do bot. O bot acha que está operando em uma exchange real (envia ordens, recebe saldo e
informações de posições). E essa exchange virtual calcula tudo e gera o relatório.
Instruções de uso
(passo a passo)
Abaixo está a ordem das ações, da primeira execução até a otimização de parâmetros. Os detalhes de cada parâmetro estão nas seções abaixo.
O que você vai precisar.
— o hamster-bot instalado na versão mais recente (o testador é embutido no bot, não é preciso instalar nada à parte);
— internet para baixar os dados históricos e os parâmetros dos instrumentos da exchange;
— os arquivos de configuração das estratégias na
pasta
tester/settings_strategy. Chaves de API e contas de settings_accounts não são
necessárias para o testador.
O testador não envia ordens para a exchange real: em vez dela, o bot trabalha com uma exchange virtual. Da
exchange são obtidos apenas dados públicos — o histórico de operações e os parâmetros do instrumento (passo de
preço, lote mínimo etc.), que ficam em cache em tester/data/{exchange}/_markets.
Passo 1. Prepare as estratégias.
O testador tem sua própria pasta de configurações — tester/settings_strategy, separada da
settings_strategy de produção. O teste não mexe nas configurações de trabalho do bot, e os
experimentos no testador não afetam o trading. É prático adicionar, copiar, editar e excluir as configurações do
testador na interface web (aba "Tester" → "Parâmetros", veja o passo 3), mas também é possível simplesmente colocar os
arquivos .json na pasta.
As configurações podem ser divididas em subpastas, por exemplo tester/settings_strategy/trend e
tester/settings_strategy/grid, e é possível alternar entre esses conjuntos na interface web (a linha
Pasta de configurações acima da tabela). A tabela, a adição de configurações e as execuções trabalham
com a pasta selecionada, sem as suas subpastas. Pelo console o testador lê apenas a raiz de
tester/settings_strategy.
Cada arquivo em tester/settings_strategy é uma estratégia em um par. Confira nele:
— exchange.name — a exchange de onde os dados serão baixados (bybit, binance,
mexc, bitmex etc., veja a seção "Dados de mercado");
— o campo exchange.account é ignorado pelo testador: todas as estratégias rodam na mesma conta do
testador de config_tester.json (seção accounts, veja "Parâmetros do testador");
— basic.symbol e basic.time_frame — o par e o timeframe;
— o tamanho do lote e as configurações da estratégia — como no trading real;
— se necessário — um período de negociação próprio para essa estratégia dentro do teste geral (seção tester
no arquivo de configuração):
"tester": { "StartDate": "2026-02-01T00:00:00", "EndDate": "2026-02-20T00:00:00" }
Antes de StartDate a estratégia não negocia; após EndDate o testador cancela suas ordens
uma vez e fecha a posição a mercado, e daí em diante o par não negocia. Qualquer um dos campos pode ser omitido — então
não há limite desse lado. É prático quando o par foi listado na exchange depois do início do teste, foi deslistado ou
quando é preciso testar um portfólio em que as estratégias entraram em momentos diferentes.
Ao iniciar pelo console, entram no teste
todos os arquivos de tester/settings_strategy de uma vez — é um teste de portfólio em um único
saldo compartilhado. Na interface web as estratégias para o teste, a busca de parâmetros e o teste de estresse são
marcadas no assistente do testador (passo 3).
Passo 2. Configure o config_tester.json.
O arquivo fica na pasta do bot. Se ele não existir, é criado com os valores padrão ao iniciar o bot (assim como o settings_program.json).
Ele pode ser editado em um editor de texto ou na interface web do bot (aba "Tester" → "Parâmetros" →
"Editar config_tester.json" — lá também há dicas para cada parâmetro).
Para o primeiro teste basta definir:
"name_comment": "first_test", "InitialBalance": 1000.0, "StartDate": "2026-01-01T00:00:00", "EndDate": "2026-03-01T00:00:00", "WarmupDays": 30, "MakerFee": 0.00036, "TakerFee": 0.001, "UpdateData": true, "parameter_mining": []
name_comment — o nome da pasta onde os relatórios serão salvos: tester/report/first_test.
Use WarmupDays no mínimo igual ao que o indicador mais longo da estratégia precisa (por exemplo, para uma MA 200 no
timeframe de 1h são necessários pelo menos 9 dias). Informe as suas taxas, considerando o nível da conta. Os demais parâmetros
podem ficar no padrão — a descrição deles está na seção "Parâmetros do testador".
Passo 3. Rode o teste. Há duas formas.
A) Pela interface web do bot — aba Tester. Enquanto isso, o bot continua funcionando no
modo normal.
Aba Parâmetros — o status do testador e as configurações do testador da pasta selecionada
tester/settings_strategy:
— Status do testador — o que está em execução agora e o progresso: teste individual, busca de
parâmetros, teste de estresse ou execução de snapshot, com horário de início e de término. Atualiza-se sozinho;
— Pasta de configurações — o caminho da pasta selecionada e as suas subpastas com o número de arquivos
de configuração; clique em uma pasta para abri-la, .. sobe um nível;
— Adicionar configuração — nova configuração: exchange, par, estratégia e timeframe (chaves de API não são necessárias,
a lista de pares é obtida da exchange por uma requisição pública). Na lista aparecem apenas as exchanges para as quais o testador sabe baixar
o histórico: Bybit, Binance (futuros e spot), MEXC (spot e futuros) e BitMEX. O par pode ser digitado manualmente,
vários — separados por vírgula; o par digitado substitui o selecionado na lista. Isso ajuda quando a lista de pares
não carregou (por exemplo, a exchange não está acessível a partir do seu IP);
— na linha da configuração: Testar — teste apenas dessa estratégia, Editar,
Copiar (cópia com novo nome, exchange e par — prático para replicar a configuração em outros pares),
JSON — copiar a configuração para a área de transferência, Excluir;
— Editar config_tester.json — editor dos parâmetros do testador (salva no arquivo);
— Baixar dados — baixar antecipadamente os dados históricos de todas as configurações do testador para o período de
config_tester.json. O status do download aparece separadamente, e o andamento — no console do bot;
— Executar testador — a janela "Assistente do testador" com as estratégias da pasta selecionada:
marque as desejadas (ou Selecionar todos).
Após Testar ou Executar testador abre-se o "Assistente do testador" com o editor dos
parâmetros do testador. Ajuste o período, o saldo etc. e escolha o que executar:
— Executar — uma única execução das estratégias marcadas no saldo compartilhado com parâmetros exatos,
sem a varredura parameter_mining;
— Busca de parâmetros — modo completo para as estratégias marcadas com o config do editor: varredura
parameter_mining, single_mode, processos paralelos (max_parallel_runs). O
progresso mostra o número de combinações concluídas e o % da execução atual;
— Teste de estresse — as mesmas configurações em condições piores (veja a seção "Verificação de
robustez").
Se o config no editor for diferente de config_tester.json, o assistente pergunta antes de iniciar:
Salvar e executar, Executar sem salvar (as alterações valem apenas para essa execução) ou
Cancelar. Só pode haver uma busca de parâmetros ou um teste de estresse por vez.
Após o início, a janela fecha e o progresso aparece no bloco Status do testador. Quando um teste
individual termina, surge na linha da estratégia o botão Resultado — ele abre direto o relatório HTML
da execução.
Aba Resultados (arquivos) — gerenciador de arquivos das pastas tester/runs,
tester/report e tester/data: ordenação, abrir o relatório no navegador, baixar ou excluir
arquivo/pasta (enquanto um teste ou download de dados está em andamento, a exclusão fica indisponível). O snapshot da execução
(run_snapshot_*.json) pode ser aberto no editor JSON, ajustado e executado com o botão
Executar — o teste é repetido com as configurações do snapshot. Se o snapshot tiver muitas
estratégias, as suas configurações não são carregadas no editor de imediato, para que a janela abra rápido: o botão
Carregar configurações de estratégias as abre para edição; sem ele o snapshot é executado com as
configurações do arquivo como estão. O botão + Parâmetro de busca também funciona no editor do
snapshot.
B) Pelo console — prático para varreduras grandes. Execute a partir da pasta do bot:
# Windows manage_tester.bat menu: teste, otimizador, baixar ou converter dados manage_tester.bat tester ou hb_c.exe --run-tester manage_tester.bat download ou hb_c.exe --download-data manage_tester.bat optimizer <pasta> ou hb_c.exe --run-report-optimizer tester\report\first_test # macOS ./run_tester_mac.sh ou ./hb_c --run-tester # Linux ./hb_c --run-tester ./hb_c --download-data ./hb_c --run-report-optimizer tester/report/first_test
--run-tester — teste, --download-data — apenas baixar os dados,
--run-report-optimizer — refazer o relatório resumo do otimizador. No Windows todos esses modos ficam em
um único arquivo manage_tester.bat (ele substituiu os antigos run_tester.bat, run_download_data.bat,
run_report_optimizer.bat e run_convert_data.bat): sem argumentos ele mostra um menu, e dá para
arrastar uma pasta de relatório para o arquivo para gerar o relatório do otimizador dela. Se o script não estiver na pasta
do bot, use o comando da coluna da direita.
Nesse modo o bot não opera: ele lê as configurações, executa os testes e encerra. Se no mesmo
computador já houver um bot operando, rode o testador a partir de uma cópia separada da pasta.
Passo 4. Acompanhe o console (log). O que é importante nele:
— [LoadBars] ..., Загружено N баров для SYMBOL ("N barras carregadas para SYMBOL") — download e carregamento dos dados.
A primeira execução em um novo período pode demorar, depois os dados são lidos do disco;
— [RUN 1/1] start. params: ... — início da execução (na varredura — com o número da execução e os valores
dos parâmetros);
— Пропуск бота ... ("bot ignorado ...") — a estratégia foi excluída do teste (sem dados, erro nas configurações), o motivo
é indicado na linha;
— [MINER] Обнаружены невалидные parameter_mining.name ("parameter_mining.name inválido encontrado") — erro de digitação no caminho do parâmetro varrido;
— no final — BACKTEST REPORT com os totais e a linha Interactive chart generated: ... com
o caminho do relatório HTML.
Passo 5. Analise os resultados. Tudo fica na pasta tester/report/{name_comment}:
— o relatório HTML da execução — abra no navegador (descrição na seção "Relatório"). Comece pelo cabeçalho: PnL, Max
Drawdown, número de operações, Profit Factor. Depois a curva de equity, as operações nos gráficos dos pares e a aba
Analytics — o quanto o resultado depende de algumas operações de sorte ou de um único par;
— reports_history.csv — uma linha com os totais de cada execução (abre no Excel / Google Sheets);
— run_snapshot_{name_comment}_{data_hora}.json — snapshot completo das configurações do teste. Cada
execução salva o seu próprio snapshot, os anteriores não são sobrescritos. Ele pode ser executado
diretamente na aba "Resultados (arquivos)" (botão Executar) ou colocado em tester/runs para repetir o
teste pelo console (parâmetro use_runs).
O log detalhado da execução (com use_logger = true) fica na pasta logs, arquivos
TESTER_*.log.
Passo 6. Otimização de parâmetros (otimizador).
1) Adicione em parameter_mining os parâmetros a varrer (exemplos na seção "Otimizador").
Calcule o número de execuções — é o produto do número de valores de todos os parâmetros;
2) baixe os dados antecipadamente: manage_tester.bat download ou o botão Baixar dados;
3) para ganhar velocidade: max_parallel_runs — de acordo com o número de núcleos do processador,
report.enable_html_report = false, use_logger = false; com milhões de combinações —
monte_carlo;
4) execute manage_tester.bat tester (ou o botão Busca de parâmetros no assistente do testador) e verifique no console
os avisos [MINER];
5) após a varredura, abra report_optimizer_*.html e ordene
reports_history.csv. Não escolha a melhor execução isolada, e sim uma região estável, onde os
valores vizinhos também são bons;
6) estreite os intervalos em torno da melhor região e repita. Verifique as configurações finais com um teste único com relatório
HTML em outro período, que não participou da otimização.
Problemas frequentes.
- A estratégia não entrou no teste. O arquivo não está em
tester/settings_strategy(a pasta de produçãosettings_strategynão é lida pelo testador), está em uma subpasta que não foi selecionada na linhaPasta de configurações(pelo console as subpastas não são lidas) ou tem um erro de JSON — no console aparecerá[TESTER] failed to load settings file. Пропуск бота ...: нет данных("bot ignorado ...: sem dados"). O par não era negociado nessa exchange no período escolhido, há um erro no nome embasic.symbol, ouUpdateData = falsee emtester/datanão há arquivos desse período.Market initialization failed. Não foi possível obter os parâmetros do instrumento: sem conexão com a exchange e sem cache, ou esse par não existe na exchange.- O teste terminou antes de
EndDate. No console há a linhaTester stopped: ...: o depósito quebrou (Equity <= 0) ou foi atingidotarget_drawdown/target_drawdown_open. - Nenhuma ou muito poucas operações.
WarmupDaysinsuficiente para os indicadores, período curto demais, ou lote menor que o mínimo do par. Um teste já está em andamento.. A busca de parâmetros, o teste de estresse e a execução de um snapshot pela aba "Resultados (arquivos)" só podem rodar uma de cada vez — aguarde o término da atual (o status é atualizado automaticamente).Compiled executable not found. O scriptrun_*.batnão foi executado a partir da pasta do bot.
Dados de mercado para
teste
As exchanges de criptomoedas compartilham publicamente dados históricos de mercado. O testador baixa sozinho o
intervalo de dados necessário, monta a partir deles velas de 1 minuto e, a partir desses minutos, forma as
barras do timeframe necessário para o bot. Nenhuma ação manual ou cadastro é necessário.
Além disso, são baixados WarmupDays dias antes do início do teste, para que todos os indicadores
de AT da estratégia já estejam calculados em StartDate.
Exchanges suportadas. A exchange é obtida do arquivo de configurações da estratégia: settings.exchange.name.
- BYBIT — futuros (
bybit) e spot (bybit-spot). Arquivos de todas as operações depublic.bybit.com. - BINANCE — futuros USDT-M (
binance,binance-papi) e spot (binance-spot). Arquivos diários de operações agregadas dedata.binance.vision. - MEXC — spot (
mexc) e futuros (mexc-futures). Velas de 1 minuto prontas pela API pública da exchange. - BITMEX — (
bitmex). Arquivos diários de operações depublic.bitmex.com. Um arquivo contém as operações de todos os pares de uma vez — o testador o baixa uma única vez e distribui pelas pastas dos pares.
Se for indicada uma exchange para a qual não há downloader, o testador usa os dados da BYBIT.
Armazenamento. Os dados são salvos na
pasta tester/data/{exchange}/{symbol} — um arquivo de velas de 1 minuto por dia
no formato Parquet (2026-02-03_1m.parquet). Os arquivos são comprimidos e
ocupam menos espaço que CSV. Os arquivos de operações baixados são apagados após a conversão, para não ocupar espaço.
Dias já baixados não são baixados de novo: nos testes seguintes o testador baixa apenas os dias que faltam
(se UpdateData = true). Com UpdateData = false o teste roda apenas com os dados que
já estão na pasta.
Ao iniciar o teste, são lidos apenas os arquivos diários do período do teste (com o aquecimento), por isso o histórico
acumulado ao longo de anos não deixa os testes curtos mais lentos. Arquivos sem data no nome não são lidos.
Na varredura paralela os processos não atrapalham uns aos outros: o mesmo par é baixado por apenas um
processo de cada vez, os demais esperam e usam os arquivos já prontos.
Dados no formato CSV antigo. Os dados baixados por versões anteriores do bot (*_1m.csv)
não precisam ser baixados de novo: no primeiro teste de um par o testador converte os arquivos CSV dele para Parquet e apaga o CSV.
Para converter de uma vez toda a pasta tester/data, use o comando manage_tester.bat convert
(no macOS, run_convert_data_mac.sh) na pasta do bot: ele executa o bot com a flag
--convert-data. Pode ser executado também enquanto o testador está rodando.
Seus próprios dados. Você pode colocar seus dados no formato
CSV na pasta tester/data/{exchange}/{symbol}. No primeiro teste desse par (ou via manage_tester.bat convert) o testador
converte os dados para Parquet e apaga o CSV original, então guarde uma cópia se precisar dele. Requisitos:
— um arquivo por dia, o nome termina com a data e _1m.csv, por exemplo 2026-02-03_1m.csv
(arquivos sem data no nome não são lidos);
— velas de 1 minuto (o testador percorre o histórico em passos de 1 minuto / opcionalmente é possível rodar a cada tick, mas fica lento);
— a primeira linha é o cabeçalho, seguida das colunas timestamp,open,high,low,close,volume (as
demais colunas são ignoradas; se houver 9 colunas ou mais, as colunas 7–9 são lidas como
buy_volume,sell_volume,trades);
— timestamp em UTC: tempo unix em segundos, milissegundos, microssegundos ou nanossegundos (o formato
é detectado automaticamente), ou uma data em texto 2026-02-03 00:01:00;
— o separador de colunas é a vírgula, o separador decimal é o ponto.
Exemplo:
timestamp,open,high,low,close,volume 1770076800000,97512.5,97540.0,97480.1,97530.2,12.345 1770076860000,97530.2,97561.7,97522.0,97555.0,8.910
Download antecipado. O comando manage_tester.bat download (item 3 do menu) executa o bot com a
flag --download-data. Nesse modo o testador não testa nada, apenas baixa todos os dados
necessários para o período do teste (+ aquecimento) de todos os pares de tester/settings_strategy, incluindo os pares da varredura
parameter_mining. É prático rodar antes de uma varredura grande.
Comportamento
do testador
Do ponto de vista do bot, o testador é apenas mais uma exchange. O bot se conecta a ela e começa a receber barras, enviar ordens etc. Enquanto isso, o testador apenas emula o comportamento de uma exchange real.
Tempo e velas. O testador percorre o histórico em passos de 1 minuto, de forma sincronizada em todos os pares.
A partir dos minutos ele monta as velas do timeframe de trabalho da estratégia (1m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d,
1w) alinhadas ao UTC, como na exchange: velas de 1h começam em XX:00, de 4h — em 00:00/04:00/08:00…, de 1d — em 00:00 UTC,
de 1w — na segunda-feira 00:00 UTC.
A estratégia é chamada a cada minuto, e não apenas no fechamento da vela — no timeframe de 1h são ~60 chamadas
por vela. O bot recebe as barras fechadas e a vela atual em formação, cujo OHLC é atualizado a cada
minuto. Por isso a lógica que depende do preço dentro da vela (trailing stops, reposicionamento de ordens, saída pelo
preço atual etc.) funciona igual ao trading real.
As barras do período de aquecimento (WarmupDays) são usadas apenas para calcular os indicadores — o trading
começa em StartDate. Se faltar um minuto nos dados (não houve operações), o testador insere
uma vela "vazia" com o último preço.
Execução de ordens. Em cada vela de 1 minuto o testador verifica todas as ordens pendentes pelo seu High/Low. Dentro do minuto é modelado o caminho do preço: em uma vela de alta Open → Low → High → Close, em uma de baixa Open → High → Low → Close. As ordens são executadas na ordem em que o preço as alcança nesse caminho, e não na ordem em que foram enviadas. Por exemplo, se em um mesmo minuto forem tocados tanto o stop quanto o take-profit, será executado aquele que o preço alcançou primeiro, e o segundo (reduceOnly) será cancelado, pois a posição já não existe.
market— executada imediatamente ao preço atual, considerando o slippage (SlippagePercent): compra mais caro, venda mais barato. Taxa de taker. Comorder_market_delay = true— pelo preço de abertura do minuto seguinte.limit— executada pelo seu próprio preço quando o preço do minuto o atinge (Low ≤ preço para compra, High ≥ preço para venda). Taxa de maker. ComLimitOrderVolumeCheck = trueo volume executado é limitado pelo volume da vela de 1 minuto — é possível execução parcial, o restante espera as próximas velas. Comorder_limit_fill_plus_tick = trueum simples toque não basta: o preço precisa passar do nível da ordem limitada.stop/stop_market— dispara ao tocar o preço de gatilho e é executada nele com slippage. Taxa de taker. Comorder_trigger_fill_worst = trueos gaps são considerados: se o minuto já abriu além do gatilho, o stop é executado pelo preço de abertura do minuto (como em uma exchange real em um movimento brusco).stop_limit— ativada pelo gatilho e executada pelo preço limite, se ele também for atingido nesse minuto. Taxa de maker.take_profit— executada pelo preço de gatilho quando ele é atingido. Taxa de taker.
As ordens podem ser alteradas (preço, volume, gatilho) e canceladas — como na exchange.
reduceOnly é suportado: uma ordem assim só pode reduzir a posição e nunca a
inverte. As configurações da estratégia use_long/use_short são respeitadas: se uma direção
está desativada, uma ordem nessa direção só pode fechar a posição oposta, e o volume "excedente" é descartado.
Posições. Modo One-Way (uma posição por par): uma compra com posição short primeiro fecha/reduz o short, e
o excedente abre um long (inversão). Ao aumentar a posição, o preço de entrada é ponderado. O PnL é realizado a
cada fechamento ou redução da posição.
Spot. O tipo de mercado é obtido pelo testador dos parâmetros do instrumento da exchange. No spot não há shorts: uma venda só pode
reduzir ou fechar um long, e o volume "excedente" é descartado. No spot não há funding.
O saldo é compartilhado entre todas as estratégias. Se comporta como os futuros da BYBIT/BINANCE com margem cruzada. O bot pode
consultar o saldo Wallet ou Margin:
— Wallet — saldo realizado: saldo inicial + PnL realizado − taxas ± funding;
— Margin (equity) — Wallet + PnL não realizado de todas as posições abertas. A curva de
equity e o drawdown máximo são calculados a partir dele.
A taxa é descontada do saldo imediatamente a cada execução de ordem.
Se o saldo Margin chegar a zero, o testador interrompe a execução — o depósito "quebrou", não faz
sentido continuar testando. A liquidação de posições individuais não é modelada: o teste continua mesmo em um drawdown profundo, para que
se veja como o sistema se comporta depois dele. É possível interromper o teste antes com os parâmetros target_drawdown_open e
target_drawdown.
Funding. A cada FundingIntervalHours horas (em UTC, no início da hora) é aplicado funding a todas as
posições de futuros abertas: tamanho da posição × preço × FundingRate. Com taxa positiva,
longs pagam e shorts recebem. Os totais aparecem no relatório (Funding paid / received / net). Para desativar o funding,
defina FundingRate = 0.
Lógica do bot. No testador roda exatamente a mesma lógica do trading real: o serviço de posições, o limitador de posições abertas simultaneamente, as opções da conta (por exemplo, fechamento por lucro da margem) — tudo isso é o código de produção compartilhado do bot.
Relatório
Ao final do teste, um relatório HTML interativo detalhado é salvo na
pasta tester/report/{name_comment}.
E é adicionado um registro em reports_history.csv com informações resumidas do teste, para facilitar a busca
pelas melhores combinações de parâmetros ao otimizar estratégias.
Relatório do otimizador. Na varredura de parâmetros (parameter_mining), além dos relatórios de cada
execução, o testador gera mais um relatório resumo, report_optimizer_*.html, com todas as execuções de uma vez.
Nele os resultados da varredura são mostrados em mapas de calor e gráficos 3D surface: nos eixos X e Y — os valores
dos parâmetros varridos, no eixo Z — as métricas (retorno, drawdown, Profit Factor etc.). Assim se veem de imediato os
"platôs" estáveis de bons valores, e não picos isolados aleatórios. O relatório é criado automaticamente na varredura
paralela (max_parallel_runs > 1) ou manualmente via manage_tester.bat optimizer,
mais detalhes na seção "Otimizador".
Quase toda métrica, coluna e gráfico dos relatórios tem uma dica: passe o cursor sobre o nome para ver o que o indicador significa e como ele é calculado.
Cabeçalho do relatório — indicadores principais:
Pairs- número de pares de trading (estratégias) no testeInitial Balance/Final Balance- saldo inicial e final em USDTTotal PnL- lucro/prejuízo total em USDT e em %Total Trades (Win/Los)- número de operações completas (da abertura da posição até o seu fechamento total), das quais lucrativas e com prejuízo, já descontadas as taxasWin Rate- percentual de operações completas lucrativasMax Drawdown, %- drawdown máximo do saldo Margin a partir do pico, em % (entre parênteses - o seu tamanho em USDT)Max Drawdown, USDT- drawdown máximo em dinheiro (entre parênteses - o seu % em relação ao pico). São duas grandezas independentes: com o depósito crescendo, o maior drawdown em dinheiro costuma ser tardio e menor em %, enquanto o maior em % é inicial. Por exemplo, 4509 USDT (9.83%) com pico de 45869 e 1885 USDT (20.42%) com pico de 9234Max Unrealized Drawdown, %- prejuízo não realizado máximo das posições abertas em % do saldo Wallet no mesmo momento:(Wallet − Margin) / Wallet(entre parênteses - o prejuízo em USDT). É o ponto mais baixo da linhaUnrealized Drawdown/Profit %no gráfico de saldo; o lucro não realizado não é considerado. É a mesma grandeza pela qualtarget_drawdown_openinterrompe o teste. Em um portfólio pode ser maior queMax Drawdown, %: enquanto um par acumula prejuízo, outros realizam lucro, o Wallet cresce, e o Margin quase não cai em relação ao picoTotal Fees- total de taxas pagasPosition avg (max), %- tamanho total médio (e máximo) das posições abertas em % do saldo Margin. Mostra o quanto o sistema carrega o depósitoProfit Factor- relação entre o lucro bruto e o prejuízo brutoDuration (days)- duração do período de teste em dias
Gráficos:
Equity Curve- gráfico do saldo Margin (considerando todas as posições abertas e o PnL não realizado) e do saldo Wallet. A linhaLiquidation Level(ativada na legenda) é o nível de liquidação em margem cruzada, aproximadamente como na UTA da Bybit: a margem de manutenção total das posições de futuros abertas em USDT (nocional × MMR do nível de risk limit − mmDeduction + taxa taker para fechar). Se o saldo Margin cair abaixo dessa linha, uma exchange real liquidaria as posições. Os níveis de risk limit são baixados da Bybit; para as demais exchanges é usadomaintenance_margin_ratedoconfig_tester.json. A linha é apenas para o gráfico — não interrompe o teste. Quando não há posições abertas, a linha é interrompidaMonthly Returns Heatmap- mapa de calor do retorno por mês e o total de cada anoOpen Positions Size- tamanho total das posições abertas em USDT: geral, longs e shorts separadamente, e também por estratégias de tendência e contratendênciaStrategy Charts- gráficos de velas separados para cada estratégia, com marcações das operações e visualização da AT da estratégiaRealized PnL by Symbol- PnL realizado acumulado por par e no total. Os pares são ativados e desativados na legenda, os botõesSelect all/Deselect allmostram ou ocultam todos de uma vez
Report Statistics — estatísticas detalhadas:
- Period & Scope (período do teste)
Report range- datas de início e fim do testeDays in test- número de dias no testeMonths in test- número de meses do calendário abrangidos pelo testeMonths with data- número de meses para os quais o retorno foi calculadoPairs count- número de pares (estratégias)
- Balance & Equity (saldo)
Initial balance/Final balance- saldo inicial e finalMin balance/Max balance- valor mínimo e máximo do saldo Margin durante todo o teste
- Monthly Performance (retorno mensal)
Average monthly return (geometric), %- retorno mensal médio considerando juros compostos (reinvestimento). A estimativa mais honesta de "quanto por mês, em média"Average monthly return (arithmetic), %- média aritmética simples dos retornos mensaisBest month, %/Worst month, %- melhor e pior mês
- PnL, Volume & Fees (lucro, volume e taxas)
Total PnL/Total PnL, %- lucro/prejuízo total em USDT e %Gross profit- soma de todos os fechamentos lucrativos (lucro bruto)Gross loss- soma, em módulo, de todos os fechamentos com prejuízo (prejuízo bruto)Trading volume (USDT)- volume total negociadoTotal transactions (buy/sell)- número total de execuções de ordens (compras e vendas)Total fees- total de taxas pagasFunding net- resultado do funding (recebido menos pago)Funding accrued (received)- quanto de funding foi recebidoFunding paid- quanto de funding foi pagoPnL without top 5 winning trades- Total PnL sem as 5 operações mais lucrativas. Se o resultado fica negativo — o lucro depende de alguns poucos outliers de sortePnL without best pair- Total PnL sem a contribuição do par mais lucrativo (com um único par — n/a). Mostra se o portfólio funciona ou se tudo é puxado por um único par
- Trades (operações). Uma operação é uma operação completa: da abertura da posição até o seu fechamento total ou
inversão. Preços médios e fechamentos parciais dentro de uma mesma posição contam como uma única operação. O resultado da operação
é calculado já descontadas as taxas.
Total Trades/Win Trades/Los Trades- total de operações, lucrativas e com prejuízoWin Rate, %- percentual de operações lucrativasExpectancy per trade- expectativa matemática: resultado médio de uma operação em USDT descontadas as taxasAvg win/Avg loss- operação lucrativa média e operação com prejuízo médiaPayoff ratio- operação lucrativa média / operação com prejuízo média (por operações completas, ao contrário deRisk/Reward, que é calculado por execuções)Expected Value- resultado esperado de uma operação:WinRate × Avg win − LossRate × |Avg loss|. LossRate — fração de operações com prejuízo sobre o total (operações no zero a zero não contam como prejuízo). Valor maior que 0 — o sistema tem vantagemLargest win/Largest loss- a operação mais lucrativa e a com maior prejuízoAvg fills per trade- quantas execuções, em média, há por operação (1 entrada + 1 saída = 2; mais — preços médios e takes parciais)Avg holding time/Max holding time- tempo médio e máximo de permanência na posiçãoMax consecutive wins/Max consecutive losses- maior sequência de operações lucrativas e com prejuízo seguidas
- Fills (execuções que reduziram ou fecharam a posição — cada take parcial separadamente, PnL antes
das taxas)
Fills/Win Fills/Los Fills- número dessas execuções, lucrativas e com prejuízoFill Win Rate, %- percentual de execuções lucrativasExpectancy per fill- resultado médio de uma execução antes das taxasMax consecutive win / loss fills- maior sequência de execuções lucrativas e com prejuízo seguidas
- Risk & Exposure (risco e carga do depósito)
Position avg / max, % of margin balance- tamanho total médio e máximo das posições abertas em % do saldo MarginLong / Short Position avg / max, % of margin balance- o mesmo, separadamente para longs e shortsMax Drawdown, %/Max Drawdown, % — amount- drawdown máximo em % e o seu tamanho em USDTMax Drawdown, USDT/Max Drawdown, USDT — %- drawdown máximo em USDT e o seu % em relação ao picoMax Unrealized Drawdown, % of wallet/— amount/— time (UTC)- prejuízo não realizado máximo em % do Wallet, em USDT e o momento em que ocorreu
- Risk by strategy (carga do depósito por tipo de estratégia)
T ...- tamanho médio e máximo das posições (geral, long, short) das estratégias de tendência em % do saldo MarginCT ...- o mesmo para as estratégias de contratendência
- Benchmark (Buy & Hold) (comparação com simplesmente comprar e manter os mesmos pares)
Strategy return, %- retorno da estratégia no período do testeBuy & Hold return (equal weight), %- o retorno caso, com o saldo inicial, no início do teste fossem comprados todos os pares do portfólio em partes iguais e mantidos até o fimExcess return vs Buy & Hold, %- o quanto a estratégia é melhor (ou pior) do que simplesmente manterStrategy Max Drawdown, %/Buy & Hold Max Drawdown (daily), %- drawdown máximo da estratégia e do portfólio Buy & Hold (pelos fechamentos diários)
- Risk-Adjusted Ratios (índices retorno/risco)
Profit Factor- lucro bruto / prejuízo bruto. Acima de 1 — o sistema é lucrativoRisk/Reward- operação lucrativa média / operação com prejuízo médiaRecovery Factor- Total PnL / Max Drawdown, USDT. Quantas vezes o lucro cobre o drawdown máximoSharpe ratio (monthly)- índice de Sharpe com base nos retornos mensais (anualizado). Retorno em relação à volatilidade totalSortino ratio (monthly)- índice de Sortino. Como o Sharpe, mas considera apenas a volatilidade negativa (quedas)CAGR, %- taxa de crescimento anual composta do capitalCalmar ratio- CAGR / Max Drawdown %. Retorno anual em relação ao drawdown máximoUlcer Index (hourly), %- raiz da média dos quadrados do drawdown a partir do pico, pelos valores horários do saldo Margin. Ao contrário do Max Drawdown, considera tanto a profundidade quanto a duração de todos os drawdowns: ficar muito tempo "debaixo d'água" aumenta o índiceMartin ratio- CAGR / Ulcer Index. Retorno em relação ao quanto os drawdowns são "dolorosos"
Details — abas com detalhamento:
Settings- configurações de todas as estratégias que participaram do testeTrades- tabelas com todas as operações de cada par: horário, ordem, estratégia, lado, ação, tamanho, preço, taxa, PnL, saldo, posição após a operação, valor da posição em USDT e em % do saldo Margin. A colunaTrade Max DD (incl. unrealized), nas execuções que fecharam ou inverteram uma operação, é o drawdown mais profundo de toda a operação incluindo a perda não realizada (MAE) em USDT, entre parênteses — em % do saldo Margin no momento da abertura da operação. 0 — a operação nunca ficou negativaMarkets- parâmetros dos instrumentos: tipo do instrumento (Type: na Bybitcrypto,stock,ETF,commodity,forexetc.), tamanho máximo da ordem a mercado, alavancagem máxima, passo do lote, preço atual e volume médio diário negociado em 1, 10 e 100 diasSummary- tabela resumo por par: número de operações completas, Win Rate, Profit Factor, PnL, retorno Buy & Hold desse par no período do teste, taxas, volume negociado, tamanho médio e máximo da posição em %, a melhor e a pior operação (Best Trade/Worst Trade, já descontadas as taxas) eMax DD (incl. unrealized)— o drawdown máximo do resultado do par incluindo a perda não realizada: do pico do PnL acumulado das operações fechadas até o ponto mais profundo de uma operação seguinteCorrelation- matriz de correlação do PnL diário dos pares (realizado + não realizado). Correlação positiva alta (vermelho) — os pares perdem ao mesmo tempo, não há diversificação. Negativa (verde) — os pares se protegem mutuamente. Também é mostrada a correlação média entre pares do portfólio. Com muitos pares são exibidos os 25 pares com maior |PnL|Drawdown- decomposição do drawdown máximo em % (Max Drawdown, %) por par: o momento do pico e do fundo do saldo Margin e o quanto mudou a contribuição de cada par (PnL realizado e não realizado, taxas, funding) nesse período. A soma das contribuições é igual ao tamanho desse drawdown em USDT. Dá para ver quais pares "fizeram" o drawdown e quais, naquele momento, o amenizaram (participação negativa)Analytics- análise avançada: o quanto o resultado é robusto e onde ele é obtido. Desativada pelo parâmetroreport.include_analytics- Robustness (robustez: o resultado é real ou sobreajustado)
Dependence on outliers- PnL das 5 melhores operações, sua participação no Total PnL, PnL sem elas; o melhor par e o PnL sem eleMonte Carlo(ativado porreport.analytics_monte_carlo). Trabalha com a sequência de operações fechadas (PnL descontadas as taxas, sem PnL não realizado — por isso o drawdown aqui costuma ser menor que o Max Drawdown do relatório). Dois métodos:
embaralhamento — as mesmas operações em ordem aleatória. O total não muda, muda o caminho. São mostrados os percentis 5/50/95 do drawdown máximo e a fração de permutações com drawdown mais profundo que o real. Se forem 80% ou mais — a ordem real das operações foi favorável, e no trading real deve-se esperar um drawdown mais profundo;
bootstrap — as operações são escolhidas aleatoriamente com repetição. São mostrados os percentis 5/50/95 do PnL final e do drawdown, a probabilidade de prejuízo e a probabilidade de zerar o saldo.
Para ambos os métodos são gerados histogramas com a marcação do valor real. São necessárias no mínimo 5 operações
- Drawdowns (drawdowns)
- número de episódios de drawdown, o drawdown mais longo (do pico até o retorno ao pico), % do tempo debaixo
d'água,
Ulcer Index,Martin ratio - tabela dos top-5 drawdowns: início (pico), fundo, data de recuperação (ou
not recovered), profundidade em USDT e %, tempo de queda, tempo de recuperação e duração total. A duração e o tempo de recuperação muitas vezes importam mais que a profundidade
- número de episódios de drawdown, o drawdown mais longo (do pico até o retorno ao pico), % do tempo debaixo
d'água,
- Trade quality (qualidade das operações completas)
Avg win/Avg loss,Payoff ratio,Expected Value(WR × avg win − LR × |avg loss|), maior ganho e maior prejuízo, com o par e a dataMAE / MFE- o pior e o melhor PnL intermediário de cada operação (realizado − taxas + não realizado pelo Low/High das velas de 1 minuto). MAE médio de todas as operações e das lucrativas, pior MAE, MFE médio, fração do lucro que as operações lucrativas capturaram em relação ao seu máximo, quantas operações com prejuízo chegaram a ficar no positivo. Gráficos de dispersão MAE → resultado e MFE → resultado: MAE profundo nas operações lucrativas — o stop não pode ficar mais perto; pontos muito abaixo da linha PnL = MFE — o lucro está sendo devolvido, o take está longe demais ou a saída é tardia demais- tabela
Long / Short / All: número de operações, Win Rate, Profit Factor, PnL, operação média e tempo médio de permanência, separadamente por lado - histograma da distribuição do PnL das operações
- When and in which conditions (quando e em quais condições o resultado é obtido)
- mapa de calor do PnL por hora do dia (UTC) e dia da semana — variação do saldo Margin na hora, com totais por dia e por hora
- gráfico de 30 dias móveis: retorno, % e índice de Sharpe (anual, pelos retornos diários). Uma queda perto do fim do teste — a estratégia está "perdendo fôlego". São necessários mais de 30 dias de dados
- PnL por regime de mercado. O PnL diário de cada par é atribuído ao regime do seu mercado naquele dia: Trend — índice de eficiência de Kaufman em 14 dias ≥ 0.3, caso contrário Flat; High vol — ATR(14) em % do preço não abaixo da mediana desse par no período, caso contrário Low vol. Para cada uma das 4 combinações e os totais por um único critério: par-dias, PnL, PnL médio por par-dia, % de dias lucrativos, participação no PnL
- Risk and costs (risco e custos)
Distance to liquidation- distância mínima até a liquidação durante o teste, quando ocorreu, e os 5 dias mais próximos. Calculada como saldo Margin / nocional total das posições abertas: quantos % todas as posições teriam que se mover contra você ao mesmo tempo para zerar o saldo. A margem de manutenção não é considerada aqui — uma exchange real liquidaria antes; considerando-a, o nível de liquidação é mostrado pela linhaLiquidation Levelno gráfico de saldoVaR 95%diário (histórico: prejuízo que é superado em 5% dos dias) eCVaR 95%(prejuízo médio nesses 5% piores dias), pior e melhor dia, assimetria e curtose ("caudas gordas") dos retornos diários. VaR/CVaR — a partir de 20 dias de dadosCosts- lucro bruto, taxas e funding pago em % do lucro bruto, custos líquidos (taxas − funding líquido), PnL antes dos custos. Mostra o quanto os custos "comem"
- Robustness (robustez: o resultado é real ou sobreajustado)
Frequency- com que frequência as ordens são executadas: gráficos de execuções por dia e por mês; resumo — total de execuções (aberturas / fechamentos / inversões), dias com execuções, média e mediana por dia, o mês mais ativo e o mais calmo, o período mais longo sem execuções; tabelas por mês e por parTester Config- parâmetros do testador e valores dos parâmetros varridos nesta execução, além das opções da contaclose_by_margin,open_positions_limitererisk_multiplier
Parâmetros
do testador
arquivo: config_tester.json Você pode editar o arquivo em um editor de texto.
name_comment - comentário do teste. Para facilitar a organização dos relatórios. Os relatórios são
salvos em uma pasta separada tester/report/{name_comment}.
comment - comentário livre da execução, ajuda a distinguir relatórios na mesma pasta. Aparece no
cabeçalho do relatório e na página de comparação de execuções. Ao iniciar, a pasta de onde vieram as configurações
das estratégias é acrescentada automaticamente: [settings: settings_strategy/…]; essa marca não é
salva em config_tester.json.
InitialBalance - saldo inicial para o teste, em USDT
StartDate - data de início do teste, no formato 2026-02-03T00:00:00
EndDate - data de término do teste, no formato 2026-02-13T00:00:00
WarmupDays - número de dias de aquecimento antes do início do teste. Os dados desses dias são
baixados adicionalmente antes de StartDate, para que os indicadores de AT já estejam calculados no início
do teste. Se houver menos dados antes de StartDate do que WarmupDays (por exemplo, o par foi listado na
exchange depois), o trading desse par começará mais tarde — quando o aquecimento completo for alcançado. No console aparecerá
uma linha com a nova data de início.
MakerFee - taxa de maker (0.0001 = 0.01%) Padrão na BYBIT: 0.00036 = 0,0360%.
(guia de como reduzir bastante a taxa)
TakerFee - taxa de taker (0.0001 = 0.01%) Padrão na BYBIT: 0.001 = 0,1000%
SlippagePercent - slippage para ordens a mercado (0.0001 = 0.01%)
LimitOrderVolumeCheck - verificação de volume para a execução correta de ordens limitadas (true/false).
A ordem limitada é executada no máximo até o volume da vela atual: o testador "morde" da ordem o volume
disponível, e o restante espera a próxima vela (execução parcial/em etapas). Se desativado — a ordem limitada é executada por inteiro
ao tocar o preço.
order_trigger_fill_worst - execução realista de ordens stop em gaps (true/false). Por padrão
o stop é executado pelo preço de gatilho (± slippage). Se ativado, o stop é executado pelo pior dos preços:
o gatilho ou o preço de abertura da vela de 1 minuto. Por exemplo, um stop de venda em 100, e o minuto abriu em 97 — execução
a 97, e não a 100. Torna o teste mais conservador em movimentos bruscos e em pares com baixa liquidez.
order_limit_fill_plus_tick - execução realista de ordens limitadas considerando a fila do livro de ofertas
(true/false). Por padrão a ordem limitada é executada ao tocar o preço. Em uma exchange real, ao tocar o nível, a ordem
muitas vezes não é executada — antes dela na fila há outras ordens. Se ativado, a ordem limitada só é executada quando
o preço passa do seu nível. Por exemplo, uma ordem limitada de compra em 95 só será executada se o Low do minuto estiver abaixo de 95 —
tocar exatamente 95 não conta. Especialmente importante para estratégias de grid e de preço médio.
order_market_delay - atraso na execução de ordens a mercado (true/false). Por padrão a ordem a mercado
é executada instantaneamente — pelo preço de fechamento do mesmo minuto que a estratégia acabou de ver. Em uma exchange
real passa algum tempo entre a decisão do bot e a execução, e o preço tem tempo de se mover. Se ativado, a ordem a mercado
é executada pelo preço de abertura do minuto seguinte (+ slippage). Nesse caso a posição só aparece para o bot
no passo seguinte, como na exchange. O fechamento das posições no fim do teste sempre acontece imediatamente.
target_drawdown_open - drawdown alvo das posições abertas, em % (0 = desativado). É calculado como a
diferença entre o saldo Margin e o saldo Wallet, ou seja, o prejuízo não realizado atual das posições abertas:
(Wallet − Margin) / Wallet × 100. Assim que ele atinge o nível definido, o teste é encerrado
(por exemplo 50 — parada quando o Margin cai 50% abaixo do Wallet). Pode ser usado como o seu próprio
nível de "liquidação" — para descartar execuções às quais você não sobreviveria em uma conta real.
target_drawdown - drawdown máximo alvo, em % (0 = desativado). É calculado da mesma forma que
Max Drawdown, % no relatório: a queda do saldo Margin a partir do seu máximo histórico (high watermark),
(Pico Margin − Margin) / Pico Margin × 100. Considera também os prejuízos já realizados, e não apenas as
posições abertas. Assim que atinge o nível definido, o teste é encerrado.
Exemplo da diferença: saldo 100, abriu-se um long, o Margin subiu para 150 e depois caiu para 90. target_drawdown_open
vê 10% (Margin 10 abaixo do Wallet 100), e target_drawdown — 40% (a partir do pico de 150).
Ao parar por qualquer um dos parâmetros, as posições abertas são fechadas ao preço atual, e o relatório é gerado com os dados até
o momento da parada. Prático na varredura de parâmetros: execuções claramente ruins são interrompidas antes e não gastam
tempo.
FundingRate - Tamanho da taxa de funding (0.0001 = 0.01%)
FundingIntervalHours - Intervalo entre os pagamentos de funding, em horas (8)
maintenance_margin_rate - taxa de margem de manutenção como fração do nocional da posição (padrão
0.005 = 0.5%). Usada na linha Liquidation Level do gráfico de saldo quando a exchange não
fornece os níveis de risk limit (hoje eles são baixados apenas da Bybit). Não afeta o andamento do teste.
accounts - a conta do testador. É usado o primeiro item da lista: dele vêm
close_by_margin e open_positions_limiter para todas as estratégias do teste. Chaves de API não são necessárias.
Se a seção não existir, é criada uma conta padrão (opções desligadas):
"accounts": [ { "name": "tester", "open_positions_limiter": 0, "close_by_margin": { "profit": 1.0,
"loss": 1.0, "size": 1.0, "each": false } } ]
open_positions_limiter - máximo de posições abertas simultaneamente nas estratégias HiDeep,
RedFlag, SmartProfit e ShadowOverlap (0 — sem limite)
close_by_margin.profit - quando Margin ≥ Wallet × profit, as posições de todas as estratégias
são reduzidas na fração size (1.04 — Margin 4% acima do Wallet; 1 — desativado).
each: ativado — o Margin é calculado como Wallet + PnL não realizado das posições do bot; desativado — o saldo Margin
da conta inteira
UpdateData - atualizar (baixar o que falta) dos dados de mercado antes do teste (true/false)
use_logger - usar o logger. Se desativado, o teste fica mais rápido (true/false)
max_parallel_runs - número de execuções paralelas do testador ao varrer parâmetros. Cada execução
é iniciada como um processo separado. Se o desempenho do computador permitir, os processos podem ser
paralelizados sem perda de velocidade de cálculo. Com valor maior que 1, após o término de todas as execuções é gerado
automaticamente o relatório resumo do otimizador (mapas de calor / 3D surface).
max_memory_load_percent - limite de uso da memória RAM em % nas execuções paralelas (padrão
97). Se a memória estiver ocupada até esse nível (considerando a memória que a nova execução vai ocupar — estimada
pelo pico médio das execuções já concluídas), as novas
execuções esperam até que ela seja liberada. Execuções que falharam por falta de memória são repetidas automaticamente. 0 — sem
controle.
single_mode - modo de teste separado (true/false). Se ativado, cada arquivo de configuração da
pasta tester/settings_strategy é testado separadamente, e não todos juntos no saldo compartilhado. Prático para
avaliar cada estratégia/par separadamente em uma única execução. A varredura parameter_mining é aplicada a
cada estratégia.
use_runs - executar testes a partir de snapshots salvos (true/false). Se ativado, o testador ignora as configurações
atuais e executa, um após o outro, todos os arquivos *.json da pasta tester/runs. Cada
arquivo é um snapshot completo (estratégias, configurações do programa e do testador, incluindo a conta do testador em
accounts). Este modo funciona apenas ao iniciar pelo console (--run-tester): o botão
Busca de parâmetros o ignora, e um snapshot individual é executado na interface web com o botão
Executar na aba "Resultados (arquivos)". Esses snapshots,
run_snapshot_{name_comment}_{data_hora}.json, são salvos pelo próprio testador na pasta do relatório
antes de cada execução (tanto na varredura paralela quanto na sequencial) —
você pode copiá-los para tester/runs para repeti-los ou colocar vários testes diferentes
na fila.
shuffle_miner, monte_carlo, monte_carlo_seed - modos adicionais do
otimizador, descritos na seção "Otimizador".
arquivo: config_tester.json/report Configuração do conteúdo do relatório:
enable_html_report - gerar o relatório HTML (true/false). Se desativado — o HTML não é gerado, apenas
uma linha com as métricas resumidas é adicionada a reports_history.csv. Acelera muito as varreduras grandes
de parâmetros e economiza espaço em disco.
chart_ohlc_height - altura do gráfico OHLC em pixels
chart_balance_height - altura do gráfico de saldo em pixels
chart_position_height - altura do gráfico de tamanho das posições abertas em pixels
include_chart_ohlc - incluir o gráfico OHLC no relatório (true/false)
include_chart_balance - incluir o gráfico de saldo no relatório (true/false)
include_chart_position - incluir o gráfico de tamanho das posições abertas no relatório (true/false)
include_settings - incluir as configurações das estratégias e os parâmetros do testador no relatório (true/false)
include_trades_table - incluir as tabelas com a lista de operações de cada estratégia (true/false)
include_summary_table - incluir a tabela resumo de todas as estratégias: volume negociado, taxas
etc. (true/false)
include_monthly_returns_heatmap - incluir o mapa de calor do retorno mensal (true/false)
include_position_stats - incluir as estatísticas das posições abertas: tamanho médio e máximo das
posições abertas em % do saldo Margin (true/false)
include_analytics - incluir a aba Analytics (true/false, padrão
true)
analytics_monte_carlo - número de iterações de Monte Carlo sobre as operações na aba Analytics
(0 = desativado, recomendado 1000). Não confundir com o monte_carlo do otimizador — aquele limita
o número de execuções da varredura. O tempo de cálculo cresce proporcionalmente a iterações × número de operações e é gasto em cada
execução, inclusive na varredura: 1000 iterações com 100 operações — frações de segundo, 10000 iterações com milhares de operações —
bem mais tempo
analytics_monte_carlo_seed - valor inicial do gerador de números aleatórios para o Monte Carlo do relatório
(padrão 42). Com o mesmo seed o resultado se repete
enable_timing_logs - exibir no console o tempo de geração de cada etapa do relatório. Útil para
diagnóstico, se os relatórios demoram para ser gerados (true/false)
arquivo: config_tester.json/reports_history Colunas adicionais de
reports_history.csv:
As colunas principais são sempre gravadas. As adicionais vêm desativadas por padrão e são ativadas uma a uma (true/false).
As colunas ativadas podem ser usadas em z_parameters do otimizador, por exemplo para buscar
parâmetros robustos a outliers.
pnl_without_top5 - coluna PnLWithoutTop5: Total PnL sem as 5 operações mais
lucrativas
pnl_without_best_pair - coluna PnLWithoutBestPair: Total PnL sem o par mais
lucrativo (vazia com um único par)
ulcer_index - coluna UlcerIndex: Ulcer Index pelos valores horários do saldo Margin, %
mc_max_dd_p95 - coluna MC_MaxDD_p95: percentil 95 do drawdown máximo pelo
bootstrap, % (requer report.analytics_monte_carlo > 0, caso contrário fica vazia)
mc_loss_probability - coluna MC_LossProbability: probabilidade de prejuízo pelo bootstrap, %
(requer report.analytics_monte_carlo > 0, caso contrário fica vazia)
Exemplo:
"reports_history": { "pnl_without_top5": true, "ulcer_index": true }
Verificação de robustez e publicação
do relatório
Walk-forward. Defina walk_forward.oos_percent em config_tester.json (por exemplo
30) — a parte final do período fica fora da otimização. A varredura roda na primeira parte, e as melhores
top_n combinações pela metric (padrão TotalPnLPercent) são executadas
automaticamente na parte reservada, na pasta {name_comment}_WF_OOS. O resultado é o relatório
walk_forward_*.html: otimização vs. verificação, retorno por 30 dias, WFE e um veredito.
oos_percent = 0 desativa o modo.
Platô de parâmetros. report_optimizer_*.html agora tem uma seção de robustez: para as melhores
combinações mostra a média dos valores vizinhos dos parâmetros e o pior vizinho. Se o melhor resultado é um pico
isolado e os vizinhos são bem piores, o relatório o marca como frágil: essas configurações muito provavelmente estão sobreajustadas.
Teste de estresse. O botão Teste de estresse no assistente do testador (ou --run-stress-test no
console) executa as estratégias marcadas com o config do editor em vários cenários: taxas x2, slippage x3, funding x3,
atraso de ordens a mercado, stops no pior preço, execução estrita de limites e tudo combinado. O relatório stress_test_*.html fica na pasta
{name_comment}_STRESS e mostra quanto a estratégia perde em cada cenário.
Comparar execuções. Na aba "Resultados (arquivos)" marque dois ou mais relatórios HTML e clique em Comparar selecionados: as curvas
de retorno no mesmo gráfico (cada uma pode ser ocultada na legenda) e as métricas principais lado a lado, com a diferença em relação à
primeira execução e o melhor valor destacado. Os relatórios podem ser marcados em pastas diferentes: a seleção
é mantida ao navegar entre as pastas, um contador mostra quantos estão marcados e Limpar seleção a
reinicia. Para cada execução a página de comparação mostra o horário de criação do relatório e o
comment. Funciona para relatórios criados por esta versão do bot ou mais recente.
Regimes de mercado. A aba Analytics divide o resultado em alta, queda, lateral e volatilidade
alta/baixa, com uma linha de resumo de onde a estratégia ganha e onde perde.
Notificação no Telegram. Quando uma execução longa iniciada pela interface web termina (varredura, snapshot,
teste de estresse), o bot envia ao seu chat do Telegram: duração, número de execuções, melhor resultado e os relatórios
resumo gerados. Desative com notify_telegram = false.
Publicação do relatório. Cada pasta de relatório na aba "Resultados (arquivos)" tem o botão Publicar. No
formulário a descrição da estratégia e o contato são opcionais, basta confirmar a concordância; é possível marcar
quais arquivos da pasta enviar. O arquivo compactado é montado e enviado em segundo plano, a janela fecha na hora e
você será notificado do resultado. O bot envia um arquivo compactado ao chat do Telegram de relatórios do testador hamster-bot:
reports_history.csv, o snapshot das configurações, os relatórios resumo e o HTML das melhores execuções. Chaves de API, tokens e a
licença são removidos antes do envio.
Otimizador
(varredura de parâmetros)
O otimizador executa o teste automaticamente muitas vezes, cada vez com uma nova combinação de valores dos
parâmetros escolhidos. O resultado de cada execução é gravado como uma linha separada na tabela resumo
tester/report/{name_comment}/reports_history.csv: as métricas do teste mais colunas com os valores
dos parâmetros varridos. Ordenando-a, é fácil encontrar as melhores combinações.
arquivo: config_tester.json/parameter_mining Configuração do otimizador (varredor
de parâmetros):
Por padrão é uma lista vazia [] — um teste único normal. A lista é preenchida com objetos como
{"name": "nome_do_parametro", "start": 1, "end": 10, "step": 0.5, "values": []}. Cada objeto é um
parâmetro varrido.
Assistente de varredura. Não é obrigatório escrever o caminho à mão: na interface web, acima do editor de
config_tester.json, há o botão + Parâmetro de mineração. O assistente pergunta passo a passo o que
varrer (configurações da estratégia ou do próprio testador), a quais estratégias aplicar (* — a todas),
permite encontrar o parâmetro na árvore por busca (por exemplo take_profit) e definir o intervalo
start/end/step ou uma lista de valores. Dá para ver na hora quantos
valores e quantas combinações no total serão geradas. Se esse parâmetro já existir em parameter_mining, o assistente
oferece substituí-lo. Depois de adicionar, não esqueça de salvar a configuração.
name - caminho do parâmetro a varrer. Você pode informar qualquer configuração do bot. O caminho começa com
um dos 4 tipos de configuração:
1) settings — configurações de estratégia (arquivos .json na pasta tester/settings_strategy). Aqui
configuramos: o par de trading, o timeframe, o gerenciamento do depósito e qual estratégia roda com quais
configurações.
Exemplo: settings[*].mrs2.ma_long.type - varre o parâmetro type da ordem de abertura
da estratégia mrs2
2) account — a conta do testador (a seção accounts do config_tester.json).
Aqui configuramos o take profit geral da conta pelo saldo de margem, ou o limitador do número de posições
abertas simultaneamente.
Exemplo: account[*].close_by_margin.profit - varre o parâmetro profit da opção
close_by_margin
3) settings_program — configurações gerais do programa do bot (arquivo
settings_program.json). Aqui configuramos o multiplicador geral do lote risk_multiplier.
Exemplo: settings_program.risk_multiplier
4) config_tester — configurações do próprio testador (arquivo config_tester.json). Por exemplo,
é possível rodar testes com diferentes níveis de taxa ou de slippage.
Exemplo: config_tester.MakerFee
Escolha de uma estratégia/conta específica. Entre colchetes indica-se a quais arquivos aplicar o
parâmetro:
settings[*] — a todos os arquivos de configuração de uma vez
settings[0] — apenas ao primeiro arquivo (numeração a partir de 0, na ordem de carregamento)
settings[my_set_btc] — apenas ao arquivo cujo campo name é igual a
my_set_btc
O mesmo funciona para account[...] e para listas aninhadas dentro das configurações (por exemplo
[*], [0] em uma lista de ordens).
start - valor inicial do parâmetro
end - valor final do parâmetro (inclusive). Também é possível varrer em ordem decrescente, se
start > end
step - passo de variação do parâmetro
values - lista explícita de valores para varrer. Se a lista não estiver vazia,
start/end/step são ignorados. Os valores são escritos como strings e
convertidos automaticamente para o tipo do parâmetro: texto, números ("5", "10", "25"), true/false
(["true", "false"]) e listas de opções (enum).
Por exemplo, para o tipo de média móvel, os valores disponíveis são:
["SMA", "EMA", "GMA", "HARMONIC", "TEMA", "DEMA", "ZLEMA", "WMA", "VWMA", "RMA", "EHMA", "THMA", "HMA", "DMA", "ATR", "H", "L", "SMA_KALMAN", "EMA_KALMAN", "GMA_KALMAN", "HARMONIC_KALMAN", "TEMA_KALMAN", "DEMA_KALMAN", "ZLEMA_KALMAN", "WMA_KALMAN", "VWMA_KALMAN", "RMA_KALMAN", "EHMA_KALMAN", "THMA_KALMAN", "HMA_KALMAN", "DMA_KALMAN", "ATR_KALMAN", "H_KALMAN", "L_KALMAN"]
Para a fonte de preço:
["open", "high", "low", "close", "hl2", "hlc3", "ohlc4", "hlcc4", "oc2"].
Para varrer uma lista de pares de trading - veja o Exemplo 1.
Verificação dos nomes. Antes de iniciar, o testador verifica cada name. Se não for
encontrado um parâmetro com esse caminho (erro de digitação, estratégia inexistente etc.), é exibido no console o aviso
[MINER] Обнаружены невалидные parameter_mining.name ("parameter_mining.name inválido encontrado"), e esse parâmetro não é aplicado — os testes
rodam com o valor original. Sempre confira o console na primeira execução de uma varredura.
O número de execuções é o produto do número de valores de todos os parâmetros. Se você indicar dois
parâmetros para varrer, por exemplo de 1 a 10 com passo 1, serão feitas 100! execuções (10 variantes do primeiro
parâmetro × 10 variantes do segundo parâmetro). Os resultados de todos os testes são salvos como relatórios html separados e
na tabela resumo reports_history.csv.
Dicas para uma varredura grande:
— desative os relatórios HTML (report.enable_html_report = false) e o logger
(use_logger = false) — isso acelera muito as execuções e economiza espaço em disco;
— aumente max_parallel_runs de acordo com o número de núcleos do processador;
— se houver combinações demais, use monte_carlo (veja abaixo).
Modos adicionais de varredura (arquivo: config_tester.json):
single_mode - cada arquivo de configuração de tester/settings_strategy é testado separadamente, e toda a
varredura parameter_mining é executada para cada um deles. Por exemplo, 5 arquivos de configuração × 20 combinações
= 100 execuções. Prático quando é preciso ajustar os parâmetros de cada par de forma independente, e não do portfólio.
shuffle_miner - varredura de pares de trading sem repetição entre estratégias (true/false). Funciona quando a
pasta tester/settings_strategy tem vários arquivos de configuração e parameter_mining tem um parâmetro
do tipo settings[*].... (por exemplo settings[*].basic.symbol). Em vez de dar a todas as
estratégias o mesmo valor, o testador distribui a elas valores diferentes da lista e percorre todas as combinações
únicas. Exemplo: 3 arquivos de configuração e 10 pares em values → C(10,3) = 120 execuções, em cada uma das quais
as estratégias operam pares diferentes. Permite encontrar o melhor conjunto de pares para um portfólio no saldo compartilhado.
monte_carlo - limitar o número de execuções por amostragem aleatória (0 = desativado). Se o número total de combinações
da varredura for maior que esse valor, o testador escolhe monte_carlo combinações aleatórias em vez da varredura
completa. Útil quando há milhões de combinações: é possível "sondar" rapidamente o espaço de parâmetros e depois estreitar
os intervalos em torno dos melhores resultados.
monte_carlo_seed - valor inicial (seed) do gerador de números aleatórios para o Monte Carlo (por padrão
42). Com o mesmo seed a amostra se repete; altere-o para obter outra amostra.
arquivo: config_tester.json/report_optimizer Relatório resumo do otimizador:
Após uma varredura paralela (max_parallel_runs > 1) o testador gera automaticamente, a partir de
reports_history.csv, o relatório report_optimizer_*.html. Também é possível gerá-lo manualmente —
por exemplo após uma varredura sequencial, ou para refazê-lo com outros z_parameters: o comando
manage_tester.bat optimizer (flag --run-report-optimizer) usa a pasta
tester/report/{name_comment}, ou a pasta passada como primeiro argumento.
— se foram varridos 2 ou mais parâmetros numéricos — mapas de calor e gráficos 3D surface. Nos eixos X e Y
ficam os dois parâmetros numéricos com mais valores, no eixo Z — as métricas escolhidas;
— se foi varrido 1 parâmetro numérico — gráficos de linha das métricas em função desse parâmetro;
— se pares de trading foram varridos ao mesmo tempo — os gráficos são gerados separadamente para cada par;
— se não houver dados para gerar gráficos — o relatório mostra uma tabela com todos os resultados.
chart_height - altura dos gráficos do otimizador em pixels (550)
z_parameters - lista de métricas para o eixo Z. Por padrão
["TotalPnLPercent", "MaxDrawdownPercent", "ProfitFactor"]. É possível usar quaisquer colunas numéricas
de reports_history.csv: TotalPnL, TotalPnLPercent,
FinalBalance, TotalTrades, WinRate, Fills, MaxDrawdown,
MaxDrawdownPercent, TotalFees, PositionAvgPercent,
PositionMaxPercent, ProfitFactor, além das colunas adicionais, se estiverem ativadas
na seção reports_history: PnLWithoutTop5, PnLWithoutBestPair,
UlcerIndex, MC_MaxDD_p95, MC_LossProbability.
Em reports_history.csv, MaxDrawdown é o drawdown máximo em USDT, e
MaxDrawdownPercent é o pior em % entre os três drawdowns do relatório: Max Drawdown, %,
o % em relação ao pico de Max Drawdown, USDT e Max Unrealized Drawdown, %.
Exemplo 1: varredura de pares de trading
parameter_mining é uma lista ([]), na qual são adicionados, separados por vírgula, objetos
de varredura ([{}, {}]).
Para varrer pares de trading, é usado o parâmetro do tipo string values, enquanto os campos numéricos
start/end/step são definidos como 1.0 (eles são ignorados quando
values não está vazio).
O parâmetro settings[*].basic.symbol será aplicado a todos os arquivos de configuração da pasta
tester/settings_strategy:
"parameter_mining": [
{
"name": "settings[*].basic.symbol",
"start": 1.0,
"end": 1.0,
"step": 1.0,
"values": [
"1000BONKUSDT", "1000FLOKIUSDT", "1000LUNCUSDT",
"1000NEIROCTOUSDT", "1000PEPEUSDT", "1000TAGUSDT",
"4USDT", "AAVEUSDT", "ACHUSDT", "ADAUSDT"
]
}
]
Resultado: o testador vai rodar o teste, um de cada vez, para cada um dos 10 pares.
Exemplo 2: varredura de vários parâmetros ao mesmo tempo
Vamos adicionar, além da varredura de pares, uma varredura do valor de % do take-profit — de 0% a 10% em passos de 0.5 (21 valores no total).
Número de combinações: 10 pares × 21 valores = 210 execuções.
"parameter_mining": [
{
"name": "settings[*].basic.symbol",
"start": 1.0,
"end": 1.0,
"step": 1.0,
"values": [
"1000BONKUSDT", "1000FLOKIUSDT", "1000LUNCUSDT",
"1000NEIROCTOUSDT", "1000PEPEUSDT", "1000TAGUSDT",
"4USDT", "AAVEUSDT", "ACHUSDT", "ADAUSDT"
]
},
{
"name": "settings[*].options.take_profit_long",
"start": 0,
"end": 10.0,
"step": 0.5,
"values": []
}
]
Exemplo 3: configurando uma varredura
Demonstração em vídeo
Todas as estratégias do bot também estão disponíveis em formato PineScript para testes no TradingView.