Web Lukes
📄

⚠️【非推奨】FIX API入門④|17個のハマりポイント→ Python cBotを使おう

公開日: 2026/1/8

🚨 重要:FIX APIは非推奨です

この記事で紹介しているFIX APIは、以下の理由から非推奨です:

  • 😱 17個のハマりポイントがあり、ドキュメントに書いてない罠が多すぎる
  • 💀 実装に1週間以上かかる(Python cBotなら数時間)
  • 🤯 800行以上のコードが必要(Python cBotなら数十行)
  • ❌ コントラクトサイズ等の情報が取得できない

🐍 代わりにPython cBotを使いましょう!

cTrader 5.4以降、ネイティブPythonサポートが追加されました。

👉 Python cBot入門ガイド - 1行で注文できる世界へ

👉 cTrader 5.4 Python完全ガイド - 環境構築から実践まで


以下の内容は参考資料として残しています。FIX APIをどうしても使いたい方のみお読みください。


😤 「ドキュメント通りに実装したのに動かない!」

FIX APIを実装して1週間。

17個のハマりポイントを発見した。

Code
公式ドキュメント: 「これがFIXプロトコルです」
現実: 「標準FIXタグ?使えません」

全部、ドキュメントに書いてない。


🎯 この記事の内容

  1. ログオン系 - 3個
  2. 注文系 - 5個
  3. ポジション系 - 2個
  4. データ取得系 - 2個
  5. その他 - 5個 (2026-01-08追加2個)

合計17個。全部実体験。


🔐 ログオン系(3個)

❌ ハマり #1: CTIDパスワードを使用

症状:

Code
ログオン送信 → 即座にLogout → RET_INVALID_DATA

原因: cTraderアプリのログインパスワード(CTID)を使用

解決: cTrader Web → 設定 → FIX API → FIX専用パスワードを設定

Python
# ❌ 間違い
PASSWORD = "ctrader_app_password"
# ✅ 正解
PASSWORD = "fix_api_specific_password"

教訓: cTraderには2種類のパスワードがある


❌ ハマり #2: TRADEとQUOTEを1セッションと勘違い

症状:

Code
TRADEセッションで価格データを要求 → 無応答

原因: TRADE(注文)とQUOTE(価格)は完全に別セッション

解決: 2つの接続を別々に管理

Python
# ✅ 正解
trade_sock = connect(TRADE_HOST, 5212) # 注文・約定
quote_sock = connect(QUOTE_HOST, 5211) # 価格データ
# Logonも別々に送る
send_logon(trade_sock, "TRADE")
send_logon(quote_sock, "QUOTE")

教訓: 1つのソケットで全部やろうとしない


❌ ハマり #3: TargetSubID(57)を忘れる

症状:

Code
Logon送信 → 応答なし → タイムアウト

原因: タグ57(TargetSubID)がないと無視される

解決:

Python
# ❌ 間違い
f"49={SENDER}{SOH}56={TARGET}{SOH}34=1{SOH}..."
# ✅ 正解
f"49={SENDER}{SOH}56={TARGET}{SOH}57=TRADE{SOH}34=1{SOH}..."

教訓: TargetSubIDは「TRADE」または「QUOTE」を指定


📝 注文系(5個)

❌ ハマり #4: シンボルを文字列で指定

症状:

Code
注文送信 → Unknown error / Reject

原因: 55=XAUUSD のように文字列で指定

解決: cTrader Webで「FIX通貨ペアID」を確認し、数値で指定

Python
# ❌ 間違い
f"55=XAUUSD{SOH}"
# ✅ 正解
f"55=41{SOH}" # ゴールドのID
シンボルID(例)
EURUSD1
GBPUSD2
USDJPY3
XAUUSD41

教訓: ブローカーによってIDが違う


❌ ハマり #5: OrderQtyをロット数で指定

症状:

Code
58=NOT_ENOUGH_MONEY(証拠金は十分あるのに)

原因: OrderQty(タグ38)はロット数じゃなくVolume

Python
# ❌ 間違い
f"38=0.01{SOH}" # ロット数
# ❌ 間違い(FXの計算式をゴールドに適用)
qty = 0.01 * 100000 # = 1000
f"38=1000{SOH}" # → 10ロット分として解釈される!

解決: 商品ごとに計算式が違う

