【保存版】VPSでFX自動売買システムを自作する。OSSとPythonで構築する最強のトレード環境

MT4も素晴らしい。だが、エンジニアなら「コード」で攻略したくないか?

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
FXの自動売買(システムトレード)といえば、「MT4(MetaTrader 4)」が王道中の王道です。
豊富なEA(自動売買プログラム)、強力なバックテスト機能、そして世界中のトレーダーに愛されるコミュニティ。間違いなく、MT4は素晴らしいプラットフォームです。

しかし、もしあなたが「普段からLinuxやコードに触れているエンジニア」だとしたら、少しウズウズしてきませんか?

  • 「GUIで設定するのではなく、Gitでロジックを管理したい」
  • 「Windows Serverではなく、使い慣れたLinux環境で軽量に動かしたい」
  • 「ブラックボックスなEAではなく、自分で書いたPythonコードで市場と対話したい」

そう、エンジニアにとってFX自動売買は、「最高のインフラ構築・プログラミングの実験場」なのです。
今回は、あえて王道のMT4を使わず、Linux、Docker、PythonといったOSS(オープンソースソフトウェア)技術だけで構築する、エンジニアのための自動売買システムの作り方を解説します。

コウ君

先生! 僕も「fx 自動 売買 vps おすすめ」で検索するとMT4ばかりで、「エンジニア向け」の情報が少なくて困ってました。
Pythonなら機械学習ライブラリも使えるし、Dockerなら環境構築もコード化できますよね。
自分の技術力を活かして、自分だけのシステムを作ってみたいです!

リナックス先生

その意気よ、コウ君。
自作システムなら、ログ解析も、通知機能も、スケーリングも自由自在。
今回は金融APIとして優秀な「OANDA API」を使って、Pythonで売買ロジックを書いていくわよ。
OSはAlmaLinux 9を前提に、コピペで確実に動く手順を用意したわ。さあ、ターミナルを開いて!

本記事では、VPSの選定基準から、セキュリティ対策、Pythonによるボット実装、そしてDockerによる永続化まで、実際の構築手順をステップバイステップで徹底解説します。


1. エンジニアが選ぶべき「FX自動売買 VPS おすすめ」の基準

まず、戦場となるサーバー(VPS)の選び方です。
一般的なアフィリエイト記事では「Windowsが使えるメモリ2GB以上のプラン」が推奨されますが、Linuxで自作する我々の基準は異なります。

1-1. OSは「Linux」一択。Windowsは不要

PythonやNode.jsで書かれたボットを動かすのに、GUI(デスクトップ画面)は不要です。
GUIの描画処理にリソースを割くくらいなら、その分をバックテストの計算能力に回すべきです。
OSは、安定性と長期サポート(LTS)の観点から AlmaLinux 9(またはUbuntu 22.04 LTS)を推奨します。

1-2. 必要なスペックとレイテンシ

ヘッドレス(画面なし)でPythonスクリプトを動かすだけなら、スペックは最小限で済みます。

  • CPU: 1〜2コア
  • メモリ: 1GB(Dockerを使うなら2GB推奨)
  • ディスク: SSD 30GB以上

そして最も重要なのが「レイテンシ(遅延)」「稼働率(SLA)」です。
FXは24時間365日動く市場です。深夜のメンテナンスで頻繁に止まる格安VPSは論外です。
また、APIサーバー(OANDAの場合は東京またはニューヨーク)に近いロケーションを選ぶのが鉄則です。

💡 プロの選定眼:国内VPSの候補
日本のAPIを利用する場合、国内リージョンのVPSが有利です。
・ConoHa VPS: 非常に高速でAPIとの相性が良く、初期費用無料。
・さくらのVPS: 圧倒的な安定感と実績。絶対に止めたくない本番環境向け。
・Xserver VPS: コスパが高く、CPU性能が良いのでバックテストも兼ねるなら選択肢に。
これらの中から、Linux OSが選べるプランを選択しましょう。


2. システムアーキテクチャ:OSSスタックの設計

今回は以下のような構成でシステムを構築します。
全て無料で使えるOSS技術で固めます。

レイヤー 採用技術 役割
Broker API OANDA API (v20) 発注、レート取得を行う接続先。開発者フレンドリーで有名。
Runtime Python 3.11+ ボットの本体。金融ライブラリが豊富。
Container Docker & Compose 環境のコード化。ローカル開発環境と同じ環境をVPSで再現する。
Database SQLite (or PostgreSQL) 過去のレートや取引履歴の保存。小規模ならSQLiteで十分。
Notification Discord Webhook 約定通知やエラー通知をスマホに飛ばす。

この構成の最大のメリットは「ポータビリティ(移植性)」です。
VPS引っ越しが必要になっても、docker-compose.yml とデータファイルを持っていくだけで、数分で環境を復元できます。


3. VPSの構築とセキュリティ堅牢化(Hardening)

