Web Lukes
📄

🎯 cTrader Open APIでリアルタイム価格を取得!Python実践チュートリアル【コピペでOK】

公開日: 2026/1/7

🎯 cTrader Open APIでリアルタイム価格を取得!Python実践チュートリアル

この記事でできるようになること

  • シンボル(通貨ペア)の一覧を取得する
  • リアルタイムでBid/Askを受信する
  • 価格データを使って独自の処理を行う

前回の記事でOpen APIへの接続ができるようになりましたね。今回は実際に価格データを取得していきます!


準備:前回の復習

まず、前回作った接続コードを土台にします。

Python
from ctrader_open_api import Client, Protobuf, TcpProtocol, EndPoints
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiMessages_pb2 import *
from twisted.internet import reactor
# 認証情報(あなたの値に置き換えて)
CLIENT_ID = "あなたのClient ID"
CLIENT_SECRET = "あなたのClient Secret"
ACCESS_TOKEN = "取得したアクセストークン"
ACCOUNT_ID = 12345678 # 数値で指定
# ライブorデモの選択
HOST = EndPoints.PROTOBUF_LIVE_HOST # ライブ
# HOST = EndPoints.PROTOBUF_DEMO_HOST # デモの場合はこちら
client = Client(HOST, EndPoints.PROTOBUF_PORT, TcpProtocol)

Step 1: シンボル一覧を取得する

MQLでいう「MarketInfo」の代わり

MQLでは Symbol() や MarketInfo() で通貨ペアの情報を取得できましたよね。

Open APIでは、まずシンボルの一覧を取得して、それぞれのシンボルIDを把握する必要があります。

Python
def getSymbols():
"""シンボル一覧を取得"""
request = ProtoOASymbolsListReq()
request.ctidTraderAccountId = ACCOUNT_ID
deferred = client.send(request)
deferred.addCallback(onSymbolsList)
def onSymbolsList(result):
"""シンボル一覧の受信"""
print(f"📋 {len(result.symbol)} 個のシンボルを取得!")
# EURUSDを探す
for symbol in result.symbol:
if "EURUSD" in symbol.symbolName:
print(f"🔍 発見: {symbol.symbolName} (ID: {symbol.symbolId})")
print(f" 小数点以下桁数: {symbol.digits}")
print(f" pip位置: {symbol.pipPosition}")

実行結果

Code
📋 127 個のシンボルを取得!
🔍 発見: EURUSD (ID: 1)
小数点以下桁数: 5
pip位置: 4

💡 ポイント: シンボルIDは口座によって異なる場合があります。必ず自分の口座で確認してください!


Step 2: 完全版コード - シンボル取得

実際に動かせる完全なコードはこちら:

Python
from ctrader_open_api import Client, Protobuf, TcpProtocol, EndPoints
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiMessages_pb2 import *
from twisted.internet import reactor
# 設定
CLIENT_ID = "あなたのClient ID"
CLIENT_SECRET = "あなたのClient Secret"
ACCESS_TOKEN = "取得したアクセストークン"
ACCOUNT_ID = 12345678
client = Client(EndPoints.PROTOBUF_LIVE_HOST, EndPoints.PROTOBUF_PORT, TcpProtocol)
# シンボル情報を保存する辞書
symbols = {}
def onConnected(client):
print("🔗 接続成功!")
# アプリ認証
request = ProtoOAApplicationAuthReq()
request.clientId = CLIENT_ID
request.clientSecret = CLIENT_SECRET
deferred = client.send(request)
deferred.addCallback(onAppAuth)
def onAppAuth(result):
print("✅ アプリ認証完了")
# アカウント認証
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = ACCOUNT_ID
request.accessToken = ACCESS_TOKEN
deferred = client.send(request)
deferred.addCallback(onAccountAuth)
def onAccountAuth(result):
print("✅ アカウント認証完了")
# シンボル一覧を取得
request = ProtoOASymbolsListReq()
request.ctidTraderAccountId = ACCOUNT_ID
deferred = client.send(request)
deferred.addCallback(onSymbolsList)
def onSymbolsList(result):
print(f"\n📋 {len(result.symbol)} 個のシンボルを取得!\n")
# 主要通貨ペアを表示
major_pairs = ["EURUSD", "USDJPY", "GBPUSD", "AUDUSD", "XAUUSD"]
for symbol in result.symbol:
# 辞書に保存
symbols[symbol.symbolName] = {
"id": symbol.symbolId,
"digits": symbol.digits,
"pipPosition": symbol.pipPosition
}
# 主要ペアのみ表示
if symbol.symbolName in major_pairs:
print(f"💰 {symbol.symbolName}")
print(f" ID: {symbol.symbolId}")
print(f" 桁数: {symbol.digits}")
print(f" pip位置: {symbol.pipPosition}")
print()
reactor.stop()
def onError(failure):
print(f"❌ エラー: {failure}")
reactor.stop()
# コールバック設定
client.setConnectedCallback(onConnected)
client.setDisconnectedCallback(lambda client, reason: print(f"切断: {reason}"))
client.startService()
reactor.run()

