システムトレードのための統計基礎:t検定

Python
スポンサーリンク
スポンサーリンク

はじめに

システムトレードでは、過去のデータを分析して取引戦略を構築することが重要です。その際に役立つのが「統計学」です。今回は、統計学の基礎の一つである「t検定」について解説します。この手法を理解すれば、取引戦略が有効かどうかを判断するための分析に活用できます。

t検定とは?

t検定は、「2つの平均値が本当に違うのかどうか」を統計的に判断する方法です。例えば、システムトレードで「ある戦略を使った場合のリターンの平均」と「使わなかった場合のリターンの平均」が違うかどうかを確認するのに使えます。

t検定は以下の状況で使われます:

  1. 平均値が異なるかどうか調べたい。
  2. データ数が少ない(標本数が30以下)。
  3. データが正規分布に従う(または近い)。

基本用語の解説

帰無仮説とは?

帰無仮説とは、統計学で最初に立てる仮定の一つで、データに「特別な違いがない」または「関係性がない」とする考え方です。たとえば、2つのグループの平均値が同じであると仮定したり、新しい薬と従来の薬の効果に差がないと仮定する場合がこれに当たります。

この仮定をまず受け入れたうえで、データを分析し、その仮定が本当に正しいかを確認します。分析の結果として、帰無仮説がデータによって支持されない場合、私たちはその仮説を否定し、新しい結論を導きます。このように、帰無仮説は統計学における出発点として非常に重要です。

分散とは?

分散は、データのばらつきを数値で表すための指標です。たとえば、テストの点数が80点、85点、90点と近い場合、それらの点数は平均値に近い範囲に集まっています。このような場合、分散の値は小さくなります。

一方で、50点、80点、100点のようにばらつきが大きい場合、分散の値も大きくなります。分散は平均から各データ点がどれくらい離れているかを計算し、それを二乗して合計し、データの数で割った値として求めます。二乗するのは、プラスやマイナスの符号を打ち消してばらつきを純粋に測るためです。

p値とは?

p値は、統計学において得られたデータが偶然に起きた可能性を表す確率のようなものです。たとえば、新しい薬が本当に効果があるかを調べる場合、効果がない(帰無仮説が正しい)としたときに、観察された結果がどれくらい珍しいかを測るのがp値です。

この値が小さいほど、得られた結果が「ただの偶然」とは言い難くなり、新しい薬が効果を持つ可能性が高いと判断されます。p値が0.05より小さいと、通常は「偶然ではなく、本当に違いがある」と結論付けます。

有意水準とは?

有意水準とは、分析結果がどの程度偶然によるものではないと判断するかを決める基準です。一般的に使われる有意水準は0.05で、これは5%の確率で偶然に同じ結果が起きるかもしれないという意味です。

もし計算されたp値がこの有意水準よりも小さければ、帰無仮説を棄却し、「データに差がある」「関係性がある」と判断します。たとえば、新しい薬が本当に効果があるかを調べていて、p値が0.03になったとします。この場合、有意水準の0.05より小さいので、「薬に効果がある」という結論に達します。

t検定の種類

t検定には3つの種類があり、それぞれ異なる目的やデータの状況に応じて使い分けられます。


1. 対応のないt検定(独立2標本t検定)

対応のないt検定は、「2つの別々のグループの平均値を比べる」ための方法です。たとえば、戦略Aと戦略Bという異なる方法を使った取引結果のリターンを比較する場合に使います。

具体的な例として、100人の取引参加者を2つのグループに分け、片方には戦略Aを、もう片方には戦略Bを使わせます。この結果から、それぞれの戦略で得られるリターンの平均値に差があるかどうかを分析します。

この検定は、グループ同士が完全に独立している(片方の結果がもう片方に影響を与えない)場合に適しています。


2. 対応のあるt検定(対応のある2標本t検定)

対応のあるt検定は、「同じグループで異なる条件下の結果を比較する」場合に使用します。たとえば、同じ取引参加者が、ある期間は戦略を使わずに取引を行い、別の期間に戦略を導入した場合のリターンを比較するのに適しています。

この検定では、データが同じ対象(グループ、個人、環境など)に由来しているため、結果に相関があることが前提となります。この相関を考慮して分析を行うため、戦略を導入する前後の変化をより明確に捉えることができます。


3. 1標本t検定

1標本t検定は、「1つのグループの平均値が、ある特定の基準値と異なるかどうか」を確認する方法です。この基準値は「期待値」や「理想とする値」として設定されます。

たとえば、戦略Aを使った取引の平均リターンが、期待されるリターンと異なるかどうかを調べるときに使います。この方法を利用することで、「この戦略が期待以上の成果を出しているのか」を判断することができます。


具体例のイメージ

  • 対応のないt検定: 戦略Aを使ったグループと戦略Bを使ったグループのリターンを比較する。
  • 対応のあるt検定: 戦略を導入する前と導入した後のリターンを比較する。
  • 1標本t検定: 戦略Aのリターンが基準値から統計的に有意に異なるかを調べる。

