O que é drawdown máximo: queda e recuperação
Drawdown máximo é a maior queda entre pico e vale. Entenda quando ela é profunda e por que a recuperação até uma nova máxima pode demorar mais.
O drawdown máximo é a maior queda de um pico até um vale numa série de valores, medida como uma percentagem do pico acumulado. Uma conta que sobe para US$ 120.000, recua para US$ 84.000 e depois se recupera tem um drawdown máximo de 30%. Esse número permanece para sempre, porque a estatística regista o pior período da série histórica, e não a situação atual. A maioria das pessoas cita apenas a profundidade da queda. Mas há outros dois números dentro da mesma estatística: o tempo entre o pico e o mínimo, e o período, muito mais longo, entre esse mínimo e a recuperação de uma nova máxima.
Como é calculado o maximum drawdown?
O cálculo percorre a série uma única vez. A cada observação, atualiza-se o máximo acumulado, mede-se o valor corrente em relação a esse máximo e mantém-se o pior resultado observado 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.
- Mantenha o resultado mais negativo. Esse é o maximum drawdown.
Não entram na conta uma série de retornos, uma estimativa de volatilidade ou qualquer hipótese de distribuição. O loop é executado sobre 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 pequena o suficiente para ser verificada manualmente:
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 e o resultado será maximum drawdown: -15.4%. Verifique manualmente: o pico anterior à mínima é 104, a mínima é 88, e 88 dividido por 104 equivale a 0,846. A série termina então em 106, uma máxima histórica, mas o drawdown de 15,4% permanece registrado. O maximum drawdown é um registro permanente do pior momento da amostra e não informa onde a série está hoje. Duas variáveis adicionais no mesmo loop capturam o momento: o índice em que o pico foi estabelecido e o índice em que ocorreu o pior resultado.
Como é uma curva de drawdown
Uma curva de drawdown mantém o passo 3 em cada ponto, em vez de reduzi-lo a um único pior valor. A linha fica em zero sempre que a série registra uma nova máxima e permanece abaixo de zero no intervalo entre máximas. Por isso, essa diferença é chamada de “underwater”. Abaixo está a curva do SPY, um ETF 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 observações de fim de mês, a linha passa longos períodos próxima de zero e cai em algumas depressões profundas. O último mês disponível registra -1.27% em relação ao pico acumulado. Dois aspectos do formato ajudam a entender o conceito. As recuperações são subidas lentas, e não repiques acentuados. Cada nova máxima redefine a curva para zero e apaga visualmente o que veio antes.
Quanto tempo demora a recuperação de um drawdown?
Há três números distintos dentro de um drawdown. Tratá-los como um só é o erro de interpretação mais comum em uma tabela de desempenho:
- Profundidade: quanto o valor caiu abaixo do pico, em porcentagem.
- Tempo até a mínima: número de dias corridos entre o pico e o fundo.
- Tempo de recuperação: número de dias corridos entre esse fundo e uma nova máxima.
O terceiro geralmente é o mais longo. É também o que um número em destaque nunca mostra. O painel abaixo reconstrói todos os períodos completos em drawdown do SPY desde 2016, com base nos fechamentos diários. Um período começa no dia em que um pico é registrado e termina no dia em que o fundo fecha pela primeira vez acima desse pico.
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. O fundo levou 33 dias corridos para ser atingido, e a recuperação levou 148 dias. Ao todo, o fundo permaneceu abaixo do pico por 181 dias. A entrada seguinte, de Jan 2022, é menos profunda, com 25.4%, mas manteve o fundo abaixo da máxima anterior por 746 dias.
Profundidade e duração são dimensões completamente diferentes. Uma queda violenta com recuperação rápida e uma queda moderada que se prolonga por anos acabam resumidas em uma única porcentagem. A queda de março de 2020 é o exemplo clássico do primeiro formato, enquanto como os mercados se recuperam de quedas acompanha a segunda etapa do percurso.
Por que o drawdown máximo piora quanto mais tempo você mede
O drawdown máximo é um máximo. Portanto, adicionar histórico só pode mantê-lo no mesmo nível ou torná-lo mais profundo. O pico acumulado em uma janela mais longa é, em cada ponto, pelo menos tão alto quanto o pico em uma 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 de 1 year, o pior recuo medido 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 ficou 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 no backtesting aborda outra forma de um backtest com aparência consistente favorecer a própria estratégia.
Drawdown máximo versus volatilidade
A volatilidade mede o tamanho típico de um movimento diário, 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 nomes conhecidos do mercado, no período de cinco anos encerrado em 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 registrou a queda mais profunda do grupo, de 45.4%, contra uma volatilidade anualizada de 22.6%. No outro extremo, 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 tendem a diluir uma queda longa e gradual. O drawdown é a pior trajetória efetivamente percorrida pelo preço. Um ativo estável que perde valor 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ção pelo critério de Kelly mostra como uma tolerância a drawdown se transforma no tamanho de uma posição.
O que o número não consegue dizer
Vale ter quatro limitações em mente:
- É um único caminho realizado. O mesmo processo poderia ter produzido um número muito pior em outra amostra.
- Depende da extensão da amostra. Portanto, dois drawdowns só podem ser comparados em janelas equivalentes.
- 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 traz informação sobre o futuro. Estar 30% abaixo de um pico não diz nada sobre a possibilidade de o 31º ponto ocorrer amanhã.
Essa última limitação explica por que um sistema automatizado precisa de uma política de drawdown, e não de um limite de drawdown. “Interromper em 20%” responde a uma pergunta e deixa duas sem resposta: o que acontece com as posições abertas no momento da interrupção e quais evidências permitem reativar o sistema. Disjuntores para robôs de trading analisa a estrutura dessa política. O custo de uma regra arbitrária e fixa aparece na etapa de recuperação, quando um sistema que para perto da mínima e só é reativado tarde fica de fora da alta. Perder os melhores dias quantifica esse efeito.
Um detalhe de medição é importante antes de comparar dois números: o drawdown da série de preços de um fundo e o drawdown de uma conta real diferem sempre que há entradas ou saídas de caixa e sempre que dividendos são creditados. Esse ponto é explicado integralmente em como são calculados os retornos mensais.
Perguntas frequentes sobre drawdown máximo
Qual é um bom drawdown máximo?
Não existe um valor universal. É preciso considerar um benchmark e uma janela de medição. Nos dez anos até 31 de julho de 2026, a pior queda do SPY em relação a um pico anterior, medida com base nos fechamentos diários, foi de 34.2%. Uma estratégia que apresenta um número menor em uma amostra mais curta não foi 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 o pior percurso entre um pico e um vale. Um ativo de baixa volatilidade que caia de forma constante durante dois anos pode ter um drawdown maior do que um ativo volátil que continue 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, do pico até a renovação da máxima. Desse período, 33 dias foram de queda.
O drawdown máximo prevê perdas futuras?
Não. Ele descreve um percurso que já ocorreu, e uma amostra mais longa quase sempre produz um número maior. O indicador registra o que uma estratégia suportou até agora, sem limitar o que pode acontecer no futuro.
Cada painel acima armazena o SQL correspondente. Abra um painel, troque o ticker ou a janela e execute o mesmo cálculo de drawdown no terminal Strasmore.