9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

時系列モメンタムとは何か? クオンツ入門としての「方向・リスク・分散」

9
Last updated at Posted at 2026-07-21

Time_Series_Momentum_-_Slide_1.png

はじめに――価格の動きには「勢い」があるのか

金価格が過去1年間上昇していたら、その後も上がりやすいのだろうか。株価指数が下落を続けていたら、下落はもう少し続くのだろうか。相場の方向には一定の持続性があり、それを感覚ではなくルールとして利用できるのだろうか。

相場には、一度始まった上昇や下落が一定期間続くことがある。この価格の持続性を数値化し、売買ルールとして利用する代表的なクオンツ戦略が、時系列モメンタム(Time Series Momentum) である。

時系列モメンタムは、来月の価格を正確に予測することを目的としない。過去の値動きから現在の方向を判定し、その方向についていく。この記事では、Moskowitz、Ooi、Pedersen による論文 "Time Series Momentum" (Journal of Financial Economics, 2012) を基礎として、この戦略の代表的な考え方を、これからクオンツ戦略に取り組む方に向けて整理する。

先に、この記事で最も伝えたいメッセージを書いておく。時系列モメンタムを「上がっているものを買い、下がっているものを売る戦略」と説明するだけでは不十分である。クオンツ戦略としての時系列モメンタムは、次の三つの要素から構成される。

方向を測る。リスクをそろえる。市場を分散する。

Time_Series_Momentum_-_Slide_2.png

売買シグナルだけではなく、リスク管理とポートフォリオ構築まで含めて、はじめて一つの戦略になる。この点を理解してもらうことが、この記事のゴールである。

なぜ今、時系列モメンタムを調べているのか

個人的な背景も書いておく。私は自動売買ボットを開発・運用しており、現在は4つのサーバーノードで20種類の金融商品を扱える構成になっている。これまではマルチカレンシー(複数通貨ペア)戦略を主力としてきたが、今後はマルチアセットによるトレンドフォロー戦略の開拓を進めたいと考えている。

対象市場をマルチアセットへ広げる狙いは、トレンドの発生機会を増やし、単一市場への依存を下げることにある。これは、まさに本記事で扱う時系列モメンタムの「複数市場への分散」という設計思想そのものである。自分のシステムへ組み込む前に、この戦略の古典であるMoskowitzらの論文へ立ち返り、シグナル・リスク調整・分散という基本構造を整理しておきたい――それが本記事を書いている動機である。

なお、運用面では、サーバーノードごとに監視・ログ解析・異常検知・再起動・リスクアラートを担うAIエージェントを配置し、人間が24時間張り付かなくても運用状況を把握できるAIOps型の設計を目指している。この基盤の話は本記事の範囲外だが、複数市場・複数ノードで戦略を回すには、戦略ロジックと同じくらい運用の仕組みが重要になるという点だけ触れておく。

関連するx(twitter)の投稿
 https://x.com/tommy_love123/status/2070502720503718308

想定読者

  • クオンツ投資に興味があり、これから学び始める方
  • Pythonを使ったバックテストを始めたい人
  • モメンタムという言葉は知っているが、実装方法を知らない人
  • シグナルとポジションサイズの違いを理解したい人

なお、本稿は論文と戦略構造の解説を目的としたものであり、投資推奨ではない(詳細な免責は末尾に記載する)。


第1部 時系列モメンタムとは何か

1. 時系列モメンタムの定義

最も簡単な定義は次のとおりである。

ある市場の過去のリターンがプラスならロング、マイナスならショートする戦略。

「売る」と書くと既存のロングを手仕舞う意味にも読めるため、本稿では論文に合わせて、プラスならロング(買い建て)、マイナスならショート(売り建て) と表現する。

重要なのは、ほかの銘柄と比較するのではなく、その市場自身の過去と比較することである。

例を挙げる。

  • 日経平均の過去12カ月リターンがプラスなら、日経平均をロングする
  • 日経平均の過去12カ月リターンがマイナスなら、日経平均をショートする
  • 金についても、米国債についても、同じ判定を独立して行う

つまり時系列モメンタムが調べるのは、「何が一番強いか」ではなく、「それぞれの市場が上向きか、下向きか」という点である。

2. クロスセクショナル・モメンタムとの違い

モメンタムには、大きく分けて二つの考え方がある。時系列モメンタムと、銘柄間の相対比較を行うクロスセクショナル・モメンタムである。最初に混同しやすい部分なので、表で整理する。

