はじめに
こんにちは。
GadgetStreemでは現在、ガジェット価格の上昇圧力を一つの数字で確認できる独自指数、
GPI(Gadget Pressure Index/ガジェット価格圧力指数)

を開発しています。
これまでのVol.13では、ドル円や物価指数など単位の異なる市場データを0〜100へ変換する、
Component Scoring
を紹介しました。
Vol.14では、そのComponent Scoreを、
USD/JPY 30%
DRAM 25%
NAND 20%
GPU 15%
Freight 10%
という固定ウェイトで合成し、一つのGPIを作る、
Composite Engine
を紹介しました。
ここまで読むと、次の疑問が出てきます。
なぜドル円は30%なのか?
DRAMは25%で本当にいいのか?
GPUを20%にした方がよい可能性はないのか?
当然の疑問です。
実は私たち自身も、
最初に30・25・20・15・10と決めたから、そのまま使えばよい
とは考えていません。
そこでGadgetStreem Intelligenceでは、
GPIの計算式そのものを疑うための仕組み
を作りました。
今回のテーマは、
- Historical Replay
- Market Regime Backtest
- Weight Validation
です。
GPIのウェイトは「答え」ではなく仮説
GPIを設計した当初、5つのComponentへ次のウェイトを設定しました。
| Component | Weight |
|---|---|
| USD/JPY | 30% |
| DRAM | 25% |
| NAND | 20% |
| GPU | 15% |
| Freight | 10% |
ドル円を最大にしたのは、日本のガジェット市場にとって為替が広範囲の輸入コストへ影響すると考えたためです。
DRAMとNANDはPCだけでなく、スマートフォン、SSD、ゲーム機など幅広い製品へ影響します。
GPUは対象製品が比較的限定されますが、PC市場では大きな価格要因です。
Freightは直接の部品価格ではありませんが、物流コストとして価格圧力へ影響する可能性があります。
ただし、これらはあくまで、
GPI Ver.0.1を開始するためのMethodology上の仮説
です。
「30%という数字が自然法則として正しい」という意味ではありません。
だからコードに自動最適化させない
ここで、
過去データに一番よく合うウェイトをコンピューターに探させればいいのでは?
とも考えられます。
例えば、
USD/JPY 42%
DRAM 18%
NAND 12%
GPU 23%
Freight 5%
の方が過去データへよく適合するなら、それを採用すればよいという考え方です。
しかしGPIでは、この方法をそのまま採用しません。
過去データだけへ強く合わせると、
過去にだけ都合のよい指数
を作ってしまう危険があるからです。
金融分野のBacktestingでも、
look-ahead biasやsurvivorship biasへの注意が必要とされ、過去の環境で良好だった結果が将来も続くとは限りません。CFA Instituteも、Backtestは「過去に実行していたらどうなったか」を検証する方法であり、構造変化やlook-ahead biasなどに注意する必要があると説明しています。(CFA Institute)
SECに提出された指数関連資料でも、Hypothetical Backtestにはhindsightを含む固有の限界があり、将来結果を示すものではないことが明示されています。
そのためGPIでは、
Backtestで良かった
↓
自動でWeight変更
とはしません。
まず「過去のGPI」を正しく再現する
Weightを検証する前に必要なのが、
Historical Replay
です。
例えば、
2024年6月15日時点のGPIは何点だったのか?
を再計算するとします。
現在のデータベースにある最新値を使えば、計算自体は簡単です。
しかし、それでは正しいBacktestになりません。
現在知っている「訂正後の数字」を過去へ持ち込んではいけない
BLSなどの統計データは、後からRevisionされる場合があります。
例えば、
2024年6月時点の公表値
100.4
後日訂正された最終値
101.1
だったとします。
2024年6月15日時点のGPIを再現するなら、
101.1
ではなく、
当時実際に利用可能だった、
100.4
を使わなければなりません。
現在の確定値を過去の計算へ使えば、
未来の情報を過去の自分へ教える
ことになります。
First RevisionとRecorded Vintage
そこでGSIでは、Historical Replayを大きく2種類に分けています。
First Revision
各観測値について、
最初に公表された値だけを使う
Replayです。
後からどれだけ訂正されても、その後のRevisionは利用しません。
Recorded Vintage
こちらは、
そのHistorical Checkpoint時点までに実際に公表されていたRevision
を使います。
例えば、
6月10日
Revision 0 公表
7月5日
Revision 1 公表
なら、
6月15日のReplayではRevision 0
7月10日のReplayではRevision 1
という具合です。
GSIのHistorical Evidence実装では、このfirst_revisionとrecorded_vintageの両方を生成し、後から分かったRevisionを過去へ遡って適用しないことを明示しています。
未来情報の漏洩を禁止する
この問題を、
Future-information Leakage
または、
Look-ahead Bias
と呼びます。
GPIではHistorical Replayにおいて、
後から取得した値を
過去Checkpointへ使用
→ 禁止
です。
さらに、
後から公表されたRevisionを
過去へ遡って使用
→ 禁止
そして、
当時存在しなかった観測値を
補間で生成
→ 禁止
です。
Historical Evidenceの設計では、未来情報Leakage防止、線形補間禁止、Missing Weightの再配分禁止まで明示しています。
土曜日ごとのGPIを再現する
GPIは週次更新を予定しています。
そのためHistorical Replayでは、
毎週のCheckpoint時点で何が利用可能だったか
を再現します。
例えば、
2024-05-04
2024-05-11
2024-05-18
2024-05-25
...
という各週について、
その日に利用可能だった
最新のUSD/JPY
その日に利用可能だった
DRAMデータ
その日に利用可能だった
NANDデータ
その日に利用可能だった
GPUデータ
その日に利用可能だった
Freightデータ
を探します。
重要なのは、
今から見て最新のデータ
ではなく、
その日から見て最新だったデータ
です。
月次データを週ごとに増殖させない
例えば月次統計が、
6月観測:1件
しかない場合。
それを、
6月第1週:1件
6月第2週:1件
6月第3週:1件
6月第4週:1件
という4つのObservationへ増やすことはしません。
同じ1件のObservationを、その時点で利用可能なら参照するだけです。
GSIのMixed-frequency設計でも、QuarterlyやMonthly Observationを週次Checkpointで参照する場合でもCanonical Observation Countを増やしてはいけないと定義しています。
古すぎるデータも「存在するからOK」にはしない
さらに重要なのが、
Freshness
です。
例えばFreightの最新データが3か月前だった場合。
データ自体は存在しています。
しかし、
今週の海上輸送価格圧力を表している
とは言いにくくなります。
そのためGPIでは、
値が存在するか
だけではなく、
その値はまだFreshか
も判定します。
古くなりすぎた値は、
Stale
としてCoverageへ含めません。
実際のFreight Backtestで問題が見つかった
これは設計上の話だけではありません。
BLS Deep Sea Freight候補について実際にHistorical Replayを行ったところ、
Weekly Checkpoints:209
Monthly Observations:48
Covered:
190 / 209
Coverage:
90.9091%
まで到達しました。
一見すると、
90%以上ならかなり良いのでは?
と思えます。
しかし詳細を見ると、
Stale checkpoints:16
Maximum selected age:
131 days
Maximum consecutive missing weeks:
15
Future-information leakage:
0
でした。
そのため判定は、
Historical Coverage:
PASS
Freshness:
FAIL
Common-gap Compatibility:
FAIL
となり、その時点ではProduction Slot Activationを認めませんでした。
これはBacktestを実装した意味がよく分かる例です。
「90%取れている」だけでは足りない
もし単純に、
Coverage > 90%
↓
PASS
だけを見ていたら、このFreight Candidateは通過していた可能性があります。
しかし、
15週間連続で有効な値を持てない期間があるなら、
週次指数としては大きな問題です。
つまり、
平均的にはデータがある
ことと、
実運用で安定して毎週使える
ことは別です。
その後FreightはProductionへ進んだ
ここで時系列を整理しておきます。
Vol.10ではBLS Deep Sea Freightについて、
海上輸送にかなり近いが、まだ10%へ正式採用しない
としました。
Historical Replayでも、先ほど説明したFreshness / Common-gap問題が検出されています。
しかし、そこで開発を止めたわけではありません。
その後、
- Vintage Reconstruction
- Freshness検証
- Methodology Review
- Qualification
- Controlled Activation
- Governance Reconciliation
という追加Gateを進めました。
現在は、
Freight
INCLUDED
10%
まで到達しています。
ただし、
Deep-sea freight price-pressure proxy / benchmarkであり、直接的なFreight Rateではない
というDisclosureを残しています。現在も固定ウェイトは30/25/20/15/10で、Missing Weight RenormalizationはNOです。
つまりBacktestでFAILしたことは、
候補データが永久に不採用になった
という意味ではありません。
問題が見つかったので、その問題を解決する次のGateへ進んだ
ということです。
次に「Market Regime」を検証する
Historical Replayができると、
GPIが過去にどのような状態だったかを時系列で確認できます。
そこで次に検証するのが、
Market Regime
です。
例えば将来GPIを、
LOW PRESSURE
NORMAL
HIGH PRESSURE
のような状態に分類するとします。
この境界値も、
なんとなく60点以上をHIGHにしよう
と決めるだけでは不十分です。
境界線の近くで表示が暴れないか
例えば、
HIGH:60以上
NORMAL:60未満
だった場合、
59.8
60.2
59.7
60.1
59.9
60.3
と動くだけで、
NORMAL
HIGH
NORMAL
HIGH
NORMAL
HIGH
と毎週表示が切り替わります。
これでは利用者から見ると非常に分かりづらい指数になります。
このような短期間の頻繁な切り替わりを、
Whipsaw
として評価します。
Regime Backtestでは何を見るのか
GSIのMarket Regime Threshold Backtestでは、
- Historical Coverage
- Regime Transition数
- Whipsaw
- Dwell Duration
- Threshold Boundaryへの近さ
などを診断する仕組みを実装しました。
例えば、
HIGH PRESSUREへ入ったら平均何週間続くのか
や、
境界値付近を行ったり来たりしていないか
を確認できます。
ただしRegime Thresholdも自動変更しない
ここでも方針は同じです。
Backtestで、
このThresholdの方が良さそう
という候補が見つかっても、
自動的にProduction Threshold変更
はしません。
Issue #72の正式結果は、
Candidate Decision:
insufficient_evidence
Automatic Threshold Change:
false
Publishability:
NOT_PUBLISHABLE
Decision:
NO_GO
でした。
つまり、
Thresholdを検証する仕組みは完成したが、変更するだけの証拠はまだ足りない
という結論です。
そして本題のWeight Validation
ここまで整備したHistorical EvidenceとMarket Regimeを使って、
いよいよ、
30
25
20
15
10
というWeightそのものを検証します。
GSIではこれを、
Weight Validation
として独立したGateにしました。
検証対象には、
- Historical Evidence Coverage
- Weight Concentration
- Effective Component Count
- Composite Index Displacement
- Market Regime Agreement
- Dominant Pressure Share
などがあります。
Weight Concentrationを見る
例えば、
USD/JPY 70%
残り4項目 30%
のような構成を考えてみます。
これでは名前はGPIでも、
実態としては、
ほぼ為替指数
になってしまう可能性があります。
そのため、
Maximum Single Weight
や、
Top Two Weight
を確認します。
Effective Component Count
さらに、
Effective Component Count
も確認します。
これは簡単に言えば、
実質的に何個のComponentへ分散している指数なのか
を見る指標です。
5Componentを均等に使えば、実質的なComponent Countは5へ近づきます。
一つに強く偏れば、1へ近づきます。
現在の固定Weight、
30 / 25 / 20 / 15 / 10
では、検証用シナリオ上のEffective Component Countは、
4.444444
でした。
かなり5に近く、
一つだけに極端に依存する構成ではありません。
わざと「ドル円70%」も試した
Weight Validationでは、
極端なCandidateも意図的に作ります。
その一つが、
fx-heavy-v0.1
です。
このシナリオでは最大Weightを、
70%
まで増やしました。
結果は、
Maximum Single Weight:
0.70
Top Two Weight:
0.80
Effective Component Count:
1.946283
Mean Dominant Pressure Share:
0.694357
Maximum Index Delta:
1.71
でした。
そして判定は、
reject_unstable
です。
理由として、
- Single Weightが大きすぎる
- Top-two Concentrationが大きすぎる
- Effective Component Countが小さすぎる
ことが明示されています。
「ドル円を増やせば良い」と単純にはいかない
これは興味深い結果です。
日本のガジェット価格にとって為替は重要です。
だからといって、
なら70%でいい
とはなりません。
あまり大きくするとGPIが、
Gadget Pressure Index
ではなく、
ほぼUSD/JPY Pressure Index
になってしまいます。
Weight Validationは、
それぞれの要素が重要であること
と、
一つの要素が指数全体を支配しないこと
の両方を見るための仕組みです。
では30・25・20・15・10は合格したのか?
ここは非常に重要です。
検証用の8観測シナリオでは、現在の固定Weight、
gpi-fixed-v0.1
について、
Maximum Single Weight:
0.30
Top Two Weight:
0.55
Effective Component Count:
4.444444
Regime Agreement:
8 / 8
Mean Dominant Pressure Share:
0.379087
となり、
review_candidate
という判定になりました。
しかし、
これで現在のWeightが最適だと証明された
という意味ではありません。
本番相当のWeight Validation判定は「証拠不足」
Weight Validationを実装した時点では、Production相当のEligible Historical Evidenceが十分ではありませんでした。
そのため正式なCurrent Evaluationは、
decision:
insufficient_evidence
automatic_weight_change:
false
missing_weight_renormalization:
false
public_numeric_release:
false
effective decision:
NO_GO
でした。
つまり、
今のWeightを変える根拠もないし、今のWeightが最適だと断定する根拠もまだ足りない
という結論です。
これはかなり重要な違いです。
Equal Weightもまだ「負けた」わけではない
比較シナリオには、
20 / 20 / 20 / 20 / 20
に相当するEqual Weight Candidateもあります。
しかし、このシナリオの判定は、
insufficient_evidence
です。
Eligible Historical Evidenceが0だったためです。
したがって、
「Equal Weightを検証したら悪かった」
とは言えません。
正確には、
そのテスト条件では判断するためのEvidenceが不足していた
です。
GPIではこの、
悪い
と、
分からない
を区別します。
「分からない」は正式な結果
データ分析では、
結論が出ない
という結果は扱いづらいものです。
しかしGPIでは、
INSUFFICIENT_EVIDENCE
を正式な判定として扱います。
証拠がないのに、
30/25/20/15/10が正しい
と断言するより、
現時点では変更するだけのEvidenceがない
とする方が正確です。
ではなぜ今も30・25・20・15・10なのか
現在のGPIでもWeightは、
30 / 25 / 20 / 15 / 10
のままです。
理由は、
Backtestでこの比率が絶対最適だと証明されたから
ではありません。
現在のMethodology Contractとして固定されており、
変更を正当化する十分なEvidenceがまだ承認されていないから
です。
そして、変更する場合も、
Weight Validation
↓
Human Review
↓
Methodology Version Change
↓
Revalidation
という工程が必要です。
自動的にProduction Weightを書き換えることは禁止されています。
Weightを変えたらMethodology Versionも変える
例えば将来、
十分なEvidenceが蓄積され、
USD/JPY
30% → 25%
GPU
15% → 20%
の方が妥当だという判断になったとします。
その場合、
こっそりWeightを書き換えることはしません。
これはMethodology Changeです。
例えば概念的には、
GPI Methodology v0.1.x
↓
GPI Methodology v0.2
のようにVersionを変更し、
旧GPIと新GPIの違いを記録する必要があります。
そうしなければ、
先週 62
今週 67
という差が、
市場変化なのかMethodology変更なのか分からなくなります。
Backtestの目的は「一番きれいな結果を探す」ことではない
GPIにおけるBacktestは、
過去のガジェット価格へ一番よく合うパラメーターを探す大会
ではありません。
むしろ、
Methodologyが壊れやすい場所を探す
ために使っています。
例えば、
データがStaleになる
一つのComponentが支配する
Regimeが毎週切り替わる
Revisionで過去結果が大きく変わる
特定期間だけCoverageが消える
Weightを少し変えるだけで
GPIが大きく動く
といった問題を見つけます。
相関が高くても「予測できる」とは限らない
将来的にはGPIと、
- メモリ小売価格
- SSD価格
- GPU価格
- ノートPC価格
- スマートフォン価格
などを比較することも考えています。
そのとき、
GPIが上昇した後
小売価格も上昇した
という関係が見つかる可能性があります。
しかし、
相関がある
ことと、
将来価格を正確に予測できる
ことは別です。
Backtestはあくまで、
過去の環境でMethodologyがどう動いたか
を見るためのものです。
CFA Instituteも、Backtestだけでは歴史に存在しなかった将来環境を十分表せず、Structural RegimeごとのScenario Analysisを併用する重要性を説明しています。(CFA Institute)
そのためGPIは、
「来週○%値上がりする」
という予測モデルとは分けて考えています。
現在のProduction状態
ここで現在地も整理します。
GPIはその後の開発で、
USD/JPY
INCLUDED
DRAM
INCLUDED
NAND
INCLUDED
※Storage-device price proxy
Freight
INCLUDED
※Deep-sea freight price-pressure proxy
GPU
HISTORY_ACCUMULATION
となっています。
GPUは、
Raw observations:
24
Transformed samples:
23 / 36
です。
Production Coverageは、
85%
Required Coverageは、
100%
です。
そして現在も、
Composite Numeric GPI:
WITHHELD / NULL
Public Numeric Release:
NOT_PUBLISHABLE
です。
Historical Backtestがあるから85%を100%にしない
Vol.14でも説明したとおり、
GPU15%が欠けているからといって、
残り85%を100%へ再配分することはありません。
Historical Replayでも、
Missing Weight Redistribution
→ 禁止
です。
もしBacktest期間中だけWeightを再配分していたら、
現在のProduction Methodologyとは別の指数を検証することになるためです。
GPIのMethodologyは「変更しない」のではなく「勝手に変更しない」
ここまで読むと、
それではWeightは永遠に30/25/20/15/10なのでは?
と思うかもしれません。
そうではありません。
Evidenceが十分に揃い、
- Historical Stability
- Concentration
- Regime Behavior
- Data Coverage
- Semantic Fit
- Sensitivity
- Human Review
を通過すれば、
Methodologyを更新する可能性はあります。
ただし、
データ不足を理由にその場でWeightを変更する
ことと、
検証結果に基づいて新Methodologyを正式採用する
ことを分けています。
今回できるようになったこと
ここまでの開発によってGPIでは、
Historical Observations
↓
Publication Vintage Reconstruction
↓
Historical Checkpoints
↓
First Revision Replay
+
Recorded Vintage Replay
↓
Coverage / Freshness
↓
Component Scoring
↓
Composite Replay
↓
Market Regime Analysis
↓
Weight Validation
↓
Human Review
↓
Methodology Decision
という検証経路を持つようになりました。
単に、
今日のデータ
↓
今日のGPI
を計算するだけのシステムではなくなってきています。
次のVol.16では「数字を出さないPublic API」を紹介
ここまでで、
- データ取得
- Validation
- Component Scoring
- Composite Engine
- Historical Replay
- Weight Validation
- Governance
まで進みました。
次に必要なのは、
これを利用者へどう見せるか
です。
実際のGadgetStreem Intelligenceでは現在すでに、
GPI Public Status Preview
まで開発が進んでいます。
ただし、現在Public APIへ出しているのは、
Production Coverage:85%
USD/JPY:INCLUDED
DRAM:INCLUDED
NAND:INCLUDED
GPU:HISTORY_ACCUMULATION
Freight:INCLUDED
Composite GPI:
WITHHELD
というStatusのみです。
Component Score、Weighted Contribution、Raw ObservationなどはPublic Payloadから明示的に除外しています。
次回のVol.16では、
「まだGPI数値を公開できないのに、なぜPublic APIとDashboardを先に作ったのか?」
を取り上げます。
- Status-only API
- Public Preview UI
- Production Coverage表示
- Numeric Leakage防止
- APIとWordPressの役割分担
- なぜPostgreSQLへWordPressを直接接続しないのか
- WITHHELDをどうUIで伝えるのか
という、GPIを実際のWebサービスへする部分へ進みます。
まとめ
Vol.14では、
30%
25%
20%
15%
10%
という固定Weightで5つのComponent Scoreを統合するComposite Engineを紹介しました。
今回のVol.15では、
そのWeightやMethodology自体をどう検証するのか
をご紹介しました。
GPIでは、
- First Revision Replay
- Recorded Vintage Replay
- Future-information Leakage防止
- Freshness
- Coverage
- Market Regime Backtest
- Weight Concentration
- Effective Component Count
- Dominant Pressure Share
などを使い、
Methodologyそのものを検証します。
実際のWeight Validationでは、
現在の固定Weightを用いるテストシナリオはreview_candidateとなった一方、
ドル円へ70%を集中させたCandidateは、
reject_unstable
となりました。
ただし、
30/25/20/15/10が最適だと証明された
わけではありません。
正式なWeight ValidationではHistorical Evidence不足により、
insufficient_evidence
という判断も記録しています。
そのため、
Automatic Weight Change:
false
です。
これが現在もWeightを固定している理由です。
GPIでは、
過去によく合う数字を探して採用する
のではなく、
現在のMethodologyを壊すだけの十分な証拠があるのかを確認する
という考え方を採っています。
Backtestの目的は、未来を当てた気になることではありません。
GPI自身が、どこで壊れるのかを先に探すことです。
現在もProduction Coverageは85%。
GPUは23/36。
Composite Numeric GPIはWITHHELDです。
まだ公開する数字はありません。
しかし、数字を公開する前に、
その数字を作るルールまで検証できるシステム
には着実に近づいています。
次回は、現在実際に稼働しているGPI Public Status Previewと、Public APIの設計へ進みます。
※GPIは現在開発中の実験的な市場分析指標です。Historical Backtestの結果は将来のガジェット価格を保証・予測するものではありません。また、本記事で扱ったWeight Validationの結果は、現在の30/25/20/15/10というWeightが統計的に最適であることを証明するものではありません。現在のPublic Numeric GPIは未公開であり、個別製品の購入・投資判断を目的とするものでもありません。

コメント