Step 3: リアルタイム価格を受信する

いよいよ本番!リアルタイムでBid/Askを受信します。

サブスクライブの仕組み

MQLでは Bid や Ask 変数でいつでも価格にアクセスできましたが、Open APIでは:

  1. 「この通貨ペアの価格を送ってね」とサブスクライブ(購読)
  2. 価格が変わるたびにイベントが飛んでくる
  3. そのイベントを受け取って処理

というプッシュ型の仕組みです。

サブスクライブのコード

Python
def subscribeSpots(symbolId):
"""リアルタイム価格をサブスクライブ"""
request = ProtoOASubscribeSpotsReq()
request.ctidTraderAccountId = ACCOUNT_ID
request.symbolId.append(symbolId)
deferred = client.send(request)
deferred.addCallback(lambda r: print(f"✅ シンボルID {symbolId} をサブスクライブ開始!"))

価格イベントを受信

Python
def onMessageReceived(client, message):
"""受信したメッセージを処理"""
if message.payloadType == ProtoOASpotEvent().payloadType:
# 価格データを取得
spot = Protobuf.extract(message)
# 価格を計算(整数値 ÷ 100000)
bid = spot.bid / 100000 if spot.HasField('bid') else None
ask = spot.ask / 100000 if spot.HasField('ask') else None
print(f"💹 シンボルID {spot.symbolId}: Bid={bid}, Ask={ask}")

💡 重要: Open APIの価格は整数値で送られてきます!

例えば EURUSD の Bid が 110523 なら、実際の価格は 1.10523 です(100000で割る)。


Step 4: 完全版コード - リアルタイム価格取得

全部組み合わせた完全版コードです。コピペでそのまま動きます!

Python
from ctrader_open_api import Client, Protobuf, TcpProtocol, EndPoints
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiMessages_pb2 import *
from twisted.internet import reactor
import time
# ============================================
# 設定(ここを自分の値に置き換えて!)
# ============================================
CLIENT_ID = "あなたのClient ID"
CLIENT_SECRET = "あなたのClient Secret"
ACCESS_TOKEN = "取得したアクセストークン"
ACCOUNT_ID = 12345678 # 数値で
# 価格を取得したい通貨ペア
TARGET_SYMBOLS = ["EURUSD", "USDJPY", "XAUUSD"]
# ============================================
client = Client(EndPoints.PROTOBUF_LIVE_HOST, EndPoints.PROTOBUF_PORT, TcpProtocol)
# データ保存用
symbols_info = {}
current_prices = {}
def onConnected(client):
print("=" * 50)
print("🔗 cTrader Open APIに接続しました!")
print("=" * 50)
request = ProtoOAApplicationAuthReq()
request.clientId = CLIENT_ID
request.clientSecret = CLIENT_SECRET
deferred = client.send(request)
deferred.addCallback(onAppAuth)
def onAppAuth(result):
print("✅ アプリケーション認証完了")
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = ACCOUNT_ID
request.accessToken = ACCESS_TOKEN
deferred = client.send(request)
deferred.addCallback(onAccountAuth)
def onAccountAuth(result):
print("✅ アカウント認証完了")
print("\n📋 シンボル一覧を取得中...")
request = ProtoOASymbolsListReq()
request.ctidTraderAccountId = ACCOUNT_ID
deferred = client.send(request)
deferred.addCallback(onSymbolsList)
def onSymbolsList(result):
print(f"✅ {len(result.symbol)} 個のシンボルを取得\n")
# ターゲットシンボルのIDを取得
subscribe_ids = []
for symbol in result.symbol:
symbols_info[symbol.symbolId] = {
"name": symbol.symbolName,
"digits": symbol.digits
}
if symbol.symbolName in TARGET_SYMBOLS:
subscribe_ids.append(symbol.symbolId)
print(f" 🎯 {symbol.symbolName} (ID: {symbol.symbolId})")
print("\n" + "=" * 50)
print("📡 リアルタイム価格のサブスクライブを開始...")
print("=" * 50 + "\n")
# スポット価格をサブスクライブ
request = ProtoOASubscribeSpotsReq()
request.ctidTraderAccountId = ACCOUNT_ID
for sid in subscribe_ids:
request.symbolId.append(sid)
deferred = client.send(request)
deferred.addCallback(lambda r: print("✅ サブスクライブ開始!価格が更新されると表示されます\n"))
def onMessageReceived(client, message):
"""リアルタイムで受信するメッセージを処理"""
# SpotEvent(価格更新)を処理
if message.payloadType == 2131: # ProtoOASpotEvent
spot = Protobuf.extract(message)
symbol_id = spot.symbolId
symbol_name = symbols_info.get(symbol_id, {}).get("name", f"ID:{symbol_id}")
digits = symbols_info.get(symbol_id, {}).get("digits", 5)
# 価格を計算
divisor = 10 ** digits
bid = spot.bid / divisor if spot.HasField('bid') else current_prices.get(symbol_id, {}).get('bid')
ask = spot.ask / divisor if spot.HasField('ask') else current_prices.get(symbol_id, {}).get('ask')
# 保存
current_prices[symbol_id] = {"bid": bid, "ask": ask}
# 表示
timestamp = time.strftime("%H:%M:%S")
spread = (ask - bid) * (10 ** (digits - 1)) if bid and ask else 0
print(f"[{timestamp}] 💹 {symbol_name}")
print(f" Bid: {bid:.{digits}f} Ask: {ask:.{digits}f} Spread: {spread:.1f}pips")
print()
def onDisconnected(client, reason):
print(f"\n❌ 切断されました: {reason}")
reactor.stop()
# コールバック設定
client.setConnectedCallback(onConnected)
client.setDisconnectedCallback(onDisconnected)
client.setMessageReceivedCallback(onMessageReceived)
# 起動
print("\n🚀 cTrader Open API リアルタイム価格取得ツール")
print(" Ctrl+C で終了\n")
client.startService()
reactor.run()

