← Voltar aos artigos
June 28, 2026
5 min read

Design da função objetivo: a métrica que você otimiza escolhe secretamente sua estratégia

#algotrading
#backtest
#overfitting
#objective-function
#optimization
#sharpe
#validation
🎯
Part 1 of 9 · Collection
Backtesting Without Fooling Yourself

Parte da série "Backtests sem ilusões".

📄 Este artigo cresceu até virar um paper de pesquisa. Cada número abaixo vem de um único script determinístico que constrói uma verdade fundamental controlada — um mercado sintético com um edge conhecido numa banda de sinal moderada e ruído de cauda pesada em toda parte — e então executa uma busca de limiar sob seis funções objetivo diferentes, medindo, fora da amostra, qual estratégia cada objetivo de fato seleciona. Leia o paper online (versão interativa + PDF) em objective-design.marketmaker.cc, código e dados em github.com/suenot/objective-design-degeneracy.

Você quer a melhor estratégia. Então roda uma busca — varre um limiar, um lookback, uma distância de stop, e mantém a configuração com a maior pontuação. A busca termina e entrega um vencedor. Razoável. Padrão. É o que todo otimizador, grid search e ajustador de hiperparâmetros na Terra faz.

Mas observe o verbo: maior pontuação. Maior em quê? Antes que a busca possa coroar qualquer coisa, você teve que dar a ela um único número a maximizar — uma função objetivo. PnL. Sharpe. Sharpe sobre as barras operadas. Retorno sobre drawdown máximo. Você digitou uma dessas, provavelmente sem pensar muito, e então a busca gastou um milhão de avaliações fazendo exatamente o que você pediu.

Essa escolha não é uma formalidade. É toda a decisão. A busca não encontra "uma boa estratégia" — isso não existe no abstrato. Ela encontra a estratégia que maximiza o escalar que você escolheu, e escalares diferentes apontam para estratégias radicalmente diferentes nos mesmos dados. O objetivo é a mão secreta no volante, e na maior parte do tempo ninguém está olhando para ela.

Aqui está o artigo inteiro em uma tabela. Uma busca de limiar, um mercado sintético com um edge real e conhecido, seis objetivos — e as seis estratégias que eles selecionam, medidas em dados reservados:

Objetivo (o que a busca maximiza) Exposição média ao mercado Sharpe in-sample Sharpe fora da amostra Vencedores degenerados
PnL bruto 0.859 1.76 1.61 0%
Sharpe de linha do tempo completa 0.740 1.82 1.71 0%
Sharpe por trade ("ativo") 0.286 1.00 0.70 57%
Piso de exposição (emin=0.20e_{\min}=0.20) 0.740 1.82 1.71 0%
Shrinkage por número de trades (conf_k=40=40) 0.523 1.54 1.31 20.7%
Robusto (piso + conf_k) 0.675 1.78 1.70 0.2%

600 seeds independentes, T=2000T = 2000 barras cada, 80 limiares candidatos por busca, in-sample e out-of-sample extraídos independentemente. Sharpe anualizado (252 períodos/ano). "Degenerado" = o vencedor selecionado está no mercado menos de 5% do tempo, ou registra um Sharpe fora da amostra não positivo. O ótimo verdadeiro deste mercado é um Sharpe anualizado fora da amostra de 1.77.

Leia a terceira linha até doer. O Sharpe por trade — um representante de toda a família de métricas condicionadas à atividade (Sharpe por trade, expectancy, o SQN de van Tharp, taxa de acerto), todas calculadas apenas nas barras operadas — seleciona uma estratégia que, fora da amostra, é pior que metade das outras, e faz isso de forma degenerada em 57% das vezes. Não é um objetivo sutilmente pior. Nestes dados é uma armadilha, e a busca cai nela mais da metade das vezes. Agora leia a linha logo acima: o simples Sharpe de linha do tempo completa nunca degenera e pontua 1.71 fora da amostra. Esse é o desfecho de todo o conserto, revelado cedo — a solução honesta é simplesmente medir na linha do tempo completa; os remendos mais sofisticados nas linhas inferiores, na melhor das hipóteses, apenas igualam esse número, nunca o superam. Este artigo é a anatomia dessa armadilha e do seu conserto, com a verdade fundamental conhecida o tempo todo, de modo que "o objetivo escolheu a estratégia certa?" é um fato, não uma opinião.

Ato 1 — A decisão secreta: a lei de Goodhart é a busca

A parameter search drawn as a funnel of many candidate strategy curves, with a single lens labeled OBJECTIVE stamping one curve as the winner while identical-looking curves are discarded, illustrating that the choice of metric silently selects the strategy

Em 1975 o economista Charles Goodhart escreveu uma frase que sobreviveu a tudo mais que ele fez:

"Any observed statistical regularity will tend to collapse once pressure is placed upon it for control purposes."

A paráfrase popular, geralmente atribuída a Marilyn Strathern, é mais direta: quando uma medida vira uma meta, ela deixa de ser uma boa medida.

Uma busca de parâmetros é a instância mais pura possível da lei de Goodhart. A função objetivo é a medida. A busca é a pressão — milhares, milhões de tentativas de empurrar essa medida o mais alto possível. E a busca não se importa nem um pouco com o que você quis dizer com a medida. Ela só se importa com o número. Se houver qualquer maneira de tornar o número grande que não tenha nada a ver com um edge real e operável — operar raramente, ficar parado a maior parte do tempo, capturar alguns outliers sortudos — a busca encontrará essa maneira, porque encontrar o máximo é a única coisa para a qual ela foi construída.

