Skip to content
Go back

米国株自動売買エンジンをゼロから構築した:S&P500スコアリング+Alpaca API

Edit page

FX(GMO Coin)と日本株(Kabustation)の2エンジンが稼働している中で、3本目の柱として米国株エンジンをゼロから構築した。 S&P500銘柄をユニバース(投資対象の全体集合)として、テクニカル指標ベースのスコアリングで銘柄を選定し、Alpaca API経由で夜間に自動売買する。

基盤構築(T1〜T3)とAlpacaデータソース統合(T4)を合わせて181テスト全PASS、約2週間で本番シミュレーション(Dry-Run)まで到達した。

本記事では、3つ目のエンジンを追加する際の設計判断、既存FX/JSエンジンとのアーキテクチャ共有、Alpaca APIの特性について記録する。


なぜ米国株を追加するのか

3エンジン体制の意義

1つのマーケット・1つの戦略に集中するのはリスクが高い。 FXが不調な月に日本株が好調ということはよくあります。相関の低い複数のマーケットで同時運用することで、月次リターンの安定性が向上することを目的として米国株エンジンの構築を行いました。

FX(GMO Coin):  EUR_JPY, GBP_JPY等 9ペア — 24時間
日本株(Kabustation): 50銘柄 — 09:00〜15:30 JST
米国株(Alpaca): S&P500 — 22:30〜05:00 JST(冬時間)

3つのマーケットの取引時間が異なるため、ポートフォリオのリスクが分散される。FXは24時間だが、日本株と米国株は異なる時間帯で動く。


アーキテクチャ設計:既存エンジンとの共通化

3エンジン共通の設計パターン

FX・JS・USの3エンジンは、以下の設計パターンを共有している。

[共通レイヤー(core/shared/)]
  ├─ UnifiedSignalEvaluator   — シグナルスコアリング
  ├─ VIXRiskManager           — VIX連動リスク管理
  ├─ KellyPositionSizer       — Kelly基準ロットサイジング
  └─ ErrorAggregator          — 障害集約通知

[エンジン固有レイヤー]
  ├─ FX: _fxTradingEngine/    — GMO Coin API
  ├─ JS: _jsTradingEngine/    — Kabustation API
  └─ US: _usTradingEngine/    — Alpaca / moomoo API

共通レイヤーは core/shared/ に配置し、3エンジンから参照する。エンジン固有の部分(API通信、注文形式、セッション管理)のみが個別実装部分です。

設計判断:完全共通化 vs 適度な独立性

最初は「すべてを共通化する」方針で始めたが、途中で「適度な独立性」に方針転換しました。理由として

無理に共通化すると、条件分岐の嵐で可読性が下がる。「概念は共通、実装は独立」が最も保守しやすいと判断したためです。


S&P500スコアリング

ユニバース(投資対象)

S&P500の全銘柄(約500銘柄)をユニバースとした。理由は:

  1. 流動性: 出来高が十分にあり、スリッページ(注文価格と約定価格のずれ)が小さい
  2. データの信頼性: 大型株は価格データの品質が高い
  3. 上場廃止リスクが低い: S&P500採用銘柄は倒産リスクが相対的に低い

25指標スコアリング

最初は5指標で始めたが、グリッドサーチの結果を踏まえて25指標に拡張した(US-A2/T5施策)。

指標のカテゴリ:

カテゴリ指標例件数
トレンドSMA, EMA, MACD, ADX6
モメンタムRSI, Stochastic, Williams %R, CCI5
ボラティリティBollinger Bands, ATR, Keltner Channel4
ボリュームOBV, Volume SMA, Volume Surge3
一目均衡表転換線, 基準線, 雲, 遅行スパン4
オシレータParabolic SAR, Ichimoku, Aroon3

各指標は「この銘柄は上昇しそうか」を0.0〜1.0のスコアで返し、全指標のスコアを合計してtotal_scoreを算出する。 閾値(min_total_score=7.0)以上の銘柄がエントリー候補になる。

グリッドサーチの結果

196パターンのSL/TP/閾値の組み合わせを検証した結果、以下が最適パラメータとなった。