Python
# FX通貨ペア
qty = int(lot_size * 100000) # 0.01 = 1000
# ゴールド(XAUUSD)
qty = int(lot_size * 100) # 0.01 = 1
# シルバー(XAGUSD)
qty = int(lot_size * 5000) # 0.01 = 50

教訓: 0.01ロットのつもりが10ロットになりうる


❌ ハマり #6: 数量の単位変換忘れ

症状:

Code
決済時に「数量不足」または「過剰数量」

原因: ExecutionReportで受け取った数量をそのまま使用

解決: 開いた時の数量を保存しておく

Python
# 約定時
positions[position_id] = {
"qty": sent_qty, # 送信した数量を保存
"side": side,
"symbol_id": symbol_id
}
# 決済時
close_qty = positions[position_id]["qty"] # 保存した数量を使用

教訓: 単位変換が複雑なので、送信した値を保存


❌ ハマり #7: UTC時刻フォーマット間違い

症状:

Code
Reject: Invalid format

原因: タイムスタンプの形式が違う

Python
# ❌ 間違い(ローカル時刻)
datetime.now().strftime("%Y%m%d-%H:%M:%S")
# ❌ 間違い(フォーマット違い)
datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

解決:

Python
# ✅ 正解
datetime.now(timezone.utc).strftime("%Y%m%d-%H:%M:%S")
# 例: "20260106-03:00:00"

教訓: UTCで、ハイフンはYYYYMMDDとHH:MM:SSの間だけ


❌ ハマり #8: シーケンス番号の管理ミス

症状:

Code
突然接続が切れる / Reject: MsgSeqNum too low

原因: シーケンス番号(34)を正しくインクリメントしていない

解決:

Python
# グローバルまたはセッションごとに管理
trade_seq_num = 1
quote_seq_num = 1
def get_next_seq(session_type: str) -> int:
global trade_seq_num, quote_seq_num
if session_type == "TRADE":
trade_seq_num += 1
return trade_seq_num - 1
else:
quote_seq_num += 1
return quote_seq_num - 1

教訓: TRADE/QUOTE別にシーケンス番号を管理


📊 ポジション系(2個)

❌ ハマり #9: ポジション照会に非対応タグ使用

症状:

Code
Invalid tag number, field=1
Invalid tag number, field=724

原因: 標準FIX 4.4のタグを使用

Python
# ❌ 全部非対応!
f"1={ACCOUNT}{SOH}" # Account
f"263=1{SOH}" # SubscriptionRequestType
f"453=1{SOH}" # NoPartyIDs
f"724=0{SOH}" # PosReqType
f"447=D{SOH}" # PartyIDSource

解決: タグ710(PosReqID)だけ使う

Python
# ✅ 正解
f"710={int(time.time())}{SOH}" # これだけ!

教訓: cTrader FIX APIは独自実装が多い


❌ ハマり #10: ExecutionReportのポジションID取得漏れ

症状:

Code
決済時にポジションIDがわからない

原因: ExecutionReport(35=8)のタグ721を取得していなかった

解決:

Python
def parse_execution_report(msg: str):
fields = parse_fix_message(msg)
if fields.get("150") == "F": # Trade
position_id = fields.get("721", "") # ← これを保存!
price = fields.get("31", "")
save_position(position_id, price)

教訓: 約定時にポジションID(721)を必ず保存


📈 データ取得系(2個)

❌ ハマり #11: SecurityListRequestType=4を使用

症状:

Code
Only SecurityListRequestType = SYMBOL(0) supported

原因: 全シンボル一覧取得(559=4)は非対応

解決: 個別シンボルのみ取得可能(ID 1〜200等をループでスキャン)

Python
# ❌ 間違い(全シンボル一括取得)
f"559=4{SOH}"
# ✅ 正解(個別シンボル照会)
f"559=0{SOH}55=41{SOH}" # → Tag 1007でシンボル名が返る

取得できる情報:

  • シンボルID(Tag 55)
  • シンボル名(Tag 1007)← これは取得可能!
  • 桁数(Tag 1008)

教訓: 一括取得はできないが、ループでスキャンすれば全シンボル取得は可能


❌ ハマり #12: コントラクトサイズが取得できないことを知らない

症状:

Code
どこを探してもコントラクトサイズの情報がない

原因: FIX APIにはコントラクトサイズを返すAPIがない

公式フォーラムの回答:

"Unfortunately this information is not available in FIX API. You can consider Open API instead."