金融取引を行うサーバーですから、セキュリティは最優先事項です。
ここでは AlmaLinux 9 を想定し、初期設定をコマンドベースで行います。
※rootユーザーでSSH接続した状態からスタートします。

3-1. 作業用ユーザーの作成と権限付与

rootでの作業はリスクが高いため、作業用ユーザー(ここでは trader)を作成します。

# ユーザー作成とパスワード設定
useradd -m -s /bin/bash trader
passwd trader
# (パスワードを2回入力)

# sudo権限の付与 (wheelグループへ追加)
usermod -aG wheel trader

3-2. SSHの堅牢化

デフォルトの22番ポートは攻撃を受けやすいため変更し、rootログインとパスワード認証を無効化します。

注意: 事前にローカルPCで作成した公開鍵(id_rsa.pubなど)の中身を用意してください。
以下のコマンドで、公開鍵をサーバーに登録します。

# 公開鍵ディレクトリの作成
su - trader
mkdir .ssh
chmod 700 .ssh
# ★ここに自分の公開鍵を貼り付けてください
vi .ssh/authorized_keys
# (公開鍵を貼り付けて保存 :wq)
chmod 600 .ssh/authorized_keys
exit

次に、SSH設定ファイルを sed コマンドで一括置換します。

# バックアップ作成
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# 設定変更 (ポート50022に変更、root禁止、パスワード禁止)
sed -i 's/^#Port 22/Port 50022/' /etc/ssh/sshd_config
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# 構文チェック
sshd -t

3-3. ファイアウォールと時刻同期設定

新しいSSHポートを開放し、時刻同期を有効化します。

# SSHポートの開放 (firewalld)
firewall-cmd --permanent --remove-service=ssh
firewall-cmd --permanent --add-port=50022/tcp
firewall-cmd --reload

# SSH再起動 (接続が切れる前に、別ターミナルで接続確認推奨!)
systemctl restart sshd

# 時刻同期 (Chrony) の確認と有効化
dnf install -y chrony
systemctl enable --now chronyd
chronyc sources -v

これでサーバーの土台は完成です。
以降は、作成した trader ユーザーでポート50022にSSH接続して作業を行ってください。


4. 環境構築:DockerとPython環境の準備

アプリケーションを動かすためのDocker環境を構築します。

Dockerのインストール (AlmaLinux 9)

# dnfリポジトリの追加
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# Dockerのインストール
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 起動と自動起動設定
sudo systemctl enable --now docker

# traderユーザーでDockerコマンドを使えるようにする
sudo usermod -aG docker trader

# 設定反映のため一度ログアウトして再ログイン
exit

再ログイン後、docker ps コマンドがエラーなく実行できれば準備完了です。


5. Pythonによるトレーディングボットの実装

ここからが本番です。OANDA APIを使って「ゴールデンクロスで買う」シンプルなボットを作成します。
プロジェクト用ディレクトリを作成して作業します。

mkdir -p ~/fx-bot/logs
cd ~/fx-bot

5-1. ライブラリ要件ファイル (requirements.txt)

必要なライブラリを定義します。

cat < requirements.txt
oandapyV20
pandas
numpy
requests
EOF

5-2. ボットのコード (bot.py)

以下のPythonコードを作成します。
※OANDAのAPIトークン等はコードに直接書かず、環境変数から読み込む設計にします。

cat < bot.py
import os
import time
import json
import logging
import requests
from oandapyV20 import API
import oandapyV20.endpoints.instruments as instruments
import oandapyV20.endpoints.orders as orders
import pandas as pd

# 環境変数から設定を読み込み
ACCESS_TOKEN = os.getenv("OANDA_ACCESS_TOKEN")
ACCOUNT_ID = os.getenv("OANDA_ACCOUNT_ID")
ENV = os.getenv("ENV", "practice") # practice or live
DISCORD_WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL")

# APIクライアント初期化
client = API(access_token=ACCESS_TOKEN, environment=ENV)

# ロギング設定
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("/var/log/trading_bot/bot.log"),
        logging.StreamHandler()
    ]
)

def send_discord(message):
    """ Discordへ通知 """
    if not DISCORD_WEBHOOK_URL:
        return
    try:
        requests.post(DISCORD_WEBHOOK_URL, json={"content": message})
    except Exception as e:
        logging.error(f"Discord notification failed: {e}")

def get_candles(instrument="USD_JPY", granularity="M5", count=50):
    """ ローソク足データの取得 """
    params = {
        "granularity": granularity,
        "count": count,
        "price": "M"
    }
    r = instruments.InstrumentsCandles(instrument=instrument, params=params)
    client.request(r)
    
    data = []
    for candle in r.response['candles']:
        if candle['complete']:
            data.append({
                'time': candle['time'],
                'close': float(candle['mid']['c'])
            })
    return pd.DataFrame(data)

