シェア:

ビットコインの「値動きの勢い」作戦! うまくいった? 徹底チェック

この作戦は、ビットコインの値段が激しく動く「勢い」をヒントに、売り買いのタイミングをはかる方法です。1時間ごとの値動きで試してみたら、勝てたのは10回のうち2回くらい(勝率 約18%)でした。この結果から何がわかるか、一緒に見ていきましょう!

取引数
141
勝率
17.73%
最終リターン
-42.21%
最大DD
43.52%

導入と前提条件

この作戦は、ビットコインの値段が激しく動く「勢い」をヒントに、売り買いのタイミングをはかる方法です。1時間ごとの値動きで試してみたら、勝てたのは10回のうち2回くらい(勝率 約18%)でした。この結果から何がわかるか、一緒に見ていきましょう!

【検証】戦略のバックテスト概要

  • 戦略名: Volatility System を使用したトレンド追従戦略
  • 対象銘柄: BTC/USDT
  • 時間足: 1h
  • 期間: 2025-04-28〜2025-08-26(119日間)
  • 初期資金: $10,000
  • 手数料・スリッページ: 0.1% / 0.1%
  • 取引所: binance

Volatility System の理論的背景

この作戦は、値段の動きの「勢い」に注目します。勢いが強い時は、値段が大きく動くチャンスです。逆に、動きがおだやかな時は、大きな変化は期待しにくいと考えます。この作戦では、最近の勢いと少し前の勢いを比べて、その差が決められたラインをこえたら「チャンスが来た!」と判断します。そして、値段が平均のラインより上なら買い、下なら売る、というルールで取引します。

具体的な売買ルール(今回の検証)

エントリー条件

  • 値段の勢いが強くなって、今の値段が平均ラインより上にある時に「買う」
  • 値段の勢いが強くなって、今の値段が平均ラインより下にある時に「売る」

エグジット条件

  • 「買い」で持っている時に、値段の勢いが弱くなったら「売って手じまい」する
  • 「売り」で持っている時に、値段の勢いが弱くなったら「買い戻して手じまい」する

リスク管理

大損しないためのルールも大事です。この作戦では、お金が一番減ってしまった時、元のお金の44%近くまで減ってしまいました。これは結構大きな数字です。なので、一回の取引で使うお金を少なく調整することが、とても大切になります。

