PESQUISA · SISTEMAS

Um backtester walk-forward reproduzível

Paridade entre linguagens, segmentação de regimes e testes de robustez para pesquisa sistemática.

Um backtester de nível pesquisa implementado em Python e Rust. A paridade entre linguagens detecta diferenças entre as implementações, enquanto os controles cobrem testes walk-forward, custos realistas e robustez. O código é open source sob Apache 2.0. Os exemplos incluídos rodam sem download; o benchmark de 150.000 candles tem uma receita de dados reproduzível separada.

Em breve

Working Paper SSRN

Em revisão, ainda não publicado.

Código no GitHub

github.com/DaruFinance/quant-research-framework-rs

Em resumo

Execução walk-forward completa

7,20 s Rust · 112,37 s Python

Um lote de 150.000 candles cobriu 10 configurações fixas e 28 janelas walk-forward. Rust foi 15,61× mais rápido nesta observação, com ledgers Rust idênticos antes e depois da correção de escrita em buffer.

Execução equivalente

4 motores · 20.137 trades cada

Um teste separado de eventos congelados comparou QRF Rust, QRF Python, Backtesting.py e vectorbt nas mesmas ordens long-only. Cronologia e preços coincidiram, com P&L normalizado dentro de 7,28e-12.

Paridade

Diferenças viram falhas de teste

Comparar suas saídas pode revelar erros de port, mas não prova edge nem elimina erros comuns às duas implementações.

O que é isto

A maioria dos backtesters open source fornece um loop de execução e deixa a disciplina de pesquisa ao usuário: como separar dados in-sample e out-of-sample, se indicadores podem enxergar o futuro e como os resultados mudam após taxas, slippage e funding. Este framework coloca esses controles no motor com otimização walk-forward, segmentação de regimes, configurações de realismo e cinco cenários de robustez. Um invariante do ledger de trades impede que uma estratégia negocie uma barra ainda não fechada.

A mesma especificação é implementada em Python e Rust e comparada ponto a ponto. Essa camada de paridade detecta diferenças entre implementações; ela não estabelece uma edge lucrativa nem protege contra um erro compartilhado. As figuras distinguem resultados históricos de pesquisa das medições de desempenho de setembro de 2026.

Como as peças se encaixam

Os dados passam por um núcleo compartilhado de indicadores para um contrato de estratégia que retorna um sinal por barra. O núcleo de execução aplica custos; então o orquestrador walk-forward reotimiza e testa cada janela. Ao fim, o arnês de paridade compara os ledgers de métricas das duas implementações.

Fig. 1:Arquitetura do sistema. Uma referência Python e um port Rust implementam a mesma especificação; um arnês de paridade compara seus ledgers de métricas.

Walk-forward por construção

Cada iteração otimiza em uma janela in-sample móvel, testa a próxima subjanela out-of-sample e avança. Nenhuma janela é pontuada nas observações usadas para ajustá-la.

Fig. 2:Esquema walk-forward móvel. A janela in-sample (IS, comprimento L_IS) avança antes de cada teste out-of-sample (OOS, comprimento V).

O que uma execução produz

O exemplo histórico desta seção usa a estratégia EMA-crossover incluída em SOL/USDT 1h. Ele emite relatórios otimizados in-sample e out-of-sample, cinco cenários de robustez e 18 janelas walk-forward móveis. Essas figuras pertencem a esse exemplo, não aos testes posteriores de desempenho com 150.000 candles.

O exemplo perde dinheiro, o que torna os controles mais fáceis de inspecionar: cada saída mostra onde uma estratégia fraca falha em vez de se tornar uma recomendação de negociação.

Curva de capital da estratégia otimizada fora da amostra, com quatro cenários de robustez sobrepostos, todos abaixo do saldo inicial.
Fig. 3:Exemplo histórico SOL/USDT. Capital otimizado fora da amostra com quatro sobreposições de robustez; os estresses de taxas e slippage aprofundam a perda.

No exemplo histórico, a curva walk-forward concatenada subiu. O procedimento não garante esse resultado: cada janela in-sample escolhe um novo lookback antes do próximo teste out-of-sample, por isso os controles de agregado e deflação continuam necessários.

Curva de capital walk-forward móvel em alta, com sobreposições de robustez e a primeira fronteira in-sample marcada.
Fig. 4:Exemplo histórico SOL/USDT. Capital walk-forward com as mesmas sobreposições; cada janela é ajustada apenas em seus dados in-sample anteriores.

As métricas que imprime

Neste exemplo, o Sharpe otimizado fora da amostra é -2,91 após os custos.

relatório otimizado in-sample + out-of-sample
  IS-opt  (LB 47) | Trades: 118   ROI: $-735.77     PF: 0.61   Sharpe: -2.69   MaxDD: $804.82
 OOS-opt  (LB 47) | Trades: 755   ROI: $-2,077.85   PF: 0.81   Sharpe: -2.91   MaxDD: $2,258.93

A varredura de robustez reexecuta a base otimizada sob quatro perturbações. O choque de slippage é o pior caso; um atraso de entrada de uma barra muda menos. A diferença registra sensibilidade a premissas fora do controle da estratégia.

