## はじめに

暗号資産取引所がAIエージェント(Claude・ChatGPT・Gemini AIなど)をトレーディングアカウントに直接接続できる仕組みを公開する動きが出てきました。
これまでウォール街の専門チームや高価なクオンツシステムが担ってきた「AIによる自動売買」の敷居が、個人開発者レベルでも現実的な射程に入ってきています。

正直なところ、「AIに売買を任せる」と聞くと身構えてしまう方も多いと思います。
私自身も最初はそうでした。
ただ、技術的な仕組みを分解してみると、「LLM + Tool Use(ツール呼び出し)」というすでに馴染みのあるパターンの延長線上にあることがわかります。
本記事では、AIエージェントをトレーディングAPIに接続する際の設計思想・コード例・リスク管理を、エンジニア目線で実践的に解説します。

## こんな人におすすめ

- LLMのTool Use(関数呼び出し)を使ったアプリを作ったことがあるエンジニア
- 暗号資産や株式のAPI連携に興味があるフィンテック開発者
- アルゴリズム取引を学び始めたい個人投資家
- AIエージェントを実業務・実資産に適用する方法を模索している方
- 金融×AI領域でプロダクトを作りたいスタートアップのエンジニア

## AIエージェントトレーディングのアーキテクチャ

AIエージェントをトレーディングに接続する際の基本構成は、3つのレイヤーで整理できます。

``text
┌─────────────────────────────┐
│ LLM(判断エンジン) │ ← Claude / GPT-4o / Gemini AI
├─────────────────────────────┤
│ Tool Use レイヤー │ ← 市場データ取得・注文送信
├─────────────────────────────┤
│ リスク管理レイヤー │ ← 損失上限・ポジション管理
└─────────────────────────────┘

┌─────────────────────────────┐
│ 取引所API │ ← REST / WebSocket
└─────────────────────────────┘
`

LLMは「今の市場状況を見て、何をすべきか」を自然言語で推論します。
Tool Useを通じて実際のAPIを呼び出し、リスク管理レイヤーが最終的なゲートキーパーとして機能する構成です。
この3層を明確に分離しておくことが、後のデバッグや改善を格段に楽にします。

## Tool UseでトレーディングAPIを呼び出す最小実装

PythonとAnthropicのSDKを使い、最小構成のAIトレーディングエージェントを実装してみます。

`python
import anthropic
import json
import os

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

# 取引所APIのスタブ(実際は各取引所のSDKに差し替え)
def get_ticker(symbol: str) -> dict:
"""指定シンボルの現在価格を取得する"""
# 実際の実装例: requests.get(f"https://api.exchange.com/v1/ticker/{symbol}")
return {"symbol": symbol, "price": 65000.0, "change_24h_pct": 2.1}

def place_order(symbol: str, side: str, amount: float) -> dict:
"""成行注文を送信する(side: 'buy' or 'sell')"""
# 実際の実装例: requests.post("https://api.exchange.com/v1/order", json={...})
return {"order_id": "order-001", "status": "accepted", "symbol": symbol, "side": side}

# LLMに提供するツール定義
tools = [
{
"name": "get_ticker",
"description": "指定した暗号資産の現在価格と24時間変動率を取得する",
"input_schema": {
"type": "object",
"properties": {
"symbol": {"type": "string", "description": "取引ペア(例: BTCUSD)"}
},
"required": ["symbol"] }
},
{
"name": "place_order",
"description": "成行注文を送信する。必ずリスク確認後に呼び出すこと",
"input_schema": {
"type": "object",
"properties": {
"symbol": {"type": "string"},
"side": {"type": "string", "enum": ["buy", "sell"]},
"amount": {"type": "number", "description": "取引数量(BTCなら0.001単位)"}
},
"required": ["symbol", "side", "amount"] }
}
]
def run_trading_agent(market_context: str, max_order_usd: float = 100.0) -> str:
"""AIトレーディングエージェントを実行する"""
messages = [
{
"role": "user",
"content": f"""
あなたはリスク管理を最優先するトレーディングアシスタントです。
以下の市場状況を分析し、必要であれば小額で取引を行ってください。

制約:
- 1回の取引はUSD換算で{max_order_usd}ドル以下
- 確信が持てない場合は取引しない
- 判断理由を必ず説明すること

市場コンテキスト:
{market_context}
"""
}
]
# エージェントループ(Tool Useが発生しなくなるまで継続)
while True:
response = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
tools=tools,
messages=messages
)

if response.stop_reason == "end_turn":
break