再現手順(HowTo)

  1. Python/依存(ccxt, pandas, ta)をインストール
  2. ccxtでBTC/USDTのOHLCVを取得して前処理
  3. 『Volatility System』に必要な指標を算出(ta 等)
  4. 閾値・クロス条件から売買シグナルを生成
  5. 手数料・スリッページを加味して検証・評価

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数141回
勝率17.73%
平均利益1.51%
平均損失-0.79%
期待値-0.38%
プロフィットファクター0.4
最大ドローダウン43.52%
最終リターン-42.21%
シャープレシオ-1.16
HODL(Buy&Hold)16.56%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Volatility System Trading Signal
ボラティリティ拡大・縮小を利用した戦略
"""
import pandas as pd
import numpy as np


def calculate_volatility_system_signals(df: pd.DataFrame,
                                       short_period: int = 6,
                                       long_period: int = 100,
                                       threshold: float = 0.5) -> pd.DataFrame:
    """
    Volatility System戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    short_period : int
        短期ボラティリティ期間(デフォルト: 6)
    long_period : int
        長期ボラティリティ期間(デフォルト: 100)
    threshold : float
        ボラティリティ比率閾値(デフォルト: 0.5)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # Historical Volatility計算
    df['returns'] = np.log(df['close'] / df['close'].shift(1))
    df['hv_short'] = df['returns'].rolling(window=short_period).std() * np.sqrt(252)
    df['hv_long'] = df['returns'].rolling(window=long_period).std() * np.sqrt(252)
    
    # ボラティリティ比率
    df['vol_ratio'] = df['hv_short'] / df['hv_long']
    
    # Volatility Cone(ボラティリティの分布)
    percentiles = [10, 25, 50, 75, 90]
    for p in percentiles:
        df[f'vol_p{p}'] = df['hv_long'].rolling(window=252).quantile(p/100)
    
    # 現在のボラティリティ位置
    df['vol_rank'] = df['hv_short'].rolling(window=252).rank(pct=True)
    
    # ATRベースのボラティリティ
    df['h_l'] = df['high'] - df['low']
    df['h_c'] = np.abs(df['high'] - df['close'].shift(1))
    df['l_c'] = np.abs(df['low'] - df['close'].shift(1))
    df['true_range'] = df[['h_l', 'h_c', 'l_c']].max(axis=1)
    df['atr'] = df['true_range'].rolling(window=short_period).mean()
    df['atr_long'] = df['true_range'].rolling(window=long_period).mean()
    df['atr_ratio'] = df['atr'] / df['atr_long']
    
    # ボリンジャーバンドによるスクイーズ検出
    df['bb_middle'] = df['close'].rolling(window=20).mean()
    df['bb_std'] = df['close'].rolling(window=20).std()
    df['bb_upper'] = df['bb_middle'] + 2 * df['bb_std']
    df['bb_lower'] = df['bb_middle'] - 2 * df['bb_std']
    df['bb_width'] = df['bb_upper'] - df['bb_lower']
    df['bb_width_ma'] = df['bb_width'].rolling(window=long_period).mean()
    df['squeeze'] = df['bb_width'] < df['bb_width_ma'] * threshold
    
        # シグナル初期化
    df['signal'] = 0
    df['is_buy'] = False
    df['is_sell'] = False
    
    # 現在のポジション状態を追跡
    position = 0
    
    for i in range(long_period, len(df)):
        # 買いシグナル(ボラティリティ拡大+価格上昇)
        if position <= 0 and df['vol_ratio'].iloc[i] > threshold and df['close'].iloc[i] > df['bb_middle'].iloc[i]:
            df.loc[df.index[i], 'is_buy'] = True
            df.loc[df.index[i], 'signal'] = 1
            position = 1
            
        # 売りシグナル(ボラティリティ拡大+価格下落)  
        elif position >= 0 and df['vol_ratio'].iloc[i] > threshold and df['close'].iloc[i] < df['bb_middle'].iloc[i]:
            df.loc[df.index[i], 'is_sell'] = True
            df.loc[df.index[i], 'signal'] = -1
            position = -1
        else:
            # ポジション維持
            df.loc[df.index[i], 'signal'] = position
    
    # NaN値を0で埋める
    df['signal'] = df['signal'].fillna(0)
    
    # エグジットシグナル
    df['exit_signal'] = 0
    
    # ボラティリティ縮小でエグジット
    df.loc[(df['signal'] == 1) & (df['vol_ratio'] < threshold), 'exit_signal'] = -1
    df.loc[(df['signal'] == -1) & (df['vol_ratio'] < threshold), 'exit_signal'] = 1
    
    return df


def get_strategy_name() -> str:
    """戦略名を返す"""
    return "Volatility System"


def get_strategy_description() -> str:
    """戦略の説明を返す"""
    return "ボラティリティの拡大・縮小サイクルを利用した戦略"

なぜこの結果になったのか(3つの理由)

  1. 1勝てたのが10回のうち2回くらい(勝率 約18%)と低かったのは、「これから動きが激しくなるぞ!」と思ったのに、すぐに動きがおとなしくなってしまったことが多かったからみたいです。
  2. 2最終的に損してしまったのは、勝った時の利益よりも、負けた時の損失のほうが、少しだけ大きかったことが積み重なったからです。
  3. 3「もうけの合計」と「そんの合計」を比べると、そんの合計のほうが大きかったので、全体としてマイナスになってしまいました。

この結果から学べる3つの教訓

  1. 1値段の勢いが強くなった!というだけでは、カンタンには勝てないことがわかりました。
  2. 2勝つ回数が少なくても、一回で大きく勝てばプラスになることもありますが、この作戦ではうまくいきませんでした。
  3. 3昔のデータでうまくいかないなら、やり方を変えたり、もっと研究したりする必要がある、ということがわかりました。

リスク管理の具体的手法

取引量の決め方

「1回の取引で使うお金の決め方」です。例えば、100万円持っていたら、1回の取引で損してもいいのは2万円まで、というように、失っても大丈夫な金額を決めておきます。

損失が大きくなったときの対処法

「もし負けが続いたらどうするか」です。もしお財布の中身がどんどん減ってきたら、いったん取引をお休みしたり、使うお金をさらに減らしたりして、大きな損を防ぎます。この作戦では特に大事なことです。

資金管理の方法

「お金の上手な管理方法」です。勝って増えたお金はすぐには使わず、次への準備のためにとっておきます。負けてしまった時も、あわてて取り返そうとせず、落ち着いてお財布を管理します。

