皆さん、こんな経験はありませんか?「画期的な」トレード戦略を思いつき、意気込んでリアルマネーを投入したものの、実は全く稼げなかったという経験。
リアルマネーを投入する前に、実は戦略の有効性を事前に検証する方法があります。それがバックテスト(Backtesting)です。
今日は正しいバックテストのやり方についてお話しします。
バックテストとは?
バックテストとは、過去のデータを使ってトレード戦略の実行をシミュレーションし、その戦略で過去に取引していたらどうなっていたかを検証することです。
たとえるなら、新しいチェスの戦法を思いついたとして、バックテストは過去の棋譜を使って検証するようなものです。あなたの方法で打っていたら、勝っていたのか負けていたのか?
もちろん、過去の実績は将来の結果を保証するものではありません。しかし少なくとも、過去のデータでも稼げない戦略がリアルトレードで稼げる確率はさらに低いでしょう。
なぜバックテストが必要か?
1. 戦略の有効性を検証する
移動平均線のゴールデンクロスで買うべきだと思っていますか?バックテストすれば、その戦略が本当に利益を出せるかわかります。
2. 戦略のパフォーマンスを数値化する
バックテストは具体的なデータを提供してくれます:年利、最大ドローダウン、勝率、リスクリワード比など。これらの数値があって初めて、戦略の良し悪しを客観的に評価できます。
3. パラメータを最適化する
同じ移動平均線戦略でも、7日と25日の組み合わせがいいのか、10日と50日がいいのか?バックテストが最適なパラメータを見つける手助けをしてくれます。
4. 自信を構築する
自分の戦略が過去5年分のデータで良好なパフォーマンスを示していると知っていれば、リアルトレードでの実行時により自信が持て、短期的な変動で簡単に諦めなくなります。
5. 問題を発見する
見た目は良さそうな戦略でも、隠れたリスクがある場合があります。例えば勝率99%の戦略でも、残り1%の損失が致命的かもしれません。バックテストはこうした問題の発見に役立ちます。
バックテストの基本手順
ステップ1:戦略ルールを明確にする
バックテストの前に、戦略のすべてのルールを明文化する必要があります:
- エントリー条件:どんな状況で買うか?
- エグジット条件:どんな状況で売るか?
- ポジション管理:毎回どれだけ買うか?
- ストップロスルール:いくら損失が出たら決済するか?
- テイクプロフィットルール:いくら利益が出たら決済するか?
- その他の制約:最大保有数量、取引時間の制限など
ルールは具体的であるほど良く、曖昧さがあってはいけません。ルールに「感覚」「だいたい」といった言葉があれば、まだ十分に具体化されていません。
ステップ2:過去のデータを取得する
バックテストしたい取引ペアのヒストリカルなローソク足データが必要です。
Binanceから取得する場合:
from binance.client import Client
client = Client(api_key, api_secret)
# BTC/USDTの2020年から現在までの日足データを取得
klines = client.get_historical_klines(
"BTCUSDT",
Client.KLINE_INTERVAL_1DAY,
"1 Jan 2020",
"1 Jan 2026"
)
データの品質が重要:
- 十分な期間をカバー(最低でも1回の完全な強気・弱気サイクル)
- 正確なデータ(始値・高値・安値・終値・出来高)
- 戦略に合った時間精度(日足戦略なら日足データ、分足戦略なら分足データ)
ステップ3:バックテストのコードを作成する
コードで戦略の実行プロセスをシミュレーションします。
シンプルな例(Python):
import pandas as pd
# データの読み込み
df = pd.DataFrame(klines, columns=[
'timestamp', 'open', 'high', 'low', 'close',
'volume', 'close_time', 'quote_volume', 'trades',
'buy_base', 'buy_quote', 'ignore'
])
df['close'] = df['close'].astype(float)
df['ma7'] = df['close'].rolling(7).mean()
df['ma25'] = df['close'].rolling(25).mean()
# トレードのシミュレーション
position = 0 # 0=ノーポジション, 1=保有中
entry_price = 0
trades = []
for i in range(25, len(df)):
# ゴールデンクロスで買い
if df['ma7'].iloc[i] > df['ma25'].iloc[i] and \
df['ma7'].iloc[i-1] <= df['ma25'].iloc[i-1] and \
position == 0:
position = 1
entry_price = df['close'].iloc[i]
# デッドクロスで売り
elif df['ma7'].iloc[i] < df['ma25'].iloc[i] and \
df['ma7'].iloc[i-1] >= df['ma25'].iloc[i-1] and \
position == 1:
position = 0
exit_price = df['close'].iloc[i]
profit = (exit_price - entry_price) / entry_price
trades.append(profit)
# 結果の集計
if trades:
wins = [t for t in trades if t > 0]
losses = [t for t in trades if t <= 0]
print(f"総取引回数: {len(trades)}")
print(f"勝率: {len(wins)/len(trades)*100:.1f}%")
print(f"平均利益: {sum(wins)/len(wins)*100:.2f}%" if wins else "利益なし")
print(f"平均損失: {sum(losses)/len(losses)*100:.2f}%" if losses else "損失なし")
print(f"総収益: {(1+sum(trades)/len(trades))**len(trades)-1:.2%}")
ステップ4:バックテスト結果を分析する
バックテスト完了後、以下の主要指標を分析します:
年利(年間リターン):戦略の年間リターン。バイ&ホールド戦略と比較しましょう。
最大ドローダウン:最高値から最安値までの最大下落率。ドローダウンが大きすぎる戦略はリアルトレードで精神的に耐えられない可能性があります。
シャープレシオ:リスク調整後のリターンを測る指標。一般的にシャープレシオ1以上は許容範囲、2以上は優秀とされます。
勝率:利益を出した取引の割合。勝率は高ければ良いというものではなく、リスクリワード比との組み合わせが重要です。
リスクリワード比:平均利益/平均損失。1.5以上が望ましいです。
取引頻度:取引回数は適切か?頻繁すぎると手数料が高くなり、少なすぎるとデータの信頼性が低くなります。
エクイティカーブ:資金曲線を描いて、安定的に右肩上がりか、大きく上下しているかを確認します。
ステップ5:最適化と検証
バックテスト結果に基づいてパラメータを調整し、再度バックテストします。ただしここには大きな落とし穴があります。それが過剰最適化です。
よくあるバックテストの落とし穴
落とし穴1:オーバーフィッティング(過剰適合)
最もよくある、そして最も危険な落とし穴です。
オーバーフィッティングとは、過去のデータで完璧なパフォーマンスが出るまでパラメータを調整し続けることです。しかしそのパラメータは過去のデータにしか通用せず、新しいデータでは全く機能しない可能性があります。
回避方法:
- データを「トレーニングセット」と「テストセット」に分け、トレーニングセットでパラメータを最適化し、テストセットで検証する
- パラメータを増やしすぎない。パラメータが多いほどオーバーフィッティングしやすい
- 戦略のロジックに市場の論理的な根拠があること。純粋なデータへのフィッティングは避ける
落とし穴2:先読みバイアス(Look-Ahead Bias)
バックテストで、その時点では知り得なかった情報を使ってしまうこと。
例:当日の終値を使って当日の取引を判断する。しかし実際の取引では、取引時点で終値はまだわかりません。
回避方法:すべての取引判断がその時点より前のデータのみを使用していることを確認する。
落とし穴3:取引コストの無視
バックテストで手数料やスリッページなどのコストを考慮しないこと。
収益率30%に見えた戦略が、手数料を差し引くと10%、あるいは赤字になることもあります。特に高頻度の戦略では手数料の影響が非常に大きいです。
回避方法:バックテストに実際の手数料率(VIPランクに応じた率を参照)を組み込み、スリッページコストも考慮する。
落とし穴4:生存バイアス(Survivorship Bias)
現在も存在する通貨のみでバックテストし、既にゼロになって上場廃止になった通貨を無視すること。
現在のトップ20の通貨だけでバックテストすれば、当然結果は良くなります。しかし数年前には、どの通貨が生き残るかわかりませんでした。
落とし穴5:市場環境の無視
2021年の強気相場では、ほぼどんな戦略でも利益が出ました。バックテストが強気相場のみをカバーしていたら、弱気相場でのパフォーマンスは悪いかもしれません。
回避方法:バックテストデータは最低でも1回の完全な強気・弱気サイクルをカバーすること。
おすすめのバックテストツール
TradingView Pine Script
プログラミングが得意でなければ、TradingViewのPine Scriptが最もシンプルな入門ツールです。
- チャート上で直接戦略を作成・実行
- 内蔵のストラテジーテスターがバックテストレポートを自動生成
- ビジュアル化が優秀
- 中低頻度の戦略のバックテストに適している
Python + Backtrader
BacktraderはPythonで最も人気のあるバックテストフレームワークの一つです。
- 高機能で、さまざまな戦略タイプをサポート
- カスタムインジケーターと取引ロジックが定義可能
- 複数銘柄・複数戦略に対応
- 学習曲線はやや急
Python + Zipline
Quantopian(すでにクローズ)が開発したバックテストフレームワークです。
- コード構造が明確
- コミュニティリソースが豊富
- 株式市場向けだが暗号通貨にも利用可能
Binanceの過去データ
Binanceは完全なヒストリカルなローソク足データのダウンロードを提供しています:
- APIからデータを取得
- またはBinanceのデータページから直接CSVファイルをダウンロード
バックテストからリアルトレードへ
バックテストに合格したら、すぐに大きな資金でリアルトレードを始めないでください。以下の順序をおすすめします:
1. デモトレードでテスト
まずデモ資金で最低1〜3ヶ月間戦略を運用します。実際のパフォーマンスがバックテストと一致するか観察しましょう。
2. 少額リアルトレード
総資金の5%〜10%でリアル運用します。このステップは非常に重要です。リアルトレードではバックテストにはなかった多くの問題(スリッページ、API遅延、ネットワーク問題など)に遭遇するからです。
3. 段階的に資金を増やす
少額リアルトレードが3ヶ月以上安定したパフォーマンスを示したら、段階的に資金を増やしていきます。
4. 継続的なモニタリング
リアル運用後は戦略のパフォーマンスを継続的にモニタリングする必要があります。実際のパフォーマンスがバックテストの予測から持続的に乖離する場合は、戦略の再評価が必要です。
実践的なアドバイス
-
シンプルな戦略ほど良い結果を生みやすい。パラメータが少なく、ロジックが明確な戦略ほどオーバーフィッティングしにくいです。
-
完璧なバックテスト結果を追求しない。年利20%・最大ドローダウン10%の戦略の方が、年利100%・最大ドローダウン50%の戦略より信頼に値します。
-
複数の期間で検証する。異なる期間すべてでバックテストし、戦略の安定性を確認しましょう。
-
実際の実行可能性を考慮する。バックテストでは実行可能でも、実際にはそうでない戦略もあります(例えば1秒以内に操作を完了する必要があるなど)。
-
バックテストの習慣を身につける。新しいトレードのアイデアが浮かんだら、まずバックテストしてから実行する。この習慣は多くの衝動的な取引を避ける助けになります。
まとめ
バックテストはトレードシステム構築の基礎ステップです。将来必ず稼げると保証するものではありませんが、少なくとも明らかに実行不可能な戦略をフィルタリングする助けにはなります。
バックテストの基本原則を覚えておきましょう:
- ルールは明確かつ具体的に
- データは十分な期間と正確性を確保
- オーバーフィッティングに警戒
- すべての取引コストを考慮
- バックテストからリアルトレードへは段階的に
市場で「授業料」を払うことに時間を費やすより、バックテストを学ぶことに時間をかける方がはるかに効率的です。
戦略の検証を始める準備はできましたか?まずBinanceのアカウントを登録して過去データを取得しましょう。