0.はじめに
Claudeを用いたAIシステム設計スキルの認定資格「Claude Certified Architect–Foundations(CCA-F)試験」の出題範囲にもある Claude Code / ClaudeAgent SDK の理解を深めるため、このSDKを使ったPythonコードを書いて何か実際の動作を調べてみることにしました。
そこで今回は、金融系の事例として「架空のオプション・ギリシャ指標を判定 → 売買指示を出す → Alpaca APIで株式注文を出す」という一連の処理を以下のものを使って構成しています。
・CLAUDE.md
・.claude/rules/
・.claude/skills/
・.claude/agents/
この記事はあくまでSDKの使い方を理解する目的で、データはすべて架空(銘柄・数値とも)で、実注文は Alpaca Paper Trading のみを想定したものです。
1. 推奨プロジェクト構造
プロジェクトは、以下のディレクトリ構成とファイルで作っていきます。
options-greeks-agent-demo/
├── CLAUDE.md # 常時ロードされるプロジェクト指示
├── .claude/
│ ├── rules/
│ │ └── trading-safety.md # 安全ルール(常時 or パススコープ)
│ ├── skills/
│ │ ├── analyze-greeks/
│ │ │ └── SKILL.md # ギリシャ指標判定スキル
│ │ └── place-alpaca-order/
│ │ └── SKILL.md # Alpaca注文スキル
│ └── agents/
│ └── options-trader.md # 専用サブエージェント
├── src/
│ ├── mock_greeks_data.py # 架空データ生成
│ ├── alpaca_order.py # Alpaca注文実行(Paper)
│ └── main_test.py # テストエントリポイント
├── requirements.txt
└── .env.example # ALPACA_API_KEY / SECRET
2. CLAUDE.md(ルート)
CLAUDE.md は Claude Code がプロジェクトを理解するための設定ファイルで、プロジェクトルートに配置し、箇条書き・命令形で簡潔に書くのが基本です。
以下のように記述します。
# Options Greeks Trading Agent Demo
このプロジェクトは ClaudeAgent の理解を深めるためのサンプルです。
架空のオプション・ギリシャ指標を判定し、必要に応じて Alpaca Paper Trading で株式注文を出します。
## 目的
- ギリシャ指標(Delta, Gamma, Theta, Vega, Rho)を評価
- 判定ルールに基づき「買い / 売り / ホールド」を決定
- 決定に従い Alpaca で株式(ヘッジ用)を注文
## 重要な制約
- 実資金の注文は禁止。必ず paper=True
- データはすべて架空。本番市場データは使わない
- 注文前に必ずユーザー確認を取る(自動実行しない)
- リスク管理ルールは `.claude/rules/trading-safety.md` に従う
## 利用可能な Skills
- analyze-greeks : ギリシャ指標の分析と売買判定
- place-alpaca-order : Alpaca Paper での株式注文
## サブエージェント
- options-trader : ギリシャ判定〜注文までの一連フローを担当
## 実行方法
1. `python src/main_test.py` で架空データを生成・判定テスト
2. Claude に「ギリシャ指標を分析して注文判断して」と依頼すると Skills / Agent が自動で使われる
3. .claude/rules/trading-safety.md
# Trading Safety Rules
このルールは常に適用される。
## 必須ルール
- Alpaca クライアントは必ず `paper=True` で初期化すること
- 1回の注文数量は最大 10 株まで
- Delta が ±0.7 を超える場合は「ヘッジ必要」と判定し、反対方向の株式注文を検討
- Gamma が 0.1 以上の場合はポジションサイズを半分にする
- 注文実行前に必ず「この注文を実行しますか?」とユーザーに確認する
- APIキーは環境変数 `ALPACA_API_KEY` / `ALPACA_SECRET_KEY` から読み込む。ハードコード禁止
- エラー時は注文を中止し、ログを出力する
## 禁止事項
- ライブ口座への接続
- オプション契約そのものの注文(このサンプルは株式ヘッジのみ)
- ユーザー確認なしの自動注文
4. Skills
.claude/skills/analyze-greeks/SKILL.md
---
name: analyze-greeks
description: 架空のオプション・ギリシャ指標(Delta/Gamma/Theta/Vega/Rho)を分析し、買い・売り・ホールドの判定を行う。ユーザーが「ギリシャを見て」「オプション分析して」「売買判断して」と言ったときに使う。
---
# Analyze Greeks Skill
## 手順
1. `src/mock_greeks_data.py` を実行して最新の架空データを取得する(またはユーザーが渡したJSONを使う)
2. 以下の判定ルールを適用する:
| 指標 | 条件 | アクション |
|------|------|----------|
| Delta | > 0.6 | コール寄り → 株式を買う(ロングヘッジ) |
| Delta | < -0.6 | プット寄り → 株式を売る(ショートヘッジ) |
| Gamma | > 0.08 | ポジションサイズを半分にする |
| Theta | < -0.05 | 時間減衰が強い → ホールド推奨 or 縮小 |
| Vega | > 0.2 | ボラ感応度高い → 慎重に |
| Rho | 参考程度 | 金利影響は無視してよい |
3. 判定結果を以下のJSON形式で出力する:
```json
{
"symbol": "AAPL",
"option_type": "call",
"decision": "buy_stock" | "sell_stock" | "hold",
"qty": 5,
"reason": "Delta=0.72 のためロングヘッジ",
"greeks": { ... }
}
判定が「buy_stock」または「sell_stock」の場合は、次に place-alpaca-order スキルを提案する。
.claude/skills/place-alpaca-order/SKILL.md
---
name: place-alpaca-order
description: Alpaca Paper Trading で株式の買い/売り注文を出す。analyze-greeks の結果を受け取った後、またはユーザーが「注文して」「Alpacaで買って」と言ったときに使う。
---
# Place Alpaca Order Skill
## 手順
1. 環境変数 `ALPACA_API_KEY` と `ALPACA_SECRET_KEY` が設定されているか確認
2. `src/alpaca_order.py` の `place_order()` を呼び出す
3. 必ず paper=True で実行
4. 注文前にユーザーへ確認メッセージを出す:
「以下の注文を Paper で実行しますか?
銘柄: {symbol}
サイド: {side}
数量: {qty}
理由: {reason}」
5. ユーザーが「はい」と答えた場合のみ実行
6. 結果(order_id, status)を返す
## 使用例コード
```python
from src.alpaca_order import place_order
result = place_order(symbol="AAPL", side="buy", qty=5)
print(result)
5. サブエージェント .claude/agents/options-trader.md
---
name: options-trader
description: 架空ギリシャ指標の分析からAlpaca注文までの一連フローを担当する専門エージェント。複雑な判定が必要なときにメインエージェントから委譲する。
skills: analyze-greeks, place-alpaca-order
---
あなたはオプション・トレーディング専門のサブエージェントです。
## 役割
1. analyze-greeks スキルを使って架空データを判定
2. 判定結果に基づき必要なら place-alpaca-order を呼び出す
3. すべての判断理由を明確に説明する
4. 安全ルール(trading-safety.md)を絶対に守る
## 出力形式
最終的に以下を返す:
- 分析サマリー
- 判定結果(JSON)
- 実行した注文(あれば)または「注文なし」
6. サンプルコード
requirements.txt
alpaca-py>=0.30.0
python-dotenv>=1.0.0
.env.example
ALPACA_API_KEY=your_paper_key_here
ALPACA_SECRET_KEY=your_paper_secret_here
src/mock_greeks_data.py
python
"""架空のオプション・ギリシャ指標データを生成する"""
import json
from datetime import datetime, timedelta
import random
def generate_mock_greeks(symbol: str = "AAPL") -> dict:
"""架空のギリシャ指標を返す"""
base_price = 185.0
strike = 190.0
days_to_expiry = 14
data = {
"symbol": symbol,
"underlying_price": round(base_price + random.uniform(-2, 2), 2),
"option_symbol": f"{symbol}{datetime.now().strftime('%y%m%d')}C00190000",
"option_type": "call",
"strike": strike,
"expiration": (datetime.now() + timedelta(days=days_to_expiry)).strftime("%Y-%m-%d"),
"greeks": {
"delta": round(random.uniform(0.55, 0.78), 4), # ややコール寄り
"gamma": round(random.uniform(0.04, 0.12), 4),
"theta": round(random.uniform(-0.08, -0.02), 4),
"vega": round(random.uniform(0.12, 0.25), 4),
"rho": round(random.uniform(0.01, 0.04), 4),
},
"implied_volatility": round(random.uniform(0.22, 0.35), 4),
"timestamp": datetime.utcnow().isoformat() + "Z",
}
return data
if __name__ == "__main__":
print(json.dumps(generate_mock_greeks(), indent=2, ensure_ascii=False))
src/alpaca_order.pypython
python
"""Alpaca Paper Trading で株式注文を出す(サンプル)"""
import os
from dotenv import load_dotenv
from alpaca.trading.client import TradingClient
from alpaca.trading.requests import MarketOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce
load_dotenv()
def place_order(symbol: str, side: str, qty: int = 5) -> dict:
"""
Paper Trading で市場注文を出す。
side: "buy" or "sell"
"""
api_key = os.getenv("ALPACA_API_KEY")
secret_key = os.getenv("ALPACA_SECRET_KEY")
if not api_key or not secret_key:
return {"error": "ALPACA_API_KEY / ALPACA_SECRET_KEY が設定されていません"}
# 必ず paper=True
client = TradingClient(api_key, secret_key, paper=True)
order_side = OrderSide.BUY if side.lower() == "buy" else OrderSide.SELL
# 安全制限
qty = min(int(qty), 10)
request = MarketOrderRequest(
symbol=symbol,
qty=qty,
side=order_side,
time_in_force=TimeInForce.DAY,
)
try:
order = client.submit_order(request)
return {
"order_id": str(order.id),
"symbol": order.symbol,
"side": str(order.side),
"qty": str(order.qty),
"status": str(order.status),
"paper": True,
}
except Exception as e:
return {"error": str(e)}
if __name__ == "__main__":
# テスト用(実際にはClaudeから呼ばれる)
print(place_order("AAPL", "buy", 3))
src/main_test.py(ローカルテスト用)
python
"""ClaudeAgent を使わずにロジックを単体テストするエントリポイント"""
from mock_greeks_data import generate_mock_greeks
from alpaca_order import place_order
import json
def decide_action(greeks_data: dict) -> dict:
g = greeks_data["greeks"]
delta = g["delta"]
gamma = g["gamma"]
decision = "hold"
qty = 5
reason = "閾値内のためホールド"
if delta > 0.6:
decision = "buy_stock"
reason = f"Delta={delta:.3f} > 0.6 → ロングヘッジ"
elif delta < -0.6:
decision = "sell_stock"
reason = f"Delta={delta:.3f} < -0.6 → ショートヘッジ"
if gamma > 0.08:
qty = max(1, qty // 2)
reason += f" / Gamma={gamma:.3f} のため数量半減"
return {
"symbol": greeks_data["symbol"],
"decision": decision,
"qty": qty,
"reason": reason,
"greeks": g,
}
if __name__ == "__main__":
data = generate_mock_greeks("AAPL")
print("=== 架空ギリシャデータ ===")
print(json.dumps(data, indent=2, ensure_ascii=False))
result = decide_action(data)
print("\n=== 判定結果 ===")
print(json.dumps(result, indent=2, ensure_ascii=False))
if result["decision"] in ("buy_stock", "sell_stock"):
print("\n※ 実際の注文は Claude 経由でユーザー確認後に実行してください")
# テストで本当に注文したい場合のみコメント解除
# side = "buy" if result["decision"] == "buy_stock" else "sell"
# print(place_order(result["symbol"], side, result["qty"]))
7. 使い方(ClaudeAgent としてのテスト手順)
- 上記ファイルを配置し、pip install -r requirements.txt
- .env に Alpaca Paper のキーを入れる
- Claude Code(または Claude Agent SDK)でこのディレクトリを開く
- 以下のように話しかける:
架空のAAPLオプションのギリシャ指標を分析して、
必要ならAlpaca Paperで株式注文の判断をしてください。
Claude は:
・analyze-greeks スキルを自動検出・ロード
・必要に応じて options-trader サブエージェントに委譲
・判定後に place-alpaca-order を提案
・安全ルールに従ってユーザー確認を取る
という流れになります。
8.まとめ
・ CLAUDE.md は「常に真である事実・制約」を短く書く(トークン節約)。
・Skills は「手順(プロシージャ)」を書く。description に自然言語のトリガーキーワードを入れると自動発動しやすい。
・Rules は横断的な安全制約に最適。
・Agents はコンテキストを汚したくない長いフローに使う。
・今回はあくまでSDKの使い方を理解する目的のために、実際に注文を飛ばさずに、 main_test.py でロジックだけ確認しています。
この構成で「ClaudeAgent がどう Skills / Rules / Agents を使い分けるか」がかなり明確に体感できることを期待しています。