改良案の具体的提案

  • やめる時のルールに、「値段の勢いが弱まったら」だけじゃなく、「値段が平均ラインまで戻ってきたら」というのを追加してみる。
  • 「勢い」だけでなく、他のヒント(例えば「買われすぎ」「売られすぎ」を示す道具)も組み合わせて、もっと正確に判断できるようにする。
  • 作戦の細かい設定を、その時のビットコインの状況に合わせて、自動で変えてくれる仕組みを考えてみる。

実用性の向上(運用上の注意)

  • この作戦は、ビットコインの値段が活発に動いている時にはチャンスがありますが、逆に大きく損する可能性もあります。まずは、なくなっても困らない少額で試してみるのがおすすめです。
  • 今回うまくいかなかったのは、ある期間のデータだからです。未来も同じ結果になるとは限りません。いつも今の状況をチェックすることが大切です。
  • 1時間ごとのデータで試しましたが、1日ごとや5分ごとなど、見る時間を変えたり、ビットコイン以外のコインで試したりすると、違う結果になるかもしれません。

検証の透明性と信頼性

  • データの出所: 昔のビットコインの値段のデータ(始まりの値段、一番高かった値段、一番安かった値段、終わりの値段)を使いました。
  • 検証のやり方: 公開されている計算プログラムを使って、決まった期間のデータで「もしこの作戦を使っていたらどうなっていたか」というお試し計算(シミュレーション)をしました。
  • コード: このシミュレーションに使った計算プログラム(Pythonコード)は、誰でも見ることができます。
  • 注意事項: このお話は、昔のデータにもとづいたもので、将来も同じようにうまくいくことを約束するものではありません。投資は、ご自身の判断と責任で行ってください。特にこの作戦は、大きく損をする可能性もあるので、十分に気をつけてください。

よくある質問

Q.「ボラティリティ」って、どういう意味?

A.値段の上がり下がりの「激しさ」のことだよ。ジェットコースターみたいに激しく動く時は「ボラティリティが大きい」、メリーゴーラウンドみたいにおだやかな時は「ボラティリティが小さい」って言うんだ。

Q.勝つ回数が少ないってことは、この作戦はダメなの?

A.そうとは限らないんだ。例えば、10回やって9回負けても、最後の1回ですごく大きなホームランを打てば、全体ではプラスになることもあるよ。でも、この作戦では、そのホームランがあまり出なかったんだ。

Q.PFって何?

A.「プロフィットファクター」の略で、「もうけの合計」を「そんの合計」で割り算した数字のことだよ。もし1より大きければ、全体でプラス。1より小さければ、全体でマイナスだったってことなんだ。

Q.最大DD(ドローダウン)って何?

A.お財布のお金が、一番へこんじゃった時の割合のことだよ。例えば100万円が、途中で一時的に60万円まで減ってしまったら、へこんだのは40万円だから、最大DDは40%になるんだ。

Q.HODLってどういう意味?

A.「ホドル」って読むよ。仮想通貨を「買ったら、売らずにずーっと持っておく」こと。実は今回のテスト期間では、この作戦で売り買いするより、ただビットコインをずーっと持ってるだけの方が、結果が良かったんだ。

Q.検証に使用した期間と時間足は?

A.1h足で検証しました。期間は記事内の概要をご確認ください。

Q.最終リターンと最大ドローダウンは?

A.最終リターンは-42.21%、最大DDは43.52%です。

Q.勝率やPFはどの程度?

A.勝率は17.73%、プロフィットファクターは0.40です。

Q.HODLとの比較結果は?

A.HODLは16.56%でした。記事内の比較表をご覧ください。

Q.手数料やスリッページは考慮済み?

A.はい。バックテスト設定の手数料・スリッページを損益に反映しています。

Q.市場環境はトレンド/レンジどちらに近かった?

A.期間中はトレンド優勢と推測されます。

Q.この戦略は初心者でも扱える?

A.基礎的な指標と検証環境の知識があれば扱えます。まずは少額・デモから。

Q.推奨のリスク管理は?

A.最大DDを踏まえた損切り・ポジションサイジングと、システム停止基準の設定を推奨します。

Q.将来の結果は期待できる?

A.過去の結果は将来を保証しません。市場環境やパラメータ適合性に大きく依存します。

Q.改良の方向性は?

A.トレンド・ボラティリティのフィルター併用、パラメータの再最適化、取引頻度の制御を検討してください。

著者情報