if response.stop_reason == "tool_use":
tool_results = [] for block in response.content:
if block.type == "tool_use":
if block.name == "get_ticker":
result = get_ticker(**block.input)
elif block.name == "place_order":
result = place_order(**block.input)
else:
result = {"error": "unknown tool"}

tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result, ensure_ascii=False)
})

messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
else:
break

final_block = next((b for b in response.content if hasattr(b, "text")), None)
return final_block.text if final_block else ""
`

実際に試してみると、LLMは「価格を確認してから判断する」という人間らしい思考手順を自然に踏んでくれます。
これはシンプルなif-elseロジックでは実現しにくい柔軟さで、複合的な条件を自然言語で指示できる点が大きな強みです。

## リスク管理レイヤーの実装

AIエージェントに「判断」を委ねる場合でも、機械的なリスク管理は省略できません。
観察された傾向として、リスク管理なしに本番接続した実装は予期しない損失を招くケースが報告されています。
目安として、注文送信前に以下のチェックを挟むパターンが堅実です。

`python
class RiskManager:
def __init__(self, max_order_usd: float, max_daily_loss_usd: float):
self.max_order_usd = max_order_usd
self.max_daily_loss_usd = max_daily_loss_usd
self.daily_loss = 0.0

def approve(self, side: str, amount: float, price: float) -> tuple[bool, str]:
order_value = amount * price

if order_value > self.max_order_usd:
return False, f"注文金額 ${order_value:.2f} が上限 ${self.max_order_usd} を超過"

if self.daily_loss > self.max_daily_loss_usd:
return False, f"日次損失上限 ${self.max_daily_loss_usd} に達しました"

return True, "OK"

def record_loss(self, loss_usd: float) -> None:
self.daily_loss += loss_usd


# place_order の呼び出し前に必ず通す
risk = RiskManager(max_order_usd=100.0, max_daily_loss_usd=50.0)
ok, reason = risk.approve("buy", 0.001, 65000.0)
if not ok:
raise ValueError(f"注文拒否: {reason}")
`

RiskManagerをTool Useのラッパーとして組み込むことで、AIがどれだけ強気な判断をしてもハードウェアの安全装置として機能させることができます。

## APIキーとセキュリティの扱い方

実際に試してみると、開発者が犯しがちなミスのパターンがいくつか見えてきます。
特に注意が必要な点を整理しておきます。

`bash
# .env ファイルに記載して環境変数から取得する(ソースコードに直書きしない)
EXCHANGE_API_KEY=your_api_key_here
EXCHANGE_API_SECRET=your_api_secret_here
ANTHROPIC_API_KEY=your_anthropic_key_here
`

`python
import os
from dotenv import load_dotenv

load_dotenv()

api_key = os.environ["EXCHANGE_API_KEY"] # 環境変数から取得
api_secret = os.environ["EXCHANGE_API_SECRET"]
``

取引所のAPIキー設定では、「出金権限をオフにする」「IP制限を設ける」「取引上限を設定する」の3点は最低限の設定として押さえておくべきです。
万が一キーが漏洩しても、出金さえできなければ損害の上限を抑えられます。

## つまづきやすいポイント

- **LLMの判断をノーガードで通さない**: 確率的な推論をするLLMは予期しない動作をすることがあります。必ずリスクレイヤーで最終確認を行ってください。
- **Sandboxから始める**: 多くの取引所はテストネット環境を提供しています。実資金を使う前にSandbox環境で十分な動作確認が不可欠です。
- **レート制限に注意する**: APIの呼び出し頻度制限を超えると注文が通らなくなります。エクスポネンシャルバックオフでリトライする仕組みを入れておきましょう。
- **価格データ異常値への対応**: 取得した価格が明らかに異常値(ゼロ・null・桁違い)の場合に取引を自動停止するサーキットブレーカーを必ず用意してください。

## まとめ

AIエージェントをトレーディングに接続する技術は、LLMのTool Useという既存パターンの自然な延長線上にあります。
主要な取引所がこの接続を公式にサポートし始めたことで、実装の敷居は着実に下がっています。
ただし、実資金を扱う以上、リスク管理レイヤーとAPIキーのセキュリティへの投資は省略できません。
まずはSandbox環境でペーパートレーディングを動かし、AIの判断精度と設計に十分な確信が持てた段階で本番移行するアプローチが、目安として堅実です。
「AIが判断する・人間が管理する」という役割分担を明確に保つことが、この領域で長続きするための核心になりそうです。

---

本記事のテーマ(AIエージェントの設計・実装・API連携)に関する技術相談やアーキテクチャレビューは、技術顧問・社外CTOとしてご相談を承っています。詳細はココナラ出品ページをご覧ください。