ドル円が162円台に乗るたびに、僕は「さすがにこれは行き過ぎだろう」と感覚だけで判断していました。。。でも冷静に振り返ると、その「行き過ぎ」の根拠は完全に気分です。以前書いた標準偏差の記事でボラティリティの大きさは数値化できるようになったものの、「今の価格が平均からどれだけ離れているか」を一言で言える指標がないことに気づき、Zスコアを調べてみることにしました。
Zスコアとは何か
Zスコア(標準化得点)は、ある値が平均からどれだけ離れているかを「標準偏差いくつ分か」という共通の単位で表したものです。計算式はシンプルで、対象の値を x、平均を μ、標準偏差を σ とすると、
Z = (x − μ) / σ
で求められます。標準偏差そのものは「バラつきの大きさ」しか教えてくれませんが、Zスコアにすると「今の値は平均よりどれだけ極端か」を−∞〜+∞の共通スケールで比較できるようになります。データが正規分布に近ければ、Zが±2を超えるのは統計的にはかなり珍しい部類(両側で見ると全体の約5%程度)で、経験則として「±2を超えたら行き過ぎ」という目安がよく使われます。
ローリング窓で計算する(落とし穴に注意)
ここで注意が必要なのが、平均と標準偏差をどの期間で計算するかです。全期間のデータを使って平均・標準偏差を出してしまうと、まだ起きていない未来の値まで計算に混ざってしまい、以前書いたルックアヘッドバイアスと同じ問題が発生します。実運用では直近20日や60日など、その時点までのローリング(移動)窓で平均・標準偏差を計算する必要があります。
import yfinance as yf
df = yf.download("JPY=X", period="1y")
close = df["Close"]
window = 20
rolling_mean = close.rolling(window).mean()
rolling_std = close.rolling(window).std()
z_score = (close - rolling_mean) / rolling_std
# 直近のZスコアを確認
print(z_score.tail())
# 閾値超えを検出(±2をひとつの目安に)
oversold = z_score < -2 # 平均より大きく下(円高方向)
overbought = z_score > 2 # 平均より大きく上(円安方向)
投資への応用:平均回帰戦略とペアトレード
Zスコアは平均回帰(ミーンリバーサル)戦略の入口としてよく使われます。「Zが+2を超えたら売り、0付近に戻ったら手仕舞い」というシンプルなルールも作れますし、以前書いたペアトレードの記事のように2銘柄のスプレッドをZスコア化すれば、「割高・割安」を数値で判断する材料にもなります。ただし相場がトレンド方向に強く動いている局面では平均自体がどんどんズレていくので、Zスコアだけで逆張りすると痛い目を見ます。あくまで「レンジ相場かどうか」を見極めた上で使う指標だと理解しています。
まとめ
Zスコアを知って一番良かったのは、「行き過ぎ」を感覚ではなく数字で言えるようになったことです。とはいえ計算窓の取り方やトレンド相場での誤動作など、注意点も多いことが分かりました。次はドル円の20日ローリングZスコアを実際に毎日眺めてみて、自分の「そろそろ行き過ぎ」という感覚とどれくらいズレがあるのか、答え合わせをしてみようと思います。