解決:

  • 事前にブローカーの仕様を調べる
  • または Open API を併用する

教訓: FIX APIは情報取得が限定的


⚙️ その他(3個)

❌ ハマり #13: ボディ長(9)の計算ミス

症状:

Code
無応答 / 接続切断

原因: BodyLength(タグ9)の計算が間違っている

Python
# ❌ 間違い(全体の長さ)
body_length = len(f"8=FIX.4.4{SOH}9=XXX{SOH}35=A{SOH}...")
# ❌ 間違い(SOHを含めない)
body_length = len("35=A49=SENDER...")

解決:

Python
# ✅ 正解(35=から10=の前までのバイト数、SOH含む)
body = f"35=A{SOH}49={SENDER}{SOH}56={TARGET}{SOH}..."
body_length = len(body.encode('ascii'))

教訓: 8=と9=は含まない、10=も含まない


❌ ハマり #14: チェックサム(10)の計算ミス

症状:

Code
無応答 / 接続切断

原因: CheckSum計算が間違っている

Python
# ❌ 間違い(3桁ゼロ埋めなし)
f"10={checksum}{SOH}" # → "10=23"
# ❌ 間違い(チェックサム自体も含めている)
checksum = sum(ord(c) for c in full_message) % 256

解決:

Python
# ✅ 正解
def calc_checksum(msg_without_checksum: str) -> str:
checksum = sum(ord(c) for c in msg_without_checksum) % 256
return f"10={checksum:03d}{SOH}" # 3桁ゼロ埋め

教訓: 10=の前までの全バイトを合計、結果は3桁ゼロ埋め


❌ ハマり #15: SSL証明書検証を無効にしようとする

症状:

Code
SSL証明書エラー → 検証を無効にしたくなる

原因: 古いサンプルコードや、テスト環境の設定を本番に使用

Python
# ❌ 危険(本番で使うな)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE

解決: cTraderサーバーは正規SSL証明書を使用。デフォルト設定で十分。

Python
# ✅ 正解
context = ssl.create_default_context()

教訓: セキュリティを犠牲にするな


❌ ハマり #16: FIXクライアントのログが出力されない

症状:

Code
main.pyからctrader_fix_client.pyを呼び出すと、FIXクライアント内のログが出力されない
ポジション確認がタイムアウトするが原因がわからない

原因: Pythonのロガーは名前ごとに独立しているため、モジュールごとにハンドラ設定が必要

Python
# ctrader_fix_client.py
log = logging.getLogger("CTraderFIX") # ← このロガー
# main.py
log = logging.getLogger("YourApp") # ← 別のロガー
# CTraderFIXロガーにはハンドラがない!

解決:

Python
def setup_logger():
# メインロガー設定
main_logger = logging.getLogger("YourApp")
main_logger.setLevel(logging.INFO)
main_logger.addHandler(console_handler)
# FIXクライアントロガーも設定(これが重要!)
fix_logger = logging.getLogger("CTraderFIX")
fix_logger.setLevel(logging.INFO)
fix_logger.addHandler(console_handler) # 同じハンドラを追加

教訓: モジュール分離時はロガー設定も分離される


❌ ハマり #17: 貴金属とFXでメンテナンス時間が違う(2026-01-08追加)

症状:

Code
07:00 JSTにXAUUSDで注文 → MARKET_CLOSED
同じ時間にUSDJPYで注文 → 正常に約定

原因: 商品カテゴリによってメンテナンス時間が異なる

Code
貴金属(XAUUSD等): 06:00-07:00 JST メンテナンス
FX通貨ペア: 同時間帯でも取引可能な場合が多い

解決:

Python
def is_market_open(symbol_name: str) -> bool:
now_jst = datetime.now(timezone(timedelta(hours=9)))
hour = now_jst.hour
# 貴金属: 06:00-07:00 JST はメンテナンス
if "XAU" in symbol_name or "XAG" in symbol_name:
if 6 <= hour < 7:
return False
return True

教訓: 「市場クローズ」は商品によって時間が違う


📋 ハマりポイント一覧表

