
はじめに:株主優待と先回り買いとは?
日本株式市場における株主優待制度は、個人投資家から特に人気のある魅力的な制度です。企業が自社製品やクーポンなどを株主に贈ることで、長期保有を促す目的があります。しかし、この優待制度には毎年決まった“権利確定日”があり、このタイミングに向けて株価が動く“アノマリー”が存在します。
そのアノマリーの一つが「先回り買い」です。これは、優待権利確定日よりも前に株を買っておくことで、需要の集中による株価上昇を狙う投資戦略を指します。
本記事では、この先回り買いが本当に有効なのかを、Pythonを使って過去10年間の実データから検証してみます。
先回り買いロジックを考える際の3つのポイント
1. 優待権利付き最終日を正確に把握する
優待を受け取るには「権利付き最終日」までに株を保有している必要があります。一般的には「権利確定日の2営業日前」とされるため、正確なカレンダーを用いた日付の特定が重要です。
2. 投資家行動による価格形成を予測
優待を目当てに投資家が集まると、需給の関係で株価が上昇しやすくなります。そのため、「いつ買うか(何ヶ月前)」「いつ売るか(直前 or 少し前)」という売買タイミングがリターンを左右します。
3. 複数年データで平均傾向を掴む
単年の上昇だけで判断すると失敗しがちです。過去5〜10年分のデータを使って統計的に検証することが信頼性を高めます。
東建コーポレーション(1766.T)を例に検証
今回は4月末に株主優待権利確定日がある東建コーポレーションを例に、「先回り買い」が有効かどうかを検証します。優待内容も比較的魅力があり、実需に支えられる値動きが期待できる銘柄です。
Pythonで検証するコード(過去10年分)
以下は、東建コーポレーションの「権利付き最終売買日から3ヶ月前」の株価推移を年別に正規化(始点100)して可視化するPythonコードです。
import yfinance as yf import pandas as pd import matplotlib.pyplot as plt from datetime import datetime, timedelta from matplotlib import font_manager as fm # ===== 日本語フォント設定(Mac用) ===== font_path = "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc" jp_font = fm.FontProperties(fname=font_path) plt.rcParams['font.family'] = jp_font.get_name() # ===== データ取得 ===== ticker = "1766.T" df = yf.download(ticker, start="2013-01-01", end=datetime.today().strftime('%Y-%m-%d')) df = df[['Close']] df.index = pd.to_datetime(df.index) # ===== 優待権利付き最終売買日(4月末営業日から2営業日前)取得 ===== def get_exrights_date(year): last_day = datetime(year, 4, 30) while last_day.weekday() >= 5: last_day -= timedelta(days=1) while last_day not in df.index: last_day -= timedelta(days=1) idx = df.index.get_loc(last_day) return df.index[idx - 2] if idx >= 2 else None # ===== 年度リスト(過去10年) ===== years = list(range(datetime.today().year - 10, datetime.today().year)) # ===== 正規化データを格納 ===== aligned_normalized = pd.DataFrame() plt.figure(figsize=(12, 6)) for year in years: ex_day = get_exrights_date(year) if ex_day is None: continue start_day = ex_day - pd.DateOffset(months=3) subset = df.loc[(df.index >= start_day) & (df.index <= ex_day)].copy() # 経過日数(0〜) subset = subset.reset_index() subset['days'] = (subset['Date'] - subset['Date'][0]).dt.days subset = subset.set_index('days') # 正規化(最初を100) base_price = subset['Close'].iloc[0] subset[f'{year}'] = subset['Close'] / base_price * 100 aligned_normalized[year] = subset[f'{year}'] # 個別線の描画 plt.plot(subset.index, subset[f'{year}'], label=f'{year}年', alpha=0.6) # ===== 平均線の追加 ===== mean_line = aligned_normalized.mean(axis=1) plt.plot(mean_line.index, mean_line.values, color='black', linewidth=2.5, label='10年平均') # ===== グラフ仕上げ ===== plt.axvline(x=90, color='red', linestyle='--', label='権利付き最終日') plt.title('東建コーポレーション:株主優待権利付き前3ヶ月の正規化株価推移(過去10年)', fontproperties=jp_font) plt.xlabel('権利付き最終日までの日数', fontproperties=jp_font) plt.ylabel('正規化株価(基準=100)', fontproperties=jp_font) plt.grid(True) plt.legend() plt.tight_layout() plt.show()
売買タイミングを検証する
過去10年間のデータを見ると、「優待権利日直前の1〜2週間」で株価が上昇する年が多く見られました。ただし、年によっては優待後に下落するパターンもあり、「どこで売るか」も非常に重要です。
複数パターン(例:3ヶ月前買い→1週間前売り、2ヶ月前買い→3日前売りなど)をコードで検証し、平均リターンを比較することで、最適な戦略を見つけることができます。
買付タイミング(1〜3ヶ月前)と売却タイミング(権利付き最終日から数営業日前)によるリターンの違いを定量的に確認するには、以下のPythonコードが有効です。
import yfinance as yf import pandas as pd from datetime import datetime, timedelta import matplotlib.pyplot as plt from matplotlib import font_manager as fm # ===== 日本語フォント設定(Mac専用) ===== font_path = "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc" jp_font = fm.FontProperties(fname=font_path) # ===== データ取得 ===== ticker = "1766.T" # 東建コーポレーション df = yf.download(ticker, start="2010-01-01", end=datetime.today().strftime('%Y-%m-%d')) df = df[['Close']] df.index = pd.to_datetime(df.index) # ===== ヘルパー関数 ===== def get_final_trading_day_april(year): last_day = datetime(year, 4, 30) while last_day.weekday() >= 5: last_day -= timedelta(days=1) while last_day not in df.index: last_day -= timedelta(days=1) return last_day def get_n_days_before(date, n): idx = df.index[df.index < date] if len(idx) >= n: return idx[-n] return None # ===== 分析ロジック ===== results = [] for year in range(2011, datetime.today().year): april_final_day = get_final_trading_day_april(year) ex_rights_date = get_n_days_before(april_final_day, 2) if not ex_rights_date: continue for buy_months_before in [1, 2, 3]: entry_day = ex_rights_date - pd.DateOffset(months=buy_months_before) entry_day = df.index[df.index.get_indexer([entry_day], method='bfill')[0]] for sell_offset in [1, 3, 5]: exit_day = get_n_days_before(ex_rights_date, sell_offset) if entry_day in df.index and exit_day in df.index and entry_day < exit_day: entry_price = df.loc[entry_day, 'Close'] exit_price = df.loc[exit_day, 'Close'] ret = (exit_price - entry_price) / entry_price * 100 results.append({ 'year': year, 'buy_months_before': buy_months_before, 'sell_days_before': sell_offset, 'entry_day': entry_day.date(), 'exit_day': exit_day.date(), 'return(%)': round(ret, 2) }) # ===== 結果集計 ===== results_df = pd.DataFrame(results) summary = results_df.groupby(['buy_months_before', 'sell_days_before'])['return(%)'].mean().unstack() # ===== 出力表示 ===== print() print("平均リターン(%):") print(summary.round(2)) # ===== グラフ描画 ===== summary.T.plot(kind='bar') plt.title('東建コーポレーション:優待権利付き最終日前の先回り買い分析', fontproperties=jp_font) plt.xlabel('売却タイミング(何営業日前)', fontproperties=jp_font) plt.ylabel('平均リターン(%)', fontproperties=jp_font) plt.grid(True) plt.tight_layout() plt.show()
他の銘柄にも拡張する方法
この先回り買いの検証ロジックは、他の優待銘柄にも簡単に応用できます。例えば、以下のようにループ処理を組めば、同様の分析が可能です。
- 銘柄コードと優待月のリストを用意
- それぞれの権利付き最終日を計算
- 3ヶ月前〜直前のデータを正規化して比較
- 結果をpandasやmatplotlibで可視化
定期的にこの分析を行えば、「毎年安定して先回り買いが有効な銘柄」の選定にも役立ちます。
まとめ:アノマリーを見逃さず、統計的に検証する時代へ
「優待狙いの先回り買い」は、昔からある戦略ですが、今やデータとコードで誰でも簡単に裏付けが取れる時代です。感覚ではなく、過去10年分のデータでリスクとリターンを見極め、投資判断に活かしていくことが重要です。
Pythonを学ぶなら「Udemy」で効率的に
独学でPythonを学ぶ場合、公式リファレンスだけでは挫折しがちです。
そんな時に心強いのが、動画で体系的に学べるUdemyの講座。
- Python初心者向け講座から、投資データ分析に特化した実践講座まで多数
- 買い切り型で、一度買えばいつでも復習可能
- セール時は90%オフなど、非常にお得
投資家にとっての“自己投資”として、Udemyは非常にコスパの高い選択肢です。
【裏ワザ】Udemyの講座は“ある方法”でさらにお得に買える
実は、Udemyの講座はポイントサイトを経由することで、さらにお得に購入できることをご存知ですか?
おすすめは「ハピタス」というポイントサイト。
ハピタスを経由してUdemyで講座を購入すると、購入金額の数15%がポイントとして還元されます(2025年4月調査時点)。
手順は3ステップ
学びながらポイントも貯まり、一石二鳥です。