O que é drawdown máximo: queda e recuperação
Drawdown máximo é a maior queda do pico ao fundo de uma série. Entenda a profundidade e por que a recuperação até um novo máximo pode demorar mais.
O drawdown máximo é a maior queda entre um pico e o fundo de uma série de valores, medida como percentagem do pico acumulado. Uma conta que sobe para 120.000 dólares, recua para 84.000 dólares e depois se recupera tem um drawdown máximo de 30%. Esse número permanece para sempre, porque a estatística registra o pior período da série histórica, e não a situação atual. A maioria das pessoas informa apenas a profundidade da queda. Mas há dois números adicionais dentro da mesma estatística: o tempo entre o pico e o fundo e o período, muito mais longo, entre esse fundo e a recuperação até um novo máximo.
Como é calculado o drawdown máximo?
O cálculo completo consiste em uma única passagem pela série. A cada observação, atualiza-se o máximo acumulado, mede-se o valor atual em relação a esse máximo e conserva-se a pior leitura observada até então.
- Defina o pico acumulado como o primeiro valor.
- A cada novo valor, eleve o pico se o valor for maior.
- Calcule o drawdown naquele ponto: valor dividido pelo pico, menos um.
- Conserve a leitura mais negativa. Esse é o drawdown máximo.
Não entram no cálculo uma série de retornos, uma estimativa de volatilidade ou qualquer hipótese sobre a distribuição. O loop percorre uma lista simples de números usando a biblioteca padrão do Python. Em uma instalação nova do Ubuntu, instale primeiro o interpretador:
apt-get update && apt-get install -y python3
Salve o loop como maxdd.py. Os preços abaixo formam uma série fictícia de dez pontos, mantida curta o suficiente para uma verificação manual:
prices = [100.0, 104.0, 98.0, 92.0, 95.0, 88.0, 90.0, 101.0, 99.0, 106.0]
peak = prices[0]
max_dd = 0.0
for price in prices:
if price > peak:
peak = price
drawdown = price / peak - 1.0
if drawdown < max_dd:
max_dd = drawdown
print(f"maximum drawdown: {max_dd * 100:.1f}%")
Execute python3 maxdd.py. O resultado é maximum drawdown: -15.4%. Verifique manualmente: o pico anterior à mínima é 104, a mínima é 88, e 88 dividido por 104 é 0,846. A série termina depois em 106, uma máxima histórica, mas o drawdown de 15,4% permanece. O drawdown máximo é um registro permanente do pior momento da amostra. Ele não informa em que nível a série está hoje. Duas variáveis adicionais no mesmo loop registram o momento de cada evento: o índice em que o pico foi estabelecido e o índice em que ocorreu a pior leitura.
Como é uma curva de drawdown
A curva de drawdown mantém o passo 3 em cada ponto, em vez de o reduzir a um único pior valor. A linha fica em zero sempre que a série regista uma nova máxima e permanece abaixo de zero no intervalo entre máximas. Por isso, esse intervalo é chamado de “underwater”. Esta é a curva do SPY, um fundo negociado em bolsa que acompanha o S&P 500, com base nos fechamentos de fim de mês desde janeiro de 2016.
O SQL exato por trás de cada número
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-01-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
runs AS (
SELECT month_start,
close_px,
max(close_px) OVER (ORDER BY month_start
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak
FROM monthly
)
SELECT formatDateTime(month_start, '%Y-%m') AS month,
round(100 * (close_px / running_peak - 1), 2) AS drawdown_pct
FROM runs
ORDER BY month_startAo longo de 127 leituras de fim de mês, a linha passa longos períodos próxima de zero e cai em algumas depressões acentuadas. O último mês disponível está em -1.27% em relação ao pico acumulado. Dois elementos do formato ajudam a entender o conceito. As recuperações são subidas lentas, e não repiques acentuados. Além disso, cada nova máxima redefine a curva para zero e apaga a memória visual do que veio antes.
Quanto tempo leva para recuperar uma perda de pico?
Três números distintos estão contidos em cada perda de pico. Tratá-los como um só é a interpretação equivocada mais comum de uma tabela de desempenho:
- Profundidade: quanto o valor caiu abaixo do pico, em percentagem.
- Tempo até ao mínimo: dias de calendário entre o pico e o fundo.
- Tempo de recuperação: dias de calendário entre o fundo e um novo máximo.
O terceiro costuma ser o mais longo. É também o que um número de destaque nunca mostra. O painel abaixo reconstitui cada período completo abaixo do pico do SPY desde 2016, com base nos fechos diários. O período começa no dia em que é registado um pico e termina no dia em que o fundo fecha pela primeira vez acima desse nível.
O SQL exato por trás de cada número
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-01-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY session_date
),
runs AS (
SELECT session_date,
close_px,
max(close_px) OVER (ORDER BY session_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak
FROM daily
),
episodes AS (
SELECT running_peak AS peak_px,
min(session_date) AS peak_date,
argMin(session_date, close_px) AS trough_date,
min(close_px) AS trough_px
FROM runs
GROUP BY running_peak
),
sequenced AS (
SELECT peak_px,
peak_date,
trough_date,
trough_px,
leadInFrame(peak_date, 1) OVER (ORDER BY peak_date
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS recovery_date
FROM episodes
)
SELECT formatDateTime(peak_date, '%b %Y') AS episode_label,
round(100 * (1 - trough_px / peak_px), 1) AS fall_from_peak_pct,
dateDiff('day', peak_date, trough_date) AS days_to_trough,
dateDiff('day', trough_date, recovery_date) AS days_to_new_high,
dateDiff('day', peak_date, recovery_date) AS days_underwater
FROM sequenced
WHERE recovery_date > trough_date
AND round(100 * (1 - trough_px / peak_px), 1) >= 5
ORDER BY fall_from_peak_pct DESC
LIMIT 8O período completo mais profundo da lista começa em Feb 2020 e chega a 34.2% abaixo do pico anterior. Passou 33 dias de calendário a cair e 148 a recuperar, permanecendo 181 dias abaixo do pico no total. A entrada seguinte, de Jan 2022, é menos profunda, com 25.4%, e manteve o fundo abaixo do máximo anterior durante 746 dias.
Profundidade e duração são dimensões completamente diferentes. Uma queda violenta com recuperação rápida e uma descida gradual e pouco profunda que dura anos acabam reduzidas a uma única percentagem. O crash de março de 2020 é o exemplo clássico do primeiro formato, enquanto como os mercados recuperam de crashes acompanha a segunda etapa do percurso.
Por que o drawdown máximo piora quanto mais tempo é medido
O drawdown máximo é um valor máximo. Portanto, acrescentar histórico só pode mantê-lo estável ou torná-lo mais profundo. O pico acumulado numa janela mais longa é, em cada ponto, pelo menos tão alto quanto o pico numa janela mais curta. Isso determina o resultado aritmético. Medir o mesmo fundo em cinco janelas, todas encerradas em 31 de julho de 2026, mostra esse efeito.
O SQL exato por trás de cada número
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-07-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY session_date
),
scoped AS (
SELECT arrayJoin([1, 2, 3, 5, 10]) AS lookback_years,
session_date,
close_px
FROM daily
),
windowed AS (
SELECT lookback_years, session_date, close_px
FROM scoped
WHERE session_date >= subtractYears(toDate('2026-07-31'), lookback_years)
),
runs AS (
SELECT lookback_years,
session_date,
close_px,
max(close_px) OVER (PARTITION BY lookback_years ORDER BY session_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak
FROM windowed
)
SELECT concat(toString(lookback_years), if(lookback_years = 1, ' year', ' years')) AS lookback,
round(100 * max(1 - close_px / running_peak), 1) AS max_drawdown_pct,
formatDateTime(argMax(session_date, 1 - close_px / running_peak), '%b %Y') AS worst_point
FROM runs
GROUP BY lookback_years
ORDER BY lookback_yearsNa janela móvel de 1 year, a pior queda medida foi de 9.1%. Ao estender a mesma série para 10 years, o resultado passa a 34.2%, com o pior ponto em Mar 2020. O fundo não se tornou mais arriscado. A amostra ficou mais longa.
A mesma aritmética distorce as comparações entre estratégias. Um backtest de três anos e outro de vinte anos podem descrever um comportamento idêntico e, ainda assim, apresentar drawdowns muito diferentes. Por isso, o número tem pouco significado sem a janela a que se refere. Viés de antecipação em backtests aborda outra forma de um backtest aparentemente consistente favorecer a própria estratégia.
Drawdown máximo versus volatilidade
A volatilidade mede o tamanho típico de uma variação diária em qualquer direção. O drawdown máximo mede uma trajetória específica de queda. Ambos são indicadores de risco, mas respondem a perguntas diferentes. O painel coloca os dois lado a lado para oito empresas conhecidas ao longo dos cinco anos até 31 de julho de 2026, com a volatilidade anualizada a partir dos fechamentos diários.
O SQL exato por trás de cada número
WITH daily AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'AAPL', 'MSFT', 'KO', 'JNJ', 'CVX', 'VZ', 'PG')
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2021-08-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session_date
),
runs AS (
SELECT ticker,
session_date,
close_px,
max(close_px) OVER (PARTITION BY ticker ORDER BY session_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak,
lagInFrame(close_px, 1) OVER (PARTITION BY ticker ORDER BY session_date
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
FROM daily
)
SELECT ticker,
round(100 * max(1 - close_px / running_peak), 1) AS max_drawdown_pct,
round(100 * sqrt(252) * stddevSampIf(close_px / prev_close - 1, prev_close > 0), 1) AS annualized_volatility_pct
FROM runs
GROUP BY ticker
HAVING countIf(prev_close > 0) > 20
ORDER BY max_drawdown_pct DESCLeia as duas colunas em conjunto. VZ registou a queda mais profunda do grupo, de 45.4%, face a uma volatilidade anualizada de 22.6%. No extremo oposto, KO caiu 20.9%, com volatilidade de 16.7%. A volatilidade é uma média de todos os dias do período, e as médias podem não refletir uma queda longa e gradual. O drawdown é a pior trajetória efetivamente percorrida pelo preço. Um ativo estável que recua lentamente durante dois anos pode apresentar um drawdown profundo e, ainda assim, uma leitura de volatilidade pouco expressiva.
A anomalia da baixa volatilidade analisa o comportamento dos ativos mais estáveis em horizontes longos, enquanto o dimensionamento de posições pelo critério de Kelly mostra como uma tolerância a drawdown se traduz no tamanho de uma posição.
O que o número não consegue dizer
Há quatro limitações que vale a pena ter em mente:
- É uma trajetória realizada. O mesmo processo poderia ter produzido um número muito pior em outra amostra.
- Depende da extensão da amostra. Por isso, dois drawdowns só podem ser comparados em janelas com a mesma duração.
- Depende da frequência de amostragem. Os fechamentos no fim do mês ocultam as mínimas intradiárias e produzem um número menor do que os fechamentos diários no mesmo período.
- Não oferece informação sobre o futuro. Estar 30% abaixo de um pico não diz nada sobre se o 31.º ponto chegará amanhã.
Essa última limitação explica por que um sistema automatizado precisa de uma política para drawdown, e não apenas de um limite de drawdown. “Parar aos 20%” responde a uma pergunta, mas deixa duas sem resposta: o que acontece às posições abertas quando o sistema para e que evidência permite reativá-lo. Disjuntores para bots de trading analisa a estrutura dessa política. O custo de uma regra fixa e arbitrária aparece na etapa de recuperação, quando um sistema que para perto da mínima e volta a operar tarde fica de fora da alta. Perder os melhores dias quantifica esse efeito.
Um detalhe de medição importa antes de comparar dois números: o drawdown da série de preços de um fundo e o drawdown de uma conta real são diferentes quando há entrada ou saída de caixa e quando são creditados dividendos. Esse tema é explicado integralmente em como são medidos os retornos mensais.
Perguntas frequentes sobre drawdown máximo
O que é um drawdown máximo considerado bom?
Não existe um valor universal. É preciso definir um benchmark e um período de análise. Nos dez anos até 31 de julho de 2026, a pior queda do SPY em relação a um pico anterior, medida pelos fechamentos diários, foi de 34.2%. Uma estratégia que apresenta um número menor em uma amostra mais curta não é necessariamente mais segura.
Drawdown máximo é o mesmo que volatilidade?
Não. A volatilidade descreve o movimento diário típico. O drawdown máximo descreve a pior trajetória entre um pico e um fundo. Um ativo de baixa volatilidade que recua de forma constante durante dois anos pode ter um drawdown mais profundo do que um ativo mais instável que continua renovando máximas.
Quanto tempo leva para se recuperar de um drawdown máximo?
Isso varia, e a recuperação costuma ser a parte mais longa. No caso do SPY desde 2016, o período mais longo concluído abaixo de uma máxima anterior durou 181 dias corridos, dos quais 33 foram de queda.
O drawdown máximo prevê perdas futuras?
Não. Ele descreve uma trajetória que já ocorreu, e uma amostra mais longa quase sempre produz um valor maior. O indicador registra o que a estratégia suportou até agora, sem limitar o que pode acontecer daqui para frente.
Todos os painéis acima armazenam o SQL utilizado. Abra um deles, troque o ticker ou o período e execute o mesmo cálculo de drawdown no terminal da Strasmore.