この記事では移動平均線(SMA/EMA)の上位互換「カルマンフィルター」の使い方を解説していきます。
カルマンフィルターとは?
カルマンフィルターは、**「ノイズだらけのデータから、本来あるべき『真の姿』を推定するための数学的な手法」**です。
FXの文脈で言えば、細かくギザギザ動く不規則な価格チャートから、ノイズが取り除かれた滑らかな「基調トレンド」を抽出するためのツールと考えることができます。
車のGPSが、衛星からの不安定な信号(ノイズ)を受け取りながらも、滑らかに自車位置を地図上に表示できるのも、このカルマンフィルターの応用例です。
FXでカルマンフィルターが果たす3つの主な役割
FXトレーディングにおいて、カルマンフィルターは主に以下の3つの目的で使われます。
1. 価格の平滑化(スムージング)
- 目的: 価格チャートの細かなノイズ(ダマシ)を取り除き、トレンドをより明確にする。
- 仕組み: カルマンフィルターは、現在の価格(観測値)が「ノイズを含んでいる」ことを前提とします。そして、「今の価格は、前の価格からこれくらい動くはずだ」という予測と、実際に観測された価格をうまく融合させて、より確からしい「真の価格」を推定します。
- 移動平均線との違い:
- ラグ(遅延)が少ない: 単純移動平均線(SMA)や指数平滑移動平均線(EMA)は、過去のデータに大きく依存するため、価格の急な変化に対する反応が遅れがちです。カルマンフィルターは「予測→観測→修正」というサイクルを繰り返すため、価格変動への追従性が高く、ラグが少ない平滑化が可能です。
- ダイナミクス(動き)を考慮: カルマンフィルターは、単に価格を平均化するだけでなく、「価格の速度(トレンドの勢い)」や「加速度」といったダイナミクス(動きの特性)もモデルに組み込むことができます。これにより、相場の勢いを考慮した高度な平滑化が実現できます。
2. 将来価格の予測
- 目的: 次の足の価格がどうなるかを予測する。
- 仕組み: カルマンフィルターは「予測」と「修正」の2つのステップを繰り返します。
- 予測ステップ: 現在の状態(価格や速度)から、次の時点の状態を予測します。
- 修正ステップ: 実際に観測された次の時点の価格を使って、予測値を修正し、より正確な現在の状態を推定します。
この「予測ステップ」で得られる値が、将来価格の予測値として利用できます。多くの自動売買システムでは、この予測価格と現在の価格を比較して、売買シグナルを生成します。
3. ペアトレーディング(統計的裁定取引)への応用
- 目的: 相関関係にある2つの通貨ペア(例: EUR/USDとGBP/USD)の価格差(スプレッド)の挙動を分析する。
- 仕組み: 2つの通貨ペアの価格差は、通常、一定の範囲で推移し、平均値に回帰する傾向があります。しかし、この価格差の時系列データもノイズを含んでいます。カルマンフィルターを使ってこの価格差を平滑化し、「真の価格差」を推定することで、価格差が異常に拡大・縮小したタイミングを正確に捉え、裁定取引のシグナルとして利用できます。
メリットとデメリット
メリット
- ラグ(遅延)が少ない: 移動平均線に比べて価格への追従性が高く、トレンド転換を早期に捉えられる可能性があります。
- ノイズ除去性能が高い: 数学的に最適な方法でノイズを除去するため、ダマシのシグナルを減らし、より本質的なトレンドを捉えられます。
- 柔軟性が高い: 価格だけでなく、「速度」や「加速度」、さらには他のテクニカル指標(RSIなど)を状態として組み込むなど、モデルを自由に拡張できます。
- 予測機能: 平滑化だけでなく、将来価格の短期的な予測も同時に行えるため、取引戦略に応用しやすいです。
デメリット
- 複雑さ: 移動平均線のように単純な計算ではなく、線形代数(行列計算)などの高度な数学的知識が必要です。実装には専門的なライブラリ(Pythonのpykalmanなど)を使うのが一般的です。
- パラメータ設定が難しい: カルマンフィルターの性能は、「プロセスノイズ(モデルの不確かさ)」や「観測ノイズ(測定の不確かさ)」といった内部パラメータに大きく依存します。これらのパラメータを市場に合わせて最適化する必要があり、この調整が非常に難しいとされています。
- 線形性を仮定: 基本的なカルマンフィルターは、システムの動きが線形(単純な比例関係)であることを前提としています。FX市場は非線形な動きをすることが多いため、そのまま適用すると限界があります。(ただし、これを克服するために拡張カルマンフィルター(EKF)やアンセンテッドカルマンフィルター(UKF)といった高度な手法も存在します。)
まとめ
FXにおけるカルマンフィルターは、**「ラグの少ない高機能な移動平均線」**のようなものであり、ノイズを除去してトレンドを明確にしたり、短期的な価格予測を行ったりするための強力なツールです。
その数学的な複雑さから初心者には敷居が高いですが、使いこなせれば、他のトレーダーが使っている標準的なテクニカル指標よりも一歩進んだ分析が可能になり、自動売買モデルの精度を向上させる大きな武器となり得ます。
カルマンフィルターの論文・好成績モデル
以下の論文ではカルマンフィルターのモデル4が優秀なトレード成績を出すことに成功しています。
論文のセクション 4.2 Pseudo code に示されているロジックは非常にシンプルです。
「カルマンフィルター(モデル4)が予測した次の足の価格が、現在の足の終値から一定の値(オフセット)を引いた/足したものを上回るか下回るかで売買を判断する」
具体的には、以下のようになります。
- 買い(Long)の条件:
KalmanFilter(モデル4のパラメータ).Predict[0] > Close[1] + Offset- 意味: カルマンフィルターが予測する「次の足の価格」が、「1本前の足の終値 + オフセット値」よりも大きい場合、買い注文を出す。
- 売り(Short)の条件:
KalmanFilter(モデル4のパラメータ).Predict[0] < Close[1] – Offset- 意味: カルマンフィルターが予測する「次の足の価格」が、「1本前の足の終値 – オフセット値」よりも小さい場合、売り注文を出す。
コード中の要素の解説
- KalmanFilter(Param1,..,ParamN).Predict[0]:
- これは、モデル4の最適化されたパラメータ(Param1からParamNまで)を使って、カルマンフィルターが予測した「次の期間の状態ベクトル」の最初の要素、つまり予測価格を指します。
- Close[1]:
- 「1本前の足の終値」を意味します。リアルタイムで新しい足が確定した瞬間に、その足の終値を使って判断することになります。
- Offset:
- 予測価格と現在価格の差がある程度開いていないとエントリーしないようにするための「閾値」や「フィルター」です。ノイズによる頻繁な売買(いわゆる「シグナルのチャタリング」)を防ぐ役割があります。このOffset値も、バックテストを通じて最適化すべき重要なパラメータの一つです。論文では明示的な値は示されていませんが、存在が示唆されています。
モデル4自体の特徴
このトレードロジックの「心臓部」であるカルマンフィルター(モデル4)は、以下の要素を組み合わせて次の価格を予測しています。
- 短期的な価格要因 (xt1):
- 市場の急な反応や短期的な動きをモデル化します。
- 長期的な価格要因 (xt2):
- より大きなトレンドや基調をモデル化します。
- オシレーター要因 (Kt_d):
- ストキャスティクス・オシレーターに似た考え方で、「過去d期間における価格レンジの中で、現在の価格がどの位置にあるか」を捉えます。
- Kt_d = (現在の終値 – 過去d期間の最安値) / (過去d期間の最高値 – 過去d期間の最安値)
- この値が価格予測の式に組み込まれており、買われすぎ/売られすぎの状態を考慮に入れることができます。
これらの要素を数式(EQ.3.24〜3.27)で組み合わせることで、単なるトレンド追随だけでなく、相場の過熱感(平均回帰の可能性)も加味した、より洗練された価格予測を行っているのがモデル4の最大の特徴です。
Pythonでの実装イメージ
このロジックをMT5と連携させるPythonスクリプトに組み込むと、以下のようになります。
import MetaTrader5 as mt5
import numpy as np
from pykalman import KalmanFilter
import time
# --- モデル4のカルマンフィルターを実装するクラス/関数 ---
# この部分は論文の数式を基に複雑な実装が必要になります。
# ここでは概念的なダミー関数として示します。
def kalman_filter_model4_predict(symbol, timeframe, params):
"""
論文のモデル4に基づいて次の足の価格を予測する関数(ダミー)
実際には、状態遷移行列(phi)、観測行列(H)、制御ベクトル(ct)などを
論文の式(EQ.3.28)に従って構築し、予測ステップを実行する必要があります。
ここでは単純に「現在の価格にランダムな値を加えたもの」を予測値として返します。
※この部分を精緻に実装することがプロジェクトの核となります。
"""
# 実際にはここでMT5から価格データを取得し、
# 論文の数式に基づいて複雑な計算を行います。
tick = mt5.symbol_info_tick(symbol)
if tick is None:
return None
# ダミーの予測値
prediction = tick.last + (np.random.rand() - 0.5) * 0.1
return prediction
# --- メインの取引ロジック ---
def trade_logic_model4():
# --- パラメータ設定 ---
symbol = "USDJPY"
offset = 0.05 # 5銭のオフセット (例)
# モデル4の最適化済みパラメータ (論文のTable 2参照)
# これらはpykalmanのKalmanFilterクラスの引数として渡す
model4_params = {
"p1": 1.00, "p2": 0.40, "p3": 1.20, "p4": 1.00, "p5": 1.00,
"p6": 0.80, "p7": 0.40, "p8": 0.70, "p9": 1.00, "p10": 0.40,
"p11": 0.50, "p12": 0.90, "p13": 0.50, "p14": 0, # N2=0
"p15": 5.00 # d=5
}
# MT5に接続されていることを確認
if not mt5.terminal_info():
print("MT5に接続していません。")
return
# 1. 1本前の足の終値を取得
rates = mt5.copy_rates_from_pos(symbol, mt5.TIMEFRAME_D1, 0, 2)
if rates is None or len(rates) < 2:
print("価格データを取得できませんでした。")
return
previous_close = rates[-1]['close'] # 確定した最新の足の終値 (Close[1]に相当)
# 2. カルマンフィルターで次の価格を予測
predicted_price = kalman_filter_model4_predict(symbol, mt5.TIMEFRAME_D1, model4_params)
if predicted_price is None:
return
print(f"1本前の終値: {previous_close}, 予測価格: {predicted_price:.5f}")
# 3. 売買条件の判定
# 既にポジションがない場合のみエントリー
positions = mt5.positions_get(symbol=symbol)
if len(positions) > 0:
print("既にポジションがあるため、新規注文は見送ります。")
return
if predicted_price > previous_close + offset:
print("買いシグナル")
# ここに買い注文(mt5.order_send)のコードを記述
elif predicted_price < previous_close - offset:
print("売りシグナル")
# ここに売り注文(mt5.order_send)のコードを記述
else:
print("シグナルなし")
# --- メインループ ---
if __name__ == '__main__':
if not mt5.initialize():
print("initialize() failed, error code =", mt5.last_error())
quit()
try:
while True:
# 日足なので、1日に1回実行するなど工夫が必要
trade_logic_model4()
time.sleep(60 * 60 * 24) # 24時間待機
except KeyboardInterrupt:
print("Bot停止")
finally:
mt5.shutdown()
まとめ
モデル4のトレードロジックは以下の通りです。
- 予測: 短期・長期・オシレーターの3つの要素を統合したカルマンフィルター(モデル4)を用いて、次の足の価格を予測する。
- 比較: その予測価格と、1本前の足の終値を比較する。
- 判断:
- 予測価格が「終値+オフセット」を上回れば買い。
- 予測価格が「終値-オフセット」を下回れば売り。
- それ以外は何もしない。
この戦略の強みは、高度な予測モデル(モデル4)によってトレンドの方向性と相場の過熱感の両方を捉え、その予測結果に基づいてシンプルながらも効果的な売買判断を下している点にあります。実装するには、論文の数式を正確にコードに落とし込む数学的・プログラミング的なスキルが求められます。
カルマンフィルターと価格予想モデル「LightGBM」を併用
LightGBMとカルマンフィルターは併用可能であり、しかも非常に強力な組み合わせになり得ます。
両者は異なるアプローチで価格変動を捉えるため、互いの弱点を補い、より洗練された予測モデルを構築できる可能性があります。
各モデルの役割と特徴
まず、それぞれのモデルが何を得意としているかを理解することが重要です。
LightGBM (勾配ブースティング)
- 役割: 多くの特徴量から、非線形な関係性を学習し、将来の値やクラスを予測する。
- 得意なこと:
- 多数のテクニカル指標、経済指標、時間的特徴などを入力として使える。
- 「このパターンの時は上がりやすい」「ボラティリティが高く、かつRSIが低い時は…」といった複雑な条件分岐を自動で学習する。
- 高速に学習・予測できる。
- 弱点:
- ノイズの多いデータに過学習(オーバーフィッティング)しやすい。
- 時系列データの「状態(State)」や「連続性」を直接的にはモデル化しない。(各データポイントをある程度独立したものとして扱う)
カルマンフィルター
- 役割: ノイズを含む観測データから、本来の「真の状態(隠れた状態)」を推定する。
- 得意なこと:
- 価格データのようなノイズの多い時系列データを平滑化(スムージング)し、より滑らかな「基調トレンド」を抽出する。
- 現在の状態から次の状態を予測し、新しい観測データでその予測を修正する、というサイクルを繰り返す。
- 弱点:
- 基本的に線形なシステムを想定している。(非線形に拡張した手法もある)
- LightGBMのように多数の外部特徴量を取り込むのは不得意。主に一つの時系列データ(例:価格)そのものを扱う。
LightGBMとカルマンフィルターの併用戦略
両者を組み合わせることで、「カルマンフィルターでノイズを除去し本質的なトレンドを捉え、その情報をLightGBMの強力な特徴量として利用する」という戦略が実現できます。
主な併用方法は以下の3つです。
戦略1:カルマンフィルターの出力をLightGBMの特徴量にする(最も一般的)
これが最も実践的で効果を期待しやすいアプローチです。
手順:
- カルマンフィルターの適用:
- 終値(close)などの価格時系列データにカルマンフィルターを適用します。
- これにより、ノイズが除去された「平滑化価格」と、その変化率である「速度(トレンドの強さ)」を推定値として得られます。
- 新しい特徴量の生成:
元のデータフレームに、カルマンフィルターから得られた以下の情報を新しい列(特徴量)として追加します。- kf_price: 平滑化された価格
- kf_velocity: 価格の速度(今のトレンドの勢い)
- price_minus_kf: 実際の価格と平滑化価格の差(=ノイズ、または買われすぎ/売られすぎの指標と解釈できる)
- LightGBMの学習:
- 元々のテクニカル指標(移動平均線、RSIなど)に加えて、上記で作成したカルマンフィルター由来の3つの特徴量をLightGBMの学習データに含めます。
なぜ効果的なのか?
- LightGBMはノイズに弱いですが、カルマンフィルターが事前にノイズを処理してくれるため、より本質的なパターンを学習しやすくなります。
- 「現在のトレンドの勢い(kf_velocity)」は、極めて強力な特徴量になり得ます。
- 「価格とトレンドの乖離(price_minus_kf)」は、逆張りのシグナルとして機能する可能性があります。
戦略2:カルマンフィルターを「トレンドフィルター」として使う
LightGBMの予測結果を、カルマンフィルターの示すトレンド方向でフィルタリングする方法です。
手順:
- LightGBMは通常通り、買い/売りの予測シグナルを生成します。
- カルマンフィルターは、現在の相場の大きなトレンド方向(上昇/下降/レンジ)を判定します。
- 最終的な取引判断:
- LightGBMが「買い」と予測し、かつカルマンフィルターが「上昇トレンド」と判定した場合のみ、実際に買い注文を出す。
- LightGBMの売りシグナルも同様に、下降トレンドの時のみ採用する。
なぜ効果的なのか?
- 「順張り」の戦略を徹底でき、小さな逆行で損失を出す「ダマシ」のシグナルを減らすことができます。LightGBMが出す短期的な予測の精度を高める効果が期待できます。
戦略3:LightGBMでカルマンフィルターのパラメータを動的に調整する(上級者向け)
これはより高度なアプローチです。カルマンフィルターの性能は、ノイズの大きさを定義するパラメータ(プロセスノイズ、観測ノイズ)に依存します。このパラメータを固定値にせず、市場の状況に応じて動的に変更する手法です。
手順:
- 市場のボラティリティなどをLightGBMで予測します。
- 予測されたボラティリティに応じて、カルマンフィルターのノイズパラメータを調整します。
- 例:ボラティリティが高い相場では、ノイズが大きいと判断し、観測ノイズの値を大きくする。
- 調整されたパラメータを持つカルマンフィルターを使って価格を平滑化し、特徴量として利用します。
まとめ
- 併用は可能であり、推奨されるアプローチの一つ。
- 役割分担:
- カルマンフィルター: ノイズ除去とトレンドの定量化。
- LightGBM: カルマンフィルターからの情報を含む多くの特徴量を統合し、最終的な売買判断を下す。
- 始め方: まずは**戦略1(カルマンフィルターの出力をLightGBMの特徴量にする)**から試してみるのが最も分かりやすく、効果も出やすいでしょう。
この組み合わせは、モデルのロバスト性(頑健性)を高め、単体で使うよりも安定したパフォーマンスをもたらす可能性を秘めています。ぜひ挑戦してみてください。
カルマンフィルターの関連記事・論文
この論文は、金融時系列データのノイズを除去し、トレンドをより正確に捉えるために「カルマンフィルター(KF)」をテクニカル指標として応用するという研究です。
- 問題意識:
移動平均線は価格の平滑化に役立つが、「ラグ(遅延)」が避けられない。DEMAやTEMAのようなゼロラグ移動平均も存在するが、価格の「ダイナミクス(動きの勢い)」までは捉えられない。 - 提案手法:
もともとミサイル追尾などに使われるカルマンフィルターを応用。KFは、ノイズの多い観測データから、対象の「真の状態(例:価格と価格の変化率)」を最適に推定するアルゴリズムであり、ラグを最小限に抑えつつダイナミクスをモデル化できる。 - 検証:
単純なKFから、トレンドの短期・長期要因やオシレーターの概念を取り入れた複雑なものまで、4種類のKFモデルを構築。S&P500先物データで取引戦略のバックテストを行った。 - 結果と結論:
- KFはDEMAやTEMAといった高性能な移動平均よりも価格への追従性が高く、ラグが少ない。
- 最も洗練された**モデル4(短期/長期要因+オシレーター)**が、年間約4万ドルの利益を上げ、他のモデルを圧倒。
- トレンドフォローとオシレーターの概念をKFに統合することが、極めて有効であることが実証された。
要するに、**「移動平均の代わりに、より高度な数学的ツールであるカルマンフィルターを使えば、ラグが少なくダイナミクスも捉えた、もっと儲かるテクニカル指標が作れる」**ことを示した論文です。
このGitHubリポジトリは、金融時系列データ、特に暗号資産の価格分析に「カルマンフィルター」を応用するためのオープンソース・教育用Pythonコードです。
- 目的:
カルマンフィルターを用いた高度な移動平均(MA)を学習・研究するためのリソースを提供すること。これは投資助言ではなく、あくまで教育目的のコードです。 - 実装されている主な機能:
- 固定QカルマンMA: 最も基本的な、パラメータが固定されたカルマンフィルター。
- ATRベース動的カルマンMA: ATR(ボラティリティ指標)に応じてフィルターの感度(追従性)が動的に変化する、より洗練されたモデル。
- 拡張モデル3カルマンMA: Benhamou(2016)の論文に基づき、トレンドを**「短期要素」と「長期要素」に分解**して追跡する、最も高度なモデル。
- 特徴:
- Benhamou(2016)の論文で提案された高度なモデルを、誰でも使えるPythonコードとして実装。
- 価格の正規化や動的なノイズ調整など、実用上の数値的安定性を高める工夫が盛り込まれている。
- 各手法の特性(追従性 vs 平滑性)や、パラメータ調整のガイドラインが丁寧に解説されている。
要するに、**「カルマンフィルターを使った高機能な移動平均線を、Pythonで手軽に試せる教育用ツールキット」**です。
バックテストデータはこちら。