おうちで体感!ボードゲームで始めるお金の勉強
オンラインキャッシュフローゲーム会
Zoomで毎月開催中 / 初心者大歓迎 / 全国どこからでも参加OK
メニュー

XAUUSD自動売買をPythonで作った|東大卒エンジニアの開発記録

FX・トレード

なぜPythonで自動売買を作ろうと思ったか

僕がFXでXAUUSD(金・ドル)を取引し始めたのは、USD/JPYでしばらくやっていた後のことです。XAUUSDに乗り換えた理由はいくつかありますが、一番大きかったのは「値動きのクセが読みやすい」と感じたこと。NYセッション(日本時間21時〜翌3時)に値動きが集中するので、会社員の副業トレードとしてスケジュールが組みやすいのも魅力でした。

ただ、問題が一つありました。「この戦略は本当に勝てるのか?」を検証する方法がなかったんです。チャートを目で見て「なんとなく機能しそう」という感覚はある。でも感覚を裏付けるデータがない。手動でバックテストしようとしたら、数百本のローソク足を一本ずつ見ていく作業になる。

エンジニアとして、これは自動化できると直感しました。「どうせPythonで書くなら、アラートも自動化してしまおう」となるのは自然な流れで、最終的にはバックテスト → リアルタイムアラート → 自動売買まで一気に作りました。

📝 著者注 本記事はシステム開発の体験記です。特定の投資手法を推奨するものではありません。FXはリスクを伴います。

システムの全体構成

作ったシステムの全体像はこうです。

コンポーネント 使用ツール 役割
データ取得 MetaTrader5 (MT5) API XAUUSDのOHLCデータを取得
バックテストエンジン Python (pandas) 過去データでZigZag+ダウ理論を検証
リアルタイム分析 Python + MT5 API 4H/1H/15M/5Mのマルチタイムフレーム分析
アラート通知 Discord Webhook エントリーシグナルをDiscordに通知
自動実行 Windowsタスクスケジューラ NYセッション開始時刻に自動起動

最初は「バックテストだけ書ければいい」と思っていましたが、せっかくMT5からデータを取得できるなら、リアルタイムでも動かしたい。そう考えてどんどん機能が膨らんでいきました。エンジニアあるあるだと思います。

バックテスト自動化から始めた理由

手動バックテストは地獄です。チャートを左から右に流しながら、「このローソク足の時点でのトレンドはどうか」「エントリー条件を満たしているか」を一本ずつ判定して記録していく。100本のローソク足をチェックするだけで1〜2時間かかります。

Pythonでやれば、同じ作業が数秒で終わります。MT5のAPIを使えば過去データは無料で取得できる。データを取ってきてpandasで処理して、条件に合う場所でエントリーしたと仮定してP/Lを計算する。それだけです。

  • 手動バックテスト:100本で1〜2時間
  • Python自動バックテスト:数千本を数秒
  • パラメータ変更して再テスト:数秒 × 何パターンでも

この差は圧倒的で、「エンジニアがFXをやるなら絶対に自動化すべき」と確信しました。

使った戦略:ダウ理論 + ZigZag

マルチタイムフレームの構成

戦略の基本はダウ理論によるトレンド判定です。高値・安値の切り上げ/切り下げでトレンド方向を判断し、それに沿ったエントリーだけを取る。シンプルですが、これを4つの時間軸で組み合わせます。

  • 4H・1H足:大きなトレンド方向を判断(上昇 / 下降 / レンジ)
  • 15M足:エントリーポイントの絞り込み
  • 5M足:最終的なエントリータイミング

ZigZagで高値・安値を自動判定

ダウ理論の「高値・安値の切り上げ」を手動でチャートを見て判定するのは主観が入ります。これをコード化するために使ったのがZigZagアルゴリズムです。

💡 ZigZagとは 値動きの転換点(山・谷)を自動検出するアルゴリズム。「この幅より小さい動きは無視する」というパラメータを設定することで、ノイズを除去して本質的な高値・安値を取り出せる。

試行錯誤の結果、以下の設定で落ち着きました。

# ZigZag パラメータ設定 ZIGZAG_DEPTH = 12 # 最低でも12本のローソク足の動きを確認 ZIGZAG_DEVIATION = 0.003 # 0.3%未満の動きはノイズとして無視 # 高値・安値の抽出 def find_zigzag_points(df, depth=12, deviation=0.003): highs = [] lows = [] for i in range(depth, len(df) – depth): window = df[‘high’].iloc[i-depth:i+depth+1] if df[‘high’].iloc[i] == window.max(): highs.append(i) window_l = df[‘low’].iloc[i-depth:i+depth+1] if df[‘low’].iloc[i] == window_l.min(): lows.append(i) return highs, lows

エントリー条件とリスクリワード

  • SL(損切り幅):固定50pips
  • TP(利確幅):固定100pips
  • リスクリワード:1:2
  • 1トレードリスク:口座残高の2%