項目 時系列モメンタム クロスセクショナル・モメンタム
比較対象 その市場自身の過去 他の銘柄との比較
基本的な問い この市場は上昇基調か どの銘柄が相対的に強いか
買いの条件 過去リターンがプラス 他銘柄よりリターンが高い
売りの条件 過去リターンがマイナス 他銘柄よりリターンが低い
全市場が上昇した場合 全市場を買う可能性がある 強い銘柄を買い、弱い銘柄を売る

例えで言うと、4人のランナーがいるとき、クロスセクショナル・モメンタムは「同じ期間に誰が最も前へ進んだか」を比較する。時系列モメンタムは「各ランナーが12カ月前の自分の位置より前にいるか、後ろにいるか」を見る。速度の変化(加速)を見ているのではなく、一定期間に前進したか後退したかを見ている点に注意してほしい。

Time_Series_Momentum_-_Slide_3.png

この違いは実際のポジションに大きく影響する。全市場が同時に上昇している局面では、時系列モメンタムは全市場をロングする可能性があり、ネットのロング量は時点によって変化する。一方、代表的なロング・ショート型のクロスセクショナル・モメンタムでは、相対的に強い銘柄を買い、弱い銘柄を売る。そのため純投資額を抑えやすいが、市場ベータが必ずゼロになるわけではない(ドル中立とベータ中立は別である)。またロングのみの実装も可能であり、「常にロング・ショートを組む」とまでは言えない。

本節の比較を1枚にまとめると次のとおりである。

Time_Series_Momentum_-_Slide_4.png

3. 論文 "Time Series Momentum" の概要

  • 著者: Tobias J. Moskowitz, Yao Hua Ooi, Lasse Heje Pedersen
  • 掲載: Journal of Financial Economics, 2012
  • 対象: 商品先物24銘柄、通貨12ペア、先進国株価指数先物9銘柄、先進国国債先物13銘柄の合計58の先物・フォワード銘柄
  • データ期間: 全データは1965~2009年。主要な12カ月判定・1カ月保有戦略の分析は、銘柄数と流動性を確保できる1985~2009年が中心

日本語で「商品」と書くとコモディティだけを指すように読めるため、対象は上記のとおり4つの資産クラスにまたがる58銘柄である点を明記しておく。

論文が報告した中心的な傾向は次のとおりである。

  1. 各銘柄自身の過去の超過収益率と将来の超過収益率との間に、主として1~12カ月のラグで正の関係が報告された。代表的な戦略仕様として、過去12カ月の累積超過収益率の符号を使い、翌1カ月保有する方法が分析されている
  2. より長い期間では、部分的な反転も報告された(初期の過小反応と、遅れて生じる過剰反応というセンチメント理論と整合的と論じられている)
  3. この傾向は、株価指数・国債・通貨・商品という複数の資産クラスで確認された
  4. 銘柄ごとのリスクを調整し、複数銘柄を組み合わせた分散ポートフォリオは、単一銘柄よりも安定した結果を示した

繰り返しになるが、これらは過去の特定のデータと期間における研究結果であり、将来も同じ傾向が続くことを保証するものではない。「論文で有効性が証明された」と読むのではなく、「過去のデータで傾向が報告されている」と読むのが正確だと考えている。

4. 代表的な標準形――12カ月判定・1カ月保有

論文を基礎にした代表的な戦略は、次の手順で構成できる。

  1. 過去12カ月のリターンを計算する
  2. リターンがプラスならロング、マイナスならショートする
  3. 翌月のポジションを保有する
  4. 毎月シグナルを計算し直す
  5. 市場ごとのボラティリティに応じてポジション量を調整する
  6. 複数の市場を組み合わせる

ここで一つ表現上の注意をしたい。これを「最も標準的な方法」と断定するのは避け、時系列モメンタムの代表的な標準形と呼ぶことにする。トレンドフォローには、移動平均、ブレイクアウト、複数期間の合成など、ほかにも広く使われる方法が存在するためである。「過去12カ月が最適な期間である」という主張も、この記事では行わない。

以降の説明の全体像を、先に一行で示しておく。

リターン系列を作る → 12カ月シグナルを計算する → 市場ごとにボラティリティ調整する → 上限を適用する → 複数市場を合成する → 翌月リターンで損益を計算する → コストを控除する

Time_Series_Momentum_-_Slide_9.png

第2部では、この流れを順に説明する。

第2部 戦略をどう構築するか

5. ステップ1――過去の方向を測る

何のリターンを測るのか

最初に、意外と見落とされやすい点を確認する。ここで使うのは生の「価格」の変化率ではなく、投資可能なリターン系列である。

