どうなった?値動きの波をとらえる作戦!「ボリンジャーバンド・スクイーズ」を試してみた!
この作戦は、値段の動きがおとなしくなった時をねらって、急に大きく動き出した時に売り買いするという考え方です。今回は「LINK/USDT」というインターネット上のお金(暗号資産)を使って、5分ごとの短い時間で試してみました。でも、残念ながらうまくいきませんでした。なぜ失敗したのか、そしてこの失敗から何を学べるのかを、わかりやすくお話ししますね。
導入と前提条件
この作戦は、値段の動きがおとなしくなった時をねらって、急に大きく動き出した時に売り買いするという考え方です。今回は「LINK/USDT」というインターネット上のお金(暗号資産)を使って、5分ごとの短い時間で試してみました。でも、残念ながらうまくいきませんでした。なぜ失敗したのか、そしてこの失敗から何を学べるのかを、わかりやすくお話ししますね。
【検証】戦略のバックテスト概要
- 戦略名: Bollinger Squeeze を使用したトレンド追従戦略
- 対象銘柄: LINK/USDT
- 時間足: 5m
- 期間: 2024-10-08〜2025-08-25(320日間)
- 初期資金: $10,000
- 手数料・スリッページ: 0.1% / 0.1%
- 取引所: bybit
Bollinger Squeeze の理論的背景
「ボリンジャーバンド」というのは、値段のグラフの周りに「だいたいこの範囲で動くことが多いですよ」という目安の線を描いてくれる道具です。この線の幅がせまくなる(スクイーズする)のは、値動きのパワーがたまっている状態みたいなものです。嵐の前の静けさのように、おとなしくなった後で、ためていたエネルギーを爆発させて、値段がドカンと大きく動くことが多い、という考え方が元になっています。この作戦では、線の幅がせまくなった後、値段がその線を勢いよく突き抜けた時(ブレイクアウトした時)を、売り買いのチャンスと考えます。例えば、上の線を突き抜けたら「買い」、下の線を突き抜けたら「売り」という感じです。
具体的な売買ルール(今回の検証)
エントリー条件
- 線の幅がせまくなって値動きがおとなしくなった後、値段が勢いよく上がって、真ん中の線を突き抜けた時に「買い」ます。
- 線の幅がせまくなって値動きがおとなしくなった後、値段が勢いよく下がって、真ん中の線を突き抜けた時に「売り」ます。
エグジット条件
- 「買い」で入った後、もし値段が下がってしまったら、決めておいた金額まで損した時点で、それ以上損が大きくならないように売ります(これを「損切り」と言います)。
- 「売り」で入った後、もし値段が上がってしまったら、決めておいた金額まで損した時点で、それ以上損が大きくならないように買い戻します(これも「損切り」です)。
リスク管理
失敗しても大ケガしないための大事なルールです。まず、一度に大きなお金を使わないように、売り買いする量を少なくします。そして、もし予想が外れて損が出そうになったら、傷が浅いうちにやめるように、「ここまで損したらやめる」というラインをあらかじめ決めておきます。
再現手順(HowTo)
- Python/依存(ccxt, pandas, ta)をインストール
- ccxtでLINK/USDTのOHLCVを取得して前処理
- 『Bollinger Squeeze』に必要な指標を算出(ta 等)
- 閾値・クロス条件から売買シグナルを生成
- 手数料・スリッページを加味して検証・評価
【結果】パフォーマンス
価格の推移
資産の推移
パフォーマンス指標
指標 | 値 |
---|---|
総トレード数 | 818回 |
勝率 | 29.1% |
平均利益 | 2.23% |
平均損失 | -1.4% |
期待値 | -0.34% |
プロフィットファクター | 0.66 |
最大ドローダウン | 95.61% |
最終リターン | -95.13% |
シャープレシオ | -0.22 |
HODL(Buy&Hold) | 132.64% |
HODL戦略との比較
実装コード(Python)
#!/usr/bin/env python3
"""
ボリンジャーバンドスクイーズ戦略
バンド幅が縮小(スクイーズ)後のブレイクアウトを狙う
"""
import pandas as pd
import numpy as np
def calculate_squeeze_signals(df: pd.DataFrame, bb_period: int = 20, bb_std: float = 2.0,
squeeze_threshold: float = 0.05) -> pd.DataFrame:
"""
ボリンジャーバンドスクイーズシグナルを生成
Parameters:
-----------
df : pd.DataFrame
OHLCVデータ
bb_period : int
ボリンジャーバンド期間(デフォルト: 20)
bb_std : float
標準偏差倍率(デフォルト: 2.0)
squeeze_threshold : float
スクイーズ判定閾値(デフォルト: 0.05)
Returns:
--------
pd.DataFrame
シグナル列が追加されたDataFrame
"""
df = df.copy()
# ボリンジャーバンド計算
df['bb_middle'] = df['close'].rolling(window=bb_period).mean()
df['bb_std'] = df['close'].rolling(window=bb_period).std()
df['bb_upper'] = df['bb_middle'] + (df['bb_std'] * bb_std)
df['bb_lower'] = df['bb_middle'] - (df['bb_std'] * bb_std)
# バンド幅(相対値)
df['bb_width'] = (df['bb_upper'] - df['bb_lower']) / df['bb_middle']
df['bb_width_ma'] = df['bb_width'].rolling(window=bb_period).mean()
# スクイーズ状態の判定
# バンド幅が移動平均より一定割合小さい場合をスクイーズと判定
df['is_squeeze'] = df['bb_width'] < (df['bb_width_ma'] * (1 - squeeze_threshold))
# スクイーズ後のブレイクアウト
df['is_buy'] = (
(df['is_squeeze'].shift(1) == True) & # 前期間がスクイーズ
(df['is_squeeze'] == False) & # 現在スクイーズ解除
(df['close'] > df['bb_middle']) # 上方向へブレイク
)
df['is_sell'] = (
(df['is_squeeze'].shift(1) == True) & # 前期間がスクイーズ
(df['is_squeeze'] == False) & # 現在スクイーズ解除
(df['close'] < df['bb_middle']) # 下方向へブレイク
)
# NaN値をFalseに置換
df['is_buy'] = df['is_buy'].fillna(False)
df['is_sell'] = df['is_sell'].fillna(False)
print(f"BBスクイーズ: 期間={bb_period}, 閾値={squeeze_threshold}")
print(f"買いシグナル数: {df['is_buy'].sum()}")
print(f"売りシグナル数: {df['is_sell'].sum()}")
return df
なぜこの結果になったのか(3つの理由)
- 1たくさん売り買いした(818回)のに、勝てたのはたったの約29%でした。これは、10回挑戦して3回も勝てなかった、ということです。つまり、ほとんどの挑戦が負けで終わってしまった可能性が高いです。
- 21回売り買いするたびに、平均で0.34%ずつお金が減ってしまっていた、という計算になります。これでは、やればやるほど損が増えてしまいます。
- 3「プロフィットファクター(PF)」という成績表みたいなものがあります。これが「1」より小さいと、残念ながら負けているという意味です。今回は0.66だったので、勝って得た利益の合計よりも、負けて失った損失の合計のほうがずっと大きかった、ということになります。
この結果から学べる3つの教訓
- 1勝つ回数が少なくても、一回の勝ちでドカンと大きな利益を出せれば、トータルでプラスになることもあります。でも、今回の作戦では、たまに勝っても利益が小さく、負けた時のダメージのほうが大きかったようです。
- 2「値動きがおとなしくなった後は、大きく動くチャンス!」という考え方そのものは、悪くないんです。でも、それを「いつ」「どんな時に」使うのか、そのタイミングがすごく大事だということがわかりました。
- 35分ごとという、とても短い時間での売り買いは、だまし討ちのような急な値動きが多くて、作戦通りにいくのが難しい場合がある、ということも勉強になりました。
リスク管理の具体的手法
取引量の決め方
1回の挑戦で使うお金の量を決めることです。例えば、「もし負けても、持っているお金全体の1%までしか減らないようにしよう」とルールを決めます。値動きが激しい時は、使うお金の量を少なくするなど、状況に合わせて調整します。
損失が大きくなったときの対処法
持っているお金が、一番多かった時からある程度(例えば10%)減ってしまったら、「ちょっと調子が悪いな」という合図です。そういう時は、一旦全部の売り買いをやめて、作戦が今の状況に合っているか、冷静に考え直す時間を作ります。
資金管理の方法
売り買いに使うお金は、ふだんの生活に必要なお金とは別に、「もしなくなっても大丈夫」と思えるお小遣いの範囲でやることが鉄則です。また、うまくいって儲かったとしても、すぐに使うお金を増やさずに、慎重に少しずつ挑戦の規模を大きくしていくのが賢いやり方です。
改良案の具体的提案
- 勝つ回数が少なすぎたので、もっと勝てるチャンスを見つけるために、別の道具を組み合わせるなど、新しいルールを加えてみるのが良さそうです。
- 負けた時の傷をできるだけ浅くするために、「損切り」のルールをもっと厳しくします。逆に、勝っている時には、焦ってやめずに、もっと利益を伸ばせるようなルールを考えるのもいいかもしれません。
- 今回使った「LINK/USDT」や「5分ごと」という条件が、この作戦に合っていなかったのかもしれません。別のお金の種類で試したり、1時間ごとなど、もっと長い時間の値動きで試したりするのも一つの手です。
実用性の向上(運用上の注意)
- このお話は、あくまでも過去のデータで試してみた結果です。「未来も絶対にこうなる」というわけではないので、注意してくださいね。
- いきなり本番でやるのではなく、まずはとても少ないお金で試してみるか、ゲームみたいに本物のお金を使わずに練習できる「デモ取引」で、たくさん練習することが大切です。
- 世の中の状況はどんどん変わっていきます。今までうまくいっていた作戦が、急に効かなくなることもあります。「あれ、なんだか上手くいかないな」と感じたら、一度立ち止まって、作戦を見直したり、やり方を変えたりすることを考えてみましょう。
検証の透明性と信頼性
- データの出所: 今回のお話で使ったデータは、「LINK/USDT」という暗号資産の、過去の5分ごとの値段の記録です。
- 検証のやり方: 過去の値段のデータを使って、「もしこの作戦で売り買いしていたら、どれくらい儲かったり損したりしたかな?」というシミュレーション(これを「バックテスト」と言います)をしました。
- コード: このシミュレーションに使ったコンピューターのプログラムは、誰でも見られるように公開されています。
- 注意事項: このお話は、投資のやり方を教えるものでも、「これをやれば儲かるよ」とおすすめするものでもありません。投資には、お金が減ってしまう危険(リスク)が必ずあります。最終的にどうするかは、必ず自分でよく考えて決めてくださいね。