Strasmore Research
Investigasi Matt ConnorOleh Matt Connor

Apakah Strategi Sell in May Berhasil?

Uji dua dekade S&P 500 membandingkan return November-April dan Mei-Oktober, termasuk selisih musim panas serta biaya nyata dari berpindah ke cash.

“Sell in May and go away” adalah aturan kalender yang paling dikenal di pasar saham: jual pada akhir April, simpan dana dalam bentuk cash selama musim panas, lalu beli kembali pada akhir Oktober. Berdasarkan harga tracker S&P 500 dari penutupan terakhir April 2005 hingga penutupan terakhir April 2026, periode November hingga April memang rata-rata menghasilkan return yang lebih tinggi dibandingkan periode Mei hingga Oktober. Selisihnya nyata, tetapi lebih kecil daripada yang tersirat dalam ungkapan tersebut. Periode musim panas juga rata-rata mencatat kenaikan. Di sinilah aturan tersebut tidak lagi memadai sebagai strategi.

Apa yang dinyatakan aturan ini dan cara mengujinya

Frasa ini berasal dari kebiasaan lama di London, ketika pelaku pasar meninggalkan kota setelah rangkaian pacuan kuda musim semi dan kembali pada musim gugur. Dalam bentuk modern yang dapat diuji, frasa ini menjadi aturan switching dengan dua tanggal. Anda memegang indeks saham yang luas sejak hari perdagangan terakhir Oktober hingga hari perdagangan terakhir April. Selama enam bulan lainnya, Anda tidak memegang posisi apa pun.

Pengujiannya memerlukan dua hal yang tidak pernah diberikan oleh pepatah tersebut: rangkaian harga dan periode yang ditetapkan. Semua angka di bawah menggunakan SPY, exchange-traded fund S&P 500 tertua, dengan harga berdasarkan minute bar jam perdagangan reguler dalam tabel global_markets.delayed_stocks_minute_aggs, dari penutupan terakhir April 2005 hingga penutupan terakhir April 2026. Return bulanan di sini adalah harga jam perdagangan reguler terakhir dibandingkan dengan harga bulan sebelumnya, tanpa memperhitungkan dividen. Dividen dibahas dalam bagian tersendiri di bawah, sedangkan cara mengukur return bulanan menjelaskan mengapa perbedaan ini mengubah hasilnya.

Apakah strategi sell in May and go away berhasil? Rekam jejak 2005 hingga 2026

QueryPelacak S&P 500: Mei hingga Oktober vs November hingga April, musim demi musim
SQL tepat di balik setiap angka
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

Setiap titik memasangkan satu periode musim panas dengan musim dingin yang mengikutinya. Grafik ini memuat 21 pasangan lengkap, dimulai dari musim panas 2005 dan berakhir pada musim dingin yang selesai pada April 2026.

Kedua garis berbeda pada sebagian besar tahun dan sama pada tahun terburuk. Antara akhir April dan akhir Oktober, 2008 periode musim panas mencatat -29.81%, pembacaan terdalam dalam rangkaian ini. Musim dingin yang mengikutinya mencatat -10.03%. Pemegang yang menjual pada April terhindar dari penurunan tajam, lalu kembali masuk ketika penurunan berlanjut pada tahap terakhir. Kalender dan kerugian hanya sejalan selama separuh perjalanan.

Apakah gap musim panas memudar sejak 2015?

Rata-rata adalah inti klaim dalam pepatah tersebut, sedangkan rentang waktu menjadi dasar perhitungan rata-rata itu. Membagi periode pada 2015 menghasilkan dua bagian dengan panjang yang sebanding dan metode perhitungan yang sama.

QueryKesenjangan musiman berdasarkan era: return rata-rata per semester dan spread di antaranya
SQL tepat di balik setiap angka
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

Di seluruh 21 musim, periode Mei hingga Oktober mencatat rata-rata 3.88%, sedangkan November hingga April mencatat 6.06%, dengan spread sebesar 2.18 percentage points. Spread tersebut menjadi satu-satunya dasar aturan itu. Perhatikan kolom musim panas: 16 dari musim panas tersebut berakhir lebih tinggi daripada titik awalnya. Artinya, rata-rata strategi tidak berinvestasi justru melewatkan kenaikan, bukan menghindari kerugian.