元論文が使っているのは、主として先物・フォワードの超過収益率である。最も流動性の高い先物契約の日次超過収益率を計算し、それを累積してリターン系列を構築している。したがって、単純な現物価格や、データベンダーの連続先物価格の変化率とは必ずしも一致しない。先物には限月交代(ロール)があるため、連続先物価格をそのまま12カ月前と比較すると、バックアジャストの方法によって結果が変わりうる。現物指数を使う場合も、可能な限り配当や利息を含むトータルリターン指数を用いるべきである。

この点は、次回Pythonで実装する際に効いてくるので、先に強調しておく。

過去12カ月リターンとシグナル

市場 $i$ の月次投資収益率を $r_{i,t}$ とすると、過去12カ月の累積収益率は次のように表せる。

R^{(12)}_{i,t} = \prod_{j=0}^{11}(1 + r_{i,t-j}) - 1

売買シグナルは、この累積収益率の符号だけを使う。

s_{i,t} =
\begin{cases}
+1 & (R^{(12)}_{i,t} > 0) \\
0 & (R^{(12)}_{i,t} = 0) \\
-1 & (R^{(12)}_{i,t} < 0)
\end{cases}

$+1$ はロング、$-1$ はショート、$0$ はポジションを持たないことを意味する。

Time_Series_Momentum_-_Slide_5.png

ここが最初のポイントである。基本形では、過去リターンが5%だったか30%だったかという「大きさ」を精密に予測へ使うのではなく、まずプラスかマイナスかだけを判定する。

つまり予測するのは、

来月の収益率が何%になるか

ではなく、

次に取るべき方向は買いか売りか

という粗い方向である。私自身は、この「予測の粒度を意図的に落とす」設計こそが、時系列モメンタムをクオンツ入門に適した題材にしていると考えている。精密な価格予測という難問を避け、より答えやすい問いに置き換えているからである。

6. シグナルとポジションサイズは別物

ここはクオンツ戦略を設計するうえで、最も混同しやすいポイントである。

  • シグナル: 買うのか、売るのか、ポジションを持たないのか(方向の判断)
  • ポジションサイズ: どれだけの金額を持つのか、どれだけのリスクを取るのか(量の判断)

同じロングシグナルであっても、値動きの大きい原油と、値動きの小さい債券に同じ想定元本を持つと、実際に取っているリスクは大きく異なる。原油が1日で3%動く一方、債券は0.3%しか動かないなら、同じ想定元本でも損益のブレは10倍違う。

そのため、売買方向を決めた後に、リスクに応じてポジション量を決めるという別の工程が必要になる。方向と量を分けて設計する――これがクオンツ戦略の基本的な考え方である。

Time_Series_Momentum_-_Slide_6.png

7. ステップ2――ボラティリティでポジションを調整する

市場 $i$ のポジションの基本式は次のとおりである。

w_{i,t} = s_{i,t} \times \frac{\sigma_{\text{target}}}{\hat{\sigma}_{i,t}}
  • $w_{i,t}$: 市場 $i$ に対する想定元本エクスポージャー(運用資産を1とした倍率)
  • $s_{i,t}$: 売買シグナル($+1$、$0$、$-1$)
  • $\sigma_{\text{target}}$: 市場単体の目標ボラティリティ
  • $\hat{\sigma}_{i,t}$: その市場の推定(事前)ボラティリティ

ここで $w_{i,t}$ は「投資金額」ではない点に注意してほしい。たとえば、

  • $w = 0.5$: 運用資産の50%相当のロング想定元本
  • $w = -1.0$: 運用資産の100%相当のショート想定元本
  • $w = 2.0$: 運用資産の200%相当のロング想定元本

を意味する。先物の場合、200%の想定元本を持つために現金を200%支払うわけではない。必要証拠金と想定元本は別物である。

式の意味は単純で、

  • ボラティリティが高い市場では、エクスポージャーを小さくする
  • ボラティリティが低い市場では、エクスポージャーを大きくする

言い換えると、

想定元本を平等にするのではなく、市場単体で見た損益変動の大きさをなるべくそろえる。

Time_Series_Momentum_-_Slide_7.png

これがボラティリティ調整の目的である。なお、逆ボラティリティ配分でそろうのは、厳密には各市場を単体で見た事前ボラティリティである。市場間の相関を考慮したポートフォリオ全体のリスク寄与が等しくなるわけではない。また、ここで計算した $w_{i,t}$ は最終的なポートフォリオ配分ではなく、市場ごとの基本エクスポージャーである(合成は第9節で扱う)。

