0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

日経225の株価予測AIを作って方向的中率67%を出すまでの全記録

0
Last updated at Posted at 2026-04-08

はじめに

「AIで株価を予測できるのか?」

この問いに対して、実際にプロダクトを作り、6万件以上のバックテストで検証した結果を全て公開します。

結論から言うと、日経225構成銘柄の3ヶ月後の値動き方向を67.3%の精度で的中させるモデルが完成しました。 ただし、ここに至るまでに6回の改善チャレンジで全敗し、「特徴量を増やすほど精度が下がる」という反直感的な壁にぶつかりました。

この記事では、モデル構築の全過程 — 成功も失敗も含めて — を技術的な詳細とともに公開します。

完成したサービス: Kabu Prediction(全機能無料)

実際のダッシュボード: kabu.microforge.works/dashboard

目次

  1. プロジェクト概要
  2. 技術スタック
  3. モデルアーキテクチャ
  4. 特徴量エンジニアリング
  5. 精度改善の6回の失敗
  6. SHAP分析で見えたモデルの本質
  7. 大型株 vs 小型株で精度が全く違った話
  8. バックテスト結果
  9. 法的リスクとの戦い
  10. まとめと教訓

プロジェクト概要

何を作ったか

日経225構成銘柄(約200銘柄)を対象に、4つのタイムフレーム(3営業日・1週間・1ヶ月・3ヶ月)で株価の方向を予測するAI分析ツールです。

項目 内容
対象 日経225構成銘柄(約200銘柄)
予測ホライズン 3営業日 / 1週間 / 1ヶ月 / 3ヶ月
方向的中率 3d: 56% / 1w: 70% / 1m: 58% / 3m: 56%
バックテスト件数 66,215件
料金 全機能無料

なぜ作ったか

機関投資家はクオンツチームを擁してデータドリブンな投資判断をしていますが、個人投資家にはそのようなツールがありません。「同等の定量分析を個人でも使えるようにしたい」というモチベーションで開発を始めました。


技術スタック

┌─────────────────────────────────────────────────┐
│  フロントエンド                                    │
│  Next.js 14 (App Router) + Tailwind CSS          │
│  Vercel にデプロイ                                │
├─────────────────────────────────────────────────┤
│  バックエンド                                      │
│  Supabase (PostgreSQL + Auth + RLS)              │
├─────────────────────────────────────────────────┤
│  分析エンジン                                      │
│  Python 3.11 + LightGBM + XGBoost + Ridge        │
│  BigQuery (株価データ基盤)                          │
├─────────────────────────────────────────────────┤
│  自動化                                           │
│  GCP Cloud Functions + Cloud Scheduler           │
│  週次パイプライン自動実行                            │
└─────────────────────────────────────────────────┘

アーキテクチャ詳細: 分析手法ページ


モデルアーキテクチャ

4モデルのスタッキングアンサンブル

単一モデルではなく、4つの異なるモデルの予測値をRidgeメタラーナーで統合しています。

# Model 1: LightGBM Primary(Optuna最適化対象)
model1 = lgb.LGBMRegressor(n_estimators=300, max_depth=6, learning_rate=0.02, ...)

# Model 2: LightGBM Diversity(異なるハイパラで多様性確保)
model2 = lgb.LGBMRegressor(n_estimators=200, max_depth=4, learning_rate=0.05, ...)

# Model 3: Ridge Regression(線形モデルでアンカー)
model3 = Ridge(alpha=1.0)

# Model 4: XGBoost(異なるブースティング実装)
model4 = xgb.XGBRegressor(n_estimators=200, max_depth=5, learning_rate=0.03, ...)

# メタラーナー: 非負制約付きRidgeで最適重み学習
meta_model = Ridge(alpha=1.0, positive=True)
meta_model.fit(np.column_stack([m.predict(X) for m in [model1, model2, model3, model4]]), y)

なぜ positive=True が重要か: 制約なしだとModel2に大きな負の重みがつき、「Model2の予測を逆に使う」という不安定な学習になりました。非負制約により、Model1とModel4が自然に選ばれる安定した重みが得られます。

ターゲット変数: 市場調整リターン(Excess Return)