Essa é a mesma falha que a literatura de segurança em IA chama de reward hacking: um agente que otimiza uma proxy do que você quer explorará toda brecha entre a proxy e o objetivo real. Sua busca é esse agente. "Sharpe ratio" é essa proxy. "Uma estratégia em que eu possa confiar para operar dinheiro real no próximo trimestre" é o objetivo real. A brecha entre eles é onde vive toda a disciplina.

Para observar essa brecha se abrir, precisamos de um mundo onde conhecemos a verdade. Então construímos um.

O mercado. A cada período, um preditor sts_t (um sinal normal padrão) chega, seguido do retorno rtr_t que ele parcialmente prevê. O edge é real, mas limitado — existe apenas dentro de uma banda de sinal moderada st1|s_t| \le 1, e desaparece fora dela:

rt=βst1[st1]+εt,β=0.3,εtt4 (unit variance).r_t = \beta\, s_t \cdot \mathbf{1}\big[\,|s_t| \le 1\,\big] + \varepsilon_t, \qquad \beta = 0.3, \qquad \varepsilon_t \sim t_{4}\ (\text{unit variance}).

Duas escolhas de design importam. Primeiro, o edge vive na banda moderada: sinais extremos não carregam informação preditiva, então uma estratégia deveria operar o meio e pular as caudas. Segundo, o ruído εt\varepsilon_t é de cauda pesada (Student-tt com 4 graus de liberdade, o tipo de cauda pesada que os retornos reais de fato têm) — mas esse ingrediente está aqui por realismo, não por mecanismo. É tentador dizer que as caudas pesadas são o que torna a armadilha possível, e foi exatamente isso que assumimos até rodarmos o controle: uma versão com ruído gaussiano deste mercado (gaussian_control nos resultados, 300 seeds) reproduz a armadilha essencialmente inalterada — o objetivo por trade ainda degenera 55.7% do tempo sob ruído gaussiano contra 57.0% com caudas pesadas, e seu Sharpe fora da amostra é 0.71 contra 0.70. Então a armadilha não é sobre caudas pesadas. É um efeito puro de amostra pequena mais seleção: pegue o máximo, entre ~20 limiares de baixa exposição, de um Sharpe calculado sobre um punhado de observações, e algum canto sortudo sempre vai parecer espetacular. Qualquer distribuição de ruído faz isso; uma estratégia no mercado por apenas algumas barras pode, por pura sorte, atravessar alguns movimentos favoráveis e registrar um número in-sample que não significa nada. Mantemos as caudas pesadas porque os retornos reais as têm, não porque a armadilha precise delas.

A estratégia. Uma família de um parâmetro. Opere na direção do sinal sempre que sua magnitude estiver abaixo de um limiar θ\theta, caso contrário fique parado:

post=sign(st)1[stθ].\text{pos}_t = \operatorname{sign}(s_t)\cdot \mathbf{1}\big[\,|s_t| \le \theta\,\big].

Um θ\theta minúsculo opera apenas nos sinais menores e mais discretos — uma loteria de trades raros, quase nunca no mercado. Um θ\theta próximo da borda da banda captura todo o edge real e está bem exposto. Um θ\theta enorme opera tudo, incluindo as barras fora da banda que não carregam edge e só adicionam ruído.

def gen_dataset(T, rng, beta=0.30, band=1.0, tail_df=4):
    s    = rng.standard_normal(T)
    edge = beta * np.where(np.abs(s) <= band, s, 0.0)          # edge ONLY inside |s| <= 1
    t    = rng.standard_t(tail_df, T) / np.sqrt(tail_df / (tail_df - 2.0))  # fat tails, unit var
    return s, edge + t

def simulate(s, r, theta):
    pos      = np.where(np.abs(s) <= theta, np.sign(s), 0.0)   # trade the band, skip outliers
    strat    = pos * r
    active   = pos != 0.0
    exposure = active.mean()                                   # fraction of bars in a position
    sharpe_full   = strat.mean()         / strat.std(ddof=1)            # on the WHOLE timeline
    sharpe_active = strat[active].mean() / strat[active].std(ddof=1)    # on ONLY the active bars
    return dict(exposure=exposure, n_trades=int(active.sum()),
                sharpe_full=sharpe_full, sharpe_active=sharpe_active, pnl=strat.sum())

Como nós construímos o mercado, podemos calcular a verdade diretamente — desempenho médio em cada limiar sobre as 600 seeds, fora da amostra. O ótimo verdadeiro fica em θ1.04\theta \approx 1.04: bem na borda da banda de sinal, no mercado cerca de 70% do tempo (derivado: um sinal normal padrão cai dentro de s1.04|s|\le 1.04 com probabilidade P(s1.04)=0.70P(|s|\le 1.04)=0.70), registrando um Sharpe anualizado fora da amostra de 1.77. Esse é o número que todo objetivo está tentando encontrar. Mantenha-o em mente: θ≈1.04, Sharpe OOS 1.77, cerca de 70% da linha do tempo no mercado. Qualquer coisa que um objetivo selecione longe disso é uma falha do objetivo, não uma dificuldade do mercado.

Ato 2 — A armadilha: oito trades sortudos, um Sharpe de 21, uma miragem

A slot machine paying out on a single lucky spin, showing eight trade tickets and a towering in-sample per-trade Sharpe of 21 that collapses to 0.13 out of sample, dramatizing a rare-trade lottery winner selected by a naive objective