注意点

ただし、この仕組みには落とし穴もある。

  • 推定ボラティリティ $\hat{\sigma}_{i,t}$ にも未来のデータを使ってはいけない(後述のバックテスト原則と同じ)
  • ボラティリティが極端に低い局面では、式の分母が小さくなり、ポジションが過大になる
  • そのため実運用では、レバレッジ上限やポジション上限を必ず設ける

「ボラティリティ調整をすれば安全」というわけではない点は強調しておきたい。

8. 簡単な計算例

教育用に、市場単体の目標ボラティリティを10%と設定する(後述する論文の40%とは別物である)。

市場 過去12カ月リターン 推定ボラティリティ シグナル 基本エクスポージャー
株価指数 +15% 20% +1 +0.5
-8% 10% -1 -1.0

計算は次のとおり。

株価指数:

+1 \times \frac{10\%}{20\%} = +0.5

金:

-1 \times \frac{10\%}{10\%} = -1.0

株価指数の +0.5 は「運用資産の50%相当のロング想定元本」、金の -1.0 は「運用資産の100%相当のショート想定元本」を意味する。

この例から分かるのは、過去リターンの大きさだけでエクスポージャーを決めているわけではないという点である。株価指数の上昇率(+15%)は金の下落率(-8%)より大きいが、株価指数のボラティリティが高いため、エクスポージャーはむしろ小さくなる。方向はシグナルが決め、量はリスクが決める。この分業が数値で確認できる。

9. ステップ3――複数の市場へ分散する

時系列モメンタムは、一つの市場だけに適用するよりも、複数市場へ適用することに重要な意味がある。対象となる資産クラスの例は次のとおりである。

  • 株価指数
  • 国債
  • 通貨
  • 商品(エネルギー、金属、農産物など)

なぜ分散が必要か

一つの市場が横ばいで小さな損失を出し続けていても、別の市場では大きなトレンドが発生している可能性がある。したがって、この戦略の考え方は、

次にどの市場でトレンドが起きるかを正確に当てるのではなく、
多くの市場を観測し、発生したトレンドを捉える

というものである。トレンドの発生場所とタイミングは予測しない。網を広く張っておく、という発想に近い。

Time_Series_Momentum_-_Slide_8.png

冒頭で触れたとおり、私が自分のボットをマルチカレンシーからマルチアセットへ拡張しようとしている理由も、ここにある。通貨ペアだけを見ていると、通貨市場全体が方向感を失った期間には打つ手がない。株価指数、債券、商品まで観測対象を広げれば、どこかでトレンドが発生している確率を高められる――と考えている。

各市場をどう合成するか

論文に近い最も単純な合成は、ボラティリティ調整済みの各市場エクスポージャーを等ウェイトで平均する方法である。

r^{\text{portfolio}}_{t+1} = \frac{1}{N_t}\sum_{i=1}^{N_t} w_{i,t}\, r_{i,t+1}
  • $N_t$: 時点 $t$ で利用可能な市場数
  • $w_{i,t}$: 各市場のボラティリティ調整済みエクスポージャー
  • $r_{i,t+1}$: 翌月のリターン

元論文も、各銘柄をボラティリティ調整した後、利用可能な銘柄を等ウェイトで平均している。

均等配分だけでは足りない場合がある

ただし、単純に全銘柄を均等平均するだけでは、市場間の相関や共通リスクを十分に管理できない場合がある。たとえば複数の株価指数を同時にロングしていれば、それらは互いに強く相関しており、見かけの分散ほどリスクは減っていない。また銘柄単位の等ウェイトでは、24銘柄ある商品先物の合計ウェイトが、9銘柄しかない株価指数より大きくなりやすい。

そのため実務では、(1) 各市場を逆ボラティリティで調整し、(2) 資産クラス内で平均し、(3) 株式・債券・通貨・商品を均等または所定のリスク比率で合成し、(4) 最後にポートフォリオ全体を目標ボラティリティへ調整する、という多段階の構築も考えられる。

発展形では、次の要素も考慮することになる。

  • 市場間の相関
  • 資産クラス別のリスク配分
  • ポートフォリオ全体の目標ボラティリティ
  • 最大レバレッジ
  • 特定資産への集中上限

第3部 なぜ機能し、どこで失敗するか

10. なぜトレンドが続くのか――複数の仮説

「そもそもなぜ価格の方向が続くのか」という問いに対しては、原因を一つに断定せず、複数の仮説が提示されている。

Time_Series_Momentum_-_Slide_10.png

