決算発表は株価が大きく動くイベントです。「うっかり決算日を忘れていて損した」を防ぐために、Pythonで決算スケジュールを自動取得してアラートを出すツールを作ります。
yfinanceで決算情報を取得する
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta
def get_earnings_info(ticker_symbol):
"""銘柄の決算情報を取得"""
ticker = yf.Ticker(ticker_symbol)
# 次回決算日
calendar = ticker.calendar
print(f"\n=== {ticker_symbol} 決算情報 ===")
if calendar is not None and not calendar.empty:
print(f"次回決算日(予定): {calendar}")
# 過去の決算実績
earnings = ticker.earnings_history
if earnings is not None:
print("\n過去の決算実績:")
print(earnings.tail(4))
# 四半期決算
quarterly = ticker.quarterly_earnings
if quarterly is not None:
print("\n四半期EPS(予想 vs 実績):")
print(quarterly.tail(4))
return calendar
# 主要銘柄の決算情報を確認
for ticker in ["AAPL", "NVDA", "9984.T"]:
get_earnings_info(ticker)
ウォッチリストの決算スケジュール一覧
def get_upcoming_earnings(watchlist, days_ahead=30):
"""今後N日以内に決算がある銘柄を抽出"""
today = datetime.today()
cutoff = today + timedelta(days=days_ahead)
upcoming = []
for ticker_symbol in watchlist:
try:
ticker = yf.Ticker(ticker_symbol)
cal = ticker.calendar
if cal is None or cal.empty:
continue
# 決算日を取得
if hasattr(cal, "loc") and "Earnings Date" in cal.index:
earnings_dates = cal.loc["Earnings Date"]
if not isinstance(earnings_dates, pd.Series):
earnings_dates = [earnings_dates]
for ed in earnings_dates:
try:
ed_date = pd.to_datetime(ed).replace(tzinfo=None)
if today <= ed_date <= cutoff:
days_until = (ed_date - today).days
upcoming.append({
"Ticker": ticker_symbol,
"決算日": ed_date.strftime("%Y-%m-%d"),
"あと何日": days_until,
})
except:
pass
except Exception as e:
pass
if not upcoming:
print(f"今後{days_ahead}日以内に決算はありません")
return pd.DataFrame()
df = pd.DataFrame(upcoming).sort_values("あと何日")
return df
watchlist = ["AAPL", "NVDA", "MSFT", "GOOGL", "AMZN", "TSLA", "META"]
upcoming = get_upcoming_earnings(watchlist, days_ahead=30)
print(upcoming)
決算サプライズ分析
def analyze_earnings_surprise(ticker_symbol, quarters=8):
"""決算サプライズ(予想vs実績)を分析"""
ticker = yf.Ticker(ticker_symbol)
earnings = ticker.earnings_history
if earnings is None or earnings.empty:
print(f"{ticker_symbol}: 決算データなし")
return
df = earnings.tail(quarters).copy()
if "epsEstimate" in df.columns and "epsActual" in df.columns:
df["サプライズ"] = df["epsActual"] - df["epsEstimate"]
df["サプライズ率(%)"] = (df["サプライズ"] / df["epsEstimate"].abs()) * 100
df["結果"] = df["サプライズ"].apply(lambda x: "上振れ" if x > 0 else "下振れ")
print(f"\n=== {ticker_symbol} 決算サプライズ履歴 ===")
print(df[["epsEstimate", "epsActual", "サプライズ", "サプライズ率(%)", "結果"]].round(2))
beat_rate = (df["サプライズ"] > 0).mean()
print(f"\n予想超過率: {beat_rate:.0%} ({quarters}四半期中)")
for t in ["AAPL", "NVDA", "MSFT"]:
analyze_earnings_surprise(t)
メール通知システムの実装
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def send_earnings_alert_email(
smtp_server, smtp_port, sender_email, sender_password,
recipient_email, upcoming_df
):
"""決算アラートメールを送信"""
if upcoming_df.empty:
return
subject = f"【決算アラート】今後の決算スケジュール ({len(upcoming_df)}銘柄)"
body = "今後の決算スケジュールをお知らせします。\n\n"
for _, row in upcoming_df.iterrows():
body += f"- {row['Ticker']}: {row['決算日']} (あと{row['あと何日']}日)\n"
body += "\n※ このメールはPythonスクリプトにより自動送信されています。"
msg = MIMEMultipart()
msg["From"] = sender_email
msg["To"] = recipient_email
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain", "utf-8"))
with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
server.login(sender_email, sender_password)
server.send_message(msg)
print(f"メール送信完了: {recipient_email}")
# Gmailで送信する場合(要:アプリパスワード設定)
# send_earnings_alert_email(
# "smtp.gmail.com", 465,
# "your@gmail.com", "your_app_password",
# "your@gmail.com", upcoming
# )
自動実行の設定(cron/タスクスケジューラ)
#!/usr/bin/env python3
"""earnings_alert.py - 毎朝8時に実行するスクリプト"""
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta
WATCHLIST = [
"AAPL", "NVDA", "MSFT", "GOOGL", "AMZN",
"7203.T", "9984.T", "6758.T"
]
def main():
print(f"決算アラートチェック: {datetime.now().strftime('%Y-%m-%d %H:%M')}")
upcoming = get_upcoming_earnings(WATCHLIST, days_ahead=7) # 1週間以内
if not upcoming.empty:
print("【要注意】1週間以内に決算があります:")
print(upcoming)
# メール送信やSlack通知をここに追加
else:
print("1週間以内に決算なし")
if __name__ == "__main__":
main()
# Linuxのcronに登録する場合(毎朝8時実行):
# 0 8 * * 1-5 /usr/bin/python3 /home/user/earnings_alert.py
まとめ
決算スケジュールを自動監視することで、大事な決算発表を見逃すリスクがなくなります。メール通知と組み合わせれば、完全自動の決算アラートシステムが完成します。

