定常性を正確に定義する

確率過程Xt強定常なら、任意の時点集合を同じ幅だけずらしても同時分布が変わりません。実務で多く使う弱定常は、平均が一定で、共分散が時点そのものではなくラグだけに依存するという、より弱い条件です。

E[Xt] = μCov(Xt, Xt-h) = γ(h)

平均・分散・自己共分散の構造が時間で変わらない。

金融市場では、この条件が永久に成立すると期待するのは現実的ではありません。そこで「検証窓の中では変化が許容範囲」という局所定常の近似を置きます。ただし窓を短くすると古いレジームの混入は減る一方、推定分散は増えます。

「非定常は絶対に定常化できない」とは言い切らない

差分・対数化・季節調整で決定的トレンドなどを除ける場合があります。またLLNやCLTにも、独立同分布以外で成立する一般形があります。重要なのは用語の断言ではなく、採用した変換後の過程に必要な仮定が妥当かを検査することです。

低ボラ高ボラ低ボラ比較的安定状態依存
全期間の平均だけでは、どの状態で利益が生じたかを区別できません。

無条件成績を条件付きへ分解する

収益Rと、意思決定時点の状態S∈{1,…,K}を考えます。無条件期待値は、状態別期待値を状態確率で加重したものです。

E[R] = Σs=1K P(S=s) E[R | S=s]

無条件期待値が低下したとき、原因は二つあります。状態別のエッジE[R|S=s]が弱くなったのか、利益を生む状態P(S=s)が出現しなくなったのかです。両者は運用対応が異なります。

分散も状態内のばらつきと、状態間の平均差へ分けられます。

Var(R) = E[Var(R | S)] + Var(E[R | S])

第1項は状態内リスク、第2項はレジーム平均の違いが作るリスク。

観測された変化考えられる原因確認するもの
P(S)だけ変化相場状態の出現頻度が変わった状態占有率、継続時間
E[R|S]が変化状態内のエッジが劣化状態別CI、勝率、ペイオフ
Var(R|S)が増加同じ状態名でも内部が不安定尾部、DD、分布距離
すべて変化状態定義自体が陳腐化上流特徴量と分類器

レジームを事前情報で定義する

状態変数Ztには、直前までの実現ボラティリティ、スプレッド、出来高、金利差、トレンド強度などを使えます。必要条件は、注文時点の情報集合ℱtで測定できることです。

Zt ∈ ℱt, St = g(Zt; θtrain)

レジーム定義は経済的意味を先に置きます。「高ボラだから逆張りを止める」なら、なぜその状態で約定・尾部・平均回帰速度が変わるのかを説明します。色分け後に一番良い区分を選べば、新しい探索です。

状態数を増やしすぎない

K状態に分けると各セルの標本数は急減します。年×時間×通貨×ボラ×トレンドを同時に切れば、見かけの差は簡単に作れます。各セルn、95%CI、探索した全定義数を報告します。

分布ドリフトを測る

平均差だけでなく、trainとOOSの分布全体を比べます。一変量なら経験CDF間のWasserstein-1距離が直感的です。

W1(P,Q) = ∫−∞ |FP(x) − FQ(x)| dx

離散化した分布にはJensen–Shannon距離も使えます。KL divergenceは一方のビン確率が0だと発散し、ビン幅にも敏感です。どの距離も単独の普遍的合格ラインはないため、train内の自然変動やブロック・ブートストラップから基準を事前に作ります。

比較対象目的最低限の併記
P(Z)入力状態の出現分布状態占有率、継続時間
P(R|S)状態内の損益分布平均CI、下位分位、DD
P(features|S)状態定義の上流安定性分布距離、欠損率
P(fill|signal,S)執行可能性滑り、拒否、スプレッド

fold内で検証する

レジーム分析はCPCVやウォークフォワードの外に付ける後処理ではありません。各foldのtrainだけで変換と状態定義を学習し、testへ固定適用します。

疑似コード:レジーム条件付きOOS
for train_idx, test_idx in purged_splits:
    scaler.fit(features[train_idx])
    z_train = scaler.transform(features[train_idx])

    regime_model.fit(z_train)
    s_train = regime_model.predict(z_train)
    s_test  = regime_model.predict(
        scaler.transform(features[test_idx])
    )

    strategy.fit(train_idx, s_train)
    r_oos = strategy.evaluate(test_idx, s_test, costs=True)

    report_by_regime(r_oos, s_test)
    compare_train_oos_distributions(...)

レジーム変数の窓が将来へ伸びる場合は、その区間もPurging対象です。境界、状態数、距離指標、窓幅、分類器を比較した数は候補数として実行前にNへ加えます。

Nnew = Nprevious + Nstrategy × Nregime definitions

複雑なモデルは柔軟ですが、推定に長い履歴を必要とします。長い履歴は古い構造を混ぜます。モデル複雑度と学習窓長は別々に後付け調整せず、一つの事前登録された選択問題として扱います。

運用中の変化検知

フォワードでは、状態別期待値の基準μ0から負方向へずれた累積を監視できます。単純な片側CUSUMは次の形です。

Ct = min(0, Ct−1 + rt − μ0 + k)Ct < −h なら診断のため一時停止

kは許容する小さな変化、hは警報閾値です。損失を見て動かすのではなく、バックテストまたはシミュレーションで誤警報率と検出遅延を決めます。自己相関があるため、iid前提の閾値をそのまま使いません。

警報は「エッジ消滅の証明」ではない

データ欠損、時刻、注文、スプレッド、状態占有率の変化を先に診断します。警報後に閾値を緩める場合は、新しい研究IDと追加Nが必要です。

限界とチェックリスト

ミニテスト

4問で確認します。

Q1. 無条件期待値が変わる二つの主因は?

P(S)とE[R|S]を分けます。

Q2. ボラ分位の境界を推定する正しい範囲は?

test情報を境界作成へ漏らしません。

Q3. レジーム定義を5通り比較して選んだら?

結果選択へ使った比較は試行です。

Q4. CUSUM警報が直接証明するものは?

まずデータ・実装・執行・市場状態を切り分けます。

参考資料

着想と実装例はQuant GuildのNon-Stationarity and Why Market Timing FailsProfitable vs TradableLaw of Total Expectation。数理的背景は Hamilton, A New Approach to the Economic Analysis of Nonstationary Time Series、Capponi et al., The Nonstationarity-Complexity Tradeoff in Return Prediction、逐次変化検知は Page, Continuous Inspection Schemesを参照してください。