Alpaca APIで米国株を自動売買する方法【Python完全ガイド】
「Pythonで米国株を自動売買してみたい」——そう思ってAPIを探すと、必ず名前が挙がるのが Alpaca です。
私は実際にAlpacaのAPIで米国株の自動売買Botを作り、ペーパートレード(仮想資金)で運用しています。この記事では、口座開設からAPIキー取得、最初の注文、そして実際にハマったエラーの対処法までを、動くPythonコード付きで解説します。
⚠️ 本記事は教育目的の情報共有です。投資は自己責任で行ってください。
目次
- Alpacaとは何か(なぜ個人開発者に人気なのか)
- 口座開設とAPIキーの取得
- Python環境の準備
- 最初のAPIリクエスト(口座情報の取得)
- ポジションの取得
- 注文を出す(成行・指値・金額指定)
- ペーパートレードと本番の切り替え
- よくあるエラーと対処法(実体験)
- まとめ
1. Alpacaとは何か
Alpaca は米国の証券会社で、APIファーストで設計されているのが最大の特徴です。個人開発者にとって嬉しいポイントは次の通り。
- 株式取引手数料が無料(米国株)
- ペーパートレード(仮想資金)が無料で使える — 本番と同じAPIで練習できる
- フラクショナル株(端株)対応 — $10,000の株も「$100分だけ」買える
- REST API + WebSocket — シンプルで扱いやすい
- 公式SDKがあるが、REST APIを直接叩いても十分シンプル
特に「ペーパートレードが本番と同一API」なのが決定的に便利です。戦略を実弾投入する前に、リスクゼロで何ヶ月でも検証できます。
2. 口座開設とAPIキーの取得
口座開設
- alpaca.markets にアクセスしてサインアップ
- メール認証を済ませる
- ダッシュボードにログイン
本番取引(Live)には本人確認が必要ですが、ペーパートレードだけなら本人確認不要ですぐ始められます。
APIキーの取得
ダッシュボード右上のアカウントメニューから「Paper Trading」アカウントを選び、API Keys のセクションで「Generate New Keys」をクリックします。
- API Key ID(
PK...で始まる) - Secret Key
の2つが表示されます。Secret Keyは一度しか表示されないので、必ずコピーして安全な場所に保管してください。
ペーパートレードのエンドポイントは以下です。
https://paper-api.alpaca.markets
本番(Live)は https://api.alpaca.markets になります。
3. Python環境の準備
公式SDK(alpaca-py)もありますが、依存ライブラリの競合を避けたい場合は requests で直接REST APIを叩くのがおすすめです。本記事はこの方式で進めます。
pip install requests
APIキーは config.py などに分離しておきます(本番では環境変数推奨)。
# config.py
PAPER_API_KEY = "PK..." # あなたのAPI Key
PAPER_SECRET_KEY = "..." # あなたのSecret Key
PAPER_BASE_URL = "https://paper-api.alpaca.markets"
🔒 APIキーはGitHubに絶対push しないこと。
.gitignoreにconfig.pyを追加しておきましょう。
4. 最初のAPIリクエスト(口座情報の取得)
まずは認証が通るか、口座情報を取得して確認します。Alpacaの認証はヘッダーにキーを入れるだけです。
import requests
from config import PAPER_API_KEY, PAPER_SECRET_KEY, PAPER_BASE_URL
def headers():
return {
"APCA-API-KEY-ID": PAPER_API_KEY,
"APCA-API-SECRET-KEY": PAPER_SECRET_KEY,
}
def get_account():
url = f"{PAPER_BASE_URL}/v2/account"
r = requests.get(url, headers=headers())
r.raise_for_status()
return r.json()
account = get_account()
print(f"ステータス : {account['status']}")
print(f"現金残高 : ${float(account['cash']):,.2f}")
print(f"総資産 : ${float(account['portfolio_value']):,.2f}")
print(f"買付余力 : ${float(account['buying_power']):,.2f}")
実行して ステータス : ACTIVE と残高(ペーパーなら初期$100,000)が表示されれば、認証成功です。
5. ポジションの取得
保有銘柄の一覧は /v2/positions で取得できます。
def get_positions():
url = f"{PAPER_BASE_URL}/v2/positions"
r = requests.get(url, headers=headers())
r.raise_for_status()
return r.json()
for p in get_positions():
pnl = float(p["unrealized_pl"])
pnl_pct = float(p["unrealized_plpc"]) * 100
print(f"{p['symbol']:>6}: {p['qty']}株 "
f"取得${float(p['avg_entry_price']):.2f} "
f"損益${pnl:+.2f} ({pnl_pct:+.2f}%)")
6. 注文を出す
成行・指値注文(株数指定)
注文は /v2/orders にPOSTします。
def place_order(symbol, qty, side, order_type="market", limit_price=None):
order = {
"symbol": symbol,
"qty": str(qty),
"side": side, # "buy" or "sell"
"type": order_type, # "market" or "limit"
"time_in_force": "day",
}
if order_type == "limit" and limit_price:
order["limit_price"] = str(limit_price)
url = f"{PAPER_BASE_URL}/v2/orders"
r = requests.post(url, headers=headers(), json=order)
r.raise_for_status()
return r.json()
# 例: AAPLを成行で10株買う
result = place_order("AAPL", 10, "buy")
print(f"注文ID: {result['id']}")
金額指定注文(フラクショナル株)
Alpacaの便利機能が金額ベースの注文です。qty の代わりに notional(ドル金額)を指定すると、端株で買えます。
def place_notional_order(symbol, side, notional):
order = {
"symbol": symbol,
"notional": str(round(notional, 2)), # ドル金額
"side": side,
"type": "market",
"time_in_force": "day",
}
url = f"{PAPER_BASE_URL}/v2/orders"
r = requests.post(url, headers=headers(), json=order)
r.raise_for_status()
return r.json()
# 例: 1株$1,700のSNDKを「$1,000分だけ」買う
place_notional_order("SNDK", "buy", 1000)
これは等加重ポートフォリオを作るときに非常に便利です。値がさ株も低位株も「同じ金額ずつ」買えるので、資金配分がきれいに揃います。
7. ペーパートレードと本番の切り替え
ペーパーと本番はURLとキーが違うだけです。設定で切り替えられるようにしておくと安全です。
USE_PAPER = True # 本番にするときだけ False
if USE_PAPER:
API_KEY, SECRET_KEY, BASE_URL = PAPER_API_KEY, PAPER_SECRET_KEY, "https://paper-api.alpaca.markets"
else:
API_KEY, SECRET_KEY, BASE_URL = LIVE_API_KEY, LIVE_SECRET_KEY, "https://api.alpaca.markets"
必ずペーパーで数ヶ月検証してから本番へ。私自身、バックテストで好成績だった戦略が、ペーパートレードで初週に-7%を経験しました。実弾でなくて本当に良かったです。
8. よくあるエラーと対処法(実体験)
ここが本記事の本題です。公式ドキュメントには載っていない、実際にハマったエラーを共有します。
HTTP 429(レート制限)
APIを連続で叩きすぎると 429 Too Many Requests が返ります。指数バックオフでリトライしましょう。
import time
def request_with_retry(method, url, max_retries=3, **kwargs):
for attempt in range(max_retries + 1):
r = requests.request(method, url, headers=headers(), **kwargs)
if r.status_code == 429 and attempt < max_retries:
delay = 1.0 * (2 ** attempt) # 1s, 2s, 4s
print(f"[429] {delay:.0f}秒待機してリトライ")
time.sleep(delay)
continue
r.raise_for_status()
return r
return r
HTTP 422(処理できないリクエスト)
422 Unprocessable Entity は原因が分かりにくいエラーです。レスポンスボディにヒントがあるので必ず中身を読みましょう。
if r.status_code == 422:
detail = r.json().get("message", r.text)
raise requests.HTTPError(f"422: {detail}")
私の場合、上場廃止された銘柄に注文を出していたのが原因でした(asset XXX is not active)。対策として、注文前にアセットの状態を確認する関数を入れました。
def is_tradable(symbol):
url = f"{PAPER_BASE_URL}/v2/assets/{symbol}"
r = requests.get(url, headers=headers())
if r.status_code != 200:
return True # 取得失敗時は安全側で許可
asset = r.json()
return asset.get("tradable", False) and asset.get("status") == "active"
HTTP 403(禁止)
403 Forbidden は権限まわりに見えますが、私の場合はまだ約定していない買い注文に対して、すぐ売り注文(損切り)を出そうとしたのが原因でした。ポジションが無い状態での売りは空売り扱いになり拒否されます。
→ 約定を確認してから次の注文を出すロジックにすることで解決しました。
9. まとめ
Alpaca APIを使えば、Pythonで米国株の自動売買が驚くほど簡単に始められます。
- ✅ 手数料無料・ペーパートレードでリスクゼロ検証
- ✅
requestsだけでREST APIを直接叩ける - ✅ 金額指定注文(notional)で端株・等加重が自由自在
- ⚠️ 422 / 403 / 429 はレスポンスボディを読めば原因が分かる
- ⚠️ 必ずペーパーで数ヶ月検証してから本番へ
次回は、ここで作った注文機能を使って 実際に動く自動売買戦略を組み立てるところを解説します。
質問や「こんなエラーが出た」などあれば、ぜひ X (@QuantNobu) までどうぞ。
⚠️ 免責:本記事は教育目的の情報共有であり、投資助言ではありません。実際の投資判断はご自身の責任で行ってください。