シェア:

ビットコインの値段の波を読もう!ジグザグ・リバーサル作戦のひみつ

この作戦は、ビットコインの値段が大きく上がったり下がったりした後に、反対に動き出すタイミングをねらって取引する方法です。4時間ごとの値動きのデータを使って、約1年間、このやり方がうまくいくか調べてみました。これがどんな作戦で、どんな結果になったのか、わかりやすくお話ししますね。

取引数
62
勝率
30.65%
最終リターン
-17.25%
最大DD
26.87%

導入と前提条件

この作戦は、ビットコインの値段が大きく上がったり下がったりした後に、反対に動き出すタイミングをねらって取引する方法です。4時間ごとの値動きのデータを使って、約1年間、このやり方がうまくいくか調べてみました。これがどんな作戦で、どんな結果になったのか、わかりやすくお話ししますね。

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

  • 戦略名: ZigZag Reversal を使用したトレンド追従戦略
  • 対象銘柄: BTC/USDT
  • 時間足: 4h
  • 期間: 2024-07-21〜2025-08-25(399日間)
  • 初期資金: $10,000
  • 手数料・スリッページ: 0.1% / 0.1%
  • 取引所: binance

ZigZag Reversal の理論的背景

この作戦の基本の考え方は、「値段の動きは、ずっとまっすぐには進まない」ということです。値段は上がったり下がったりを繰り返します。そして、ある程度どちらかに動くと、その勢いが弱まって反対に動き出すことがよくあるんです。このギザギザした動きがジグザグに見えることから、この名前がつきました。この作戦では、値段が大きく動いたポイントを見つけて、そこから反対に動き始める「変わり目」を予想して、もうけをねらいます。

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

エントリー条件

  • 値段が大きく下がって「谷」を作った後、次に上がり始めたタイミングで「買う」約束をします。
  • 値段が大きく上がって「山」を作った後、次に下がり始めたタイミングで「売る」約束をします。

エグジット条件

  • 「買う」約束をした後、もうけが出ている時に、反対に「売る」タイミングが来たら取引を終えます。
  • 「売る」約束をした後、もうけが出ている時に、反対に「買う」タイミングが来たら取引を終えます。

リスク管理

この作戦では、予想がはずれて損しそうになったら、すぐに取引をやめることがとても大切です。今回の調べでは、持っているお金が最大で約27パーセントも減ってしまった時期がありました。これは、一度の失敗で大きく損してしまう可能性があるということです。だから、一度に取引する量を少なくしたり、損が出たらすぐにやめるという自分ルールを決めておくことが、大きな損を防ぐために重要になります。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数62回
勝率30.65%
平均利益0.97%
平均損失-0.86%
期待値-0.3%
プロフィットファクター0.49
最大ドローダウン26.87%
最終リターン-17.25%
シャープレシオ-0.23
HODL(Buy&Hold)67.45%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
#!/usr/bin/env python3
"""
ジグザグリバーサル戦略
価格の山と谷を検出して転換点を特定
"""
import pandas as pd
import numpy as np


def calculate_zigzag_signals(df: pd.DataFrame, deviation: float = 1.0) -> pd.DataFrame:
    """
    ジグザグリバーサルシグナルを生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    deviation : float
        転換判定の最小変動率(%)(デフォルト: 5.0)
    
    Returns:
    --------
    pd.DataFrame
        シグナル列が追加されたDataFrame
    """
    df = df.copy()
    
    # ジグザグポイントの初期化
    df['zigzag'] = np.nan
    df['pivot_type'] = ''  # 'high' or 'low'
    
    # 最初のポイントを設定
    df.loc[df.index[0], 'zigzag'] = df.loc[df.index[0], 'close']
    last_pivot_idx = 0
    last_pivot_val = df.loc[df.index[0], 'close']
    last_pivot_type = None
    
    for i in range(1, len(df)):
        current_idx = df.index[i]
        current_high = df.loc[current_idx, 'high']
        current_low = df.loc[current_idx, 'low']
        
        # 変動率計算
        high_change = ((current_high - last_pivot_val) / last_pivot_val) * 100
        low_change = ((current_low - last_pivot_val) / last_pivot_val) * 100
        
        if last_pivot_type is None:
            # 最初の転換点を決定
            if high_change >= deviation:
                df.loc[current_idx, 'zigzag'] = current_high
                df.loc[current_idx, 'pivot_type'] = 'high'
                last_pivot_idx = i
                last_pivot_val = current_high
                last_pivot_type = 'high'
            elif low_change <= -deviation:
                df.loc[current_idx, 'zigzag'] = current_low
                df.loc[current_idx, 'pivot_type'] = 'low'
                last_pivot_idx = i
                last_pivot_val = current_low
                last_pivot_type = 'low'
        
        elif last_pivot_type == 'high':
            # 前回が高値の場合、安値転換を探す
            if low_change <= -deviation:
                df.loc[current_idx, 'zigzag'] = current_low
                df.loc[current_idx, 'pivot_type'] = 'low'
                last_pivot_idx = i
                last_pivot_val = current_low
                last_pivot_type = 'low'
            # より高い高値が出てもピボットは更新しない(リーク防止)
            # elif current_high > last_pivot_val:
            #     pass
        
        else:  # last_pivot_type == 'low'
            # 前回が安値の場合、高値転換を探す
            if high_change >= deviation:
                df.loc[current_idx, 'zigzag'] = current_high
                df.loc[current_idx, 'pivot_type'] = 'high'
                last_pivot_idx = i
                last_pivot_val = current_high
                last_pivot_type = 'high'
            # より低い安値が出てもピボットは更新しない(リーク防止)
            # elif current_low < last_pivot_val:
            #     pass
    
    # シグナル生成(ピボットポイントの次のバーで逆張り)
    # ピボットが確定してから1本遅れてシグナルを出す
    df['is_buy'] = df['pivot_type'].shift(1) == 'low'
    df['is_sell'] = df['pivot_type'].shift(1) == 'high'
    
    # NaN値をFalseに置換
    df['is_buy'] = df['is_buy'].fillna(False)
    df['is_sell'] = df['is_sell'].fillna(False)
    
    print(f"ジグザグリバーサル: 偏差={deviation}%")
    print(f"買いシグナル数: {df['is_buy'].sum()}")
    print(f"売りシグナル数: {df['is_sell'].sum()}")
    
    return df

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

  1. 1勝てたのは10回中3回くらい(勝率約30パーセント)と少なめで、勝ったり負けたりを繰り返しても、トータルでは損をしてしまう結果になったからです。
  2. 2「もうかった金額の合計」を「損した金額の合計」で割った数字が、1よりも小さい0.49でした。これは、もうけたお金より、損したお金のほうが多かったということです。
  3. 3もしこの作戦を使わずに、ただビットコインを1年間ずっと持っていたら約67パーセントもうかっていたのに、この作戦では逆に17パーセント以上も損をしてしまったからです。

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

  1. 1値段がいつ上がって、いつ下がるのか、その「変わり目」をピッタリ当てるのは、すごく難しいということが分かりました。
  2. 2勝つ回数が少なくても、1回勝った時にすごく大きくもうければ、トータルでプラスになることもあります。でも、今回の作戦では、そうはなりませんでした。
  3. 3簡単なルール一つだけで勝ち続けるのは難しいです。その時々のニュースや世の中の動きなども見ながら、やり方を柔軟に変えていくことが大切だと学びました。

