⚠️【非推奨】FIX APIでゴールド注文失敗「証拠金不足」の原因→ Python cBotを使おう
🚨 重要: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をどうしても使いたい方のみお読みください。
😭 事件発生:04:00のエントリーが通らない
2026年1月6日、朝4時。
ゴールドロールオーバーBotが稼働開始。
04:00:00 [INFO] エントリー実行 (2026-01-06 04:00:00)04:00:00 [INFO] 新規注文: BUY 0.01ロット SymbolID=4104:00:00 [INFO] [STATUS] OPEN | ポジ:なし…ポジ:なし?
注文したのにポジションが立ってない。
ExecutionReport(約定レポート)も来ない。
何が起きた? 🤔
🔍 調査開始:テストスクリプトで検証
テスト1: GBPUSD(通貨ペア)
# GBPUSD 0.01ロット BUYsymbol_id = 2qty = int(0.01 * 100000) # = 1000結果:
38=1000約定成功 @ 1.35311 ✅通貨ペアは問題なし。
テスト2: XAUUSD(ゴールド)
# XAUUSD 0.01ロット BUYsymbol_id = 41qty = int(0.01 * 100000) # = 1000結果:
38=100058=NOT_ENOUGH_MONEY:Not enough funds ❌え? 証拠金不足?
口座残高を確認。
2,499,945円
250万円あるのに証拠金不足???
😱 衝撃の真実:OrderQtyの単位が違った
FIX APIのOrderQty (タグ38) の仕様
調べてみると、OrderQtyはロット数じゃない。
Volume(基準単位)で指定する。
| 商品 | 基準単位 | 1ロット | 0.01ロット | OrderQty |
|---|---|---|---|---|
| FX | 通貨 | 100,000 | 1,000 | 38=1000 |
| ゴールド | オンス | 100 | 1 | 38=1 |
| シルバー | オンス | 5,000 | 50 | 38=50 |
| 原油 | バレル | 1,000 | 10 | 38=10 |
何が起きていたか
【送信した内容】38=1000(1000オンス)
【ブローカーの解釈】1000オンス ÷ 100オンス/ロット = 10ロット
【必要証拠金】$4,450/oz × 1000oz ÷ 100(レバレッジ) = $44,500約667万円
【口座残高】250万円
【結果】NOT_ENOUGH_MONEY 💀0.01ロットのつもりが、10ロットの注文になっていた!!
🔧 修正:商品別のOrderQty計算
Before(間違い)
# 全商品で同じ計算qty = int(quantity * 100000)# 0.01 * 100000 = 1000After(正解)
def calculate_order_qty(symbol_id: int, lot_size: float) -> int: """商品タイプに応じたOrderQty計算"""
# ゴールド (XAUUSD) if symbol_id == 41: return int(lot_size * 100) # 0.01 lot = 1
# シルバー (XAGUSD) elif symbol_id == 42: return int(lot_size * 5000) # 0.01 lot = 50
# 原油 (USOIL) elif symbol_id == 43: return int(lot_size * 1000) # 0.01 lot = 10
# FX通貨ペア (デフォルト) else: return int(lot_size * 100000) # 0.01 lot = 1000✅ 修正後のテスト
テスト3: XAUUSD(修正版)
# XAUUSD 0.01ロット BUYsymbol_id = 41qty = int(0.01 * 100) # = 1結果:
38=1約定成功 @ 4452.02 ✅ポジションID: 1001179やっと通った! 🎉
😈 さらなる罠:コントラクトサイズが取得できない
「じゃあコントラクトサイズをAPIで取得すればいいじゃん」
できません。
"Unfortunately this information is not available in FIX API. You can consider Open API instead."
FIX APIではコントラクトサイズ情報を取得できない!
取得できる情報 vs 取得できない情報
SecurityListRequest(35=x)で取得可能:
- シンボルID(Tag 55)
- シンボル名(Tag 1007)← これは取れる!
- 桁数/Digits(Tag 1008)
取得不可能(Open APIでのみ):
- コントラクトサイズ ← 今回の問題
- ロットステップ
- スワップレート
つまり「XAUUSD」という名前は分かるけど、「1ロット=100オンス」という情報は取れない。
事前にブローカーの仕様を調べるか、Open APIを使うしかない。
これが14個目のハマりポイントだ。
📋 FIX APIハマりポイント(2026-01-08更新)
| # | ハマりポイント | 今回の事件 |
|---|---|---|
| 1 | CTIDパスワードを使用 | - |
| 2 | 1セッションで全部やろうとした | - |
| 3 | シンボルを文字列で指定 | - |
| 4 | TargetSubID忘れ | - |
| 5 | SecurityListRequestType=4 | - |
| 6 | ポジション照会に標準タグ使用 | - |
| 7 | ハートビート遅延 | - |
| 8 | シーケンス番号ミス | - |
| 9 | UTC時刻フォーマット間違い | - |
| 10 | BodyLength計算ミス | - |
| 11 | Checksum計算ミス | - |
| 12 | 数量の単位変換忘れ | - |
| 13 | SSL証明書検証 | - |
| 14 | 商品別OrderQty単位 | ← 今回の事件! |
| 15 | コントラクトサイズ取得不可 | ← 今回発覚 |
| 16 | ロガー設定漏れ | - |
| 17 | メンテナンス時間差 | ← 2026-01-08追加 |
17個のハマりポイント。
ドキュメントには書いてない。
🔥 もう1つの問題:約定確認してなかった
問題
注文送信後、約定を確認せずに次の処理に進んでいた。
# 修正前new_order(symbol_id, "BUY", 0.01)# 約定確認なし!次の分を待つ…ネットワーク遅延で約定が遅れても、リトライしない。
解決策:リトライ機能追加
# 修正後new_order(symbol_id, "BUY", 0.01)
for retry in range(10): time.sleep(1)
if has_position: log.info(f"✅ ポジション確認OK (リトライ{retry}回)") break else: log.warning(f"⚠️ ポジション未確認 - リトライ {retry+1}/10") if retry < 9 and is_spread_ok(): new_order(symbol_id, "BUY", 0.01)金融取引では「送信したら終わり」じゃない。
- 注文送信
- ExecutionReport待機
- 約定確認
- 失敗ならリトライ
この流れを実装しないと、注文が通らなかったことに気づかない。
📊 デバッグにかかった時間
| 作業 | 時間 |
|---|---|
| 問題発見 | 10分 |
| ログ解析 | 30分 |
| 原因調査 | 2時間 |
| 修正実装 | 1時間 |
| テスト | 30分 |
| 合計 | 4時間 |
0.01ロットの注文1つに4時間。
🆚 Python cBotなら?
# Python cBotでの注文api.ExecuteMarketOrder(TradeType.Buy, "XAUUSD", 1000)# ↑ これだけ。ロット計算も約定確認も全自動。4時間のデバッグ vs 1行のコード。
どっちがいい?
📝 教訓まとめ
教訓1: NOT_ENOUGH_MONEYは数量を疑え
「証拠金不足」は本当に資金が足りない場合だけじゃない。
数量のフォーマットが間違っている可能性がある。
桁を間違えると、意図した100倍や1000倍の注文になる。
教訓2: 商品ごとにOrderQtyの単位が違う
| 商品 | 計算式 |
|---|---|
| FX | lot × 100,000 |
| ゴールド | lot × 100 |
| シルバー | lot × 5,000 |
| 原油 | lot × 1,000 |
教訓3: FIX APIは情報が足りない
コントラクトサイズすら取得できない。
事前に調べるか、Open APIを併用するしかない。
教訓4: 約定確認とリトライは必須
送信して終わりじゃない。
確認して、失敗ならリトライ。
教訓5: テストスクリプトを作れ
本番コードで試すより、小さなテストスクリプトで検証。
test_order.py- 注文テストclose_position.py- 決済テスト
🎯 結論
FIX APIの現実
知識ゼロからXAUUSD注文が通るまで:
- ハマりポイント: 17個- デバッグ時間: 4時間(今回だけで)- 累計開発時間: 1週間以上- コード量: 800行以上- 精神的ダメージ: 甚大Python cBotの現実
api.ExecuteMarketOrder(TradeType.Buy, "XAUUSD", 1000)- ハマりポイント: 0個- 開発時間: 数分- コード量: 1行- 精神的ダメージ: なし🔥 最後に
250万円あるのに「証拠金不足」。
原因は0.01ロットが10ロットになっていた。
OrderQtyの単位が商品ごとに違うなんて、ドキュメントに書いてない。
FIX APIは地獄。
Python cBotは天国。
同じ結論に何度でも辿り着く。
📚 関連記事
FIX APIで消耗するのは、もうやめよう。 😭
質問・同じ経験した人はコメントで!
🎁おすすめツール・サービス
※上記リンクにはプロモーション(広告)が含まれています
量子相場謀略|ホソノP
ブログでは書けない本音のトレード戦略とEA開発の裏側を公開。 データに基づいた検証で、再現性のある手法だけをお届けします。