Agora vamos soltar um objetivo ingênuo em uma tiragem concreta deste mercado — seed 6. Divulgação completa sobre a seed: ela não foi a primeira tiragem nem uma aleatória. Escaneamos seeds procurando um vencedor por trade marcadamente degenerado e escolhemos esta, precisamente para que o mecanismo seja impossível de ignorar. O resultado que ela mostra é totalmente típico — como o Ato 3 vai confirmar, o objetivo por trade escolhe uma loteria com menos de 5% de exposição em 56% de todas as seeds — mas a magnitude da seed 6 está na extremidade dessa distribuição. Leia-a como uma instância especialmente marcante de uma falha comum, não como uma mediana. Otimizamos o Sharpe por trade: o Sharpe ratio calculado apenas nas barras em que a estratégia está de fato posicionada. É algo extremamente natural de reportar. "Quando opera, quão boas são suas operações?" Parece isolar habilidade de inatividade. Faz o oposto.

Aqui está a estratégia que o Sharpe por trade coroa na seed 6:

  • Limiar θ=0.005\theta = 0.005 — opera apenas nos sinais menores possíveis.
  • Exposição ao mercado 0.4% — parado 99.6% do tempo.
  • Oito trades. Oito. Em 2000 barras.
  • Sharpe anualizado por trade in-sample: 21.09.
  • Sharpe de linha do tempo completa in-sample: 0.82.
  • Sharpe de linha do tempo completa fora da amostra: 0.13.

A métrica por trade marca 21.09 — um número que nenhuma estratégia real jamais registrou, do tipo que lançaria um fundo. E é uma miragem completa. Aqueles oito trades pegaram por acaso alguns movimentos favoráveis; medido apenas nessas oito barras, a razão entre média e desvio padrão é astronômica. Mas na linha do tempo completa — onde a estratégia está parada 99.6% do tempo — esse "edge" contribui com praticamente nada: um Sharpe de linha do tempo completa de 0.82 in-sample, que desaba para 0.13 em dados novos. O vencedor selecionado pelo objetivo é, para todos os efeitos de negociação, parado.

E nem sequer é um edge real naquele limiar. Lembre-se do mercado: o edge vive na banda s1|s|\le 1, e θ=0.005\theta = 0.005 está bem no centro morto onde o sinal é mais fraco. A curva verdadeira fora da amostra em θ=0.005\theta = 0.005 é −0.01 — indistinguível de zero (derivado da curva de verdade fundamental). A busca não encontrou um pequeno edge real. Encontrou oito tiragens sortudas de ruído e as reportou como um Sharpe de 21.

Esta é a armadilha em miniatura: o Sharpe por trade recompensa a estratégia por operar o mais raramente possível, porque quanto menos barras você mantém, mais fácil é que algumas delas sejam sortudas, e a métrica nunca pergunta "mas você realmente esteve no mercado?" A magnitude da seed 6 foi escolhida a dedo — buscamos deliberadamente uma marcante — mas seu tipo não foi. Em todas as 600 seeds, o Sharpe por trade seleciona um vencedor degenerado (um que mal opera, ou perde fora da amostra) em 57% delas, e especificamente uma loteria com menos de 5% de exposição em 56%. A escolha degenerada típica é bem mais amena que o Sharpe de 21 da seed 6: em média sobre as 600 seeds, o vencedor do objetivo por trade tem um Sharpe por trade in-sample de 4.58 e exposição média 0.286 — ainda parado a maior parte do tempo, só que não 99.6% parado. A seed 6 dramatiza o mecanismo; os 56% são a parte que deveria preocupar você. Mais da metade das vezes, essa métrica cotidiana entrega um bilhete de loteria e o chama de estratégia.

Ato 3 — A verdade estatística: seis objetivos, 600 seeds

Six objective functions as contestants on a leaderboard, the per-trade Sharpe glowing brightest in sample but stamped degenerate 57 percent while the exposure-aware objectives hold steady out of sample, illustrating that a great in-sample number does not mean a good selection

Uma seed não prova nada; apenas ilustra. Para medir um objetivo precisamos perguntar o que ele seleciona em média, através de muitos mercados independentes, e pontuar essa seleção em dados que a busca nunca viu. Então: 600 seeds, cada uma uma tiragem independente do mercado; em cada uma, rodamos a busca de 80 limiares sob cada objetivo; registramos a exposição, o Sharpe in-sample e fora da amostra do que foi escolhido, e se essa escolha foi degenerada.

Objetivo Exposição média Sharpe in-sample Sharpe fora da amostra Queda IS→OOS (abs.) Degenerado
PnL bruto 0.859 1.76 1.61 0.15 0.0%
Sharpe de linha do tempo completa 0.740 1.82 1.71 0.11 0.0%
Sharpe por trade 0.286 1.00 0.70 0.30 57%
Piso de exposição (emin=0.20e_{\min}=0.20) 0.740 1.82 1.71 0.11 0.0%
Shrinkage conf_k (k=40k=40) 0.523 1.54 1.31 0.23 20.7%
Robusto (piso + conf_k) 0.675 1.78 1.70 0.08 0.2%

A coluna "Queda IS→OOS" é a queda absoluta no Sharpe anualizado de in-sample para fora da amostra (por exemplo, 1.000.701.00\to0.70 é uma queda de 0.30), não uma porcentagem. E observe que a linha "Piso de exposição" é idêntica byte a byte a "Sharpe de linha do tempo completa": isso não é coincidência, e o Ato 5 explica por quê.