仮説1: 情報が価格へゆっくり反映される。 経済環境や金融政策が変化しても、すべての投資家が同時に反応するわけではない。情報が徐々に価格へ反映されることで、価格方向が継続する可能性がある。

仮説2: 投資家の行動バイアス。 新しい情報を過小評価する、過去の価格に固執する、利益を早く確定し損失を長く保有する、周囲の投資家と同じ方向へ動く――こうした行動が、初期の過小反応とその後の過剰反応を生むという説明である。論文も、短中期の継続と長期の部分的反転を、この種のセンチメント理論と整合的だと論じている。

仮説3: ヘッジ需要とリスクプレミアム。 企業や商品生産者などは、利益最大化だけではなく、事業リスクを減らすために先物を売買する。その反対側を引き受ける投資家(投機家)が、リスクを負担する対価を得ている可能性がある。論文のCFTCポジションデータの分析では、投機家が平均的にトレンド方向へポジションを取り、ヘッジャーがその反対側を取る傾向が報告されている。この結果は、投機家がヘッジ需要や流動性需要を引き受ける対価として収益を得ている可能性と整合的である。ただし、投機家・ヘッジャーの分類にはノイズがあり、ポジションの関連性だけで「誰が誰に利益を支払ったか」を確定できるわけではない。論文自身も慎重な表現を使っている。

いずれも「これが原因である」と断定できるものではない。行動バイアス、情報の遅い反映、ヘッジ需要など、複数の説明が考えられている、というのが誠実な表現だと考えている。

11. 時系列モメンタムが苦手な相場

どんな戦略にも弱点がある。時系列モメンタムが損失を出しやすい典型的な状況を挙げる。

Time_Series_Momentum_-_Slide_11.png

横ばい相場

方向が頻繁に入れ替わると、買った直後に下落し、売った直後に上昇する。この状態では小さな損失が繰り返される。いわゆる「往復ビンタ」である。

急激な相場反転

トレンドを確認してから売買するため、必ず一定の遅れがある。大幅下落後の急反発や、大幅上昇後の急落では、古い方向のポジションを持ったまま反転に巻き込まれ、大きな損失が発生する可能性がある。

ボラティリティの急変

過去のボラティリティが低いと、エクスポージャーが大きくなる。その直後に市場が急変すると、想定以上の損失が発生する。ボラティリティ調整だけでは、急激なジャンプや市場間の相関上昇を十分に防げない。

取引コストが高い市場

売買方向が頻繁に変わると、手数料やスプレッドが利益を削る。バックテストで利益が出ていても、コスト控除後には消える場合がある。

ここで押さえておきたいこと

時系列モメンタムは、必ずしも高い勝率を目指す戦略ではない。
典型的には、横ばい相場で小さな損失を重ねる一方、持続的なトレンドが発生した局面で大きな利益を得ることを狙う戦略である。

ただし、必ずこの損益分布になるとは限らない。勝率や損益分布は、シグナルの仕様、売買頻度、対象市場、コストによって異なる。勝率が5割を下回っても戦略として成立する場合がある、という損益構造を理解せずに運用を始めると、連敗の途中で耐えられなくなる。

12. 論文の「40%ボラティリティ」をどう理解するか

論文を読むと、各銘柄のポジションを年率40%という高い事前ボラティリティへスケーリングしている箇所がある。この数値を見て「そんなにリスクを取るのか」と驚くかもしれないが、二つの点を押さえておきたい。

第一に、40%は各銘柄の単体ポジションに設定した事前年率ボラティリティであり、分散ポートフォリオ全体の目標ボラティリティではない。論文では、各銘柄を40%へスケーリングした後に全銘柄を等ウェイトで平均しており、完成した分散TSMOMポートフォリオの実現年率ボラティリティは、1985~2009年の標本で約12%だった。分散効果によって、単体の40%よりはるかに低いリスク水準に落ち着いている。

第二に、この40%は銘柄間の比較を行いやすくするための正規化であり、個人投資家がそのまま使うべき推奨値ではない

重要なのは40%という数値ではなく、

値動きの大きい市場を小さく持ち、値動きの小さい市場を大きく持つ、というリスク調整の構造

である。実運用では、より低い目標ボラティリティを設定し、レバレッジ上限とポジション上限を設け、ポートフォリオ全体の実現ボラティリティを継続的に確認する必要がある。

第4部 どう検証するか

13. バックテストの基本手順

