ボリンジャーバンドのバンド外に出たのにトレードに乗り遅れた、という経験が何度もある。子育て中だと相場を見張る時間がない。そこで「バンド逸脱を自動検知してLINEに飛ばす」仕組みを作った。
ボリンジャーバンドとは
移動平均線 ± 標準偏差×係数で引いたバンド。±2σの外に価格が出ると「異常値」と判断する。ドル円のような平均回帰性の高い通貨ペアでは、バンド逸脱後の反転を狙う戦略が比較的機能しやすい(ただし必ず検証すること)。
実装コード
import yfinance as yf
import pandas as pd
import requests
from datetime import datetime
def get_usdjpy(period="3mo") -> pd.DataFrame:
"""ドル円の日足データを取得"""
df = yf.download("JPY=X", period=period, interval="1d", auto_adjust=True)
df.columns = [c[0] if isinstance(c, tuple) else c for c in df.columns]
return df
def calc_bollinger(close: pd.Series, window=20, num_std=2):
"""ボリンジャーバンドを計算"""
ma = close.rolling(window=window).mean()
std = close.rolling(window=window).std()
upper = ma + num_std * std
lower = ma - num_std * std
return ma, upper, lower
def check_band_breakout(df: pd.DataFrame) -> str | None:
"""バンド逸脱を検知してメッセージを返す"""
_, upper, lower = calc_bollinger(df["Close"])
latest_close = df["Close"].iloc[-1]
latest_upper = upper.iloc[-1]
latest_lower = lower.iloc[-1]
if latest_close > latest_upper:
return (f"⚠️ ドル円バンド上抜け!
"
f"現在値: {latest_close:.2f}円
"
f"上限バンド: {latest_upper:.2f}円
"
f"時刻: {datetime.now().strftime('%H:%M')}")
elif latest_close < latest_lower:
return (f"✅ ドル円バンド下抜け!(反転機会?)
"
f"現在値: {latest_close:.2f}円
"
f"下限バンド: {latest_lower:.2f}円
"
f"時刻: {datetime.now().strftime('%H:%M')}")
return None
def send_line_notify(token: str, message: str):
"""LINE Notifyでメッセージを送信"""
headers = {"Authorization": f"Bearer {token}"}
data = {"message": f"
{message}"}
requests.post("https://notify-api.line.me/api/notify",
headers=headers, data=data)
# 実行
LINE_TOKEN = "YOUR_LINE_TOKEN" # LINE Notifyトークン
df = get_usdjpy()
alert = check_band_breakout(df)
if alert:
send_line_notify(LINE_TOKEN, alert)
print("LINEに通知送信:", alert)
else:
print("シグナルなし。現在値:", df["Close"].iloc[-1])
これをcronで15分ごとに実行している。子供が寝かしつけで離れている間に動きがあっても、スマホに通知が来るので見逃さない。
次は時間帯フィルタ(東京時間はスキップ)も追加してみようと思っている。