Três fatos saltam aos olhos, e cada um é uma lição.

O Sharpe por trade é o único objetivo ingênuo que degenera. Sua exposição média é 0.286 — ele seleciona estratégias que ficam paradas a maior parte do tempo — e seu Sharpe in-sample de 1.00 cai 0.30 para um fora da amostra de 0.70, o pior do grupo. Note o indício: seu número in-sample (1.00) nem sequer é impressionante, mas em qualquer seed individual ele reportará alegremente uma cifra por trade de 21. A média se dilui porque as janelas sortudas apontam em direções aleatórias; o que sobrevive até fora da amostra é apenas 0.70, e 57% das seleções individuais são pura lixo.

Objetivos conscientes da exposição são naturalmente seguros. PnL bruto e Sharpe de linha do tempo completa nunca degeneram (0.0%). A razão é estrutural: ambos são medidos sobre a totalidade da linha do tempo, então uma estratégia parada 99.6% do tempo ganha quase nada sob eles. Você não consegue manipular uma métrica de linha do tempo completa operando raramente — ficar parado é penalizado direta e automaticamente, porque as barras paradas estão no denominador. Esta é a ideia mais importante do artigo, e voltamos a ela no Ato 6.

O PnL bruto é seguro mas não ótimo — ele sobre-expõe. Olhe de perto: a exposição média do PnL bruto é 0.859, a mais alta de todas, e seu Sharpe fora da amostra (1.61) fica um degrau abaixo do Sharpe de linha do tempo completa (1.71) e do ótimo verdadeiro (1.77). O PnL recompensa estar no mercado, então a busca empurra θ\theta alto demais (na seed 6, o PnL bruto escolhe θ=1.84\theta=1.84 contra o ótimo 1.04), arrastando barras fora da banda que não carregam edge e só adicionam ruído. Ele não explode — mas se desvia do ótimo real na direção oposta à armadilha por trade. Objetivo diferente, viés diferente, mesma lição: a métrica escolheu a estratégia.

As duas linhas que ainda não discutimos — o piso de exposição e conf_k — são o conserto. Esse é o próximo ato.

Ato 4 — Por que oito trades nunca podem ser confiáveis

A single Sharpe point estimate marked with an enormous confidence-interval error bar because it rests on only eight observations, beside a ruler labeled minimum track record length, illustrating that a ratio measured on a handful of trades is statistically meaningless

Antes de consertar a armadilha, vale ser preciso sobre por que oito trades produzem um Sharpe de 21 que não significa nada — porque a solução decorre diretamente dessa razão.

Um Sharpe ratio é uma estimativa, e estimativas têm margens de erro. O resultado de Andrew Lo de 2002 dá o erro padrão de um Sharpe ratio estimado a partir de TT observações, sob a suposição mais generosa possível (retornos gaussianos IID):

SE(SR^)1+SR^2/2T.\operatorname{SE}\big(\widehat{SR}\big) \approx \sqrt{\frac{1 + \widehat{SR}^{\,2}/2}{T}}.

O erro diminui apenas como 1/T1/\sqrt{T}. Vamos aplicá-lo à armadilha. O Sharpe por trade na seed 6 é 21.0921.09 anualizado, o que é 1.331.33 por observação, calculado sobre T=8T = 8 barras. O erro padrão é

SE1+1.332/280.49 por observac¸a˜o = 7.7 anualizado\operatorname{SE} \approx \sqrt{\frac{1 + 1.33^2/2}{8}} \approx 0.49 \ \text{por observação} \ = \ \textbf{7.7 anualizado}

(derivado da fórmula de Lo). A estimativa pontual é 21.0921.09; sua margem de erro de um sigma é da ordem de ±7.7\pm 7.7 — leia isso como uma ordem de grandeza ilustrativa, não como um intervalo de confiança calibrado, já que a fórmula assume retornos gaussianos IID que nosso ruído de cauda pesada t4t_4 viola. Ainda assim, a mensagem é inequívoca: o "Sharpe de 21" é um número tirado de uma distribuição tão larga que carrega praticamente nenhuma informação — e esse é o cálculo caridoso, porque a extensão de Mertens mostra que caudas pesadas e assimetria apenas inflam ainda mais o erro padrão. O Sharpe de um backtest com trades raros é menos confiável que seu valor pontual em todas as direções ao mesmo tempo: poucas observações demais, e a distribuição errada.

É exatamente isso que a Minimum Track Record Length formaliza (Bailey & López de Prado, 2012). Ela inverte a pergunta — quantas observações eu preciso antes de poder acreditar num Sharpe deste tamanho com confiança pp?

MinTRL=1+[1γ^3SR^+γ^414SR^2](Z1pSR^SR)2,\text{MinTRL} = 1 + \Big[\,1 - \hat\gamma_3\,\widehat{SR} + \tfrac{\hat\gamma_4 - 1}{4}\,\widehat{SR}^{\,2}\,\Big]\left(\frac{Z_{1-p}}{\widehat{SR} - SR^*}\right)^{2},

transformando "confie menos em backtests com poucos trades" num número explícito e verificável de trades. O ponto profundo para o design de objetivos é este: um bom objetivo deveria impor um track record mínimo de dentro para fora, em vez de deixar um humano notar, depois do fato, que o vencedor repousa sobre oito observações. O Sharpe por trade faz o oposto — ele é maximizado ao empurrar a contagem de observações em direção ao mínimo. Qualquer objetivo cujo ótimo esteja em "o menor número possível de trades" é, por construção, um objetivo que busca sua própria estimativa menos confiável.

