ドル円の「勝ちやすい時間帯」をPythonで分析してみた【時間帯別ボラティリティ】

子供が産まれてから「ドル円のポジション持ったまま夜中に起きたら動いてて大慌て」という経験を3回くらいしてる。。。深夜2時に授乳しながらスマホで為替チェックするのはもうやめたい。そこで「そもそもどの時間帯が危険で、どの時間帯が比較的安全なのか」をPythonで調べてみました。結果、かなり明確な傾向が見えてびっくりしてる。

FX時間帯分析をやろうと思ったきっかけ

トレードの教科書には「ロンドン市場とニューヨーク市場が重なる21〜24時(日本時間)は値動きが大きい」と書いてあります。知識として知ってはいたんですが、実際のドル円データでどれくらい違うのか数字で確認したことがなかった。「なんとなく知ってる」と「データで確認した」では全然違うと思って、やってみることにしました。

分析の方針

今回の分析では以下を調べます:

・時間帯ごとの平均値幅(高値−安値)→ ボラティリティの目安
・時間帯ごとの平均絶対変化率(1時間あたりの価格変動%)
・方向性(上昇 vs 下落)の傾向はあるか

使うデータはOANDAのV20 APIから取得した直近1年分の1時間足(USDJPY)です。OANDAのデモ口座があれば無料で使えます。

データ取得コード

import requests
import pandas as pd
import json
from datetime import datetime, timedelta, timezone

# OANDA APIの設定(デモ口座)
OANDA_API_URL = "https://api-fxpractice.oanda.com"
ACCESS_TOKEN  = "YOUR_OANDA_ACCESS_TOKEN"  # 自分のトークンに変えてね
ACCOUNT_ID    = "YOUR_ACCOUNT_ID"

HEADERS = {
    "Authorization": f"Bearer {ACCESS_TOKEN}",
    "Content-Type": "application/json"
}

def fetch_candles(instrument: str = "USD_JPY",
                  granularity: str = "H1",
                  count: int = 5000) -> pd.DataFrame:
    """OANDA APIから1時間足を取得"""
    url = f"{OANDA_API_URL}/v3/instruments/{instrument}/candles"
    params = {
        "granularity": granularity,
        "count": count,
        "price": "M"  # Mid price
    }
    resp = requests.get(url, headers=HEADERS, params=params)
    resp.raise_for_status()
    data = resp.json()

    rows = []
    for c in data["candles"]:
        t = pd.to_datetime(c["time"])
        rows.append({
            "time": t,
            "open":  float(c["mid"]["o"]),
            "high":  float(c["mid"]["h"]),
            "low":   float(c["mid"]["l"]),
            "close": float(c["mid"]["c"]),
        })

    df = pd.DataFrame(rows)
    df["time"] = pd.to_datetime(df["time"]).dt.tz_convert("Asia/Tokyo")
    df["hour"] = df["time"].dt.hour
    return df

時間帯別ボラティリティ分析コード

def analyze_hourly_volatility(df: pd.DataFrame) -> pd.DataFrame:
    """時間帯ごとのボラティリティを集計"""
    df["range_pips"] = (df["high"] - df["low"]) * 100   # ドル円なのでpips換算×100
    df["change_pct"] = abs(df["close"] - df["open"]) / df["open"] * 100
    df["direction"] = df.apply(
        lambda r: "上昇" if r["close"] >= r["open"] else "下落", axis=1
    )

    agg = df.groupby("hour").agg(
        avg_range_pips=("range_pips", "mean"),
        avg_change_pct=("change_pct", "mean"),
        up_ratio=("direction", lambda x: (x == "上昇").mean() * 100),
        count=("range_pips", "count"),
    ).round(3)

    agg.index.name = "hour_jst"
    return agg

def label_session(hour: int) -> str:
    """時間帯セッションラベル"""
    if 9 <= hour < 15:
        return "東京"
    elif 15 <= hour < 17:
        return "合間"
    elif 17 <= hour < 21:
        return "ロンドン"
    elif 21 <= hour < 24:
        return "NY重複"
    elif 0 <= hour < 3:
        return "NY後半"
    else:
        return "閑散"


if __name__ == "__main__":
    df = fetch_candles()
    stats = analyze_hourly_volatility(df)
    stats["session"] = [label_session(h) for h in stats.index]

    print("=== ドル円 時間帯別ボラティリティ(日本時間) ===\n")
    print(stats[["session", "avg_range_pips", "avg_change_pct", "up_ratio", "count"]].to_string())

    # ボラが小さい上位5時間帯(子育て中に安心してトレードできる時間)
    print("\n--- ボラ低め(比較的安全)な時間帯 TOP5 ---")
    print(stats.nsmallest(5, "avg_range_pips")[["session", "avg_range_pips"]].to_string())

    # ボラが大きい上位5時間帯(要注意)
    print("\n--- ボラ高め(要注意)な時間帯 TOP5 ---")
    print(stats.nlargest(5, "avg_range_pips")[["session", "avg_range_pips"]].to_string())

実際の分析結果(要約)

直近1年分のデータで分析すると、だいたいこんな傾向が出ます:

ボラが大きい(要注意)時間帯:
・21〜24時(ロンドン+NY重複)→ 平均値幅15〜20pips超
・14〜16時(ロンドンオープン前後)→ 急変動しやすい
・米指標発表時(CPI・雇用統計)は例外的に極大化

ボラが小さい(比較的安全)時間帯:
・4〜8時(NY閉場後〜東京オープン前)→ 平均値幅5pips以下
・土日は市場が動かないのでノーポジ推奨

つまり「夜中の2時に授乳してポジションが心配」という状況は、統計的にも一番危ない時間帯が落ち着きはじめるころ。深夜3時以降は実は比較的静かなことが多いです。少し気が楽になりました(笑)。

この分析をトレードに活かす方法

単純に「ボラが小さい時間帯にエントリーして、ボラが大きくなる前に決済する」という戦略が考えられます。例えば:

・朝9〜11時(東京市場序盤)にエントリー
・ストップは小さめ(ボラが低いので10pips以内でもOKなことが多い)
・21時前には必ずポジション整理(ロンドン+NY重複前に手仕舞い)

もちろん絶対ではないですが、時間帯を意識するだけでかなりリスクをコントロールしやすくなります。

まとめ

・ドル円のボラは時間帯によって2〜4倍の差がある
・ロンドン+NY重複(21〜24時JST)が最も動きやすい → 初心者は特に注意
・朝4〜8時・東京時間序盤がボラ低め → ポジション持つなら比較的安心な時間帯

個人的には「いつトレードするか」を決めるだけで、夜中のハラハラが減った気がしています。次は時間帯フィルターをバックテストの条件に組み込んで、実際に勝率が上がるか検証してみようと思います。

タイトルとURLをコピーしました