Strasmore Research
심층 분석 Matt Connor작성자 Matt Connor

5월에 팔고 떠나기, 실제로 효과가 있을까

2005년부터 2026년까지 S&P 500 ETF로 검증한 ‘5월에 팔고 떠나라’ 전략의 여름 수익률 격차와 실제 전환 비용을 확인합니다.

주식시장에서 가장 잘 알려진 달력 효과 규칙은 ‘5월에 팔고 떠나라’이다. 4월 말에 매도한 뒤 여름 동안 현금으로 보유하고, 10월 말에 다시 매수하는 전략이다. 2005년 4월 마지막 거래일 종가부터 2026년 4월 마지막 거래일 종가까지 S&P 500 추종 ETF 가격을 기준으로 측정하면, 11월부터 4월까지의 반년 수익률이 5월부터 10월까지의 반년 수익률보다 평균적으로 높다. 이 격차는 실제로 존재하지만, 속설이 암시하는 것만큼 크지는 않다. 여름 반기에도 평균적으로 수익이 발생한다. 이 점에서 이 규칙은 투자 전략으로서 한계를 보인다.

규칙의 내용과 검증 방법

이 표현은 봄 경마 대회가 끝난 뒤 런던을 떠났다가 가을에 돌아오던 오래된 관행에서 유래했다. 현대적인 검증 가능한 형태로 보면, 두 개의 날짜를 기준으로 매매하는 전환 규칙이다. 10월 마지막 거래일부터 4월 마지막 거래일까지는 광범위한 주가지수를 보유한다. 나머지 6개월 동안은 아무것도 보유하지 않는다.

이 규칙을 검증하려면 격언에 없는 두 가지가 필요하다. 가격 시계열과 명시된 기간이다. 아래의 모든 수치는 가장 오래된 S&P 500 ETF인 SPY를 사용한다. 정규 거래시간의 분봉 가격을 global_markets.delayed_stocks_minute_aggs 표에서 취합했으며, 2005년 4월 마지막 거래일 종가부터 2026년 4월 마지막 거래일 종가까지를 대상으로 한다. 여기서 월간 수익률은 배당을 제외하고, 해당 월의 마지막 정규 거래시간 가격을 직전 월의 가격과 비교해 산출한다. 배당은 아래에서 별도 항목으로 다룬다. 월간 수익률을 측정하는 방법에서는 이 구분이 결과를 바꾸는 이유를 설명한다.

‘5월에 팔고 떠나라’ 전략은 유효한가? 2005년부터 2026년까지의 기록

조회S&P 500 추종 ETF: 5월~10월과 11월~4월의 시즌별 비교
모든 수치 뒤에 숨겨진 정확한 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
Run this yourself

각 점은 한 번의 여름과 그 뒤를 이은 겨울을 짝지어 나타낸다. 차트에는 21개의 완전한 조합이 포함되어 있으며, 2005년 여름에 시작해 2026월에 끝난 겨울로 마무리된다.

대부분의 개별 연도에서는 두 선의 방향이 엇갈렸고, 최악의 해에는 방향이 일치했다. 4월 말부터 10월 말까지 2008 여름 구간은 -29.81%를 기록했으며, 전체 기간 중 가장 큰 하락폭이었다. 그 뒤를 이은 겨울 구간은 -10.03%를 기록했다. 4월에 매도한 투자자는 큰 폭의 하락을 피한 뒤, 마지막 하락 구간에 다시 진입한 셈이다. 달력상 구분과 실제 손실이 일치한 구간은 전체 기간의 절반에 불과했다.

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
Run this yourself

전체 21개 시즌에서 5월부터 10월까지의 평균 수익률은 3.88%였고, 11월부터 4월까지는 6.06%였다. 격차는 2.18%포인트다. 이 격차가 이 규칙의 근거 전부다. 여름철 열을 함께 보면, 해당 여름의 16가 시작 시점보다 높은 수준으로 마감했다. 따라서 평균적인 투자 중단은 손실을 피한 것이 아니라 수익을 놓친 결과가 됐다.

두 기간의 결과는 서로 다르다. 앞선 구간의 격차는 4.84%포인트였고, 이후 구간은 -0.24%포인트였다. 대중적으로 다시 인용되는 설명은 격차를 제시하면서 그 격차가 어느 연도에서 비롯됐는지는 밝히지 않는다. 그러나 핵심은 바로 그 연도에 있다. 계절성 통계는 특정 역사적 기간에 대한 주장이고, 그 기간은 이를 반복해 인용하는 사람이 선택한 것이다.