varredura de robustez (fora da amostra)
 Baseline OOS | ROI: $-2,077.85   PF: 0.81   Sharpe: -2.91   MaxDD: $2,258.93
     ENT OOS | ROI: $-1,623.33   PF: 0.84   Sharpe: -2.30   MaxDD: $1,809.32   entry drift +1 bar
     FEE OOS | ROI: $-2,832.73   PF: 0.74   Sharpe: -3.99   MaxDD: $2,876.37   fees x2
     SLI OOS | ROI: $-4,303.79   PF: 0.64   Sharpe: -6.11   MaxDD: $4,346.15   slippage shock
 ENT+IND OOS | ROI: $-1,629.68   PF: 0.85   Sharpe: -2.29   MaxDD: $1,875.23   drift + indicator jitter

O relatório móvel mostra cada janela separadamente. W01 ganha US$ 899,57 fora da amostra, mas as janelas posteriores e o resultado agregado determinam se a estratégia sobrevive à avaliação.

janelas walk-forward (W01 de 18)
 Running Walk-Forward Windows
  W01 IS  (LB 47) | Trades: 118   ROI: $308.25   PF: 1.14   Sharpe:  0.63   MaxDD: $448.35
 W01 OOS  (LB 47) | Trades:  92   ROI: $899.57   PF: 1.57   Sharpe:  1.95   MaxDD: $243.77
  ...   W02 through W18 each re-optimise on the rolling in-sample window
        and forward-test the next window on data they never saw   ...

Três modos Monte Carlo

A fila deixa explícita a regra de amostragem. A permutação de trades reordena retornos concluídos sem reposição. A reamostragem de trades os sorteia com reposição. A permutação de barras reconstrói trajetórias OHLCV, depois regenera sinais e roda novamente uma estratégia e um conjunto de parâmetros congelados em cada trajetória. Cada modo selecionado produz seu próprio resultado, e o modo de barras não é acionado pela API comum de retornos de trades.

A permutação de barras é cara: seu padrão de 500 execuções implica centenas de backtests completos. A estratégia EMA incluída usa o worker Rust do repositório nos dois pacotes; uma estratégia Python personalizada usa o caminho explícito de callback Python.

Consistency é o exemplo de score de otimização personalizado de Daniel Gatto, não uma métrica financeira padrão. Usuários podem substituir no código seu cálculo e a busca pelo objetivo pelo próprio score.

Fig. 5:Três cargas de trabalho Monte Carlo distintas. Selecione um modo para inspecionar o que é amostrado, reexecutado e salvo.

Desempenho, medido de duas formas

O primeiro painel mede um lote walk-forward completo em 150.000 candles reais BTCUSDT spot de 30 minutos: 5 famílias de estratégias, cada uma com 2 lookbacks fixos, em 28 janelas fora da amostra. O segundo isola um contrato de execução comum em 4 motores com eventos de ordem congelados. Eles respondem perguntas diferentes e suas razões não são intercambiáveis. Método do benchmark, resultados brutos e receita de dados.

Fig. 6:Tempo observado e RSS de pico para 2 cargas distintas de 150.000 candles. Cada motor rodou uma vez em processo novo no mesmo host WSL; caches do sistema operacional e bibliotecas não foram reiniciados.

Paridade entre linguagens

O registro histórico de paridade abaixo cobre 210 pontos de métricas do núcleo determinístico em 3 superfícies de configuração. Ele é separado dos novos benchmarks de 10 configurações: suas métricas walk-forward completas diferiram no máximo 6,66e-14 e seus ledgers de execução equivalente concordaram em cronologia, lado, preços e quantidade normalizada.

Fig. 7:Registro histórico de paridade. Todos os 210 pontos de métricas do núcleo determinístico nas superfícies padrão, regime mais walk-forward e forex ficaram dentro de 1e-3; o maior desvio observado foi cerca de 5e-5.

Como se compara

Cada capacidade existe em outros backtesters. Este projeto as combina e torna os controles de pesquisa aplicáveis, em vez de convenções opcionais.

Lista completa de recursos

PBO e DSR aparecem primeiro porque avaliam se um resultado otimizado merece análise adicional. Os rótulos abaixo distinguem o pipeline principal, os relatórios opcionais, as APIs independentes e os pacotes opcionais.

Clone e examine os exemplos incluídos

Os comandos abaixo usam os dados de exemplo do repositório, sem chave API ou download. O benchmark de 150.000 candles é separado e usa a receita de dados reproduzível ligada na documentação do benchmark.

As estratégias incluídas demonstram o pipeline, não reivindicam uma edge negociável. Perdas fora da amostra após custos mostram que o motor expõe uma estratégia fraca em vez de ocultá-la.

Citação

O artigo associado está em revisão na SSRN. Até ser publicado, cite o framework pelo repositório.

Veja também

Leia o teste de permutação dentro da estratégia para o método de seleção que este backtester suporta e visite a Research Review para reproduções independentes baseadas em walk-forward e avaliação consciente de deflação.