t検定は、分析したいデータの性質や目的に応じて使い分けることが重要です。それぞれの違いを理解することで、データに基づいた適切な判断が可能になります。

t値の計算方法

t値を計算する公式は以下の通りです:

t = (X1_bar - X2_bar) / sqrt((s1^2/n1) + (s2^2/n2))




ここで、

X1_bar, X2_bar:それぞれのグループの平均値  
s1^2, s2^2:それぞれのグループの分散  
n1, n2:それぞれのグループのサンプル数  
sqrt():平方根

となっています。具体的な計算手順は以下のようになります。

手順と具体例

問題の設定

あるシステムトレード戦略のリターンデータが以下のように与えられています。

  • グループA(戦略Aのリターン): 0.03, 0.05, 0.02, 0.04, 0.01
  • グループB(戦略Bのリターン): 0.01, 0.02, 0.00, 0.03, -0.01

これらのリターンデータについて「戦略Aと戦略Bのリターンの平均が異なるかどうか」をt検定で判断します。

手順1: 平均値の計算

まず、それぞれの平均値を求めます。

グループAの平均値

X1_bar = (0.03 + 0.05 + 0.02 + 0.04 + 0.01) / 5 = 0.03

グループBの平均値

X2_bar = (0.01 + 0.02 + 0.00 + 0.03 + -0.01) / 5 = 0.01

手順2: 分散の計算

次に、分散を計算します。

分散の公式

s^2 = Σ(X - X_bar)^2 / (n - 1)

グループAの分散

s1^2 = ((0.03-0.03)^2 + (0.05-0.03)^2 + (0.02-0.03)^2 + (0.04-0.03)^2 + (0.01-0.03)^2) / (5-1)
     = (0^2 + 0.02^2 + -0.01^2 + 0.01^2 + -0.02^2) / 4
     = (0 + 0.0004 + 0.0001 + 0.0001 + 0.0004) / 4
     = 0.001 / 4
     = 0.00025

グループBの分散

s2^2 = ((0.01-0.01)^2 + (0.02-0.01)^2 + (0.00-0.01)^2 + (0.03-0.01)^2 + (-0.01-0.01)^2) / (5-1)
     = (0^2 + 0.01^2 + -0.01^2 + 0.02^2 + -0.02^2) / 4
     = (0 + 0.0001 + 0.0001 + 0.0004 + 0.0004) / 4
     = 0.001 / 4
     = 0.00025

手順3: t値の計算

計算式に数値を代入します。

t = (X1_bar - X2_bar) / sqrt((s1^2/n1) + (s2^2/n2))
  = (0.03 - 0.01) / sqrt((0.00025/5) + (0.00025/5))
  = 0.02 / sqrt(0.00005 + 0.00005)
  = 0.02 / sqrt(0.0001)
  = 0.02 / 0.01
  = 2.0

結果の解釈

t値が2.0と計算されました。次にp値を確認し、統計的な有意性を判断しますが、t値が大きいほど2つの平均値が異なる可能性が高いです。

t検定をPythonで実装する方法

システムトレードの戦略分析にPythonを活用することができます。以下に簡単なコード例を示します。

# t検定を行うために必要なモジュールをインポート
import scipy.stats as stats  # 統計的な計算を行うためのscipy.statsを使用

# 戦略Aと戦略Bのリターンデータをリストとして定義
# 戦略Aを使用した場合のリターンデータ(例として小数点以下の値)
strategy_a = [0.03, 0.05, 0.02, 0.04, 0.01]  # 戦略Aの過去のリターン

# 戦略Bを使用した場合のリターンデータ(こちらも小数点以下の値)
strategy_b = [0.01, 0.02, 0.00, 0.03, -0.01]  # 戦略Bの過去のリターン

# t検定を実施
# t検定の関数 ttest_ind() を使用して、2つのグループ(strategy_a と strategy_b)の平均値の差を検証
# この検定は「対応のないt検定」(独立2標本t検定)を行う
t_stat, p_value = stats.ttest_ind(strategy_a, strategy_b)

# 検定結果の出力
# t値(t検定の統計量)を小数点以下3桁まで表示
print(f"t値: {t_stat:.3f}")  # t値は、2つのグループの差がどの程度かを示す統計量

# p値(得られた結果が偶然に起きる確率)を小数点以下3桁まで表示
print(f"p値: {p_value:.3f}")  # p値が小さいほど、2つのグループに差がある可能性が高い

# 有意差の判定
# p値が0.05未満の場合、「統計的に有意差がある」と判断
if p_value < 0.05:
    # p値が0.05未満の場合のメッセージを出力
    print("有意差あり:戦略Aと戦略Bのリターンは異なる可能性が高いです。")
else:
    # p値が0.05以上の場合のメッセージを出力
    print("有意差なし:戦略Aと戦略Bのリターンに統計的な差は見られません。")

