Что такое максимальная просадка и как она рассчитывается
Максимальная просадка показывает наибольшее падение стоимости актива от пика до минимума. Узнайте, почему глубина просадки важна и как долго длится восстановление до нового максимума.
33
Максимальная просадка (maximum drawdown) — это наибольшее падение стоимости актива от пика до минимума, выраженное в процентах от текущего максимума. Если стоимость счета выросла до 120 000 долларов, упала до 84 000 долларов, а затем восстановилась, максимальная просадка составляет тридцать процентов. Этот показатель остается неизменным, так как статистика фиксирует худший период за всю историю, а не текущее состояние счета. Большинство участников рынка ограничиваются только глубиной падения. Однако в этот же показатель входят еще два значения: время от пика до минимума и значительно более длительный период восстановления от этого минимума до нового максимума.
Анализ рисков
- Максимальная просадка отражает исторический риск.
- Глубина падения не учитывает временные затраты на восстановление.
- Статистика просадок не меняется при достижении новых максимумов.
Методология оценки просадок
Для полноценной оценки стратегии недостаточно знать только процентное снижение. Инвестору необходимо учитывать продолжительность «подводного» периода, когда капитал находится ниже своего исторического максимума. Часто время, затраченное на выход из просадки, оказывается более критичным для портфеля, чем сама глубина падения.
Как рассчитывается максимальная просадка?
Весь расчет выполняется за один проход по ряду данных. На каждом шаге вы обновляете текущий максимум, сравниваете с ним текущее значение и сохраняете худший из зафиксированных показателей.
- Установите текущий пик равным первому значению.
- При появлении нового значения повышайте пик, если текущее значение выше.
- Рассчитайте просадку в этой точке: значение, деленное на пик, минус единица.
- Сохраняйте наиболее отрицательное значение. Это и есть максимальная просадка.
Здесь не используются ряды доходности, оценки волатильности или предположения о распределении. Цикл работает с простым списком чисел через стандартную библиотеку Python. На чистой системе Ubuntu сначала установите интерпретатор:
apt-get update && apt-get install -y python3
Сохраните цикл как maxdd.py. Приведенные ниже цены — это вымышленный ряд из десяти точек, достаточно короткий для проверки вручную:
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}%")
Запустите python3 maxdd.py, и программа выведет maximum drawdown: -15.4%. Проверьте вручную: пик перед минимумом составляет 104, минимум равен 88, а 88, деленное на 104, дает 0,846. Затем ряд заканчивается на 106, историческом максимуме, и значение 15,4% остается актуальным. Максимальная просадка — это неизменная фиксация худшего момента в выборке, она ничего не говорит о текущем положении ряда. Две дополнительные переменные в том же цикле позволяют зафиксировать время: индекс, на котором был установлен пик, и индекс, на котором было зафиксировано худшее значение.
Как выглядит кривая просадки
Кривая просадки отслеживает шаг 3 в каждой точке, а не сводит его к одному худшему значению. Линия находится на нуле всякий раз, когда ряд фиксирует новый максимум, и опускается ниже нуля в промежутках, поэтому этот разрыв называют «подводным». Ниже представлена такая кривая для SPY, биржевого фонда (ETF), отслеживающего индекс S&P 500, по ценам закрытия на конец месяца с января две тысячи шестнадцатого года.
Точный SQL-код для каждого числа
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_startНа протяжении 127 ежемесячных отсчетов линия подолгу остается вблизи нуля и лишь несколько раз резко уходит вниз. В последнем месяце зафиксировано значение -1.27% относительно текущего пика. Две особенности этой формы показательны. Восстановление представляет собой медленный подъем, а не резкий отскок, при этом каждый новый максимум возвращает кривую к нулю, стирая визуальную память о том, что было ранее.
Сколько времени занимает восстановление после просадки?
Внутри одной просадки скрываются три отдельных показателя, и их смешение — самая распространенная ошибка при чтении таблицы доходности:
- Глубина: насколько упала стоимость относительно пика, в процентах.
- Время до минимума: календарные дни от пика до «дна».
- Время восстановления: календарные дни от этого «дна» до достижения нового максимума.
Третий показатель обычно самый продолжительный, и именно его никогда не показывают в заголовках. Ниже приведена таблица всех завершенных периодов просадки для SPY с 2016 года, рассчитанных по ценам закрытия. Период начинается в день установления пика и заканчивается в день, когда фонд впервые закрывается выше этого уровня.
Точный SQL-код для каждого числа
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 8Самый глубокий завершенный период в списке начинается в Feb 2020 и достигает 34.2% ниже предыдущего пика. На падение ушло 33 календарных дней, а на восстановление — 148, что в сумме составило 181 дней «под водой». Следующий эпизод, начиная с Jan 2022, оказался менее глубоким — 25.4%, при этом фонд оставался ниже своего старого максимума в течение 746 дней.
Глубина и длительность — совершенно разные параметры. Резкое падение с быстрым возвратом к исходным значениям и затяжное «сползание» рынка, длящееся годами, в статистике часто сводятся к одному процентному показателю. Мартовский обвал 2020 года — хрестоматийный пример первого сценария, а то, как рынки восстанавливаются после крахов, описывает вторую фазу этого процесса.
Почему максимальная просадка увеличивается при расширении периода измерения
Максимальная просадка — это экстремальное значение, поэтому добавление исторических данных может либо оставить его неизменным, либо увеличить. Скользящий пик в более длинном окне всегда как минимум не ниже пика в коротком окне, что предопределено арифметикой. Измерение показателей одного и того же фонда на пяти временных интервалах, заканчивающихся 31 июля 2026 года, демонстрирует этот эффект.
Точный SQL-код для каждого числа
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_yearsНа скользящем окне 1 year максимальное падение составило 9.1%. При расширении того же ряда до 10 years значение достигает 34.2%, а худшая точка приходится на Mar 2020. Фонд не стал более рискованным. Просто увеличилась выборка.
Та же арифметика искажает сравнение стратегий. Бэктест за три года и за двадцать лет могут описывать идентичное поведение, но показывать совершенно разные просадки. Поэтому показатель не имеет смысла без указания временного окна. Ошибка предвидения в бэктестинге описывает еще один способ, которым внешне безупречный бэктест приукрашивает результаты.
Максимальная просадка против волатильности
Волатильность измеряет типичный размер ежедневного изменения цены в любом направлении. Максимальная просадка измеряет конкретный нисходящий путь. Оба показателя являются метриками риска, но они отвечают на разные вопросы. В таблице ниже они сопоставлены для восьми известных компаний за пять лет по тридцать первое июля две тысячи двадцать шестого года, при этом волатильность рассчитана в годовом исчислении на основе дневных цен закрытия.
Точный SQL-код для каждого числа
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 DESCРассматривайте эти два столбца вместе. Акция VZ демонстрирует самое глубокое падение в группе на 45.4% при годовой волатильности 22.6%. На другом конце спектра, KO упала на 20.9% при волатильности 16.7%. Волатильность — это среднее значение за каждый день в рассматриваемом периоде, а средние показатели сглаживают длительное и медленное снижение. Просадка — это худший реальный путь, который прошла цена. Спокойный актив, который дрейфует вниз в течение двух лет, может показать глубокую просадку при ничем не примечательном уровне волатильности.
Аномалия низкой волатильности рассматривает поведение спокойных активов на длинных горизонтах, а Определение размера позиции по критерию Келли показывает, как допустимый уровень просадки превращается в размер позиции.
Чего не показывают цифры
Стоит учитывать четыре ограничения:
- Это лишь один реализованный сценарий. Тот же процесс при ином стечении обстоятельств мог привести к гораздо худшему результату.
- Показатель зависит от длины выборки, поэтому просадки можно сравнивать только на совпадающих временных интервалах.
- Показатель зависит от частоты выборки. Данные на закрытии месяца скрывают внутридневные минимумы и дают меньшее значение, чем данные на закрытии дня за тот же период.
- Показатель не несет прогнозной информации. Нахождение на тридцать процентов ниже пика ничего не говорит о том, наступит ли тридцать первый процент завтра.
Последнее ограничение объясняет, почему автоматизированной системе нужна политика в отношении просадок, а не просто пороговое значение. Решение «остановиться на двадцати процентах» отвечает на один вопрос, но оставляет без ответа два других: что происходит с открытыми позициями в момент остановки и какие данные служат сигналом для возобновления работы системы. В статье Автоматические выключатели для торговых роботов подробно разбирается структура такой политики. Цена произвольного жесткого правила проявляется на этапе восстановления, когда система, остановившаяся вблизи минимума и поздно возобновившая торговлю, пропускает подъем. В статье Упущенные лучшие дни эта арифметика подкреплена расчетами.
Перед сравнением двух показателей важно учесть одну деталь: просадка по ценовому ряду фонда и просадка по реальному счету различаются всякий раз, когда происходит ввод или вывод средств, а также при выплате дивидендов, что подробно описано в материале как измеряется месячная доходность.
Часто задаваемые вопросы о максимальной просадке
Какая максимальная просадка считается приемлемой?
Универсального показателя не существует, есть только ориентир и временной интервал для оценки. За десять лет по тридцать первое июля две тысячи двадцать шестого года худшее падение SPY от локального максимума составило 34.2% по ценам закрытия. Стратегия, демонстрирующая меньшее значение на более короткой выборке, не обязательно является более безопасной.
Является ли максимальная просадка тем же самым, что и волатильность?
Нет. Волатильность описывает типичное дневное изменение цены, тогда как максимальная просадка — это худший путь от пика до минимума. Актив с низкой волатильностью, который плавно снижается в течение двух лет, может иметь более глубокую просадку, чем волатильный инструмент, который постоянно обновляет максимумы.
Сколько времени занимает восстановление после максимальной просадки?
Это зависит от ситуации, причем путь обратно часто занимает больше времени. Для SPY с две тысячи шестнадцатого года самый глубокий завершенный период нахождения ниже предыдущего максимума длился 181 календарных дней от пика до нового максимума, из которых 33 дней пришлись на фазу падения.
Предсказывает ли максимальная просадка будущие убытки?
Нет. Она описывает один уже пройденный путь, и более длинная выборка почти всегда дает большее значение. Этот показатель фиксирует то, что стратегия уже пережила, без каких-либо ограничений на то, что произойдет в будущем.
Каждая панель выше содержит SQL-запрос, на основе которого построены данные. Откройте любую из них, замените тикер или временной интервал и выполните тот же расчет просадки в терминале Strasmore.