「正常を学べば、異常が浮かぶ」を市場へ
アクセスログの異常検知でやったことは単純でした。正常なパターンだけを AutoEncoder に学習させる。 すると学習していないパターン——攻撃——が来たとき、再構成に失敗して誤差が跳ね上がる。 「正常を知れば、異常が浮かぶ」。
同じ発想を市場に当てます。平穏な相場だけを学習させ、危機が来たら誤差で気づく。 さらに一歩進めて、その異常度に応じて資産配分を自動で守りに寄せたらどうなるか。 これが「動的オート・リバランス」です。
平穏だけを、学習させる
擬似データは2資産です。リスク資産(平常時は緩やかに上昇、危機時は高ボラティリティで下落)と、 安全資産(低ボラティリティで微増)。ここに危機レジームを2回、意図的に埋め込みます。
入力は「直近10日のリターン」
リスク資産のリターンを10日ぶんの窓に切り、標準化して AutoEncoder に入れます。
構造は 10 → 4 → 10。真ん中で4次元に圧縮するので、よくあるパターンしか通れません。
学習は前半の平穏期だけ。危機のデータは一切見せません。
const model = tf.sequential(); model.add(tf.layers.dense({ inputShape:[10], units:6, activation:'tanh' })); model.add(tf.layers.dense({ units:4, activation:'tanh' })); // ボトルネック model.add(tf.layers.dense({ units:6, activation:'tanh' })); model.add(tf.layers.dense({ units:10 })); // 再構成 model.compile({ optimizer: tf.train.adam(0.01), loss:'meanSquaredError' }); // 学習データは「平穏期の窓」だけ。危機は見せない await model.fit(calmWindows, calmWindows, { epochs:60, batchSize:16 });
入力と出力が同じ(calmWindows, calmWindows)なのが AutoEncoder です。
「自分自身を復元する」訓練を平穏データだけで積むと、危機の形は復元できなくなる。
その失敗の大きさが、異常度です。
この規模のネットワークなら GPU は不要です。以前のベンチでも「LSTMはCPU、モンテカルロはGPU」という住み分けが出ました。小さな全結合はカーネル起動のオーバーヘッドの方が大きく、CPUの方が速いことすらあります。
2つのルールを比べる
再構成誤差を、学習期間の平均と標準偏差で z スコアに直します。平常なら 0 付近、危機なら跳ね上がる。 これを配分に変換する方法を、2つ用意しました。
ルールA:連続シフト
異常度に比例して、リスク資産の比率をなめらかに下げます。少し変なら少しだけ守る。
target = clamp(base - k * max(0, z), floor, base); // zが大きいほど守りへ
ルールB:閾値+ヒステリシス
閾値を超えたら守りに切り替え、別の(低い)閾値を下回るまで戻さない。 境界付近でのバタつきを防ぐ仕組みで、これが売買回数に効きます。
if (!defensive && z > thrOn) defensive = true; // 危機入り if ( defensive && z < thrOff) defensive = false; // 平常復帰(thrOff < thrOn) target = defensive ? floor : base;
比較対象として、何もしない静的配分(リスク資産60% / 安全資産40%を維持)も並べます。
4つの罠を、先に塞ぐ
この手の検証は、油断すると実際より良く見えてしまいます。塞いだ罠は4つです。
① ルックアヘッド・バイアス
未来を知った状態で学習・判定してしまう罠。ここでは AutoEncoder の学習も、z スコアの基準(平均・σ)も、 前半の平穏期だけから作ります。危機のデータは学習に一切入りません。
② 検知遅延
当日の異常を当日中に使えるのは非現実的です。配分の決定には前日までの情報だけを使います。 危機が始まってから守りに入るまで、必ず遅れが出る——それが現実です。
③ 取引コスト
リバランスのたびに手数料とスプレッドがかかります。無視すると動的戦略が過大評価されるので、 売買した分だけコストを引きます。売買回転率も指標として表示します。
④ 後知恵の最適化
閾値や感度を「一番成績が良くなる値」に合わせ込めば、過去にだけ効く戦略が出来上がります。 なのでこのデモでは最適値を提示しません。スライダーはあなたが動かし、 条件を変えると結論がどう揺れるかを見てもらいます。
ブラウザで、実際に学習させる
「学習してシミュレーション」を押すと、TensorFlow.js がこの場で AutoEncoder を訓練します(数秒)。 学習が終わると、異常スコアと3戦略の資産曲線、配分推移が描かれます。
スライダーを動かすと、結論が揺れます。閾値を下げれば早く逃げられますが誤検知で売買が増え、 コストを上げると動的戦略から順に不利になる。「どの設定でも動的が勝つ」わけではないのが見えるはずです。
数回では、見誤った
下は、実際にブラウザで AutoEncoder を学習させて回した2つの相場です (どちらも危機2回・コスト0.1%・閾値 z>2.0・感度0.35。違うのは乱数だけ)。
| 相場A | 最終資産 | 最大DD | 年率vol | Sharpe | 売買回転 |
|---|---|---|---|---|---|
| 静的 60/40 | 1.502 | -9.7% | 0.136 | 1.60 | 0.0 |
| 動的・連続シフト | 1.185 | -3.9% | 0.072 | 1.26 | 23.4 |
| 動的・閾値+ヒス | 1.212 | -4.6% | 0.078 | 1.32 | 9.6 |
| 相場B | 最終資産 | 最大DD | 年率vol | Sharpe | 売買回転 |
|---|---|---|---|---|---|
| 静的 60/40 | 1.094 | -20.1% | 0.153 | 0.39 | 0.0 |
| 動的・連続シフト | 1.053 | -6.4% | 0.075 | 0.41 | 30.3 |
| 動的・閾値+ヒス | 1.056 | -10.2% | 0.088 | 0.38 | 10.4 |
相場Aでは静的が最良、相場Bでは連続シフトが最良。 さらに別の乱数では閾値ルールが勝つ回もありました。何度押しても勝者が入れ替わる。 ——ここで私は「勝者は相場次第、リターンの優劣は運任せ」と結論づけました。
30相場まわすと、構造が見えた
デモの「30相場で検証」は、学習済みの AutoEncoder を使い回して30通りの相場を回し、 勝者を数えます。取引コストを変えて2回押した結果が、これです。
| Sharpe が最良だった回数 | 静的 60/40 | 連続シフト | 閾値+ヒス |
|---|---|---|---|
| 取引コスト 0.1% | 4 / 30 | 6 / 30 | 20 / 30 |
| 取引コスト 0.5% | 8 / 30 | 0 / 30 | 22 / 30 |
個別に数回見たときは勝者がばらばらだったのに、30回まとめると 閾値+ヒステリシスが両方の条件で最良(20勝・22勝)。 「運任せ」ではなく、はっきりした順序がありました。数回の観測では、それがノイズに埋もれて見えなかった。
コストを上げると、何が起きたか
さらに面白いのは、コストを 0.1% → 0.5% に上げたときの動き方です。
- 連続シフトは 6勝 → 0勝に消滅。回転が閾値の3.4倍あるため、コストに真っ先に殺される
- 静的は 4勝 → 8勝に倍増。何も売買しない=回転ゼロの強みが、高コスト環境で効いてくる
- 閾値+ヒステリシスは 20勝 → 22勝。両方の環境で安定して最良
同じ異常スコアを使っていても、動き方の設計だけで「一度も勝てない」ところまで落ちる。 連続シフトの敗因は検知の精度ではなく、じりじり動き続ける設計そのものでした。 ヒステリシスで往復を止めるという一手が、コストを通じてこれだけの差を生みます。
30相場で、変わらなかったこと
勝敗の分布が動く一方で、リスク側の効果はどちらのコスト水準でも安定していました。
- DD圧縮 平均41〜49% — リスク縮小は例外なく起きる
- vol削減 平均47% — 両条件でまったく同じ。値動きは確実に穏やかになる
- 回転比 平均3.4倍(連続÷閾値)— これも両条件で不動
検知と、利益は別
AutoEncoder 自体の性能は良好です。危機期の再構成誤差は平常の数十倍に跳ね、 グラフの紫線は赤帯にきれいに重なります。それでも検知できることと、得することは別でした。 利益を決めたのは検知精度ではなく、検知したあとの動き方——配分ルールの設計です。
検知は、判断を置き換えない
アクセスログでも市場でも、AutoEncoder がやることは同じでした。正常を学び、外れたら気づく。 その先で「気づいたあと、どう動くか」を決めるのは、検知器ではなく設計です。 ログなら遮断ルール、資産なら配分ルール。そこの巧拙で、結果は逆転します。
この記事のまとめ
- 平穏期だけで学習した AutoEncoder は、危機で再構成誤差が数十倍に跳ねる。
- 動的リバランスはDDを41〜49%圧縮・volを47%削減。コスト水準によらず安定。
- 連続シフトの売買回転は閾値ルールの約3.4倍。この差も不動。
- 30相場では閾値+ヒステリシスが20勝/22勝で両条件とも最良。数回の観測では見えなかった。
- コストを 0.1%→0.5% に上げると連続シフトは6勝→0勝に消滅、静的は4勝→8勝に倍増。回転の重さが命取りになる。
- 少数の観測は構造を隠す。バックテストに必要なのは良い1回ではなく、たくさんの回。
- 正直なバックテストの4条件:ルックアヘッド回避・検知遅延・取引コスト・後知恵最適化の禁止。
- 利益を決めたのは検知精度ではなく検知したあとの配分ルール。
擬似データで構造を確かめたら、次は実データで同じことをやる番です。ただしそのときこそ、 この4つの罠が牙をむきます。正直に組めば、たいてい期待値は下がる。 それでも下がった後に残るものがあるなら、それは本物かもしれません。