標本は時間区間を持つ

標本iの予測時点をti,0、損益やラベルが確定する時点をti,1とします。標本は点ではなく区間Ii=[ti,0, ti,1]です。

Ii = [ti,0, ti,1]

固定5本保有、利確・損切り到達、トリプルバリアなどで終点は変わります。

たとえば金曜に出したシグナルを翌火曜まで保有するなら、金曜の学習標本は月曜・火曜のテスト価格をラベルへ含みます。単純な日付分割だけでは独立しません。

TEST学習標本A学習標本BEmbargo重複→Purge開始日ではなく情報区間の重なりを見る
Aは開始がテスト前でもラベル区間が重なるため学習から除外します。

Purging

テスト標本集合をStestとします。学習候補iの区間が、どれか一つでもテスト区間と交差するなら除外します。

iをpurge ⇔ ∃j∈Stest : Ii ∩ Ij ≠ ∅

重要なのは「保有期間の最大本数を境界から機械的に削る」だけでなく、各標本の実際の終了時点を持つことです。可変保有なら、標本ごとの区間で判定します。

Python風擬似コード:区間重複
def overlaps(train_start, train_end, test_start, test_end):
    return (train_start <= test_end) and (test_start <= train_end)

purged_train = [
    i for i in train_candidates
    if not any(overlaps(t0[i], t1[i], t0[j], t1[j])
               for j in test_indices)
]

Embargo

Purgingがラベルの直接重複を除くのに対し、Embargoはテスト区間の直後へ長さhの空白を置き、近接情報による漏洩を抑えます。

Ej = (tj,1, tj,1 + h]

テスト区間が複数あるCPCVでは、それぞれの境界へ適用します。Embargoは未来情報を消す魔法ではなく、特徴量の長いlookback、自己相関、ラベル終了の不確実性に対する追加バッファです。

PurgingとEmbargoを混同しない

Purgingは実際の区間重複に基づく必須除外、Embargoは境界周辺へ加える事前定義の安全幅です。Embargoだけ置いて、重なるラベルを残してはいけません。

前処理もfold内で行う

時系列を分けても、全期間で次を計算すればリークします。

transformers = fit(Xtrain,s)X′test,s = transformers(Xtest,s)

各splitでfitし直し、テストへはtransformだけを適用します。最終OOSを見て前処理を変えたら、そのOOSはもう未使用ではありません。

幅をどう決めるか

Purging幅はラベル区間から決まり、Embargo幅は予測・保有・特徴量の時間構造から事前に決めます。候補幅を結果で比較すれば、それ自体が新しい試行です。

設計要因確認事項
ラベル期間固定か、利確・損切りで可変か
特徴量lookback境界をまたぐ集計がないか
ポジション重複同じ価格変動を複数標本が共有しないか
サンプル数除外後に各foldが薄くなりすぎないか

ミニテスト

4問で確認します。

Q1. Purgingの判定対象は?

開始日が前でもラベル期間が重なれば除外します。

Q2. Embargoの役割は?

近接情報への安全幅です。

Q3. 標準化の平均・分散を計算する範囲は?

テスト情報を前処理へ入れません。

Q4. 可変保有戦略のPurgingで必要なものは?

実際の情報区間で交差を判定します。

参考資料

Purged cross-validationとCPCVは Marcos López de Prado, Advances in Financial Machine Learning を参照。入門説明は検証コース第10回にもあります。