Duas falhas se combinam na armadilha, e nomeá-las nos diz como corrigi-la. Primeiro, ruído de amostra pequena: oito observações não conseguem fixar nenhuma razão. Segundo, seleção: essas oito barras não nos foram dadas — a busca escolheu o limiar que caiu nelas, em parte porque elas foram sortudas. A busca é um maximizador; ela sempre encontrará o canto do espaço onde o ruído por acaso parece sinal. Não é possível contornar isso com uma estimativa pontual melhor. É preciso mudar o que "melhor" significa para que o canto sortudo não seja o máximo.

Ato 5 — O conserto: um piso de exposição e um shrinkage por número de trades

A control panel with two knobs labeled exposure floor and conf_k shrinkage, both lifting an out-of-sample performance surface up onto a high flat plateau while a degeneracy indicator goes dark, illustrating two independent fixes that together recover the true optimum

Temos duas doenças identificadas — opera com raridade demais e repousa sobre observações de menos — então escrevemos duas curas, cada uma mirando uma delas.

Cura 1: um piso de exposição. A solução mais simples possível. Rejeite completamente qualquer estratégia que não esteja no mercado pelo menos emine_{\min} do tempo — se ela mal opera, sua pontuação é -\infty e a busca não pode selecioná-la. Mas há uma sutileza honesta em o que é colocado no piso, e essa é a lição silenciosa de todo este artigo. Como objetivo independente, colocamos um piso no Sharpe de linha do tempo completa, e neste mercado isso não muda absolutamente nada: o próprio vencedor do Sharpe de linha do tempo completa já está em ~74% de exposição, então um piso de 20% nunca é acionado. É exatamente por isso que as linhas "piso de exposição" e "Sharpe de linha do tempo completa" nas tabelas acima são idênticas byte a byte — parafusar um piso a uma métrica já segura simplesmente re-deriva o Sharpe completo. O piso só faz trabalho visível quando está protegendo uma métrica que de outra forma correria para o canto: uma métrica por trade, como no objetivo robusto abaixo. Em outras palavras, "exigir exposição" e "medir na linha do tempo completa" são, nestes dados, dois nomes para a mesma intervenção.

Cura 2: um shrinkage por número de trades — "conf_k". Para quando você está preso a uma métrica por trade e quer uma correção suave em vez de um corte duro: desconte o Sharpe continuamente de acordo com em quantos trades ele repousa. Multiplique por n/(n+k)n/(n+k), onde nn é a contagem de trades e kk é uma "constante de confiança" fixa — uma força de prior equivalente em trades escolhida antes da busca:

score(θ)=SR^(θ)n(θ)n(θ)+k.\text{score}(\theta) = \widehat{SR}(\theta)\cdot \frac{n(\theta)}{n(\theta) + k}.

Quando n0n \to 0 a pontuação é esmagada a zero não importa quão grande seja o Sharpe bruto; quando nn \to \infty a pontuação converge para o Sharpe bruto. É a mesma lógica corretiva de MinTRL e do erro padrão do Ato 4 — encolher uma estimativa de amostra pequena em direção a zero como função decrescente do seu tamanho amostral — embutida diretamente no objetivo em vez de aplicada como filtro posterior. O precedente nomeado mais próximo é o System Quality Number de van Tharp (SQN=Ntrade/σtrade\text{SQN} = \sqrt{N}\cdot \overline{\text{trade}}/\sigma_{\text{trade}}), que igualmente faz uma métrica de qualidade por trade escalar com a contagem de trades NN — embora a forma funcional seja diferente (N\sqrt{N} cresce sem limite, enquanto n/(n+k)n/(n+k) satura em 1). Em forma, a nossa é um shrinkage bayesiano ponderado por precisão / ao estilo empírico-bayesiano; é nossa construção para este problema, não um estimador nomeado tirado da literatura.

def obj_active_sharpe(m):                  # the trap: Sharpe on only the active bars
    return m["sharpe_active"]

def _shrink(n, conf_k):                     # trade-count shrinkage n / (n + k)
    return n / (n + conf_k) if (n + conf_k) > 0 else 0.0

def obj_confk(m, conf_k=40.0):              # few trades -> little credit
    return m["sharpe_active"] * _shrink(m["n_trades"], conf_k)

def obj_robust(m, e_min=0.20, conf_k=40.0): # both cures at once
    if m["exposure"] < e_min:               # floor: reject strategies that barely trade
        return -np.inf
    return m["sharpe_active"] * _shrink(m["n_trades"], conf_k)

Agora a parte honesta: quanto de piso, quanto de shrinkage? Varre-se os dois e lê-se toda a superfície. Cada célula é o Sharpe médio fora da amostra ao longo de 200 seeds (um subconjunto de um terço das 600, para manter a varredura bidimensional barata) com a taxa de degenerescência ao lado:

emine_{\min} \ conf_k k=0k=0 k=40k=40 k=80k=80
0.00 0.66 (59.5%) 1.26 (22.5%) 1.47 (11.5%)
0.05 1.43 (10.0%) 1.53 (6.0%) 1.60 (4.0%)
0.10 1.64 (1.5%) 1.65 (1.0%) 1.67 (1.0%)
0.20 1.71 (0.0%) 1.71 (0.0%) 1.71 (0.0%)
0.35 1.73 (0.0%) 1.73 (0.0%) 1.73 (0.0%)