Kedua bagian tersebut menunjukkan hasil yang berbeda. Periode awal mencatat spread sebesar 4.84 points, sedangkan periode berikutnya mencatat -0.24. Uraian populer sering menyebut gap tanpa menjelaskan tahun-tahun yang mendasarinya. Padahal, tahun-tahun itulah inti argumennya. Setiap statistik musiman merupakan klaim tentang satu rentang sejarah, dan rentang tersebut dipilih oleh pihak yang mengulanginya.

Apakah ini benar-benar efek Agustus dan September?

Enam bulan merupakan ukuran yang terlalu kasar. Membagi kalender berdasarkan bulan membantu menilai apakah periode musim panas secara keseluruhan memang lemah atau hanya satu bulan yang menyumbang hampir seluruh hasil tersebut.

QueryReturn rata-rata pelacak S&P 500 berdasarkan bulan kalender, Mei 2005 hingga April 2026
SQL tepat di balik setiap angka
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

Kelemahan terkonsentrasi pada September. Rata-ratanya sebesar -0.75% dan bulan tersebut ditutup lebih tinggi dalam 12 dari 21 tahun, dengan median 0.38%. Rata-rata Agustus mencapai 0.28%. Juli, yang berada di tengah periode yang dilewati penjual, mencatat rata-rata 2.63%. Oktober, bulan terakhir sebelum aturan tersebut kembali membeli, mencatat rata-rata 0.97%.

Pola efek dalam periode ini cukup sempit: satu fase lemah pada akhir musim panas, sementara bulan-bulan di sekitarnya tampak serupa dengan bulan-bulan lain dalam kalender. Keluar pada akhir April untuk menghindari September juga berarti melewatkan Mei, Juni, Juli, dan Agustus.

Biaya sebenarnya dari perpindahan strategi

Selisih musiman adalah angka bruto. Sebuah aturan harus mampu bertahan setelah memperhitungkan friksi yang ditimbulkannya sendiri.

QueryPertumbuhan satu dolar: memegang sepanjang tahun vs hanya memegang November hingga April
SQL tepat di balik setiap angka
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

Satu dolar yang diinvestasikan sepanjang setiap musim sejak akhir April 2005 tumbuh menjadi $6.21 pada akhir April 2026. Dolar yang sama, tetapi hanya diinvestasikan di pasar dari November hingga April dan menganggur sepanjang sisa waktu, tumbuh menjadi $3.14. Kedua garis hanya mencerminkan harga, tanpa pengurangan apa pun, sehingga hasil strategi perpindahan terlihat lebih baik. Berikut hal-hal yang tidak ditampilkan grafik.

  • Dua transaksi setiap tahun, dalam seluruh 21 musim. Biaya eksekusi gratis di sebagian besar broker saat ini. Namun, bid-ask spread yang dibayar pada setiap round trip tidak gratis.
  • Pajak. Dalam akun kena pajak, penjualan pada April merealisasikan keuntungan yang terbentuk sejak November. Periode kepemilikan dari November hingga April secara otomatis kurang dari satu tahun, sehingga bagi wajib pajak AS, keuntungan tersebut dikenai tarif pajak jangka pendek.
  • Dana menganggur. Garis strategi yang hanya berinvestasi pada musim dingin mengasumsikan dana yang tidak diinvestasikan menghasilkan nol. Investor sebenarnya dapat menempatkannya di instrumen tertentu, dan tempat menempatkan dana menganggur membahas instrumen yang umum digunakan.
  • Dividen, yang diperhitungkan pada panel berikutnya.
QueryDistribusi SPY berdasarkan bulan ex-dividend: dalam window Mei hingga Oktober vs di luarnya
SQL tepat di balik setiap angka
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

Tanggal ex-dividend SPY jatuh pada Maret, Juni, September, dan Desember. Dengan demikian, dua dari empat tanggal tersebut berada dalam enam bulan ketika investor tidak memegang aset. Pada 2025, distribusi sebesar $3.592 per saham memiliki ex-date antara Mei dan Oktober, dibandingkan dengan $3.689 pada enam bulan lainnya. Kedua kolom bergerak searah sepanjang grafik. Tidak berinvestasi selama setengah tahun berarti kehilangan sekitar setengah pendapatan dana tersebut setiap tahun, di luar perubahan harga selama bulan-bulan itu. Tanggal ex-dividend adalah batas waktu yang menentukan pihak yang menerima pembayaran.

