yfinanceとは?なぜ自動売買に使えるのか
Pythonで株式投資の自動化を始めようとしたとき、最初に悩むのが「どうやって株価データを取得するか」です。有料のデータサービスを使わなくても、yfinanceというライブラリを使えば、Yahoo Financeの株価データを無料で手軽に取得できます。
2026年現在、yfinanceはバージョン0.2系が安定しており、日本株・米国株・ETF・先物・為替など幅広いデータに対応しています。今回はyfinanceで株価データを取得し、シンプルな自動売買BOTのロジックを構築するところまで解説します。
yfinanceのインストールと基本的な使い方
pip install yfinance pandas schedule
単一銘柄のデータ取得
import yfinance as yf
# ティッカーシンボルを指定(日本株は末尾に.T)
ticker = yf.Ticker("7203.T") # トヨタ自動車
# 過去1年分の日足データを取得
df = ticker.history(period="1y")
print(df.tail())
# 銘柄情報も取得できる
info = ticker.info
print(f"会社名: {info.get('longName', 'N/A')}")
print(f"現在値: {info.get('currentPrice', 'N/A')}円")
複数銘柄を一括取得
tickers = ["7203.T", "6758.T", "9984.T", "8306.T", "6861.T"]
data = yf.download(tickers, period="6mo", auto_adjust=True)
close_prices = data['Close']
print(close_prices.tail())
リアルタイムに近い株価の取得
yfinanceは厳密なリアルタイムAPIではありませんが、約15〜20分遅れのデータを1分足〜日足まで取得できます。短期トレードではなく、日次・週次の自動売買BOTなら十分実用的です。
import yfinance as yf
from datetime import datetime
def get_latest_price(ticker_symbol: str) -> dict:
ticker = yf.Ticker(ticker_symbol)
df = ticker.history(period="2d", interval="1m")
if df.empty:
return {}
latest = df.iloc[-1]
return {
"symbol": ticker_symbol,
"datetime": df.index[-1].strftime("%Y-%m-%d %H:%M"),
"close": round(float(latest['Close']), 2),
"volume": int(latest['Volume']),
}
price_data = get_latest_price("7203.T")
print(price_data)
移動平均クロス自動売買BOTの実装
移動平均線のゴールデンクロス・デッドクロスを検知して、売買シグナルを自動で通知するBOTを作ります。
import yfinance as yf
import pandas as pd
import schedule
import time
from datetime import datetime
WATCH_LIST = ["7203.T", "6758.T", "9984.T"]
SHORT_MA = 5
LONG_MA = 25
def calc_signals(ticker_symbol: str) -> dict:
df = yf.download(ticker_symbol, period="3mo", auto_adjust=True, progress=False)
if len(df) < LONG_MA + 2:
return {"signal": "データ不足", "ticker": ticker_symbol}
close = df['Close'].squeeze()
sma_short = close.rolling(SHORT_MA).mean()
sma_long = close.rolling(LONG_MA).mean()
prev_diff = sma_short.iloc[-2] - sma_long.iloc[-2]
curr_diff = sma_short.iloc[-1] - sma_long.iloc[-1]
signal = "HOLD"
if prev_diff < 0 and curr_diff >= 0:
signal = "BUY" # ゴールデンクロス
elif prev_diff > 0 and curr_diff <= 0:
signal = "SELL" # デッドクロス
return {
"ticker": ticker_symbol,
"signal": signal,
"price": round(float(close.iloc[-1]), 2),
"sma_short": round(float(sma_short.iloc[-1]), 2),
"sma_long": round(float(sma_long.iloc[-1]), 2),
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
}
def run_bot():
print(f"[{datetime.now().strftime('%H:%M:%S')}] BOTチェック開始")
for ticker in WATCH_LIST:
result = calc_signals(ticker)
signal = result.get("signal", "ERROR")
if signal == "BUY":
print(f"[買いシグナル] {ticker} @ {result['price']}円")
elif signal == "SELL":
print(f"[売りシグナル] {ticker} @ {result['price']}円")
else:
print(f"[HOLD] {ticker} @ {result.get('price', 'N/A')}円")
# 毎日15:30(東京市場の引け後)に実行
schedule.every().day.at("15:30").do(run_bot)
run_bot() # テスト用:すぐ1回実行
while True:
schedule.run_pending()
time.sleep(60)
Discord通知を追加してスマホで確認する
import requests
def notify_discord(message: str, webhook_url: str):
payload = {"content": message}
response = requests.post(webhook_url, json=payload)
return response.status_code
DISCORD_WEBHOOK = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN"
if signal == "BUY":
notify_discord(
f"[買いシグナル] {ticker}\n"
f"価格: {result['price']}円\n"
f"時刻: {result['timestamp']}",
DISCORD_WEBHOOK
)
yfinanceを使う際の注意点
yfinanceは無料で便利な反面、いくつかの制限があります。まず、データの信頼性については、Yahoo Financeのデータはあくまでも参考値であり、証券会社の公式データとは若干異なる場合があります。本番運用では有料のデータフィードの利用も検討しましょう。
次にリクエスト制限です。短時間に大量のリクエストを送ると一時的にブロックされることがあります。複数銘柄を監視する場合は、time.sleep(1)などで適切なインターバルを設けましょう。また、日本株の時間外データは取得できない場合があります。マーケットが開いている時間(9:00〜15:30 JST)に実行するのが基本です。
まとめ
今回はyfinanceを使ったリアルタイムに近い株価取得と、移動平均クロス戦略による自動売買BOTの基礎を解説しました。重要なのは、このコードをそのまま実弾で使うのではなく、まずバックテストで戦略を検証し、デモ取引で動作確認をしてから少額でスタートすることです。次のステップとして、証券会社のAPIと連携してこのBOTに実際の注文機能を追加する方法も今後の記事で紹介していきます。お楽しみに!

