← Issues一覧 完了 暗号資産

Issue #009: 急変動検知と予測改善

報告日

2026-02-24


関連issue

008 方向予測ロジック再設計active)— R8-3で急変動検知の課題を認識
009 急変動検知と予測改善  このissue

調査経緯

  1. 008実装中に「一致度(value_confidence)」の分析を実施
  2. 3モデル(XGB/LGBM/CAT)の特性を274件の実績データから分析
  3. 急変動時にモデルがほぼ追従できないことが判明
  4. 急変動検知メカニズムの調査を実施(学術論文・市場分析含む)
  5. ベースライン指標をDB実績データから計算
  6. Phase 1(特徴量追加+サンプル重み改善)を実装、効果検証中

問題

問題1: 30M足の方向精度がランダム以下

DB実績データ441件から計算:

30M 方向精度: 48.8% ランダム=50%を下回る
  UP:   126/255 = 49.4%
  DOWN:  89/186 = 47.8%

比較:

H足 方向精度:  74.5% (585件、バックテスト)
  UP:  209/269 = 77.7%
  DOWN: 227/316 = 71.8%

30M足はシグナルとして機能していない。 H足との差が25ポイント以上。

問題2: 急変動に全く追従できない

30M足の急変動時(上位25%、110件):

指標 30M H
Avg MagRatio 0.19 0.68
Direction agree 62.7% 98.6%
Under-predict率 100% 72.6%

問題3: CatBoostの負の相関

274件の3モデル比較分析で判明:

特性 XGBoost LightGBM CatBoost
バイアス +0.0006(中立) +0.0086(やや強気) -0.0125(弱気)
方向精度 56.2% 56.9% 53.6%
予測振幅(Stdev) 0.1139% 0.1225%(大胆) 0.0858%(保守的)
実績との相関 +0.028 +0.025 -0.084(負の相関)
急変動MagRatio 0.078 0.081 0.063
不一致時正答率 52.5% 55.9% 40.7%
3モデル一致率 78.5%

CatBoostの問題: - 実績と負の相関 — 実績が上がるとモデルは下がると予測する傾向 - 不一致時の正答率40.7% — 他2モデルと意見が違う時に間違いやすい - 予測振幅が最も保守的(急変動への追従力が最低) - 現在の重み: xgb:0.50, lgbm:0.37, cat:0.13

問題4: 根本原因(構造的な2つの限界)

1. 損失関数(MAE)の限界 - 3モデルとも objective='mae' / loss_function='MAE' を使用 - MAEは中央値への収束を促し、テール事象(急変動)を構造的に無視する - 急変動を正確に予測しても、多数の通常時予測の精度が下がるため、モデルは保守的な予測に収束

2. 急変動の「予兆」を捉える特徴量の不足 - 既存: price_shock(2σ超で検出)→ 既に起きた後の検出 - 既存: atr_ratio(短期/長期ATR)→ 遅行指標 - 欠如: BBスクイーズ(低ボラ→急変動の前兆) - 欠如: OI+FRの組合せ(清算カスケードの前兆) - 欠如: ボラティリティの急変そのものを表す特徴量

既存の対策とその限界

既存施策 場所 問題点
price_shock フラグ feature_engineering.py 2σ超の検出のみ。予兆は捉えない
atr_ratio(短期/長期ATR) feature_engineering.py 既に動いた後のスパイク検出(遅行)
_compute_sample_weights ショック3倍 model.py 一律3倍では不十分。大きな急変動も小さな急変動も同じ重み
高ボラ時クリッピング ±10% model.py 急変動を抑制してしまう逆効果
scale_prediction_by_volatility model.py 現在のATR使用(予測ATRではない)
レジーム別パラメータ調整 model.py 高ボラ時にn_est↓、depth↓ = むしろ表現力低下

TF別の急変動方向精度

TF XGB LGBM CAT 備考
15M 47% 47% 47% ランダム以下。ノイズが多すぎる
30M 63% 61% - 方向はバランス良好だが振幅が足りない
H - 78% - 方向は優秀だが振幅をほぼ無視(MagRatio 0.015-0.019)