素の株価リターンではなく、市場平均からの超過リターンを予測ターゲットにしています。

# Raw return
fwd_return = (price_t+N / price_t - 1) × 100

# Market average
market_avg = mean(fwd_return across all stocks on same date)

# Excess return(これを予測する)
fwd_excess = fwd_return - market_avg

なぜ必要だったか: 市場全体が下落トレンドの時期に学習すると、全銘柄が「下がる」と予測してしまう問題がありました。Excess returnにすることで、「市場平均と比べてどうか」を学習させ、この問題を解消しました。

ウィンソライズ(外れ値処理)

小型株時代の名残ですが、大型株でも決算発表後のストップ高/安は起こります。ターゲット変数の1%/99%パーセンタイルでクリッピングしています。

lo = train_df[target_col].quantile(0.01)
hi = train_df[target_col].quantile(0.99)
train_df[target_col] = train_df[target_col].clip(lo, hi)

ホライズン別サンプル重み

短期予測(3日)は最新データを重視、長期予測(3ヶ月)はデータ全体から均等に学習するのが最適でした。

horizon_decay = {
    "3d": 0.5,   # 最新を1.65倍重視
    "1w": 0.4,
    "1m": 0.2,
    "3m": 0.1,   # ほぼ均等
}
weights = np.exp(np.linspace(0, 1, n_samples) * decay)

特徴量エンジニアリング

最終的に使用している特徴量は79個。大きく分けて7カテゴリです。

特徴量カテゴリ別の構成

カテゴリ 特徴量数 代表例
テクニカル 18 ATR, MACD, RSI, ボリンジャーバンド, 出来高比率
ファンダメンタル 7 PER, PBR, ROE, EPS, 配当利回り
センチメント 10 ニュース感情スコア7日平均, ソーシャルバズ
クロスセクション 14 リターンZスコア, 市場ブレッドス, セクターモメンタム
マクロ 10 日経, S&P500, VIX, ドル円
ランク 7 RSIランク, モメンタムランク, ボラティリティランク
その他 13 セクターコード, 決算接近度, ペア特徴量

クロスセクションランク特徴量(v0.5.0で追加、効果あり)

生の指標値ではなく、当日の全銘柄中の相対順位を特徴量にしたものです。これにより市場レジーム(上昇相場/下落相場)が変わっても安定した入力が得られます。

rank_targets = {
    "rsi_14": "rsi_rank",
    "momentum_10d": "momentum_10d_rank",
    "momentum_20d": "momentum_20d_rank",
    "volume_ratio": "volume_ratio_rank",
    "volatility_20d": "volatility_20d_rank",
    "return_5d": "return_5d_rank",
    "return_20d": "return_20d_rank",
}
for src_col, rank_col in rank_targets.items():
    df[rank_col] = df.groupby("trade_date")[src_col].rank(pct=True)

精度改善の6回の失敗

ここが最も学びの大きかった部分です。特徴量の追加・削減・ターゲット変更・データ期間延長、すべて中長期の精度を悪化させました。

失敗の一覧

試行 内容 3d 1w 1m 3m
Baseline (v0.5.0) 79特徴量 51.6% 56.5% 59.9% 67.3%
v0.6.0 +フラクショナル微分 +日本市場特徴量 +レジデュアルモメンタム +0.3 +0.2 -2.7 -5.2
ニュース拡充 +業績トレンド +センチメント強化 ±0 +0.5 -3.4 -5.9
v0.7.0 +クロスアセット連動 +サプライチェーン +FF因子残差 (計+20特徴量) -2.5 -4.8 -11.8 -16.2
SHAP削減 79→35に絞り込み +1.5 -0.4 -8.0 -16.7
10年データ 5年→10年に期間延長 +2.5 -3.3 -8.4 -20.6

なぜ失敗するのか

200銘柄×5年(約20万行)というデータ量に対して、79特徴量が過学習の限界点でした。

  • 特徴量を増やす → ノイズが増えて過学習が悪化
  • 特徴量を減らす → 中長期に必要な情報が失われる
  • データ期間を延ばす → コロナ前後で市場構造が異なりノイズに