def create_order(units):
    """ 成行注文の発行 """
    data = {
        "order": {
            "instrument": "USD_JPY",
            "units": str(units),
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }
    r = orders.OrderCreate(ACCOUNT_ID, data=data)
    client.request(r)
    logging.info(f"Order Executed: {json.dumps(r.response)}")
    send_discord(f"🚀 Order Executed: {units} units USD/JPY")

def logic():
    """ 売買ロジック """
    try:
        df = get_candles()
        # 移動平均線の計算
        df['sma_short'] = df['close'].rolling(window=5).mean()
        df['sma_long'] = df['close'].rolling(window=20).mean()
        
        current = df.iloc[-1]
        prev = df.iloc[-2]

        # ゴールデンクロス判定 (前回は短期<長期、今回は短期>長期)
        if prev['sma_short'] < prev['sma_long'] and current['sma_short'] > current['sma_long']:
            logging.info("Golden Cross Detected! Buying...")
            create_order(1000) # 1000通貨買い
        else:
            logging.info("No signal.")

    except Exception as e:
        logging.error(f"Error in logic: {e}")
        send_discord(f"⚠️ Error: {e}")

if __name__ == "__main__":
    logging.info("Bot Started.")
    send_discord("🤖 Bot Started.")
    while True:
        logic()
        time.sleep(300) # 5分待機
EOF

6. Dockerによるコンテナ化とデプロイ

作成したスクリプトをDockerコンテナとしてパッケージングします。

6-1. Dockerfile の作成

Python 3.11の軽量イメージを使用します。

cat < Dockerfile
FROM python:3.11-slim

# タイムゾーンをJSTに設定
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/\$TZ /etc/localtime && echo \$TZ > /etc/timezone

WORKDIR /app

# ライブラリのインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# コードのコピー
COPY bot.py .

# ログディレクトリの作成
RUN mkdir -p /var/log/trading_bot

# バッファリングを無効化してログを即時出力
CMD ["python", "-u", "bot.py"]
EOF

6-2. docker-compose.yml の作成

コンテナの構成定義ファイルです。

cat < docker-compose.yml
services:
  trading-bot:
    build: .
    container_name: fx-bot
    restart: always
    env_file:
      - .env
    volumes:
      - ./logs:/var/log/trading_bot
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
EOF

6-3. 環境変数ファイル (.env) の作成

ここにあなたのOANDA APIキーとアカウントIDを記述します。
※このファイルは絶対に他人に公開してはいけません。

cat < .env
OANDA_ACCESS_TOKEN=あなたのアクセストークン
OANDA_ACCOUNT_ID=あなたのアカウントID-001
ENV=practice
DISCORD_WEBHOOK_URL=あなたのDiscordウェブフックURL
EOF

6-4. 起動コマンド

すべてのファイルが揃ったら、以下のコマンドでボットを起動します。

# ビルドしてバックグラウンドで起動
docker compose up -d

# ログの確認
docker compose logs -f

ログに「Bot Started.」と表示されれば成功です。
これで、あなたが寝ている間もサーバー上でボットが市場を監視し続けます。


7. 運用監視と通知システム(Discord連携)

コード内に仕込んだ send_discord 関数により、注文発生時やエラー時にDiscordへ通知が飛びます。

運用中に「ボットを止めたい」場合は以下のコマンドを使います。

docker compose down

「ロジックを修正して反映したい」場合は、bot.py を編集した後、以下を実行します。

docker compose up -d --build

まとめ:市場をコードで攻略せよ

お疲れ様でした!
これで、特定のプラットフォームに依存しない、あなただけの最強の自動売買環境が整いました。

今回の構築ポイント:

  • VPS選定: Linuxが使え、安定性の高い国内VPS(ConoHaやさくら)を選ぶ。
  • 脱MT4: Python + OANDA API で、ロジックを完全に掌握する。
  • コンテナ化: Dockerを使うことで、環境構築の手間を減らし、移植性を高める。
  • 運用監視: ログの永続化とDiscord通知で、システムの健康状態を常に把握する。
コウ君

先生、できました!
Dockerで動いてるから、自分のPCで作ったロジックをそのままVPSに持っていくだけで動くんですね。
しかも、余計なGUIがないからメモリも全然食わないし、VPSの一番安いプランで余裕です!

そう、それが「エンジニアの戦い方」よ。
あとは、いかに勝てるロジック(アルゴリズム)を作るか。
機械学習(AI)を取り入れるもよし、複数の通貨ペアを監視するもよし。
基盤は整ったわ。あとはあなたのコードで市場を攻略するだけよ!

この環境をベースに、ぜひあなただけの「聖杯」を探求してみてください。
Good Luck!

▼ 自動売買に最適なVPSはこれだ! ▼

低遅延・高安定・Docker対応
「おすすめVPS」

VPSランキングを見る

Pythonスキルを活かす
「ITエンジニア転職」

転職エージェントを見る

コメント