戦略を思いついたら、過去データで検証する。ここで最も重要なのは時間の順序である。

  1. 月末時点までの価格データを取得する
  2. 過去12カ月リターンを計算する
  3. 同じ時点までのデータでボラティリティを推定する
  4. 翌月のポジションを決める
  5. 翌月のリターンで損益を計算する
  6. 月末に再計算する

原則は一つだけである。

今日までの情報で、明日以降のポジションを決める。

当月末の価格を使って、すでに始まっている当月の損益を計算してはいけない。これを破ると「未来の情報を使ったバックテスト」(ルックアヘッドバイアス)になり、実際には得られない好成績が出てしまう。

Time_Series_Momentum_-_Slide_12.png

バックテストで確認すべき項目

データと実装

  • 現物価格、トータルリターン、先物超過収益率のどれを使っているか
  • 連続先物の接続方法とロールルールは明確か
  • シグナル計算用の価格と、損益計算用のリターンが整合しているか
  • 未来の価格を使っていないか(シグナルとリターンを1期間ずらしているか)
  • 未完成の価格データや、不適切な欠損値補完を使っていないか
  • 銘柄の開始・終了や上場廃止を含め、サバイバーシップ・バイアスがないか
  • 世界各市場の時差と月末時刻をどうそろえるか、価格確定後のどの時点で発注する想定か
  • 為替換算を正しく行っているか

取引・保有条件

ここで、先物の「ロール」に関わる二つの概念を区別しておきたい。ロール時の取引コスト(手数料、スプレッド、スリッページ)は明確なコストである。一方、ロール収益・ロール損失(コンタンゴやバックワーデーションなど先物カーブの形状から生じるキャリー)は手数料ではなく、先物リターンを構成する一部である。元論文も先物収益を価格変化とロール収益に分解している。両者を混同しないこと。

  • 売買手数料、ビッド・アスク・スプレッド、スリッページ
  • 先物ロール時の売買コスト
  • 先物カーブから生じるロール収益・損失(キャリー)――コストではなくリターンの構成要素として扱う
  • 証拠金・担保資金の利息、レバレッジの資金調達コスト
  • 現物やETFをショートする場合の借株料
  • 税金は投資家ごとに異なるため、戦略成績とは分けて税引後分析を行う

ポートフォリオとリスク

  • 年率ボラティリティ、最大ドローダウン
  • $w_{i,t}$ をそのまま合計するのか、銘柄数で割るのか。資産クラス内と資産クラス間をどう配分するか
  • ポートフォリオ全体を再度ボラティリティ調整するか
  • ボラティリティ下限、ポジション上限、総想定元本上限
  • レバレッジ、証拠金使用率、ストレス時の追加証拠金
  • 特定市場への集中、市場間の相関

14. 評価指標

最低限、次の指標を見る習慣をつけたい。

指標 確認する内容
年率リターン 1年あたりの収益。算術平均の年率換算か、幾何平均(CAGR)かを明記する
年率ボラティリティ リターンの変動の大きさ
シャープレシオ 取ったリスクに対する収益
最大ドローダウン 過去の高値からの最大下落
勝率 利益になった期間の割合
損益比 平均利益と平均損失の関係
売買回転率 どの程度頻繁に売買したか
コスト控除後リターン 実際の運用に近い収益

強調したいのは、勝率だけで戦略を評価しないことである。時系列モメンタムでは、勝率が低くても、利益トレードが損失トレードより大きければ、戦略全体として利益になる可能性がある。勝率と損益比はセットで見る。

15. 比較対象を用意する

時系列モメンタムのバックテスト結果を単体で示しても、その成績が本当に優れているかは判断できない。必ず比較対象(ベンチマーク)を用意する。

  1. 現金・短期国債の保有
  2. 対象資産の単純な買い持ち(バイ・アンド・ホールド)
  3. 常時ロング + 逆ボラティリティ調整(時系列モメンタムと同じボラティリティ調整を行うが、方向シグナルは使わない)
  4. 時系列モメンタム + ボラティリティ調整なし(過去12カ月の符号だけを使う)
  5. 時系列モメンタム + 逆ボラティリティ調整
  6. 複数市場へ分散した戦略
  7. すべてを同じポートフォリオ・ボラティリティへ再調整した比較
  8. 取引コスト控除後の比較

Time_Series_Momentum_-_Slide_13.png

図では要点を3つの階層に簡略化しているが、考え方は同じである。下の階層から一段ずつ要素を足し、どの部品が成績に寄与したのかを切り分けていく。

特に重要なのが3番と7番である。