Sharpe anualizado médio fora da amostra, com a taxa de degenerescência entre parênteses. A célula superior esquerda (0,0)(0,0) é o Sharpe por trade bruto — sem piso, sem shrinkage: OOS 0.66, degenerado 59.5%. É o mesmo objetivo da linha por trade do Ato 3, que lia 0.70 / 57%; a pequena diferença é puramente do conjunto de seeds — esta varredura usa 200 seeds, o Monte Carlo usou todas as 600. Mesma métrica, amostra menor.

A superfície conta uma história clara em três leituras.

Cada cura funciona sozinha. Mova-se para a direita ao longo da linha superior (adicione shrinkage, sem piso): OOS sobe 0.661.261.470.66 \to 1.26 \to 1.47 e a degenerescência cai 59.5%22.5%11.5%59.5\% \to 22.5\% \to 11.5\%. Mova-se para baixo na coluna esquerda (adicione piso, sem shrinkage): OOS sobe 0.661.431.641.710.66 \to 1.43 \to 1.64 \to 1.71 e a degenerescência cai 59.5%10%1.5%0%59.5\% \to 10\% \to 1.5\% \to 0\%. Qualquer botão, girado sozinho, eleva independentemente o desempenho fora da amostra e mata a degenerescência. O piso de exposição é a alavanca individual mais forte aqui, porque ataca de frente a característica definidora da armadilha — exposição próxima de zero.

Juntas elas alcançam o platô — e o platô é exatamente o Sharpe de linha do tempo completa. Em emin=0.20e_{\min} = 0.20 a linha fica plana em OOS 1.71 com 0% de degenerescência em todos os níveis de shrinkage; empurrando para emin=0.35e_{\min}=0.35 sobe um pouco para 1.73. Mas olhe bem o que é esse 1.71: é exatamente a pontuação que o simples Sharpe de linha do tempo completa registra no Ato 3 sem piso e sem nenhum shrinkage. Na melhor das hipóteses, os remendos não superam o Sharpe de linha do tempo completa — eles o reconstroem. E o objetivo robusto totalmente reparado nem chega lá por completo: em todas as 600 seeds ele fica em OOS 1.70 com uma degenerescência residual de 0.17%, um triz abaixo do 1.71 / 0% do Sharpe completo — ele é fracamente dominado pela métrica mais simples. Uma configuração intermediária modesta, emin=0.10e_{\min}=0.10 com k=40k=40, alcança OOS 1.65 com 1% de degenerescência — útil se uma métrica por trade for imposta a você, mas nunca um motivo para preferir uma.

Os números exatos dependem da escala — a forma é o resultado. Os valores específicos emin=0.20e_{\min}=0.20, k=40k=40 que consertam completamente este mercado são ajustados a este processo gerador de dados; em outro mercado com frequências de trade e espessura de cauda diferentes, o platô fica em outro lugar. O que generaliza não são as coordenadas, mas a superfície: uma elevação monotônica em ambas as direções, degenerescência levada a zero, um platô na verdade. Você encontra suas próprias coordenadas fazendo a varredura, exatamente como acima.

Junte as duas curas — o objetivo robusto, piso 0.20 mais conf_k 40 — e volte à seed 6. A armadilha coroou θ=0.005\theta = 0.005, oito trades, um Sharpe OOS de linha do tempo completa de 0.13. O objetivo robusto, em vez disso, seleciona θ=0.979\theta = 0.979: exposição ao mercado 0.66, 447 trades, Sharpe anualizado fora da amostra 1.77. Esse θ=0.979\theta = 0.979 está um ponto de grade abaixo do ótimo verdadeiro θ=1.04\theta = 1.04, então ele recupera um limiar quase ótimo e bem exposto em vez de acertar exatamente na mosca — seu Sharpe fora da amostra de seed única (1.77) coincide por acaso com o ótimo populacional. Mesmos dados, mesma busca, mesmos 80 limiares candidatos. Só a definição de "melhor" mudou, e isso moveu o vencedor de uma miragem parada de oito trades para o edge real e bem exposto — que, revelador, é exatamente o mesmo limiar que o simples Sharpe de linha do tempo completa escolhe nesta seed.

Uma advertência que a varredura torna explícita: conf_k sozinho não é suficiente neste mercado. Em k=40k=40 sem piso, a degenerescência ainda é 22.5% entre as seeds — e na seed 6 especificamente, conf_k sozinho escolhe θ=0.015\theta = 0.015, 35 trades, um Sharpe fora da amostra de −0.06. Trinta e cinco trades sobrevivem a um shrinkage de 35/(35+40)0.4735/(35+40) \approx 0.47 com pontuação suficiente sobrando para vencer. O piso de exposição é o que fecha essa última lacuna, porque mira diretamente a verdadeira assinatura da armadilha — estar parado — em vez de confiar na contagem de trades como proxy para isso.

Ato 6 — A lição mais profunda: medir na linha do tempo inteira

Two ways of scoring the same strategy contrasted: a narrow spotlight illuminating only the few bars a strategy traded versus a floodlight measuring the entire timeline including the flat stretches, illustrating that exposure-aware objectives cannot be gamed by rare lucky trades

Dê um passo atrás do conserto e observe o que realmente separou os objetivos seguros da armadilha. Não foi sofisticação. PnL bruto e Sharpe de linha do tempo completa são mais simples que o Sharpe por trade, e nunca degeneraram — 0% em 600 seeds — sem piso, sem shrinkage, sem nenhum ajuste.

