Coleções/12 partes/217 min no total

High-Performance Backtest Engines

How to build a backtest engine that runs hundreds of times faster without changing a single PnL number - data layout, caching, adaptive resolution, and architecture, from first speedups to production internals.

01

VectorBT: The Fastest Backtesting Framework for Python

Overview of VectorBT - an innovative quantitative analysis library that changes the approach to backtesting thanks to the power of NumPy and Numba.

02

A Escada de Velocidade do Backtest: 298x em uma CPU de Laptop, PnL Idêntico Até o Último Trade

Cinco implementações do mesmo sweep de 80 combinações de parâmetros, todas verificadas para produzir PnL idêntico: pandas rolling.apply leva 69,9 segundos, numpy 3,1, numba 2,0, numba paralelo 0,23 - um speedup medido de 298x em um Apple M2 Max sem nenhuma mudança de hardware, e ainda assim ~13x sobre uma baseline vetorizada competente. O que cada degrau compra, por que a GPU não é a peça que falta, e onde realmente está o gargalo na busca massiva de parâmetros.

03

O imposto do framework: quando sua biblioteca de backtest é mais lenta que um loop ingênuo de pandas

Comparamos oito motores de backtest em uma mesma varredura de parâmetros idêntica - 150k barras, 80 combinações de cruzamento de HMA, com a paridade de número de operações travada em 2707. Dois dos frameworks orientados a eventos mais populares ficaram mais lentos que um loop de pandas escrito à mão, enquanto um motor vetorizado/compilado rodou o mesmo trabalho cerca de 13,000× mais rápido. Um estudo sobre a sobrecarga por barra que as bibliotecas populares nunca foram feitas para amortizar.

04

Cache Parquet Agregado: Como Acelerar Backtests Multi-Timeframe Centenas de Vezes

Como pré-calcular timeframes e indicadores a partir de candles de um minuto, salvá-los em parquet e usá-los para testes em massa de estratégias sem recálculos redundantes.

05

O espaço de parâmetros de dois eixos: por que a maior parte do seu sweep deveria ser quase gratuita

Nem todos os parâmetros custam o mesmo para pesquisar. Os parâmetros de uma estratégia dividem-se num eixo caro (indicadores - recalculados sobre toda a série) e num eixo barato (limiares de decisão - uma passagem O(n) sobre sinais pré-calculados). Como os indicadores são invariantes aos limiares, calculam-se uma vez e percorrem-se milhares de configurações de limiares a ~5.600 cfg/s - cerca de 1.600 vezes mais barato do que recalcular por configuração. Uma reavaliação do custo da maldição da dimensionalidade.

06

Drill-Down Adaptativo: Backtest com Granularidade Variável de Minutos a Trades Brutos

Como a granularidade adaptativa de dados acelera backtests e economiza armazenamento: drill-down de 1m para 1s, 100ms e trades brutos apenas onde o preço se moveu significativamente ou o volume disparou, não em toda a série histórica.

07

O Portão de Fidelidade: o Backtest do Grosseiro ao Fino Engana Você Mais Rápido, a Menos que o Proxy Barato Classifique Como o Caro

A busca drill-down / multi-fidelidade (ASHA, eliminação sucessiva, Hyperband) filtra milhares de configs de forma barata e promove apenas os sobreviventes para a avaliação completa e cara. É um ganho de velocidade genuíno - mas colapsa silenciosamente se a classificação de baixa fidelidade discordar da de alta fidelidade. Medimos a correlação de ranking por dobra: em uma dobra, o ρ de Spearman pode ser 0.03 (classifica quase aleatoriamente), subindo para 0.43, 0.67, 0.78, 0.91 à medida que as dobras se acumulam. A correção é um portão obrigatório - meça ρ(barato, completo) primeiro, e eleve automaticamente a fidelidade mínima para o primeiro degrau em que ρ ≥ 0.5.

08

Busca Aleatória vs. Busca Inteligente: o Cruzamento é o Custo de Avaliação, Não o Algoritmo

Quando um backtest é barato, o Sobol embaralhado e burro vence em throughput bruto - samplers inteligentes (TPE, CMA-ES, ASHA) pagam uma taxa de ask/tell em Python que os derruba em 20x, fazendo com que avaliem muito menos pontos no mesmo tempo de relógio e percam. Torne cada avaliação cara (multi-TF + folds de walk-forward) e o cruzamento se inverte. Medimos os dois regimes, e por que a fidelidade de rank por fold (ρ@1 subindo de 0.03→0.43) é a pré-condição para que o pruning valha a pena.

09

Descida por Coordenadas vs. Otimização Bayesiana: Quem Encontra Melhores Parâmetros

Por que a busca exaustiva é impossível com 12+ parâmetros, como a descida por coordenadas deixa passar interações, e como o Optuna com um sampler TPE encontra em 500 iterações o que o OAT não consegue encontrar em 96. Exemplos práticos de código, comparação de samplers e otimização multiobjetivo.

10

A Armadilha de Precisão da GPU: Como um Backtest em fp32 na Apple Metal Retorna Lixo Silenciosamente

A GPU Metal da Apple não tem float64. Portar um backtest vetorizado para ela de forma ingênua faz a tentadora WMA por soma de prefixos estourar o fp32 - erro relativo máximo de 211× - mas ainda assim ele roda e devolve números com aparência plausível. A correção não é mais precisão; é uma formulação diferente: uma convolução direta por janela, segura em fp32 até 8×10⁻⁷ e 55.9× mais rápida que o numba de thread única. A armadilha, a aritmética por trás dela, e como provar que você não caiu nela.

11

Quando a GPU Compensa: O Roofline do Sweep de Parâmetros, Onde um 167x de Manchete É na Verdade 27x de Algoritmo Vezes 6.2x de Hardware

A vantagem da GPU sobre a CPU cresce com o tamanho do batch - de 54.5x com um combo por chamada até 359.6x com 61 na nossa pré-computação de indicadores multi-timeframe - porque um sweep pequeno não consegue amortizar o overhead de lançamento de kernel e de transferência. Decompomos um 167x de manchete em uma vitória algorítmica de 27x que também ajuda a CPU e uma vitória de hardware de 6.2x, mostramos que a vantagem verdadeira GPU-vs-melhor-CPU é de apenas 3.2x em single-timeframe e 6.2x em multi, e damos um guia de decisão sobre quão largo um sweep precisa ser antes que valha a pena apostar em uma GPU.

12

O imposto IPC: coloque o motor de backtest atrás de um socket e perca 13% - quase nada disso é do socket

Portamos um kernel de backtest numba linha por linha para Rust e o chamamos através de uma fronteira de processo de quatro formas, com um portão de equivalência confirmando PnL idêntico até a última operação. Enviar toda a série de preços de 1,2 MB por um socket Unix custa ~2 ms - cerca de 0,1% do trabalho. Codificar o mesmo payload em JSON custa 1348x mais que bytes brutos, chamadas tagarelas por combinação reenviam os dados 80 vezes, e um padrão de chamada por barra pagaria 2,1 s de IPC pura em um trabalho de 2,0 s. A fronteira é barata; o imposto está em como você a atravessa.