opendeviation-eval-metrics について
オープン偏差バーのデータで機械学習モデルを評価するための、リファレンスとスクリプト集です。非 IID のバー系列を考慮した指標計算とレポート作成を研究者向けに提供します。
主な機能
- 01取引・予測指標の計算
- 02日次集計による Sharpe 計算
- 03Walk-Forward の各 fold 分析
- 04Markdown 評価レポートの生成
- 05指標スキーマの検証
活用シーン
- 01fold 間のモデル結果比較
- 02可変時間バーでの Sharpe 評価
- 03予測品質とモデル崩壊の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill opendeviation-eval-metricsインストール後、Claude Code で/opendeviation-eval-metricsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
requirements.txtreferences/anti-patterns.mdbeyond-hit-rate.mdcrypto-markets.mdevolution-log.mdmetrics-schema.mdml-prediction-quality.mdrisk-metrics.mdsharpe-formulas.mdsota-2025-2026.mdstructured-logging.mdtemporal-aggregation.mdworked-examples.mdscripts/compute_metrics.pycompute_metrics.test.ts詳細
オープン・デビエーション・バー評価指標
最先端のオープン・デビエーション・バー(ODB、価格ベースのブリム・トゥ・ブリム・サンプリング)データを評価する指標の機械可読リファレンスと計算スクリプトです。
相互参照:プロジェクトの研究リポジトリにある signal-archaeology スキルのプロジェクトレベル実験カタログには、監査可能な SQL を含む、BHR で検証済みの実験が 10 件掲載されています。
自己進化型スキル:このスキルは使用を通じて改善されます。指示に誤りがある、パラメーターがずれている、または回避策が必要だった場合は、先送りせずにこのファイルをすぐに修正してください。実際に再現可能な問題がある場合のみ更新してください。
このスキルを使用する場面
以下の場合にこのスキルを使用します。
- オープン・デビエーション・バーのデータに対する ML モデルのパフォーマンスを評価する
- 非 IID のバー系列でシャープレシオを計算する
- ウォークフォワード最適化の指標分析を実行する
- PSR または MinTRL の統計検定を計算する
- フォールドの結果から評価レポートを生成する
試行回数の補正は禁止(オペレーター規則、2026-10-15):Deflated Sharpe Ratio、最小バックテスト期間(MinBTL)、またはその他の試行回数補正(Holm や Benjamini-Yekutieli などの FWER/FDR 手続き、e-LOND、その他のオンライン多重検定を含む)を、計算、報告、順位付け、引用してはなりません。モデル自体の簡潔さを評価し、実行前の登録と未使用データによって選択を管理し、各ルール固有の統計量(Sharpe、PSR、MinTRL)を報告してください。これらは意図的にこのスキルから削除されています。再追加しないでください。PBO/CSCV はこの規則の対象外です。
クイックスタート
# Compute metrics from predictions + actuals
python scripts/compute_metrics.py --predictions preds.npy --actuals actuals.npy --timestamps ts.npy
# Generate full evaluation report
python scripts/generate_report.py --results folds.jsonl --output report.md
指標の層
| 層 | 目的 | 指標 | 計算 |
|---|---|---|---|
| 主要(5) | 研究上の判断 | weekly_sharpe、hit_rate、cumulative_pnl、n_bars、positive_sharpe_rate | フォールドごと+集計 |
| 二次/リスク(5) | 追加の情報 | max_drawdown、bar_sharpe、return_per_bar、profit_factor、cv_fold_returns | フォールドごと |
| ML 品質(3) | 予測の健全性 | ic、prediction_autocorr、is_collapsed | フォールドごと |
| 診断(4) | 最終検証 | psr、autocorr_lag1、effective_n、binomial_pvalue | 集計のみ |
| 拡張リスク(5) | 詳細なリスク分析 | var_95、cvar_95、omega_ratio、sortino_ratio、ulcer_index | フォールドごと(任意) |
オープン・デビエーション・バーに特別な扱いが必要な理由
オープン・デビエーション・バーは、標準的な IID の前提に反します。
- 継続時間が一定でない:バーは時間ではなく価格変動に基づいて形成されます
- 自己相関:高ボラティリティの期間にはバーが集中するため、時間的相関が生じます
- 情報量が一定でない:ボラティリティが高い期間にはバーが増えるため、1 日あたりの情報量が増加します
標準的な解決策:シャープレシオの計算前に、_group_by_day() を使って日単位に集計します。
参考資料
コアリファレンスファイル
| トピック | リファレンスファイル |
|---|---|
| シャープレシオの計算 | sharpe-formulas.md |
| リスク指標(VaR、Omega、Ulcer) | risk-metrics.md |
| ML 予測品質(IC、自己相関) | ml-prediction-quality.md |
| 暗号資産市場に関する考慮事項 | crypto-markets.md |
| 時系列集計ルール | temporal-aggregation.md |
| 指標の JSON Schema | metrics-schema.md |
| アンチパターン(取引コスト) | anti-patterns.md |
| SOTA 2025-2026(SHAP、BOCPD など) | sota-2025-2026.md |
| ヒット率を超えて(BHR)フレームワーク | beyond-hit-rate.md |
| 計算例(BTC、EUR/USD) | worked-examples.md |
| 構造化ロギング(NDJSON) | structured-logging.md |
関連スキル
| スキル | 関連性 |
|---|---|
| sharpe-ratio-non-iid-corrections | ρ 補正 PSR、MinTRL、検出力 — 非 IID の単一検定フレームワーク全体 |
| adaptive-wfo-epoch | WFE の計算に weekly_sharpe、psr を使用 |
依存関係
pip install -r requirements.txt
# Or: pip install numpy>=1.24 pandas>=2.0 scipy>=1.10
主な数式
日次集計シャープレシオ(主要指標)
def weekly_sharpe(pnl: np.ndarray, timestamps: np.ndarray) -> float:
"""Sharpe with daily aggregation for open deviation bars."""
daily_pnl = _group_by_day(pnl, timestamps) # Sum PnL per calendar day
if len(daily_pnl) < 2 or np.std(daily_pnl) == 0:
return 0.0
daily_sharpe = np.mean(daily_pnl) / np.std(daily_pnl)
# For crypto (7-day week): sqrt(7). For equities: sqrt(5)
return daily_sharpe * np.sqrt(7) # Crypto default
情報係数(予測品質)
from scipy.stats import spearmanr
def information_coefficient(predictions: np.ndarray, actuals: np.ndarray) -> float:
"""Spearman rank IC - captures magnitude alignment."""
ic, _ = spearmanr(predictions, actuals)
return ic # Range: [-1, 1]. >0.02 acceptable, >0.05 good, >0.10 excellent
確率的シャープレシオ(統計的検証)
from scipy.stats import norm
def psr(sharpe: float, se: float, benchmark: float = 0.0) -> float:
"""P(true Sharpe > benchmark)."""
return norm.cdf((sharpe - benchmark) / se)
年率換算係数
| 市場 | 日次 → 週次 | 日次 → 年次 | 根拠 |
|---|---|---|---|
| 暗号資産(24/7) | sqrt(7) = 2.65 | sqrt(365) = 19.1 | 週あたり7取引日 |
| 株式 | sqrt(5) = 2.24 | sqrt(252) = 15.9 | 週あたり5取引日 |
暗号資産市場では、sqrt(252) を絶対に使用しないでください。
重要:セッションフィルターによる年率換算の変更
| 表示 | フィルター | days_per_week | 根拠 |
|---|---|---|---|
| セッションフィルターあり(ロンドン〜NY) | 平日 08:00-16:00 | sqrt(5) | 株式と同様の取引 |
| 全バー(フィルターなし) | なし | sqrt(7) | 暗号資産の24時間365日取引 |
セッションフィルター適用データに sqrt(7) を使用すると、シャープレシオが約18%過大評価されます!
詳しい根拠については、crypto-markets.md を参照してください。
2種類の指標表示
包括的な分析のため、両方の表示で指標を計算してください。
- セッションフィルターあり(ロンドン 08:00〜NY 16:00):戦略評価の主要指標
- 全バー:レジーム検出、データ品質の診断
学術的な参考文献
| 概念 | 引用 |
|---|---|
| 確率的シャープレシオ | Bailey & López de Prado (2012) |
| 非正規分布におけるシャープレシオの標準誤差 | Mertens (2002) |
| シャープレシオの統計 | Lo (2002) |
| オメガレシオ | Keating & Shadwick (2002) |
| アルサー指数 | Peter Martin (1987) |
ヒット率を超える(BHR)フレームワーク
ヒット率は必要な指標ですが、それだけでは不十分です。 必ず結果の予測可能性を測る指標も併せて使用してください。フレームワークの全容は beyond-hit-rate.md を参照してください。
最小限のシグナル評価
すべてのシグナルでは、少なくとも次の項目で評価する必要があります。
- 1つの系列構造テスト:W/L系列に対するエントロピー、LZC、またはラン検定
- 1つの時間的減衰テスト:エクイティカーブまたはローリングヒット率に対するCUSUM
- 1つのレジーム認識テスト:セッションごとのヒット率またはHMM分解
3つすべてに合格したシグナルは堅牢です。ヒット率が高いだけのシグナルはノイズです。
結果予測可能性指数(OPI)
OPI = 0.25 * (1 - LZC_norm) + 0.25 * |z_runs| + 0.25 * Var(HR_per_regime) + 0.25 * AUC_meta
OPIが高いほど、勝敗のタイミングを予測しやすくなります。HRが45%でOPI=0.8のシグナルは、HRが65%でOPI=0.1のシグナルより価値があります。
判断フレームワーク
実行基準(研究)
go_criteria:
- positive_sharpe_rate > 0.55
- mean_weekly_sharpe > 0
- cv_fold_returns < 1.5
- bhr_sequence_test_passes: true # At least one of: entropy, LZC, runs test significant
- bhr_cusum_verdict: "ALIVE" # No recent regime break
公開基準
publication_criteria:
- binomial_pvalue < 0.05
- psr > 0.85
- registered_before_run: true # Hypothesis, rule and window fixed before results were seen
- confirmed_on_unused_data: true # Holdout no run or selection step has touched
- bhr_lzc_shuffle_z < -2.0 # W/L sequence has genuine structure
- bhr_alpha_halflife > 200 # Edge persists for 200+ trades
スクリプト
| スクリプト | 目的 |
|---|---|
scripts/compute_metrics.py | 予測値/実績値からすべての指標を計算する |
scripts/generate_report.py | フォールド結果からMarkdownレポートを生成する |
scripts/validate_schema.py | 指標JSONをスキーマに照らして検証する |
修正(2026-01-19 マルチエージェント監査)
以下の修正は、12のサブエージェントによる敵対的監査に基づいて適用されました。
| 問題 | 根本原因 | 修正 | 出典 |
|---|---|---|---|
weekly_sharpe=0 | 予測値が一定 | モデル崩壊の検出+アーキテクチャの修正 | model-expert |
IC=None | 予測値の分散がゼロ | 定数の場合は1.0を返す(意味的に正しい) | model-expert |
prediction_autocorr=NaN | ゼロ除算 | std < 1e-10の場合をガードし、1.0を返す | model-expert |
| アルサー指数のゼロ除算 | ピークエクイティが0 | np.where(peak > 1e-10, ...)でガードする | risk-analyst |
| オメガ/プロフィットファクターの信頼性不足 | サンプル数が少なすぎる | min_daysパラメーター(デフォルト:5)を追加 | robustness-analyst |
| BiLSTMの平均値崩壊 | アーキテクチャが小さすぎる | hidden_size: 16→48、dropout: 0.5→0.3 | model-expert |
profit_factor=1.0 (n_bars=0) | 早期リターンの値が誤り | 計算対象のデータがない場合はNaNを返す | risk-analyst |
モデル崩壊の検出
# ALWAYS check for model collapse after prediction
pred_std = np.std(predictions)
if pred_std < 1e-6:
logger.warning(
f"Constant predictions detected (std={pred_std:.2e}). "
"Model collapsed to mean - check architecture."
)
推奨BiLSTMアーキテクチャ
# BEFORE (causes collapse on open deviation bars)
HIDDEN_SIZE = 16
DROPOUT = 0.5
# AFTER (prevents collapse)
HIDDEN_SIZE = 48 # Triple capacity
DROPOUT = 0.3 # Less aggressive regularization
実装の詳細については、参考ドキュメントを参照してください。
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| weekly_sharpe が 0 | 予測値が一定 | モデル崩壊を確認し、hidden_size を大きくします |
| IC が None を返す | 予測値の分散がゼロ | モデルが崩壊しています。アーキテクチャを確認します |
| prediction_autocorr が NaN | ゼロ除算 | 自己相関の計算で std < 1e-10 をチェックします |
| Ulcer Index の除算エラー | ピーク時の equity がゼロ | ガードを追加します:np.where(peak > 1e-10, ...) |
| profit_factor = 1.0 | 処理されたバーがない | n_bars が 0 の場合は NaN を返します |
| Sharpe が 18% 過大 | データに対する年率換算が誤り | セッションでフィルタリングした場合は sqrt(5)、24/7 の場合は sqrt(7) を使用します |
| PSR が計算されない | scipy がない | インストールします:pip install scipy |
| タイムスタンプが解析されない | 形式が誤っている | datetime 文字列ではなく、Unix タイムスタンプを使用します |
実行後の振り返り
このスキルの実行後、終了する前に確認してください:
- コマンドは成功しましたか? — 成功しなかった場合は、失敗の原因となった指示またはエラーテーブルを修正します。
- パラメーターや出力に変更はありましたか? — 基盤となるツールのインターフェースに変更があった場合は、使用例とパラメーターテーブルを更新して一致させます。
- 回避策が必要でしたか? — 即興で対応した場合(異なるフラグ、追加の手順など)は、次回の実行で同じ回避策が必要にならないよう、この SKILL.md を更新します。
問題が実際に発生し、再現可能な場合にのみ更新してください。推測に基づく更新は行わないでください。