A linha divisória é uma única propriedade: qual janela a métrica mede? O Sharpe por trade mede apenas as barras em que a estratégia escolheu ficar posicionada — uma janela autosselecionada que a busca pode encolher à vontade. O Sharpe de linha do tempo completa e o PnL total medem a totalidade da linha do tempo, barras paradas incluídas. E você não consegue tornar grande uma métrica de linha do tempo completa operando raramente, porque cada hora que você fica parado é uma hora no denominador que não ganha nada. O piso de exposição e conf_k são, no final, apenas formas de remendar a métrica por trade com a consciência de exposição que as métricas de linha do tempo completa têm de graça — e a varredura já nos disse o teto desse remendo: na melhor das hipóteses ele iguala o Sharpe de linha do tempo completa (OOS 1.70 contra 1.71), nunca o supera. Se você é livre para escolher a janela, escolha a linha do tempo inteira e pule o remendo completamente.

Então o princípio de design, dito claramente:

Projete o objetivo de forma que ele não possa ser manipulado por trades raros e sortudos. Você tem três ferramentas, em ordem aproximada de preferência:

  1. Meça na linha do tempo completa. O padrão do qual quase nunca se deveria desviar. Sharpe de linha do tempo completa e retorno total são conscientes da exposição por construção — a inatividade é automaticamente penalizada porque as barras paradas contam. Se você se pegar reportando uma métrica calculada "apenas nas barras em que estivemos ativos", pare e pergunte o que a busca fará com a liberdade de escolher essas barras.
  2. Exija exposição. Se você precisa usar uma métrica condicionada à atividade, coloque um piso na exposição para que a busca não possa selecionar uma estratégia que mal opera. Esta é a alavanca individual mais forte contra essa armadilha específica.
  3. Encolha pela contagem de trades. Desconte qualquer razão por n/(n+k)n/(n+k) para que um Sharpe que repousa sobre um punhado de observações ganhe apenas uma fração do crédito de um que repousa sobre milhares. Isso é a aplicação em nível de objetivo da Minimum Track Record Length: um número vindo de poucas observações é não confiável (Ato 4), então um objetivo honesto precifica essa não confiabilidade em vez de confiar que um humano a note depois.

Nada disso torna a busca mais inteligente. Torna a meta honesta, de modo que quando a busca faz exatamente o que sempre faz — encontrar o máximo — esse máximo é uma estratégia que você realmente quer.

Notas de honestidade

Três ressalvas, ditas claramente, porque um estudo controlado só merece suas conclusões nomeando seus limites.

  • O mercado é sintético, e deliberadamente. Um sinal normal padrão, um edge linear confinado a s1|s|\le 1, ruído Student-tt(44) de cauda pesada — escolhidos por verdade fundamental controlada, não por realismo de mercado. Só podemos provar que um objetivo escolhe a estratégia errada rodando-o em dados onde sabemos qual estratégia é a certa. Mercados reais são não estacionários, autocorrelacionados e mudam de regime. As caudas pesadas são um ingrediente realista que mantivemos, mas — ao contrário de um primeiro palpite natural, e ao contrário de um rascunho anterior deste próprio artigo — elas não são o que alimenta a armadilha: um controle com ruído gaussiano (300 seeds) degenera 55.7% do tempo contra 57.0% aqui, com Sharpe fora da amostra 0.71 contra 0.70. A armadilha é um artefato de amostra pequena mais seleção que sobrevive com ou sem caudas pesadas. O produto entregue é o diagnóstico e o padrão de conserto, não uma estratégia nem uma constante universal.
  • Os valores do conserto dependem da escala. O piso específico emin=0.20e_{\min}=0.20 e o shrinkage k=40k=40 que fecham completamente a armadilha estão ajustados a este processo gerador de dados — suas frequências de trade, sua espessura de cauda, o tamanho do seu edge. Em outros dados, o platô se move. O que se transfere é a forma da superfície de varredura (elevação monotônica em ambos os botões, degenerescência a zero, um platô na verdade) e o método para encontrar suas próprias coordenadas: varra os dois e leia a superfície, não copie os números.
  • conf_k é nossa construção, não um estimador nomeado. O shrinkage por contagem de trades SR^n/(n+k)\widehat{SR}\cdot n/(n+k) é um dispositivo bayesiano ponderado por precisão / ao estilo empírico-bayesiano que construímos para este problema; sua justificativa se apoia no resultado verificado de erro padrão de Lo/Mertens e no MinTRL de Bailey–López de Prado, e seu parente nomeado mais próximo é o System Quality Number de van Tharp (Ntrade/σtrade\sqrt{N}\cdot \overline{\text{trade}}/\sigma_{\text{trade}}, uma forma funcional diferente), mas não afirmamos que n/(n+k)n/(n+k) em si apareça sob um nome na literatura. Suas curas companheiras — o piso de exposição, a medição na linha do tempo completa — são prática padrão dita com precisão. E observe quais objetivos já eram seguros aqui: PnL bruto e Sharpe de linha do tempo completa nunca precisaram de conserto, porque são conscientes da exposição desde o início — tanto que colocar um piso no Sharpe de linha do tempo completa se reduz ao Sharpe de linha do tempo completa, cujo vencedor já supera qualquer piso razoável. A armadilha é especificamente o Sharpe por trade / ativo — e mesmo o objetivo por trade totalmente reparado apenas iguala o Sharpe de linha do tempo completa (OOS 1.70 contra 1.71), nunca o supera. A lição principal não é o conserto; é medir na linha do tempo completa desde o início.