3番の「常時ロング + 同じボラティリティ調整」を比較に入れないと、成績が方向シグナルによるものか、単にボラティリティ調整(低ボラティリティ時にリスクを増やしたこと)によるものかを区別できない。元論文も、各銘柄を同じリスクへ調整した受動的ロング戦略と比較している。後続研究では、TSMOMの成績のどの部分が方向シグナルによるもので、どの部分がボラティリティ・スケーリングや時変的なネットロング・エクスポージャーによるものかが議論されており、成績の要因分解は現在も重要な論点である。

7番が必要なのは、リスク水準が異なる戦略をリターンだけで比較するのは適切ではないためである。なお、論文の主要図表のシャープレシオはグロス(コスト控除前)で示されている点にも注意したい。

この比較によって、次の問いに答えられる。

  • 利益は市場全体の上昇によるものではないか
  • 売買方向の判定に効果があったのか
  • ボラティリティ調整に効果があったのか
  • 複数市場への分散に効果があったのか
  • 取引コストを引いても成績が残るのか

要素を一つずつ足しながら比較することで、「どの部品が効いているのか」を分解して確認できる。単一のバックテスト結果だけで判断しないことが重要である。

16. 最小限のPython実装スケルトン

ここまでの内容を、Pythonコードの形でまとめる。実データの取得やコストモデルは省略した骨組みだが、記事で説明した処理の順序と、ルックアヘッド防止のための shift(1) の位置を、コードとコメントで確認してほしい。

import numpy as np
import pandas as pd

# =============================================================
# 前提となる入力データ
# -------------------------------------------------------------
# returns: 月次の「投資可能な」リターン (DataFrame)
#   - 行: 月末日付、列: 市場(銘柄)
#   - 生の価格変化率ではなく、先物ならロールを含む超過収益率、
#     現物指数なら配当込みトータルリターンを使う(第5節参照)
# =============================================================

# --- パラメータ(教育用の設定。最適値という意味ではない) ---
LOOKBACK = 12        # シグナル判定期間(カ月)
VOL_WINDOW = 12      # ボラティリティ推定期間(カ月)
SIGMA_TARGET = 0.10  # 市場単体の目標ボラティリティ(年率10%)
MAX_EXPOSURE = 2.0   # 市場単体の想定元本上限(運用資産の200%)
COST_RATE = 0.0005   # 片道の取引コスト(想定元本に対する比率、仮の値)


def backtest_tsmom(returns: pd.DataFrame) -> pd.Series:
    """時系列モメンタムの最小構成バックテスト。

    月次ポートフォリオリターン(コスト控除後)の系列を返す。
    """

    # -------------------------------------------------------------
    # ステップ1: 過去12カ月の累積リターンを計算する(第5節)
    #   R(12) = Π(1 + r) - 1
    #   時点tの値は、tを含む過去12カ月のデータだけから計算される
    # -------------------------------------------------------------
    cum_return_12m = (1.0 + returns).rolling(LOOKBACK).apply(
        np.prod, raw=True
    ) - 1.0

    # -------------------------------------------------------------
    # ステップ2: 符号だけを取り出してシグナルにする(第5節)
    #   +1: ロング / -1: ショート / 0: ポジションなし
    # -------------------------------------------------------------
    signal = np.sign(cum_return_12m)

    # -------------------------------------------------------------
    # ステップ3: 過去データだけでボラティリティを推定する(第7節)
    #   月次リターンの標準偏差を年率換算(×√12)
    #   ここでも rolling なので、時点tの推定に未来のデータは入らない
    # -------------------------------------------------------------
    sigma_hat = returns.rolling(VOL_WINDOW).std() * np.sqrt(12)

    # -------------------------------------------------------------
    # ステップ4: 逆ボラティリティでエクスポージャーを決める(第7節)
    #   exposure = signal × (目標ボラ ÷ 推定ボラ)
    #   値は「運用資産を1とした想定元本の倍率」であり、投資金額そのもの
    #   ではない(第7節)。ボラが極端に低いと分母が小さくなり
    #   エクスポージャーが跳ね上がるため、次のステップで上限を掛ける
    # -------------------------------------------------------------
    exposure = signal * (SIGMA_TARGET / sigma_hat)

    # -------------------------------------------------------------
    # ステップ5: ポジション上限を適用する(第7節の注意点)
    #   実運用ではポートフォリオ全体のレバレッジ上限も別途設ける
    # -------------------------------------------------------------
    exposure = exposure.clip(lower=-MAX_EXPOSURE, upper=MAX_EXPOSURE)

    # -------------------------------------------------------------
    # ステップ6: ルックアヘッドを防ぐ ―― 本記事で最も重要な1行
    #   「今日までの情報で、明日以降のポジションを決める」(第13節)
    #   t月末に計算したエクスポージャーで保有するのは t+1月。
    #   shift(1) により、当月のリターンを当月のシグナルで
    #   取ってしまう誤りを防ぐ
    # -------------------------------------------------------------
    position = exposure.shift(1)

    # -------------------------------------------------------------
    # ステップ7: 各市場の損益を等ウェイトで平均する(第9節)
    #   r_portfolio = (1/N) Σ w_i × r_i
    #   その時点で利用可能な(NaNでない)市場数で平均する。
    #   資産クラス配分を行う場合はここを多段階に置き換える
    # -------------------------------------------------------------
    market_pnl = position * returns
    gross_return = market_pnl.mean(axis=1, skipna=True)

    # -------------------------------------------------------------
    # ステップ8: 取引コストを差し引く(第13節)
    #   ポジションの変化量(売買した想定元本)にコスト率を掛ける。
    #   実際にはスプレッド、スリッページ、ロール時の売買コストなどを
    #   市場ごとにモデル化する必要がある(ここでは一律の仮定)
    # -------------------------------------------------------------
    turnover = position.diff().abs()
    cost = (turnover * COST_RATE).mean(axis=1, skipna=True)
    net_return = gross_return - cost

    # ステップ9: 翌月も同じ計算を繰り返す
    #   → rolling と shift で全期間分が一括計算されている

    return net_return