この「増やしても減らしても悪化する」状態は、現在の特徴量セットが局所最適解であることを意味しています。


SHAP分析で見えたモデルの本質

SHAP(SHapley Additive exPlanations)で各特徴量の寄与度を分析した結果、モデルの予測はたった3つの柱で構成されていることが分かりました。

特徴量重要度トップ10

Rank 特徴量 SHAP寄与 カテゴリ
1 atr_14 56.1%(3m) ボラティリティ
2 vix_level 24.9%(1w) マクロ
3 macd_hist 13.6%(3d) トレンド
4 sector_code 6.6% セクター
5 volatility_60d 5.2% ボラティリティ
6 volatility_20d_zscore 5.1% ボラティリティ
7 market_return_20d 4.1% マクロ
8 price_to_vwap 3.6% テクニカル
9 bb_width 2.8% ボラティリティ
10 rsi_14 2.5% トレンド

モデルの3つの柱

  1. ボラティリティ(40-60%): ATR, VIX, 60日/20日ボラティリティ → 「市場の不安定さ」が最大の予測因子
  2. トレンド(15-25%): MACD, RSI, モメンタム → 「現在の勢い」が次の方向を示唆
  3. マクロ環境(10-20%): セクター、市場リターン → 「どのセクターが強いか」

衝撃的だったのは、ファンダメンタル(PER, PBR, ROE)やニュースセンチメントがほぼゼロ寄与だったこと。 79特徴量のうち下位20個はSHAP≒0でした。


大型株 vs 小型株で精度が全く違った話

当初はグロース市場の小型株498銘柄を対象にしていましたが、日経225に切り替えたところ精度が劇的に向上しました。

Horizon Growth 498銘柄 Prime 200銘柄 差分
3d 51.7% 51.6% ±0
1w 51.6% 56.5% +4.9%
1m 51.5% 59.9% +8.4%
3m 54.3% 67.3% +13.0%

なぜ大型株の方が予測しやすいのか

  1. データが豊富: 出来高が大きく、ニュースも毎日出る。センチメント特徴量が機能する
  2. ノイズが少ない: 小型株は出来高が少なく、少額の売買で株価が大きく動く
  3. セクター連動が安定: 大型株はマクロ指標との連動が明確(ドル円↑→自動車株↑ etc.)

バックテスト結果

66,215件のバックテスト結果を全て公開しています。

バックテスト全データ: kabu.microforge.works/track-record

方向的中率の推移

各テスト期間での的中率にはバラつきがありますが、全体として50%を安定的に上回っています。

テスト日 3d 1w 1m 3m
2025-10 44% 53% 45% 47%
2025-11 59% 66% 57% 55%
2025-12 55% 50% 57% 50%
2026-01 47% 57% 52% -
2026-02 60% 55% 48% -
平均 53% 56% 52% 51%

上記のベンチマーク(5テスト日の平均)とバックフィル全体(66,215件)の数値は異なります。これはテスト日のサンプリングによるバイアスです。バックフィル全体での精度は答え合わせページで確認できます。


まとめと教訓

技術的な教訓

  1. 特徴量は増やせばいいというものではない — 200銘柄×5年のデータ量では79特徴量が限界
  2. モデルの本質はSHAPで見える — 79特徴量のうち実質的に予測に使われているのは上位10個
  3. 大型株は予測しやすい — データ量・ノイズの少なさ・セクター連動の安定性
  4. 古いデータは毒になる — コロナ前後で市場構造が変わるため、5年が最適
  5. スタッキングの非負制約が重要positive=True がモデルの安定性を大幅に向上

ビジネス面の教訓

  1. 金融系サービスは法的リスクが大きい — 弁護士相談が必須
  2. 「投資助言」に該当しない建て付けが重要 — 全機能無料+登録不要
  3. 用語1つで法的リスクが変わる — "Buy" → "ポジティブ" に変えるだけで安全に

コード

本プロジェクトのサービスは https://kabu.microforge.works で全機能無料で公開しています。


免責事項: 本記事および本サービスは統計的な計算結果の提示を目的としており、特定の金融商品の売買を推奨するものではありません。投資判断はご自身の責任で行ってください。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?