ベースライン指標(改善前の基準値)

30M足 — DB実績データ(441件、リアル予測確定済み)

指標
方向精度 48.8% (215/441)
RMSE $338.63
MAE $202.10
急変動 MagRatio 0.1891
急変動 方向一致 62.7%
急変動 Under-predict率 100%

30M足 — バックテスト MAE (periods=3)

期間 Close High Low
+1 bars (30min先) 0.33% 0.29% 0.32%
+2 bars (1h先) 0.48% 0.45% 0.49%
+6 bars (3h先) 0.87% 0.83% 0.89%

30M足 — セッション別 MAE

セッション(UTC) Close High Low n
Asia (0-8) 0.48% 0.46% 0.49% 2,535
Europe (8-14) 0.50% 0.47% 0.49% 1,902
US (14-21) 0.73% 0.68% 0.76% 2,184
Late (21-24) 0.48% 0.45% 0.50% 936

USセッションのMAEが突出(0.73% vs Asia 0.48%)。ボラティリティが高い時間帯の予測精度が低い。

H足 — バックテスト(585件)

指標
方向精度 74.5% (436/585)
RMSE $379.16
MAE $254.26
急変動 MagRatio 0.6842
急変動 方向一致 98.6%
急変動 Under-predict率 72.6%

改善計画

Phase 1: 特徴量追加 + サンプル重み改善(難易度: 低)— 実装済み

P1-1: BBスクイーズ指標 — 実装済み

ヘルパー関数 _add_bb_squeeze_features() を作成し、4TF(D/H/30M/15M)全てに適用。

追加特徴量 計算式 意味
bb_width (bb_upper - bb_lower) / MA バンド幅(正規化)
bb_width_percentile 過去100期間でのbb_widthの百分位 現在の幅が歴史的にどの位置か
bb_squeeze 1 if bb_width < 過去20期間min × 1.1 スクイーズ検出フラグ
bb_expansion_rate bb_widthのpct_change 急拡大検知

根拠: 「低ボラ後に急変動が来る」は最も再現性の高い知見(Bollinger Squeeze then Surge)

挿入箇所: | TF | 関数 | MA列 | 挿入位置 | |----|------|------|---------| | D | create_daily_features() | ma20 | BB計算直後 | | H | create_hourly_features() | ma_24h | BB計算直後 | | 30M | create_30min_features() | ma_48 | BB計算直後 | | 15M | create_15min_features() | ma_96 | BB計算直後 |

P1-2: デリバティブ組合せ特徴量 — 実装済み

_add_derivative_features() に3特徴量を追加。

追加特徴量 計算式 意味
oi_spike abs(oi_change) > 5 OI急変(5%超)
fr_oi_combo FR極端 AND OIスパイクの同時発生 清算カスケード前兆
liquidation_risk FR極端 AND OIスパイク AND LS比極端 最も危険なコンボ

根拠: 清算カスケードは「OI増加 → FR偏り → 価格圧縮 → カスケード」の明確なシーケンスを踏む

P1-3: サンプル重みの改善 — 実装済み

_compute_sample_weights() を変更。