실제로 8월과 9월 효과인가?

6개월이라는 구분은 너무 포괄적이다. 달력의 범위를 월별로 나누면 여름 구간이 전반적으로 부진한지, 아니면 특정 한 달이 전체 결과를 좌우하는지 확인할 수 있다.

조회월별 S&P 500 추종 ETF 평균 수익률: 2005년 5월~2026년 4월
모든 수치 뒤에 숨겨진 정확한 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))
Run this yourself

약세는 9월에 집중된다. 9월 평균 수익률은 -0.75%였고, 21년 중 12년에 상승 마감했으며, 중간값은 0.38%였다. 8월 평균 수익률은 0.28%였다. 매도자가 건너뛰는 구간의 중간에 있는 7월은 평균 2.63%를 기록했다. 해당 규칙에 따라 다시 매수하기 전 마지막 달인 10월은 평균 0.97%였다.

이 구간에서 효과는 특정 시기에 집중되어 있다. 여름 후반에 한 차례 약세 구간이 나타날 뿐, 그 전후의 월별 흐름은 달력의 다른 시기와 크게 다르지 않다. 4월 말에 매도해 9월을 피하면 5월, 6월, 7월, 8월도 함께 놓치게 된다.

What the switch actually costs

The seasonal gap is a gross number. A rule has to survive its own frictions.

조회1달러의 성장: 연중 보유와 11월~4월만 보유 비교
모든 수치 뒤에 숨겨진 정확한 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 year
Run this yourself

A 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.
조회배당락월별 SPY 분배금: 5월~10월 구간과 그 외 구간 비교
모든 수치 뒤에 숨겨진 정확한 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 year
Run this yourself

SPY'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.

유명한 달력 규칙을 의심해야 하는 이유

12개월 중 투자할 하위 집합을 고르는 방법은 빈 집합을 제외해 4,095가지다. 하나의 가격 이력에 이 모든 경우를 대입해 검색하면 그중 하나는 인상적으로 보이게 마련이다. 이는 검색 과정 자체의 특성이다.

‘5월에 팔아라’가 지난주에 발굴된 규칙보다 정직하게 우월한 점은 하나다. 이 표본이 시작되기 훨씬 전부터 유명했기 때문에, 이 페이지의 연도들은 적합화된 결과가 아니라 표본 외 검증으로 활용할 수 있다. 검증 결과는 격차가 크지 않았고, 그 차이는 한 달에 집중됐다. 또한 같은 기간 매수 후 보유 전략보다 성과가 낮은 전환 규칙에 기반했다. 룩어헤드 바이어스는 백테스트가 미래 정보를 미리 학습해 결과에 반영하는 방식을 설명한다. 달력 규칙은 그 대표적인 사례다. 수익률을 확인한 뒤에 투자할 월을 선택하기 때문이다.

FAQ

Does sell in May and go away still work?

On SPY prices from April 2005 through April 2026, November to April averaged 6.06% against 3.88% for May to October, so the seasonal gap survives in the full sample. The summer half still averaged a gain, with 16 of the 21 summers finishing higher than they started.

Which months are actually the weak ones?

In this window the weakness concentrates in September, which averaged -0.75% and finished higher in 12 of 21 years. July, another month the rule sits out, averaged 2.63% over the same span.

Does selling in May beat buying and holding?

Not over this sample. A dollar held continuously from the end of April 2005 grew to $6.21 by April 2026, against $3.14 for the winter-only switch, and that comparison counts no trading costs, no tax, and no dividends.

What happens to dividends if you sell in May?

A fund's ex-dividend dates do not pause for the summer. Two of SPY's four quarterly ex-dates fall inside the May to October window, and a holder who is out of the fund on an ex-date does not receive that distribution.

Is a seasonal pattern the same as a prediction?

No. A historical average across 21 seasons describes what happened over a stated window. Individual years scatter widely around that average, as the first chart shows, and the window itself is a choice.


Every panel here is a stored query with its SQL attached. Change the ticker, move the window, and check whether the seasonal gap holds on the Strasmore terminal.

#seasonality#backtesting#sp-500#market-history#quant