実行結果

Code
🚀 cTrader Open API リアルタイム価格取得ツール
Ctrl+C で終了
==================================================
🔗 cTrader Open APIに接続しました!
==================================================
✅ アプリケーション認証完了
✅ アカウント認証完了
📋 シンボル一覧を取得中...
✅ 127 個のシンボルを取得
🎯 EURUSD (ID: 1)
🎯 USDJPY (ID: 2)
🎯 XAUUSD (ID: 41)
==================================================
📡 リアルタイム価格のサブスクライブを開始...
==================================================
✅ サブスクライブ開始!価格が更新されると表示されます
[09:15:23] 💹 EURUSD
Bid: 1.10523 Ask: 1.10525 Spread: 0.2pips
[09:15:23] 💹 USDJPY
Bid: 149.852 Ask: 149.855 Spread: 0.3pips
[09:15:24] 💹 XAUUSD
Bid: 2654.35 Ask: 2654.85 Spread: 5.0pips

リアルタイムで価格が流れてきます!😆


応用:価格データを使って条件判定

取得した価格を使って、何かアクションを起こしてみましょう。

例:スプレッドが広がったら警告

Python
def checkSpread(symbol_name, bid, ask, digits):
"""スプレッドをチェックして警告"""
spread_pips = (ask - bid) * (10 ** (digits - 1))
# 通貨ペアごとの閾値
thresholds = {
"EURUSD": 1.0,
"USDJPY": 1.0,
"XAUUSD": 10.0
}
threshold = thresholds.get(symbol_name, 2.0)
if spread_pips > threshold:
print(f"⚠️ 警告: {symbol_name} のスプレッドが {spread_pips:.1f}pips に拡大!")
# ここでSlack通知やメール送信などを追加

例:価格がラウンドナンバーに接近

Python
def checkRoundNumber(symbol_name, bid, digits):
"""ラウンドナンバーへの接近をチェック"""
if symbol_name == "USDJPY":
# 150.000 に接近したら通知
if 149.95 < bid < 150.05:
print(f"🎯 {symbol_name} が 150.000 に接近中! 現在: {bid}")
elif symbol_name == "EURUSD":
# 1.10000 に接近したら通知
if 1.0995 < bid < 1.1005:
print(f"🎯 {symbol_name} が 1.10000 に接近中! 現在: {bid}")

トラブルシューティング

Q: 価格が表示されない

A: 以下を確認してください:

  1. シンボルIDは正しい?

    • 口座によってIDが違います
    • onSymbolsList で確認
  2. 市場は開いている?

    • 週末や祝日は価格更新がありません
  3. サブスクライブは成功した?

    • ProtoOASubscribeSpotsRes のエラーをチェック

Q: 価格が変な値になる

A: 桁数(digits)の扱いを確認:

Python
# 正しい計算
divisor = 10 ** digits
actual_price = raw_price / divisor
# 例:EURUSD (digits=5) で raw_price=110523
# actual_price = 110523 / 100000 = 1.10523 ✅

Q: 「too many requests」エラー

A: サブスクライブは一度だけで十分です。ループで何度も送らないでください。


MQLとの比較:価格取得

やりたいことMQLOpen API (Python)
現在の BidBidProtoOASpotEvent を受信
現在の AskAskProtoOASpotEvent を受信
シンボル情報MarketInfo()ProtoOASymbolsListReq
価格更新検知OnTick()onMessageReceived()

MQLの方がシンプルに見えますが、Open APIはより柔軟です。複数シンボルを一度にサブスクライブしたり、必要なものだけ受信したりできます。


次のステップ

この記事で学んだこと:

  • ✅ シンボル一覧の取得方法
  • ✅ リアルタイム価格のサブスクライブ
  • ✅ 価格データの正しい変換方法
  • ✅ 応用例(スプレッド監視など)

次の記事では、ついに注文を出す方法を解説します!Market Order、Limit Order、SL/TP設定まで、実際にトレードできるようになります。


まとめ

リアルタイム価格が取得できるようになりましたね!🎉

これができれば:

  • 価格アラートシステム
  • スプレッド監視ツール
  • ティックデータの収集・分析
  • 独自インジケーターの計算

など、いろいろなことができるようになります。

MQLでは「OnTick()の中でBid/Askを見る」だけでしたが、Open APIでは外部から自由に価格を監視できます。この自由度こそがOpen APIの真骨頂です!

次回は、いよいよ注文を出しましょう! 🚀


参考リンク

🎁おすすめツール・サービス

FX自動売買VPSなら50%OFF

キャンペーンで月1,790円〜。MT4/MT5プリインストール済み、自動復旧機能付き。14日間無料お試し。

シンクラウドデスクトップ for FX
ゴトー日EAを探しているならソースコード付

4年で資金4.7倍のバックテスト実績。ソースコード付きで自由にカスタマイズ可能。

ゴトー日EA Ultimate版(3,980円)

※上記リンクにはプロモーション(広告)が含まれています

🔮
MEMBERSHIP

量子相場謀略|ホソノP

ブログでは書けない本音のトレード戦略とEA開発の裏側を公開。 データに基づいた検証で、再現性のある手法だけをお届けします。

✓EAソースコード公開
✓バックテスト生データ共有
✓リアルタイム相場分析
✓メンバー限定記事
メンバーシップに参加する※ noteアカウントで簡単登録

📚あわせて読みたい

📄

😤「MQLは書けるのにcTraderで自動売買できない!」そんなあなたへ贈る cTrader Open API × Python 入門ガイド

MQL経験者がcTrader Open APIとPythonで自動売買を始めるための完全入門ガイド。環境構築からアプリ登録、認証の仕組みまで丁寧に解説します。

trading2026/1/7
📄

🔥 cTrader Open APIで自動売買!Pythonで注文を出す完全ガイド【Market/Limit/SL/TP対応】

cTrader Open APIとPythonで実際に注文を出す方法を完全解説。成行注文、指値注文、SL/TP設定、ポジション決済まで、コピペで動くサンプルコード付き。

trading2026/1/7
📄

⚠️【非推奨】FIX API完全版①|2セッション構成→ Python cBotを使おう

【非推奨】FIX APIは17個のハマりポイントがあり初心者には推奨しません。代わりにPython cBotを使いましょう。この記事は参考資料として残しています。

trading2026/1/8
📄

🎊 cTrader 5.4でPython cBotが書ける!ネイティブPythonサポート完全ガイド【Open APIとの違いも解説】

cTrader 5.4で追加されたネイティブPythonサポートを徹底解説。cBot、インジケーターをPythonで作成する方法、Open APIとの違い、MQL経験者のための移行ガイド。

trading2026/1/7
📄

😤「ピラミッティングで爆益!」は本当か?60日ブレイクアウトで徹底検証した結果...

60日高値安値ブレイクアウトで単ポジションとピラミッティングを比較検証。「積みながら建値ガードで安心!トレンド乗れれば爆益!」という夢は実現するのか?7年分のデータで検証した衝撃の結果をお届けします。

trading2025/12/20
📄

🎰【検証】ゴトー日でナンピンしたら地獄?ピラミッディングしたら天国?330回分のデータで白黒つけてみた

ゴトー日トレードでナンピン・ピラミッディング・時差分割エントリーは有効なのか?5年分330トレードのデータで徹底検証。意外な結果に驚愕...

trading2024/12/16