このコードで伝えたいのは、クオンツ戦略とは複雑なAIモデルを使うことではない、という点である。

市場に関する仮説を、誰が実行しても同じ結果になる再現可能な手順へ変換すること。

これがクオンツの基本である。時系列モメンタムはその最小構成の教材として優れていると考えている。

なお、このスケルトンはあくまで構造を示すためのものである。実データで検証する際は、第13節のチェックリスト(リターン系列の構築方法、ロールの扱い、サバイバーシップ・バイアス、コストモデルなど)を一つずつ潰していく必要がある。

17. より実務的な発展形

本記事では深掘りしないが、標準形を理解した後の発展テーマを挙げておく。

  • 3カ月、6カ月、9カ月、12カ月シグナルの合成
  • 移動平均やブレイクアウトによるトレンド判定
  • シグナルの連続値化(符号だけでなく強さを使う)
  • ボラティリティ推定方法の比較(単純標準偏差、EWMAなど)
  • 複数市場間の相関調整、リスクパリティ
  • ロングのみとロング・ショートの比較
  • Walk-Forward検証(月次・1カ月保有の本戦略なら、まずこちらから)、Purged Cross-Validation(保有期間が重複するラベルを扱う場合に有用)
  • パラメータ感応度分析(12カ月を変えても傾向が残るか)
  • 取引コストに対する頑健性、危機局面での性能分析

特にパラメータ感応度は重要である。過去12カ月という設定は代表例にすぎず、期間を変えても傾向が残るかを確認しなければ、単なるカーブフィッティングと区別がつかない。

まとめ

時系列モメンタムの売買ルールは単純である。過去に上昇していればロング、下落していればショートする。

しかし、クオンツ戦略として重要なのは売買方向だけではない。市場ごとのボラティリティに応じてポジション量を調整し、株式、債券、通貨、商品などの複数市場へ分散し、取引コストを含めて検証する必要がある。

時系列モメンタムの代表的な標準形は、次の三つから構成される。

方向を測る。リスクをそろえる。市場を分散する。

Time_Series_Momentum_-_Slide_14.png

時系列モメンタムは、未来の価格を正確に予言する戦略ではない。いつ、どの市場で発生するか分からない大きなトレンドを、一定のルールで捉えることを目的とする戦略である。そして過去の研究で傾向が報告されているとはいえ、将来の収益を保証するものではない。実運用ではコスト、執行条件、リスク管理を含めて、自分のデータで検証することが出発点になる。

次回は、この標準形をPythonで実装し、実データでバックテストする予定である。その先で、自分の自動売買システムへのマルチアセット・トレンドフォローの組み込みについても、検証結果を交えて書いていきたいと考えている。


参考文献

本記事は論文の完全な再現ではなく、過去リターンの符号による売買方向、ボラティリティによるポジション調整、複数市場の分散、過去データによる検証という基本構造を入門的に説明したものである。


免責事項: 本記事は情報提供を目的としたものであり、特定の金融商品の売買を推奨するものではありません。投資判断はご自身の責任で行ってください。

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?