リスク管理の具体的手法

取引量の決め方

1回の取引で損してもいい金額を、自分が持っているお金の1パーセントから2パーセントくらいに決めます。例えば、100万円持っていたら、1回の取引での損は最大でも1万円から2万円におさまるように、取引する量を調整します。

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

もし、持っているお金が合計で10パーセント減ってしまったら、一度すべての取引をやめて、作戦を見直す、といったルールを作っておくことです。

資金管理の方法

取引に使うお金は、もしなくなっても自分の生活に困らないお金だけにします。また、勝ってうれしくても、負けてくやしくても、感情的にならずに、自分で決めたルールをしっかり守り続けることが大切です。

改良案の具体的提案

  • 「値段の変わり目だ!」と判断するためのルール(例えば「1パーセント動いたら」の部分)を、もっと細かく調整して、より正確なタイミングを見つけられるようにすること。
  • もうけが出た時に、いつ取引を終えるかという「利食い」のルールを、もっとハッキリと決めること。
  • この作戦一つだけに頼るのではなく、他の作戦と組み合わせたり、今の状況に合った作戦を選んだりすることを考えること。

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

  • このお話は、あくまで昔のデータで試した結果です。これから先も、同じようにもうかることを約束するものではありません。
  • 本当に自分のお金で取引を始める前に、まずは少ない金額で試してみたり、ゲームのような練習用の取引で練習したりすることをおすすめします。
  • 世の中のニュースや、ビットコイン全体が今どんな状況なのかも気にしながら、いろんな情報をもとに判断することが大切です。

検証の透明性と信頼性

  • データの出所: この説明は、もとになった計算プログラムと、その結果のデータを見て作っています。
  • 検証のやり方: 取引した回数や勝った割合などの結果データを使って、この作戦がどうだったかを確かめました。
  • コード: この作戦を計算するためのプログラムもちゃんと用意されています。
  • 注意事項: これは「こうすればもうかるよ」というアドバイスではありません。取引は、自分の判断と責任で行ってください。昔うまくいったからといって、これからも同じとは限りません。

よくある質問

Q.ジグザグって、どんな動きのこと?

A.値段が上がったり下がったりを繰り返して、まるでジグザグの線のように見える値動きのことだよ。

Q.「変わり目(転換点)」って、どうやって見つけるの?

A.値段がある程度動いた後に、反対の動きが始まったところを「変わり目」だと考えるんだ。この作戦では、1パーセント以上動いたら「変わり目のサインかも」と判断しているよ。

Q.勝つ回数が少ないのに、どうやってもうけるの?

A.もともとは、勝つ回数が少なくても、1回勝った時にすごく大きくかせいで、負けた時の損は小さくおさえることで、トータルでプラスにするんだ。でも、今回の結果では、勝った時のもうけより、負けた時の損のほうが大きくなってしまったみたい。

Q.「最大DD」って、どういう意味?

A.「最大ドローダウン」の略で、持っているお金が一番減ってしまった時の、その減った割合のことだよ。この数字が大きいと、一度に大きく損をしてしまう危険があるってことなんだ。

Q.この作戦は、実際に使っても大丈夫?

A.今回の調べでは、あまり良い結果が出なかったから、このまま使うのはおすすめできないかな。もし試すなら、もっと工夫したり、他のやり方と組み合わせたりする必要があると思うよ。

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

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

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

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

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報