ウォークフォワード分析とは?Pythonで戦略を自動評価するWebアプリを作成

カーブフィッティングは簡単に発生する

株やFX、先物取引で「過去に儲かった戦略」が、未来でも通用するとは限りません。

カーブフィッティング,つまり有意性のないトレードロジックを有意性があると誤認識する現象は,普通のバックテストだと下記のように簡単に発生します。

💡 実例的な違い(目安)

分析手法フィッティングのリスク実運用成績との乖離
通常のバックテスト高い(70~90%が過剰最適化)大きく乖離しやすい
ウォークフォワード分析中~低(30~50%に減少)実運用に近い成績

※これは目安であり、戦略の複雑さや市場のノイズによって変動します。


この記事では、PythonとFlask、Optunaを使って、トレード戦略をウォークフォワード分析で検証できる無料Webアプリをご紹介します。

ウォークフォワード分析とは?

ウォークフォワード分析(Walk Forward Analysis)は、過去のデータを訓練期間とテスト期間に分けて、戦略の「本番での再現性」をチェックする方法です。

このアプリでできること

  • ブラウザ上で簡単にパラメータ入力
  • 戦略を自動で最適化(Optuna使用)
  • 成績をリアルタイムで表示
  • CSVに自動保存

無料で誰でも使用可能なWeb アプリですので,ぜひお試しを。

https://my-flask-app-mksr.onrender.com

Qiitaでもシステムの技術的な側面を紹介をしています。

FastAPI + Optunaでウォークフォワード分析Webアプリを作ってみた - Qiita
📌 はじめに 株式や先物のトレード戦略を作る際、過剰最適化を避けるために「ウォークフォワード分析(WFA)」が有効です。 今回は、Pythonのフレームワーク FastAPI と最適化ライブラリ Optuna を使って、 誰でもブラウザから...

Noteでもアプリの使用方法などをまとめています。

記事編集 | note

実際の検証結果

前提条件

スタートの資産は1、損切りは価格の1/15、ポジションサイズは損切り時に資産が-5%になるように、スプレッドは価格の0.1%、日足、Long方向のみ。log10資産の最終値(青バー)、決定係数(オレンジバー)をグラフで出力している

指標名買いエントリー条件条件式(Entry)エグジット条件条件式(Exit)
Random20%の確率でランダムにrandom.randint(1,10)>820%の確率でランダムにrandom.randint(1,10)>8
Dow理論期間k1の高値上抜けmax(high[i-k1:i-1]) < close[i]期間k1の底値下抜けmin(low[i-k1:i-1]) > close[i]
RSIRSIが30以下から上抜けRSI(k1, i-1) < 30 and RSI(k1, i) > 30RSIが70以上から下抜けRSI(k1, i-1) > 70 and RSI(k1, i) < 70
SMAcloseがSMAを下から上抜けclose[i-1] < SMA(k1, i-1) and close[i] > SMA(k1, i)closeがSMAを上から下抜けclose[i-1] > SMA(k1, i-1) and close[i] < SMA(k1, i)
EMAEMA短期 > EMA長期(ゴールデンクロス)EMA(k1, i-1) < EMA(k1*2, i-1) and EMA(k1, i) > EMA(k1*2, i)EMA短期 < EMA長期(デッドクロス)EMA(k1, i-1) > EMA(k1*2, i-1) and EMA(k1, i) < EMA(k1*2, i)
MACDMACDがSIGNALを上抜けMACD(k1, i-1) < SIGNAL(k1, i-1) and MACD(k1, i) > SIGNAL(k1, i)MACDがSIGNALを下抜けMACD(k1, i-1) > SIGNAL(k1, i-1) and MACD(k1, i) < SIGNAL(k1, i)
BBANDScloseがBBLで反発しBBMを上抜けclose[i-1] < BBL(k1, i-1) and close[i-1] < BBM(k1, i-1) and close[i] > BBM(k1, i)closeがBBUに接触または上抜けclose[i-1] < BBU(k1, i-1) and close[i] >= BBU(k1, i)
ATRATR上昇+高値ブレイクATR(k1, i) > ATR(k1, i-1) and close[i] > max(close[i-k1:i])ATR減少 or 高値割れATR(k1, i) < ATR(k1, i-1) or close[i] < close[i-1]
ADXADXが20→25を上抜け + 価格上昇ADX(k1, i-1) < 25 and ADX(k1, i) > 25 and close[i] > close[i-1]ADXが低下 or 価格下落ADX(k1, i) < ADX(k1, i-1) or close[i] < close[i-1]
STOCH%Kが%Dを下から上抜け + %K<30STOCHK(k1, i-1) < STOCHD(k1, i-1) and STOCHK(k1, i) > STOCHD(k1, i) and STOCHK(k1, i) < 30%Kが%Dを上から下抜け + %K>70STOCHK(k1, i-1) > STOCHD(k1, i-1) and STOCHK(k1, i) < STOCHD(k1, i) and STOCHK(k1, i) > 70
HISTHISTがマイナスからゼロを上抜けHIST(k1, i-1) < 0 and HIST(k1, i) > 0HISTがプラスからゼロを下抜けHIST(k1, i-1) > 0 and HIST(k1, i) < 0

エントリー&エグジット条件と検証結果

(1)Randomでのエントリー & Randomでのエグジット

実はこれだけでも勝てるという非常に重要な事実。当然通貨によるが。ちなみに為替は勝てないので除外している。

(2)Randomでのエントリー & Trailing stopエグジット

Trailing stop(ダウ理論)は非常に有意性がある という発見。~システムトレード 基本と原則(実践編)~ でも同様の結論だったため,信憑性はありそう。損小利大 is ジャスティス

(3)Golden crossのエントリー & Dead crossエグジット

意外といまいち。決済の回数が少ないのが原因か。

(4)RSIでのエントリー & エグジット

いまいち。決済の回数が少ないのが原因か。

(5)価格のバウンドでエントリー& Trailing stopエグジット

Close[i-k1]>Close[i] and Close[i]>Close[i-k1//3-1] でエントリー。とりあえず現状一番これがよい。なぜかはわからん。

使ってみる(無料)

https://my-flask-app-mksr.onrender.com

まとめ

ウォークフォワード分析を通じて、より「実践で通用する戦略」を作ることが可能になります。 本アプリは、PythonとFlaskを用いた個人開発ですが、どなたでも自由にご利用いただけます

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