株主優待権利日前の“先回り買い”は有効か?Pythonで10年データを分析する方法【入門+実践コード】

はじめに:株主優待と先回り買いとは?

日本株式市場における株主優待制度は、個人投資家から特に人気のある魅力的な制度です。企業が自社製品やクーポンなどを株主に贈ることで、長期保有を促す目的があります。しかし、この優待制度には毎年決まった“権利確定日”があり、このタイミングに向けて株価が動く“アノマリー”が存在します。

そのアノマリーの一つが「先回り買い」です。これは、優待権利確定日よりも前に株を買っておくことで、需要の集中による株価上昇を狙う投資戦略を指します。

本記事では、この先回り買いが本当に有効なのかを、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年分

売買タイミングを検証する

過去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ステップ

  1. ハピタスに無料登録
  2. その買うを、もっとハッピーに。|ハピタス

  3. 「Udemy」と検索して表示されたリンクをクリック
  4. 講座を通常通り購入するだけ

学びながらポイントも貯まり、一石二鳥です。