#カテゴリハマりポイント症状
1ログオンCTIDパスワード使用RET_INVALID_DATA
2ログオンTRADE/QUOTE 1セッション無応答
3ログオンTargetSubID欠落無応答
4注文シンボル文字列指定Unknown error
5注文OrderQtyロット数指定NOT_ENOUGH_MONEY
6注文数量単位変換忘れ数量不一致
7注文UTC時刻フォーマットReject
8注文シーケンス番号ミス切断
9ポジション非対応タグ使用Invalid tag
10ポジションポジションID取得漏れ決済不可
11データ559=4使用非対応エラー
12データコントラクトサイズ取得不可
13その他ボディ長計算ミス無応答
14その他チェックサム計算ミス無応答
15その他SSL検証無効化セキュリティリスク
16その他ロガー設定漏れログ出力なし
17その他メンテナンス時間差MARKET_CLOSED

🎯 デバッグのコツ

1. ログを詳細に出力

Python
def send_message(sock, msg: str):
print(f"→ 送信: {msg.replace(SOH, '|')}")
sock.send(msg.encode('ascii'))
def receive_message(sock) -> str:
data = sock.recv(4096)
msg = data.decode('ascii')
print(f"← 受信: {msg.replace(SOH, '|')}")
return msg

2. タグごとにパース

Python
def parse_fix_message(msg: str) -> dict:
fields = {}
for part in msg.split(SOH):
if "=" in part:
tag, value = part.split("=", 1)
fields[tag] = value
print(f" {tag} = {value}")
return fields

3. テストスクリプトで検証

本番コードではなく、小さなテストスクリプトで試す:

Python
# test_order.py
# 単一の注文だけをテスト
# test_close.py
# 単一の決済だけをテスト

4. 公式フォーラムを検索

エラーメッセージで検索すると、同じ問題にハマった人がいる。


🆚 FIX API vs Python cBot

比較

項目FIX APIPython cBot
ハマりポイント17個0個
実装時間1週間〜数時間
コード量800行以上数十行
情報取得限定的豊富
公式ライブラリなしあり

Python cBotで同じことをやると

Python
# Python cBot
api.ExecuteMarketOrder(TradeType.Buy, "XAUUSD", 1000)
# ↑ これだけ。

FIX API:

  • ログオン実装
  • メッセージ組み立て
  • チェックサム計算
  • ボディ長計算
  • シンボルID調査
  • OrderQty計算
  • ExecutionReport解析
  • ポジションID管理
  • ハートビート実装
  • エラーハンドリング
  • ...

800行 vs 1行。


📝 最終結論

FIX APIを使うべき人

Code
✅ 機関レベルの低レイテンシが必要
✅ FIXプロトコルの勉強をしたい
✅ 苦労を楽しめるマゾ気質
✅ 既存のFIXインフラがある

FIX APIを避けるべき人

Code
❌ 普通に自動売買したいだけ
❌ 詳細な情報が欲しい
❌ すぐに動くものが欲しい
❌ デバッグ時間を節約したい

本音

「Python cBotでええやん」


🔥 最後に

17個のハマりポイントを踏み抜いた。

ドキュメントには書いてない。

フォーラムで探し回ってやっと見つかる。

それがFIX API。


この記事が誰かの時間を節約できれば幸いです。

同じ地雷を踏む人が一人でも減りますように。 🙏


📚 関連記事

FIX API完全版シリーズ(2026年版・Fundora検証済み)

その他


📖 参考リンク


FIX 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アカウントで簡単登録

📚あわせて読みたい

📄

⚠️【非推奨】FIX API入門②|PythonでLogon→ Python cBotを使おう

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

fx2026/1/8
📄

⚠️【非推奨】FIX API入門③|Python注文送信→ Python cBotを使おう

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

fx2026/1/8
📄

🚨【結論】FIX APIは非推奨!Python cBotを使いましょう - 17個の地獄を経験した結論

FIX APIは17個のハマりポイントがあり非推奨です。cTrader 5.4以降のPython cBotなら1行で注文可能。FIX APIで813行書いた経験者が断言します。

fx2026/1/8
📄

⚠️【非推奨】FIX API入門①|FIXプロトコルとは?→ Python cBotを使おう

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

fx2026/1/8
📄

🚨【結論】cTrader API比較:FIX APIは非推奨→Python cBotを使おう

【FIX APIは非推奨】cTrader 5.4以降はPython cBotがベスト。Open APIよりもさらに簡単。FIX APIで17個のハマりポイントを踏んだ経験者が断言します。

fx2026/1/8
📄

⚠️【非推奨】FIX APIでゴールド注文失敗「証拠金不足」の原因→ Python cBotを使おう

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

fx2026/1/8