バックテストの結果(正直に公開)

ここが一番正直に書くべき部分です。

勝率
〜51%
RR比
1:2
検証期間
〜2年分
損益分岐点勝率
33%

RR比1:2であれば、理論上は勝率33%でも損益ゼロです。実測の勝率は50〜51%程度で、損益分岐点はクリアしています。ただし、これは「かろうじてプラス圏」という結果です。

⚠️ 正直なところ 「爆発的に勝てる」システムではありません。スプレッドや手数料を引いた後の実績はさらに厳しくなります。現在このシステムは調整中で、実運用は一時停止しています。「完璧なシステムを作った」という話ではなく、「作って検証して、現実を知った」という記録です。

それでも、バックテストを自動化したことで「この戦略はどの程度機能するか」を数値で把握できるようになったのは大きな進歩でした。感覚でトレードするより、遥かに明確な改善サイクルが回せます。

NYセッション自動アラートの実装

バックテストが形になったあと、次に作ったのがリアルタイムアラートです。NYセッション中(日本時間21:00〜03:00)に、エントリー条件が揃ったタイミングでDiscordに通知が来るようにしました。

import requests import MetaTrader5 as mt5 def send_discord_alert(message: str, webhook_url: str): payload = {“content”: message} requests.post(webhook_url, json=payload) def check_entry_signal(symbol=“XAUUSD”): # 4H足のトレンド確認 df_4h = get_ohlc(symbol, mt5.TIMEFRAME_H4, bars=100) trend = detect_trend_dow(df_4h) # 5M足でエントリータイミング確認 df_5m = get_ohlc(symbol, mt5.TIMEFRAME_M5, bars=50) signal = check_entry_5m(df_5m, trend) if signal: msg = f“🔔 XAUUSD {signal[‘direction’]} シグナル\n” + f“エントリー: {signal[‘entry’]:.2f}\n” + f“SL: {signal[‘sl’]:.2f} | TP: {signal[‘tp’]:.2f}” send_discord_alert(msg, WEBHOOK_URL)

このコードをNYセッション中に5分ごとに実行することで、チャートを張り付かなくても「シグナルが出たらDiscordで通知が来る」という運用が実現しました。

Windowsタスクスケジューラで自動起動

毎晩21時に手動でスクリプトを起動するのは継続できないので、Windowsタスクスケジューラを使って自動化しました。

  1. タスクスケジューラを開く(スタートメニューで検索)
  2. 「タスクの作成」→ トリガーで「毎日 21:00」を設定
  3. 操作で「プログラムの開始」→ python.exe のパスを指定
  4. 引数にスクリプトのパスを入力して完了
  5. 翌朝3時00分に停止するタスクも別途設定
💡 ポイント python.exeのパスは仮想環境(venv)のものを指定するとライブラリが正しく読み込まれます。絶対パスで指定してください。

現在の状況と今後

正直に書きます。このシステムは現在停止中です。

バックテストの結果は「惜しいが不十分」でした。RR比1:2、勝率51%程度では、スプレッドや手数料を考えると安定したプラス収支にならない。もう少し勝率を上げるか、エントリー精度を高める改良が必要です。

具体的に試したいのは、以下の改良です。

  • ZigZagのパラメータをさらに最適化(depth・deviationの組み合わせ探索)
  • エントリー条件にボラティリティフィルターを追加
  • 固定SL/TPをATR(平均真の値幅)ベースの動的設定に変更
  • 取引時間帯をNYセッション内でさらに絞り込む

「完璧なシステムを作った」話ではなく、「作って、検証して、現実を知って、改良を続けている」——これがリアルです。そして、エンジニアとしてこのプロセス自体がすごく面白い。

まとめ:作って気づいたこと

このシステムを作って、一番よかったのは「感覚をデータで検証できるようになった」ことです。

手動トレードのときは「この戦略が機能している気がする」という感覚だけが頼りでした。Pythonで自動化してからは、「この設定では勝率48%、あの設定では51%」という数値で比較できる。改善の方向性が明確になります。

エンジニアがFXをやるなら、絶対に自動バックテストは組むべきだと思います。コードはそこまで複雑ではないので、Pythonが書ければ誰でもできます。


むろちゃん(室 / @muro.lifeup)

東京大学法学部卒。現役エンジニア2年目。Python/TypeScriptで業務開発をしながら、FX・副業・お金の勉強を実践中。毎週「FX勉強会」「キャッシュフローゲーム会」「家計簿勉強会」「営業・マーケ勉強会」を開催。

FXをもっと深く学びたい方へ

毎週オンライン・オフラインで「FX勉強会」を開催しています。
XAUUSD・バックテスト・資金管理など、この記事に書いたことを直接話しています。
参加費1,000円(1〜2時間)。初心者・経験者問わず歓迎です。

FX勉強会に参加する →

コメント

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