Conclusões principais

  1. O objetivo é a decisão, não uma formalidade. Uma busca não encontra "uma boa estratégia" — ela encontra o maximizador de qualquer escalar que você tenha dado a ela, e escalares diferentes selecionam estratégias radicalmente diferentes em dados idênticos. Escolher o objetivo é escolher a estratégia; tudo a jusante é contabilidade. Essa é a lei de Goodhart: no momento em que sua métrica se torna a meta da busca, a busca explorará toda brecha entre ela e o que você quis dizer.
  2. O Sharpe por trade é uma armadilha. Medido apenas nas barras que uma estratégia opera, é maximizado operando o mais raramente possível — quanto menos observações, mais fácil que algumas movimentações sortudas inflem a razão (um controle gaussiano confirma que caudas pesadas não são necessárias; é um efeito de amostra pequena mais seleção). Em 600 seeds ele escolhe uma loteria com menos de 5% de exposição em 56% delas e degenera em 57%; a escolha degenerada típica tem em média um Sharpe por trade in-sample de 4.58. Numa seed deliberadamente marcante, coroou uma estratégia de oito trades e 0.4% de exposição com um Sharpe por trade in-sample de 21.09 que desaba para um Sharpe fora da amostra de linha do tempo completa de 0.13. Uma razão construída sobre oito observações tem um erro padrão da ordem de ±7.7 anualizado (Ato 4) — nunca foi informação.
  3. Objetivos conscientes da exposição são naturalmente seguros. PnL bruto e Sharpe de linha do tempo completa nunca degeneraram (0%), porque medem a totalidade da linha do tempo e a inatividade é automaticamente penalizada. Você não consegue manipular uma métrica de linha do tempo completa operando raramente. O único defeito do PnL bruto é o viés oposto — ele sobre-expõe (exposição média 0.859, OOS 1.61 contra o verdadeiro 1.77), desviando θ\theta além do ótimo para estar mais no mercado.
  4. Os consertos funcionam — mas só trazem você de volta ao Sharpe de linha do tempo completa. Um piso de exposição e um shrinkage por número de trades (conf_k) elevam cada um independentemente o Sharpe fora da amostra e levam a degenerescência a zero; juntos alcançam um platô. Mas esse platô é o Sharpe de linha do tempo completa: a degenerescência cai de 59.5% em (emin,k)=(0,0)(e_{\min},k)=(0,0) para 0% em emin=0.20e_{\min}=0.20 e o Sharpe OOS sobe de 0.66 para 1.71 — exatamente o número que o Sharpe completo simples registra sem ajuda, e o objetivo robusto totalmente reparado na verdade fica um triz abaixo dele (OOS 1.70, 0.17% de degenerescência: fracamente dominado). Na seed 6, o objetivo robusto recupera um limiar quase ótimo e bem exposto (θ=0.979\theta = 0.979, um ponto de grade abaixo do verdadeiro 1.041.04; 447 trades; Sharpe OOS 1.77). Trate conf_k como um recurso de reserva para quando uma métrica por trade for imposta a você, não como um upgrade em relação a medir a linha do tempo completa. As coordenadas exatas dependem da escala; a forma da superfície é o resultado transferível.
  5. Projete o objetivo de forma que ele não possa ser manipulado por trades raros e sortudos. Em ordem de preferência: meça na linha do tempo completa (padrão), exija exposição (alavanca individual mais forte), encolha pela contagem de trades (Minimum Track Record Length em nível de objetivo). Nada disso torna a busca mais inteligente — torna a meta honesta, de modo que o máximo que a busca inevitavelmente encontra seja uma estratégia que você de fato operaria.

Uma busca de parâmetros é um gênio obediente. Ele concede exatamente o desejo que você formula, não o que você quis dizer — e "maximize esta métrica" é o desejo. Formule-o como um Sharpe por trade e ele conjurará oito trades sortudos e os chamará de fortuna. Formule-o de modo que ficar parado seja punido e um punhado de trades ganhe apenas um punhado de crédito, e o mesmo gênio, nos mesmos dados, entrega a você o edge real. A estratégia que você implanta foi escolhida no momento em que você digitou o objetivo. Escolha-a de propósito.

O experimento completo — o mercado sintético, os seis objetivos, o Monte Carlo de 600 seeds e a superfície de varredura de conserto, cada número regenerável a partir de um único script determinístico — está no paper complementar em objective-design.marketmaker.cc, com código e dados em github.com/suenot/objective-design-degeneracy.

Esta é uma frente da mesma guerra que nossos outros estudos travam de ângulos diferentes. O Deflated Sharpe Ratio precifica o vencedor de uma busca após múltiplos testes — enquanto este artigo pergunta se o objetivo escolheu a estratégia certa em primeiro lugar, o DSR pergunta se a estratégia escolhida supera o que a sorte sozinha produziria. O próximo estudo de probabilidade de overfitting de backtest ataca o mesmo viés de seleção pelo lado do resampling, pontuando o procedimento em vez do vencedor. E a taxonomia de look-ahead bias cataloga o outro grande fabricante de Sharpe falso — um vazamento do futuro — que produz o mesmo sintoma idêntico (um backtest glorioso que morre ao vivo) através de um mecanismo inteiramente diferente. Design de objetivo, deflação, probabilidade de overfitting, look-ahead: quatro nomes para uma única disciplina — não se deixar enganar pelo próprio backtest.

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Fique à frente do mercado

Assine nossa newsletter para insights exclusivos sobre trading com IA, análises de mercado e atualizações da plataforma.

Respeitamos sua privacidade. Cancele a inscrição a qualquer momento.