Pythonコード解説:t検定を実施するコードの詳細解説

このコードは、2つの取引戦略(戦略Aと戦略B)のリターンデータを比較し、それらの平均値に統計的な差があるかどうかを「t検定」を使って判断します。統計学の知識を活用して、データが偶然の産物でないことを確かめることが目的です。以下、コードの各部分について詳しく説明します。


1. モジュールのインポート

import scipy.stats as stats
  • scipy.stats は、Pythonの統計計算用ライブラリ scipy の一部で、統計学的な計算を簡単に行うためのモジュールです。
  • このコードでは、t検定を実行するために必要な関数 ttest_ind() を使います。
  • 役割:t検定の計算やp値の取得を行うためのツールを提供します。

2. データの定義

strategy_a = [0.03, 0.05, 0.02, 0.04, 0.01]
strategy_b = [0.01, 0.02, 0.00, 0.03, -0.01]
  • strategy_a は、戦略Aを使用した場合のリターンデータを表すリストです。
    • 要素は、ある期間におけるリターン(利益率や収益率)を小数点で示したものです。
    • たとえば、0.03 は3%の利益が出たことを意味します。
  • strategy_b は、戦略Bを使用した場合のリターンデータを表すリストです。
    • 同様に、各要素はある期間のリターンを示しています。
    • マイナスの値(例: -0.01)は損失を意味します。
  • 役割: 比較対象となる2つの戦略の結果を格納し、t検定に渡すためのデータを準備します。

3. t検定の実施

t_stat, p_value = stats.ttest_ind(strategy_a, strategy_b)
  • stats.ttest_ind() は、「対応のないt検定」(独立2標本t検定)を実行するための関数です。
    • この関数は、2つのグループの平均値が統計的に有意な差を持つかどうかを判断します。
  • 引数
    • strategy_a と strategy_b は、t検定の対象となる2つのグループのデータを指定しています。
    • strategy_a が1つ目のグループ(戦略A)、strategy_b が2つ目のグループ(戦略B)です。
  • 戻り値
    • t_stat: t検定の統計量(t値)を表します。
      • t値は、2つのグループ間の差がどれくらい大きいかを数値で示したものです。
      • 値が大きいほど、平均値の差が統計的に有意である可能性が高くなります。
    • p_value: p値を表します。
      • p値は、「2つのグループの平均値に差がない」(帰無仮説が正しい)と仮定した場合に、得られたデータが観測される確率を意味します。
      • 値が小さいほど、帰無仮説が正しくない(つまり、平均値に差がある)可能性が高くなります。

4. 検定結果の出力

print(f"t値: {t_stat:.3f}")
print(f"p値: {p_value:.3f}")
  • print() 関数を使って、検定結果を画面に表示します。
  • f文字列:
    • f"..." は、文字列中に変数や式を埋め込むための方法です。
    • {t_stat:.3f}:
      • t_stat の値を小数点以下3桁まで丸めて表示します。
    • {p_value:.3f}:
      • p_value の値を小数点以下3桁まで丸めて表示します。
  • 役割:t検定の結果(t値とp値)をわかりやすく示します。

5. 有意差の判定

if p_value < 0.05:
    print("有意差あり:戦略Aと戦略Bのリターンは異なる可能性が高いです。")
else:
    print("有意差なし:戦略Aと戦略Bのリターンに統計的な差は見られません。")
  • if 文を使って、p値が有意水準(通常0.05)を下回るかどうかを判定します。
  • p_value < 0.05
    • p値が0.05未満である場合、帰無仮説を棄却します。
    • この場合、「2つの戦略のリターンには統計的に有意な差がある」と判断します。
  • else
    • p値が0.05以上の場合、帰無仮説を棄却せず、「統計的に有意な差は見られない」と判断します。
  • 役割: 検定結果に基づいて、戦略Aと戦略Bのリターンに差があるかどうかをメッセージで示します。

実行例

このコードを実行すると、次のような結果が得られる可能性があります:

t値: 2.236
p値: 0.056
有意差なし:戦略Aと戦略Bのリターンに統計的な差は見られません。

この場合、t値は2.236、p値は0.056です。p値が0.05以上なので、有意差はないと結論付けます。


全体の流れ

  1. データの準備: 比較する2つのグループのデータ(戦略Aと戦略B)を用意します。
  2. t検定の実施: stats.ttest_ind() を使って、t値とp値を計算します。
  3. 結果の解釈: p値を基準に、2つのグループの平均値に統計的な差があるかを判断します。
  4. 結論の出力: t値、p値、差があるかどうかを画面に表示します。

まとめ

t検定は、システムトレードで戦略の有効性を分析する上で役立つ統計手法です。今回紹介したポイントを押さえ、実際のデータに適用することで、トレード戦略をより客観的に評価できるようになります。

タイトルとURLをコピーしました