SL = 1.0 × ATR(平均値動き幅の1倍)
TP = 1.5 × ATR
min_total_score = 3.0(7.0は拡張後の値)
シャープ比 = 1.036
勝率 = 43.8%

勝率43.8%は一見低いが、RR比(TP/SL = 1.5)が十分にあるため、期待値はプラスだ。


Alpaca APIの特性

なぜAlpacaか

米国株の自動売買APIはいくつかの選択肢がある。

API手数料取引時間Paper Trading日本居住者
Alpaca無料レギュラー+プレ/アフター✅(一部制約)
Interactive Brokers低い全セッション
moomoo無料〜低いレギュラー+プレ/アフター

Alpacaを選んだ理由:

Alpaca DataSourceの実装

def fetch_bars(
    symbol: str,
    timeframe: str = "1Day",
    start: str = "2022-01-01",
    end: str = "2026-03-27",
) -> pd.DataFrame:
    """Alpaca APIから価格データを取得"""
    bars = api.get_bars(
        symbol,
        timeframe,
        start=start,
        end=end,
        adjustment="all",  # 分割・配当調整済み
    ).df
    return bars

adjustment="all"が重要だ。米国株は株式分割(Stock Split)が頻繁に行われる。調整済みデータを使わないと、過去の価格が現在と比較不能になり、テクニカル指標の計算結果が全く意味をなさなくなります。

USTradeRecorder

トレード記録はFX/JSエンジンと同じ設計で、SQLiteベースのUSTradeRecorderに記録。

記録項目:
  - シンボル(AAPL, MSFT, ...)
  - エントリー日時・価格
  - エグジット日時・価格
  - PnL(損益)
  - シグナルスコア
  - 使用した指標のスナップショット

launchd統合:夜間自動実行

米国株のレギュラーセッションは22:30〜05:00 JST(冬時間)です。launchdで以下のスケジュールを設定した。

22:00 JST: データ更新・シグナル計算
22:30 JST: プレマーケット監視開始
23:00 JST: レギュラーセッション注文実行
04:30 JST: セッション終了前のポジション確認
05:00 JST: サマリーレポート生成

夜間に自動実行されるため、人間の介入は不要だ。異常時にはSlack通知で即座に把握できる。


学んだこと

1. 3つ目のエンジンは「2つ目の10倍速い」

FXエンジン(1つ目)の構築には数ヶ月かかった。JSエンジン(2つ目)は1ヶ月半。USエンジン(3つ目)は2週間。共通レイヤー(スコアリング、Kelly、VIX管理)が既にあるため、エンジン固有部分(API統合、注文管理)だけを実装すれば済む。

2. 「概念の共通化」と「実装の共通化」は分けて考える

Kelly基準やVIXリスク管理は概念レベルで3エンジン共通だが、実装レベルでは取引単位やセッション管理が異なるため、無理に1つのコードにまとめるべきではない。共通インターフェースを定義し、各エンジンが独自に実装する方が保守性が高い。

3. Paper Tradingはケチらない

AlpacaのPaper Trading(仮想取引)は本番と同じAPIを使ってシミュレーションできる。Dry-Runフェーズでは「本番と全く同じコード」を仮想口座で実行することで、Go/No-Go判断の信頼性が格段に上がる。


まとめ

米国株エンジン構築の設計で重要なのは以下の3点です。

  1. 共通レイヤーの活用: スコアリング・Kelly・VIX管理は既存を流用。エンジン固有部分のみ新規実装
  2. S&P500 × 25指標スコアリング: 流動性の高い大型株に、多面的な指標でスコアを付けて銘柄選定
  3. Alpaca APIのPaper Trading: 本番と同じコードで仮想取引を実行し、Go/No-Go判断の精度を確保

3エンジン体制の構築により、FX不調月でもJS/USが補完するポートフォリオ分散が実現。月利の安定性は、ピーク月利の大きさと同じくらい重要だと思います。


Edit page
Share this post on:

Related Posts


Previous Post
ザラ場動的キャンセル機構:発注後の相場急変に自動対応する
Next Post
LightGBMでテクニカル指標の重みを動的に学習する