はじめに:株主優待と先回り買いとは?
日本株式市場における株主優待制度は、個人投資家から特に人気のある魅力的な制度です。企業が自社製品やクーポンなどを株主に贈ることで、長期保有を促す目的があります。しかし、この優待制度には毎年決まった“権利確定日”があり、このタイミングに向けて株価が動く“アノマリー”が存在します。
そのアノマリーの一つが「先回り買い」です。これは、優待権利確定日よりも前に株を買っておくことで、需要の集中による株価上昇を狙う投資戦略を指します。
本記事では、この先回り買いが本当に有効なのかを、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ステップ
学びながらポイントも貯まり、一石二鳥です。