Ada satu biaya lain yang tidak tercatat sebagai pos tersendiri. Imbal hasil indeks muncul secara berkelompok, dan melewatkan hari-hari terbaik menunjukkan dampak beberapa sesi yang terlewat terhadap saldo jangka panjang. Tidak berinvestasi selama enam bulan setiap tahun berarti melewatkan banyak sesi perdagangan. Perhitungan yang sama mendasari dollar cost averaging sebagai disiplin untuk mempertahankan waktu di pasar, bukan mencoba menentukan waktu pasar.

Mengapa aturan kalender yang terkenal layak dicurigai

Dua belas bulan memiliki 4.095 cara tidak kosong untuk memilih subset yang akan diinvestasikan. Jika ruang tersebut diuji terhadap satu riwayat harga, akan ada sesuatu yang tampak mencolok. Itu merupakan konsekuensi dari proses pencarian.

Sell in May memiliki satu keunggulan yang jujur dibandingkan aturan yang ditambang minggu lalu: aturan ini sudah terkenal jauh sebelum sampel ini dimulai. Karena itu, tahun-tahun pada halaman ini berfungsi sebagai pengujian out-of-sample, bukan hasil yang di-fitting. Pengujian tersebut menunjukkan selisih yang moderat, terkonsentrasi pada satu bulan, dan berasal dari aturan perpindahan posisi yang kinerjanya tertinggal dibandingkan strategi membeli dan menahan selama periode yang sama. Bias look-ahead menjelaskan cara backtest secara diam-diam mempelajari jawabannya terlebih dahulu. Aturan kalender merupakan contoh klasik: bulan-bulan tersebut dipilih setelah return sudah diketahui.

Pertanyaan Umum

Apakah strategi sell in May and go away masih efektif?

Pada harga SPY dari April 2005 hingga April 2026, periode November hingga April rata-rata menghasilkan 6.06% dibandingkan dengan 3.88% pada periode Mei hingga Oktober. Jadi, kesenjangan musiman tetap terlihat dalam seluruh sampel. Periode musim panas tetap mencatat kenaikan rata-rata, dengan 16 dari 21 periode musim panas berakhir lebih tinggi daripada saat dimulai.

Bulan mana yang sebenarnya lemah?

Dalam rentang ini, pelemahan terkonsentrasi pada September. Bulan tersebut mencatat rata-rata -0.75% dan berakhir lebih tinggi pada 12 dari 21 tahun. Juli, yang juga dilewati oleh strategi ini, mencatat rata-rata 2.63% dalam periode yang sama.

Apakah menjual pada Mei mengungguli strategi membeli dan menahan?

Tidak dalam sampel ini. Satu dolar yang terus diinvestasikan sejak akhir April 2005 tumbuh menjadi $6.21 pada April 2026. Sebagai perbandingan, strategi yang hanya berinvestasi pada musim dingin tumbuh menjadi $3.14. Perbandingan ini tidak memperhitungkan biaya transaksi, pajak, maupun dividen.

Apa yang terjadi pada dividen jika Anda menjual pada Mei?

Tanggal ex-dividend suatu dana tidak berhenti selama musim panas. Dua dari empat tanggal ex-dividend kuartalan SPY jatuh dalam periode Mei hingga Oktober. Pemegang yang tidak memiliki dana tersebut pada tanggal ex-dividend tidak menerima distribusi itu.

Apakah pola musiman sama dengan prediksi?

Tidak. Rata-rata historis dari 21 musim menggambarkan apa yang terjadi dalam periode yang ditentukan. Hasil tiap tahun dapat menyimpang jauh dari rata-rata tersebut, seperti ditunjukkan pada grafik pertama. Periode pengamatan itu sendiri juga merupakan pilihan.


Setiap panel di sini merupakan stored query dengan SQL yang dilampirkan. Ubah ticker, geser periode pengamatan, lalu periksa apakah kesenjangan musiman tetap terlihat di terminal Strasmore.

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