項目 Before After
ショック重み 一律3倍 1 + abs(return) / median(abs(return))(変動幅に比例)
上限 なし 5倍(np.minimum(proportional_weight, 5.0)
y_train利用 なし Close変化率の第1列を使用
フォールバック y_trainがNoneの場合は従来の3倍を維持

Phase 2: モデル改善(難易度: 中)— 実装・検証済み

P2-1: 振幅補正(方向と振幅の分離) — 実装済み、効果大

当初計画の「ボラティリティ分類器」を、より直接的な「振幅予測器」に変更。

[predict_magnitude] abs(close_change_pct)を別途予測
    モデル: LightGBM (MAE)  abs値は常に正なので中央値回帰でも有効

[既存予測パイプライン]  pred_pct方向+振幅

[振幅補正] final = pred_pct * (blended_mag / current_mag)
    blended_mag = current_mag × (1-α) + predicted_mag × α
    α = magnitude_blend_ratio (default 0.5)

挿入箇所: model.pyregime_ensemble_predict_multi() 内、高ボラクリッピングの前

P2-2: 分位点回帰スケーリング — 実装済み、効果限定的

変更 内容
LightGBM objective='quantile', alpha=0.90/0.10 で上下分位点を予測
活用 q_width / hist_iqr = vol_scale として予測値に乗算
結果 単独効果は小さい(MagRatio +0.006、方向精度 +2%)

挿入箇所: model.pypredict_quantile_width(), _fit_predict_quantile()

P2-3: CatBoost除外 — 検証完了

config.pyの30M/15M重みを [0.54, 0.46, 0.00] に変更。効果ゼロ — 元の重み0.06が小さすぎた。 ただしCatBoostスキップ最適化(if cat_w > 0: チェック)で速度28%改善。

P2-4: HAR-J型特徴量(実現ボラティリティ分解) — 実装済み

ヘルパー関数 _add_har_j_features() を作成し、4TF(D/H/30M/15M)全てに適用。

追加特徴量 意味
rv_short 短期リターン二乗和(実現ボラティリティ)
rv_long 長期リターン二乗和
bv_short 短期Bipower Variation(連続成分)
jump_component RV - BV(ジャンプ成分、≥0にクリップ)
rv_up 上昇方向のsemivariance
rv_down 下落方向のsemivariance
rv_asymmetry rv_down / rv_total(下落リスク指標)
rv_ratio rv_short / rv_long(急変シグナル)

パラメータ: | TF | window_short | window_long | |----|-------------|-------------| | D | 14 | 60 | | H | 12 | 48 | | 30M | 12 | 48 | | 15M | 24 | 96 |

根拠: HAR-Jモデルは学術的裏付けが最も強い。BTC市場では下落方向のsemivarianceが将来ボラティリティに強い予測力を持つ。

P2-5: blend_ratio最適化 — 完了

50サンプルでblend_ratio 0.0-1.0を比較。

ratio MAE RMSE MagR>0.5
0.0 0.1700 0.2498 26%
0.3 0.1660 0.2379 54%
0.5 0.1668 0.2345 68%
0.6 0.1680 0.2343 70%
1.0 0.1815 0.2428 84%

結論: RMSE最小は0.6。MAE/RMSE/MagRatioのバランスから0.6を採用(0.5→0.6に更新)。

P2-6: 方向予測pred復帰 — 実装済み、大幅改善

30M足の方向精度が39.9%と低い原因: predシグナルが投票から完全除外されていた(#008で変更)。 30M/15M足に限り、predを投票に復帰。

設定 精度 評価件数 レンジ判定
A: pred除外(旧) 54.2% 24件 76%
B: pred復帰 90.0% 20件 80%
C: pred復帰+閾値0.55 79.2% 24件 76%

結論: pred投票復帰で54.2% → 90.0%に劇的改善。direction_pred_in_voting_30M=Trueを採用。

Phase 2 追加検証: H足/15M足へのP2-1展開 — 検証完了

TF 指標 Baseline P2-1 改善
H足 MagR>0.5 4% 60% +56pt
H足 MAE 0.2552 0.2803 +0.025
15M足 MagR>0.5 14% 62% +48pt
15M足 MAE 0.2584 0.2588 +0.0004

結論: P2-1はH足・15M足でもMagRatioを大幅改善。MAE微増は許容範囲。全TFで有効。

Phase 4: 急変動シグナルUI表示(難易度: 低)— 実装済み

P4-1: predict_magnitude結果のDB保存 + 急変動バッジ表示

predict_magnitude() は毎予測で実行されて振幅補正に使われるが、予測値自体はDB保存されず捨てられていた。 この予測値を活用し「次の足が通常より大きく動く可能性がある」ことを示す急変動シグナルを出す。

変更箇所 内容
crypto/models.py BtcPredictionDetailpredicted_magnitude(予測振幅%), volatility_alert(0=通常,1=警戒)追加
_predict_ohlc/model.py predict_v3_multiregime_ensemble_predict_multimagnitude_result引数追加(ミュータブルリストパターン)
predict_ohlc.py _predict_singleでmagnitude取得、直近100足のmedian×2.0閾値で判定、DB保存
crypto/views.py historical_rows/prediction_rowsにpN_volatility_alertを追加
prediction_ohlc.html シグナル列3段目に急変動バッジ(通常:グレーフェードアウト、警戒:赤bg-danger)

閾値判定ロジック: - pred_mag > median(直近100足のabs(return_1d)) × 2.0volatility_alert = 1(警戒) - それ以外 → volatility_alert = 0(通常)

Phase 3: アーキテクチャ拡張(難易度: 中〜高)— 関数実装済み、統合保留

P3-1: ボラティリティ予測の独立モデル

predict_volatility() 関数をmodel.pyに実装。ATR%を1期先予測するLightGBMモデル。 ただしP2-1(振幅補正)と機能重複のため、regime_ensemble_predict_multiへの統合は保留。 P2-1がMagRatio +149%を達成済みで、追加の独立ボラティリティモデルの限界効果は小さい。


検証計画

検証1: ベースライン — 完了

上記「ベースライン指標」セクション参照。

検証方法: - バックテスト: predict_ohlc -t 30M --backtest --periods 3 --step 1 --save(65分) - DB実績データ: BtcPredictionDetail の確定済み441件から方向精度/RMSE/MagRatio算出 - スクリプト: test_scripts/009_baseline_metrics.py, test_scripts/009_30m_metrics.py

注意: periods=100は1バーあたり約25分で非現実的。periods=3(65分)を標準条件とする。

検証2: Phase 1 全適用 — 完了

P1-1 + P1-2 + P1-3 を全て適用した状態でバックテスト実行。

結果: 特徴量追加だけでは改善しない

指標 ベースライン Phase 1 変化
特徴量数 96 103 (+7)
MAE +1 Close 0.33% 0.34% +0.01(横ばい)
MAE +2 Close 0.48% 0.48% ±0
MAE +6 Close 0.87% 0.88% +0.01(横ばい)
急変動 MagRatio 0.1891 0.1839 -0.005(横ばい)
急変動 Under率 100% 98.4% わずかに改善
急変動 方向一致 62.7% 72.6% +10pt(データ母集団が異なる※)

※ベースラインはリアル予測441件、Phase 1はバックテスト7662件(期間が異なるため単純比較不可)

考察: - 特徴量を7つ追加しても、MAEとMagRatioはほぼ変化なし - これは根本原因が損失関数(MAE)にあることを裏付ける - MAE損失はテール事象を構造的に無視するため、急変動の「予兆」特徴量を入れても中央値予測に収束する - Phase 2(損失関数の変更・モデル構造の改善)が必要

検証3: Phase 2 サンプリング効果測定 — 完了

50ケース(上位25%高ボラ + ランダム25件)での A/B テスト結果:

Method MAE RMSE MagRatio DirAcc
baseline 1.0048 1.3575 0.1523 86.0%
magnitude (P2-1) 0.8740 1.1878 0.2631 84.0%
quantile (P2-2) 0.9851 1.3570 0.1587 88.0%
both 0.8783 1.2256 0.2518 88.0%

分析: - P2-1(振幅補正)が最も効果的: MagRatio 0.15 → 0.26 (+73%!)、MAE 1.00 → 0.87 (-13%) - P2-2(分位点): MagRatio微増のみ、方向精度+2% - 振幅補正の方向精度は微減(-2%) — 振幅拡大により誤方向時のペナルティも増加するため - Top10ケースでは全て方向は正しく追従、振幅も1.5-5倍に拡大

結論: P2-1を採用、P2-2は保留

検証4: CatBoost除外バックテスト — 完了

ensemble_weights_30M: [0.54, 0.46, 0.00] でフルバックテスト(30M, 7662件)。

結果: CatBoost除外の効果はほぼゼロ - MAE +1: 0.34% (変化なし) - MagRatio: 0.1831 (0.1839 → わずかに低下) - 元の重み0.06(6%)が小さすぎて全体への影響が限定的

検証5: P2-1フルバックテスト — 完了

CatBoost除外 + P2-1振幅補正の組み合わせで7662件のフルバックテスト。

指標 ベースライン CatBoost除外 P2-1有効 改善率
MagRatio 0.1891 0.1831 0.4698 +149%
RMSE $490.41 $490.41 $468.69 -4.4%
Direction 38.6% 38.6% 39.9% +1.3pt
Under率 98.5% 98.5% 96.4% -2.1pt
OK(0.8-1.2)率 1.4% 1.4% 3.6% +2.5x
MAE +1 Close 0.34% 0.34% 0.33% -3%
MAE +6 Close 0.88% 0.88% 0.83% -6%
実行時間 3781s 3635s 2710s -28%

P2-1の効果は絶大: - MagRatio 2.5倍改善: 実績の19%追従 → 47%追従 - MAEも全期間で改善(特に+6 bars -6%) - CatBoostスキップ最適化で速度28%向上(cat_w > 0 チェック追加)

検証6: blend_ratio最適化 — 完了

50サンプルでblend_ratio 0.0-1.0を9段階比較。RMSE最小は0.6。 MAE/RMSE/MagRatioのバランスから0.6を採用(config更新済み)。

検証7: 方向予測pred投票復帰 — 完了

100サンプルで3設定を比較。pred投票復帰で54.2% → 90.0%に改善。 30M/15M足でdirection_pred_in_voting=Trueを採用。

検証8: H足/15M足P2-1展開 — 完了

50サンプルで各TFのP2-1効果を確認。 - H足: MagR>0.5が4% → 60% - 15M足: MagR>0.5が14% → 62% 全TFでP2-1有効を確認。


対象ファイル

ファイル 変更内容 Phase 状態
_predict_ohlc/feature_engineering.py BBスクイーズ4特徴量、デリバティブ3特徴量、HAR-J 8特徴量(全4TF) P1+P2 実装済み
_predict_ohlc/model.py サンプル重み比例化、predict_magnitudepredict_quantile_widthpredict_volatility、P2統合、CatBoostスキップ最適化 P1+P2+P3 実装済み
_predict_ohlc/config.py CatBoost除外重み、P2フラグ、magnitude_blend_ratio:0.6volatility_prediction_enabled、pred投票復帰 P2 実装済み
_predict_ohlc/direction_prediction.py pred投票復帰(direction_pred_in_votingフラグで制御) P2-6 実装済み
crypto/models.py BtcPredictionDetailにpredicted_magnitude, volatility_alert追加 P4 実装済み
crypto/views.py rowデータにpN_volatility_alert追加 P4 実装済み
templates/crypto/prediction_ohlc.html シグナル列3段目に急変動バッジ追加 P4 実装済み
test_scripts/009_baseline_metrics.py ベースライン指標算出スクリプト 検証 作成済み
test_scripts/009_30m_metrics.py 30M足専用指標算出スクリプト 検証 作成済み
test_scripts/009_p2_effect_test.py P2効果測定(50ケースA/B) 検証 作成済み
test_scripts/009_p2_debug.py P2統合デバッグ 検証 作成済み
test_scripts/009_blend_ratio_optimize.py blend_ratio最適化(50サンプルグリッドサーチ) 検証 作成済み
test_scripts/009_direction_test.py 方向予測A/Bテスト(pred投票復帰検証) 検証 作成済み
test_scripts/009_p2_h15m_test.py H足/15M足P2-1展開検証 検証 作成済み
test_scripts/test_harj.py HAR-J特徴量単体テスト 検証 作成済み
test_scripts/test_harj_integration.py HAR-J統合テスト(create_30min_features) 検証 作成済み

参考文献