Работает ли правило «Продай в мае и уходи»?
Правило «Продай в мае и уходи» проверено на двух десятилетиях S&P 500: сравните разрыв доходности летом и узнайте реальную цену сезонной смены стратегии.
«Продай в мае и уходи с рынка» — самое известное календарное правило на фондовом рынке. Оно предполагает продать акции в конце апреля, держать деньги в кэше летом и вновь купить бумаги в конце октября.
Если измерять результат по ценам ETF, отслеживающих S&P 500, от закрытия торгов в последний день апреля 2005 года до закрытия торгов в последний день апреля 2026 года, период с ноября по апрель действительно в среднем приносит более высокую доходность, чем период с мая по октябрь. Разрыв существует, но он меньше, чем предполагает это правило. Период с мая по октябрь также в среднем оказывается прибыльным. Именно поэтому данная закономерность не может служить самостоятельным торговым планом.
Что утверждает это правило и как его проверить
Эта фраза происходит от старой лондонской традиции: после весенних скачек уезжать из города и возвращаться осенью. В современной проверяемой форме это правило переключения с двумя датами. Вы держите широкий фондовый индекс с последнего торгового дня октября по последний торговый день апреля. В остальные шесть месяцев позиции нет.
Для проверки нужны две вещи, которых сама поговорка не даёт: временной ряд цен и заранее заданный период. Все приведённые ниже показатели рассчитаны по SPY — старейшему ETF на S&P 500. Используются минутные бары в обычные часы торгов из таблицы global_markets.delayed_stocks_minute_aggs за период с закрытия в последний торговый день апреля 2005 года по закрытие в последний торговый день апреля 2026 года. Под доходностью месяца здесь понимается изменение его последней цены в обычные часы торгов относительно последней цены предыдущего месяца; учитываются только цены. Дивидендам посвящён отдельный раздел ниже, а в материале как измеряется месячная доходность объясняется, почему это различие меняет результат.
Работает ли стратегия «продай в мае и уходи с рынка»? Результаты с 2005 по 2026 год
Точный SQL-код для каждого числа
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
)
SELECT toYear(apr_m.month_start) AS year,
round(100 * (toFloat64(oct_m.month_close) / toFloat64(apr_m.month_close) - 1), 2) AS may_oct_pct,
round(100 * (toFloat64(apr_next.month_close) / toFloat64(oct_m.month_close) - 1), 2) AS nov_apr_pct
FROM monthly AS apr_m
INNER JOIN monthly AS oct_m ON oct_m.month_start = addMonths(apr_m.month_start, 6)
INNER JOIN monthly AS apr_next ON apr_next.month_start = addMonths(apr_m.month_start, 12)
WHERE toMonth(apr_m.month_start) = 4
ORDER BY yearКаждая точка сопоставляет одно лето с последующей зимой. На графике показано 21 полных пар: отсчёт начинается с лета 2005 и заканчивается зимой, завершившейся в апреле 2026.
В большинстве отдельных лет две линии расходятся, но в худший год они совпали. В период с конца апреля до конца октября 2008 летняя половина показала результат -29.81% — это самое глубокое снижение за весь период. Последовавшая зима показала результат -10.03%. Инвестор, продавший активы в апреле, избежал сильного падения, но затем вновь вошёл в рынок перед последним этапом снижения. Календарный сигнал совпал с динамикой рынка только на половине периода.
Исчез ли летний разрыв после 2015 года?
Именно средние значения лежат в основе этого правила, а период наблюдения определяет, на каких данных они рассчитаны. Разделение ряда в 2015 году даёт две сопоставимые по длительности половины, рассчитанные одинаковым способом.
Точный SQL-код для каждого числа
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
pairs AS (
SELECT toYear(apr_m.month_start) AS season_year,
toFloat64(oct_m.month_close) / toFloat64(apr_m.month_close) - 1 AS may_oct,
toFloat64(apr_next.month_close) / toFloat64(oct_m.month_close) - 1 AS nov_apr
FROM monthly AS apr_m
INNER JOIN monthly AS oct_m ON oct_m.month_start = addMonths(apr_m.month_start, 6)
INNER JOIN monthly AS apr_next ON apr_next.month_start = addMonths(apr_m.month_start, 12)
WHERE toMonth(apr_m.month_start) = 4
),
tagged AS (
SELECT may_oct,
nov_apr,
arrayJoin(['All seasons 2005-2025',
if(season_year <= 2014, 'First half 2005-2014', 'Second half 2015-2025')]) AS era
FROM pairs
)
SELECT era,
count() AS season_count,
round(100 * avg(may_oct), 2) AS avg_may_oct_pct,
round(100 * avg(nov_apr), 2) AS avg_nov_apr_pct,
round(100 * (avg(nov_apr) - avg(may_oct)), 2) AS winter_minus_summer_pct,
countIf(may_oct > 0) AS summers_positive
FROM tagged
GROUP BY era
ORDER BY eraЗа все 21 сезонов средний результат за период с мая по октябрь составил 3.88%, а за период с ноября по апрель — 6.06%. Разница составила 2.18 процентного пункта. На ней полностью строится аргумент в пользу этого правила. Посмотрите на столбец летних периодов: 16 из них завершились выше уровня начала, то есть средняя стратегия выхода с рынка приводила к пропуску роста, а не к предотвращению убытка.
Две половины ряда дают разные результаты. В более раннем периоде разница составила 4.84 пункта, в более позднем — -0.24. В популярных пересказах часто приводят разрыв, не называя годы, на которых он основан. Но именно годы имеют решающее значение. Любая сезонная статистика — это утверждение о конкретном историческом периоде, а выбор этого периода зависит от того, кто её повторяет.
Действительно ли эффект приходится на август и сентябрь?
Шесть месяцев — слишком грубый интервал. Разбивка года по месяцам позволяет понять, одинаково ли слабы летние месяцы или весь результат формирует только один из них.
Точный SQL-код для каждого числа
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
month_returns AS (
SELECT m1.month_start AS month_start,
100 * (toFloat64(m1.month_close) / toFloat64(m0.month_close) - 1) AS ret_pct
FROM monthly AS m1
INNER JOIN monthly AS m0 ON m0.month_start = addMonths(m1.month_start, -1)
)
SELECT formatDateTime(month_start, '%b') AS label,
count() AS readings,
round(avg(ret_pct), 2) AS avg_return_pct,
round(quantileDeterministic(0.5)(ret_pct, cityHash64(month_start)), 2) AS median_return_pct,
countIf(ret_pct > 0) AS positive_readings
FROM month_returns
GROUP BY label
ORDER BY min(toMonth(month_start))Слабость приходится на сентябрь. Средний результат в этом месяце составил -0.75%, а год завершался ростом в 12 из 21 лет; медианный результат равнялся 0.38%. Средний результат августа составил 0.28%. Июль, который находится в середине периода отсутствия продавца, в среднем давал 2.63%, а октябрь, последний месяц перед обратной покупкой по правилу, — 0.97%.
В этом периоде эффект имеет узкую форму: один слабый отрезок в конце лета, тогда как соседние месяцы мало отличаются от остальных месяцев года. Выход из позиции в конце апреля, чтобы пропустить сентябрь, означает также пропуск мая, июня, июля и августа.
What the switch actually costs
The seasonal gap is a gross number. A rule has to survive its own frictions.
Точный SQL-код для каждого числа
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
pairs AS (
SELECT toYear(apr_m.month_start) + 1 AS year,
toFloat64(oct_m.month_close) / toFloat64(apr_m.month_close) AS summer_ratio,
toFloat64(apr_next.month_close) / toFloat64(oct_m.month_close) AS winter_ratio
FROM monthly AS apr_m
INNER JOIN monthly AS oct_m ON oct_m.month_start = addMonths(apr_m.month_start, 6)
INNER JOIN monthly AS apr_next ON apr_next.month_start = addMonths(apr_m.month_start, 12)
WHERE toMonth(apr_m.month_start) = 4
)
SELECT year,
round(exp(sum(log(summer_ratio * winter_ratio)) OVER (ORDER BY year)), 2) AS buy_and_hold_growth,
round(exp(sum(log(winter_ratio)) OVER (ORDER BY year)), 2) AS winter_only_growth
FROM pairs
ORDER BY yearA dollar held through every season from the end of April 2005 grew to $6.21 by the end of April 2026. The same dollar in the market only from November through April, idle the rest of the time, grew to $3.14. Both lines are price only with nothing deducted, which flatters the switching rule. Here is what the chart leaves out.
- Two trades every year, in every one of the 21 seasons. The ticket is free at most brokers now. The bid ask spread paid on each round trip is not.
- Tax. In a taxable account the April sale realizes whatever gain built up since November. A November to April holding period runs under a year by construction, which places the gain at short-term rates for a US taxpayer.
- Idle cash. The winter-only line credits the sidelined money with zero. A real holder would park it, and where to park idle cash covers the instruments people use for that.
- Dividends, which the next panel prices out.
Точный SQL-код для каждого числа
SELECT toYear(ex_dividend_date) AS year,
round(sumIf(cash_amount, toMonth(ex_dividend_date) >= 5 AND toMonth(ex_dividend_date) <= 10), 3) AS may_oct_dividends_usd,
round(sumIf(cash_amount, toMonth(ex_dividend_date) < 5 OR toMonth(ex_dividend_date) > 10), 3) AS nov_apr_dividends_usd
FROM global_markets.stocks_dividends
WHERE ticker = 'SPY'
AND cash_amount > 0
AND ex_dividend_date >= toDate('2005-01-01')
AND ex_dividend_date <= toDate('2025-12-31')
GROUP BY year
ORDER BY yearSPY's ex-dividend dates land in March, June, September and December, so two of the four fall inside the six months a seller sits out. In 2025, $3.592 per share of distributions carried a May to October ex-date, against $3.689 in the other six months. The two columns track each other across the whole chart. Sitting out half the calendar forgoes roughly half the fund's income every year, on top of whatever the price does in those months. The ex-dividend date is the cutoff that decides who gets paid.
One more cost carries no line item. Index returns arrive in clusters, and missing the best days puts numbers on what a handful of absent sessions does to a long-run balance. Six months out of every year is a lot of absent sessions. That is the same arithmetic behind dollar cost averaging as a discipline about time in the market rather than timing.
Почему к известному календарному правилу стоит относиться скептически
Двенадцать месяцев дают 4,095 непустых вариантов выбора подмножества месяцев для инвестирования. Если проверить все варианты на одной истории цен, какой-то результат покажется впечатляющим. Это свойство самого поиска.
У правила «продай в мае» есть одно объективное преимущество перед правилом, найденным на прошлой неделе: оно стало известным задолго до начала этой выборки. Поэтому годы, представленные на этой странице, служат вневыборочным тестом, а не результатом подгонки. Тест показывает умеренный разрыв, сосредоточенный в одном месяце, и относится к стратегии переключения, которая за тот же период отстаёт от покупки и удержания. Смещение заглядывания вперёд показывает, как бэктест незаметно получает ответ заранее. Календарные правила — классический пример: месяцы выбирают уже после того, как становятся известны доходности.
Часто задаваемые вопросы
Сохраняет ли стратегию «продай в мае и уходи» эффективность?
По ценам SPY с апреля 2005 года по апрель 2026 года средний результат за период с ноября по апрель составил 6.06% против 3.88% за период с мая по октябрь. Таким образом, сезонный разрыв сохраняется на всей выборке. В летнем полугодии средний результат также был положительным: 16 из 21 лет завершились ростом относительно начала периода.
Какие месяцы действительно были слабыми?
В этом периоде слабость в основном приходится на сентябрь. Его средний результат составил -0.75%, а ростом завершились 12 из 21 лет. Июль, ещё один месяц, который стратегия пропускает, за тот же период в среднем дал 2.63%.
Приносит ли продажа в мае результат лучше, чем покупка и удержание?
Не на этой выборке. Один доллар, непрерывно вложенный в конце апреля 2005 года, вырос до $6.21 к апрелю 2026 года. При сезонном переключении только на зимний период он вырос бы до $3.14. При этом сравнение не учитывает торговые издержки, налоги и дивиденды.
Что происходит с дивидендами, если продать актив в мае?
Даты ex-dividend фонда не переносятся на лето. Две из четырёх квартальных дат ex-dividend для SPY приходятся на период с мая по октябрь. Инвестор, который не владеет фондом в дату ex-dividend, не получает соответствующее распределение.
То же ли сезонная закономерность, что и прогноз?
Нет. Исторический средний результат за 21 сезонов описывает события в определённом временном интервале. Отдельные годы заметно отклоняются от этого среднего, как показывает первый график. Кроме того, сам временной интервал выбран исследователем.
Каждая панель здесь представляет собой сохранённый запрос с прикреплённым SQL. Измените тикер, задайте другой временной интервал и проверьте, сохраняется ли сезонный разрыв, в терминале Strasmore.