シェア:

未来の値段がわかる?「3本線」で挑戦するビットコイン取引!

ビットコインの取引って、なんだか宝探しみたいでワクワクしますよね!ここでは「3本線」っていう面白い方法を使って、いつビットコインを買ったり売ったりすればいいのか、そのヒントを一緒に探していきましょう。難しい言葉は使わないから安心してね!

取引数
97
勝率
26.80%
最終リターン
-25.04%
最大DD
25.30%

導入と前提条件

ビットコインの取引って、なんだか宝探しみたいでワクワクしますよね!ここでは「3本線」っていう面白い方法を使って、いつビットコインを買ったり売ったりすればいいのか、そのヒントを一緒に探していきましょう。難しい言葉は使わないから安心してね!

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

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

Three Line Break の理論的背景

この作戦の基本は、値段の動きには「勢い」がある、という考え方です。一度上がり始めると、しばらく上がり続けることが多いし、下がり始めると、下がり続けることが多いんです。「3本線」は、この勢いの向きが「いつ変わるか」を見つけるためのサインみたいなものです。例えば、ずっと値段が下がっていたのに(黒い線が3本)、急に上がり始めたら(白い線が出た!)、『お、これから上がるかも!』と考えるんです。反対も同じで、ずっと上がっていたのに急に下がったら、『下がるサインかも?』と考えるんですね。こうやって、小さなギザギザした動きじゃなくて、大きな値段の流れをつかもうとする作戦なんです。

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

エントリー条件

  • 【買うタイミング】値段がずっと下がっていた(黒い線が3本続いていた)のに、初めて上がった(白い線が出た)とき。
  • 【売るタイミング】値段がずっと上がっていた(白い線が3本続いていた)のに、初めて下がった(黒い線が出た)とき。

エグジット条件

  • 【買った後、売るタイミング】「上がるかも!」と思って買った後、今度は値段が下がり始めた(黒い線が出た)とき。ここで利益を確定するか、損を小さくするために取引を終わりにします。
  • 【売った後、買い戻すタイミング】「下がるかも!」と思って売った後、今度は値段が上がり始めた(白い線が出た)とき。ここで取引を終わりにします。

リスク管理

大きな損をしないためのルールも大事です。「もし予想が外れたら、ここまで下がったらやめよう」と、あらかじめラインを決めておきましょう。これを「損切り」と言います。一度に大きなお金を使わず、お小遣いの範囲で少しずつ試すのが、安全に続けるコツですよ。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数97回
勝率26.8%
平均利益0.51%
平均損失-0.59%
期待値-0.3%
プロフィットファクター0.31
最大ドローダウン25.3%
最終リターン-25.04%
シャープレシオ-1.22
HODL(Buy&Hold)9.89%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Three Line Break Trading Signal
日本の3線転換図をベースにしたトレンド判定戦略
"""
import pandas as pd
import numpy as np


def calculate_three_line_break_signals(df: pd.DataFrame,
                                      num_lines: int = 3,
                                      filter_atr: float = 0.5) -> pd.DataFrame:
    """
    Three Line Break戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    num_lines : int
        ブレイクライン数(デフォルト: 3)
    filter_atr : float
        ノイズフィルターのATR倍数(デフォルト: 0.5)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # 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=14).mean()
    
    # Three Line Breakラインの構築
    lines = []
    line_colors = []  # 1: 白(上昇)、-1: 黒(下降)
    
    # 初期ライン
    if len(df) > 0:
        lines.append({'high': df['high'].iloc[0], 'low': df['low'].iloc[0], 'close': df['close'].iloc[0]})
        line_colors.append(1 if df['close'].iloc[0] > df['open'].iloc[0] else -1)
    
    # ラインの生成
    for i in range(1, len(df)):
        current_price = df['close'].iloc[i]
        current_atr = df['atr'].iloc[i] if pd.notna(df['atr'].iloc[i]) else 0
        
        if len(lines) > 0:
            last_line = lines[-1]
            
            # 上昇ライン条件
            if current_price > last_line['high']:
                # ノイズフィルター
                if current_price - last_line['high'] > current_atr * filter_atr:
                    lines.append({
                        'high': current_price,
                        'low': last_line['high'],
                        'close': current_price
                    })
                    line_colors.append(1)
            
            # 下降ライン条件
            elif current_price < last_line['low']:
                # ノイズフィルター
                if last_line['low'] - current_price > current_atr * filter_atr:
                    lines.append({
                        'high': last_line['low'],
                        'low': current_price,
                        'close': current_price
                    })
                    line_colors.append(-1)
            
            # 転換条件チェック
            if len(lines) >= num_lines:
                # 上昇転換(num_lines本の下降ラインの後)
                if all(line_colors[-j] == -1 for j in range(1, min(num_lines + 1, len(line_colors) + 1))):
                    reversal_level = max(lines[-j]['high'] for j in range(1, min(num_lines + 1, len(lines) + 1)))
                    if current_price > reversal_level:
                        lines.append({
                            'high': current_price,
                            'low': reversal_level,
                            'close': current_price
                        })
                        line_colors.append(1)
                
                # 下降転換(num_lines本の上昇ラインの後)
                if all(line_colors[-j] == 1 for j in range(1, min(num_lines + 1, len(line_colors) + 1))):
                    reversal_level = min(lines[-j]['low'] for j in range(1, min(num_lines + 1, len(lines) + 1)))
                    if current_price < reversal_level:
                        lines.append({
                            'high': reversal_level,
                            'low': current_price,
                            'close': current_price
                        })
                        line_colors.append(-1)
    
    # シグナル初期化
    df['signal'] = 0
    df['is_buy'] = False
    df['is_sell'] = False
    df['tlb_trend'] = 0
    
    # ラインカラーをDataFrameにマップ
    for i in range(len(df)):
        if i < len(line_colors):
            df.loc[df.index[i], 'tlb_trend'] = line_colors[i]
    
    # 現在のポジション状態を追跡
    position = 0
    
    for i in range(10, len(df)):
        # 買いシグナル(Three Line Breakが陽線に転換)
        if position <= 0 and df['tlb_trend'].iloc[i] == 1 and df['tlb_trend'].iloc[i-1] == -1:
            df.loc[df.index[i], 'is_buy'] = True
            df.loc[df.index[i], 'signal'] = 1
            position = 1
            
        # 売りシグナル(Three Line Breakが陰線に転換)  
        elif position >= 0 and df['tlb_trend'].iloc[i] == -1 and df['tlb_trend'].iloc[i-1] == 1:
            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['tlb_trend'] == -1), 'exit_signal'] = -1
    df.loc[(df['signal'] == -1) & (df['tlb_trend'] == 1), 'exit_signal'] = 1
    
    return df



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

  1. 1この作戦で勝てたのは、100回中27回くらいでした。勝率がちょっと低く見えるのは、この作戦が「これぞ!」という大きなチャンスが来るまでじっくり待つタイプだからです。だから、取引する回数自体が少なめになるんです。
  2. 2全体の結果を見てみると、残念ながら今回は少し損をしてしまいました(最終的にマイナス25%くらい)。これは、この作戦を試した期間、ビットコイン全体の値段が下がり気味だったからです。下がり続ける場面では、この作戦はちょっと苦手だったのかもしれません。
  3. 3「勝った時の合計金額」と「負けた時の合計金額」を比べると、残念ながら負けた時の金額の方が大きかった、ということです。成績表の数字(PF)が1より小さいと、そうなります。これも、試した期間のビットコインの動きと、作戦のルールがうまく合わなかったからかもしれませんね。

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

  1. 1どんなにすごいと思った作戦でも、いつでも勝てるわけじゃないんだな、と分かりました。相性があって、うまくいく時といかない時があるんですね。
  2. 2やたらに取引するんじゃなくて、チャンスが来るまでじっくり待つ、というのも大事な作戦の一つだと学びました。
  3. 3一番うまくいかなかった時、持っていたお金が一時的に25%くらい減ってしまいました。こういうこともあるから、「ここまで損したら一旦やめる」っていうルールを決めておくのが、本当に大事なんだと改めて感じました。

リスク管理の具体的手法

取引量の決め方

一度の取引で使うお金は、持っているお金全部じゃなくて、ほんの少しだけ(例えば100分の1とか)にしましょう。そうすれば、もし負けてもダメージは小さいです。

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

もし損が思ったより大きくなっちゃったら、一度お休みしましょう。「どうして負けたんだろう?」って冷静に考える時間も大切です。焦って取り返そうとすると、もっと大きな失敗につながることもあります。

資金管理の方法

取引に使うのは、お小遣いとか、もし無くなっても生活に困らないお金だけにしましょう。大事なお金でやっちゃダメですよ。長く続けるためには、まず自分のお金を守ることが一番大切です。

改良案の具体的提案

  • 「どれくらいの値段の動きをサインと考えるか」というルールを、もっと細かく調整してみる。そうすれば、ちょっとした値動きにだまされずに済むかもしれません。
  • 「3本線」のサインが出たときに、他の方法(例えば「今の勢いはどれくらい強い?」を数字で見る方法)も一緒に見て、ダブルチェックしてみる。もっと確実なタイミングが分かるかもしれません。
  • この作戦が、違う期間や、ビットコイン以外のコイン(イーサリアムとか)でもうまくいくか、試してみるのも面白そうです。

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

  • この作戦を試すなら、いきなり本物のお金でやるんじゃなくて、まずはゲームみたいに練習できる「デモトレード」でやってみるのがおすすめです。本物のお金を使うなら、ジュース1本分くらいのすごく小さい金額から始めましょう。
  • 「3本線」のルールは、自分で変えてみることもできます。例えば「4本線」にしてみたり、「サインと考える値段の動き」を大きくしたり小さくしたり。自分だけの最強ルールを見つけるのも楽しいですよ。
  • 取引をしたら、ノートに記録をつけておくのがおすすめです。「いつ、なぜ買って、結果どうだったか」を書いておくと、自分の得意なパターンや苦手なパターンが分かって、どんどん上手になります。

検証の透明性と信頼性

  • データの出所: 今回のお話で使った値段のデータは、練習用の架空のものです。実際のデータとは違います。
  • 検証のやり方: 「もし過去にこの作戦を使っていたら、どうなっていたかな?」という計算(シミュレーション)をして、結果を確かめてみました。
  • コード: はい、この作戦を計算するプログラムの作り方(コード)は、みんなが見られるようになっています。
  • 注意事項: このお話は、あくまで取引の勉強のためのものです。「こうすれば絶対もうかるよ!」という話ではありません。実際に取引をするときは、損をする可能性もあることを忘れないでくださいね。最終的にどうするかは、自分でよく考えて決めましょう。

よくある質問

Q.「3本線」って、どうやって描くの?

A.値段が前の線よりも上がったら白い線、下がったら黒い線を1本ずつ描いていきます。例えば、ずっと黒い線が続いていたのに、初めて白い線が出たら「お、流れが変わったかな?」というサインになります。

Q.「ATR」って言葉が出てきたけど、何?

A.ATRは、値段がだいたい「1時間でどれくらい動くか」の平均みたいなものです。この作戦では、このATRを使って「これくらい小さな動きは、ただの気のせいだから気にしないでおこう」というフィルターをかけているんです。

Q.勝てる確率が低いのは、この作戦がダメってこと?

A.そんなことはありませんよ。野球で言うと、毎回ヒットを打つんじゃなくて、ホームランだけを狙うバッターみたいな作戦なんです。勝つ回数は少なくても、一回勝ったときにすごく大きな利益が出れば、トータルではプラスになる、という考え方です。

Q.ビットコイン以外でも使えるの?

A.はい、使えます。ビットコインだけじゃなく、株や他のコインみたいに、値段が動くものなら何でも試せます。ただ、モノによって動き方のクセが違うので、ルール(線の数とか)を少し変えてあげると、もっとうまくいくかもしれません。

Q.「期待値」とか「PF」って、どういう意味?

A.「期待値」は、この作戦をずっと続けたとき、1回あたり平均でどれくらいプラスになるか、マイナスになるかを表す数字です。「PF」は、勝って得たお金の合計を、負けて失ったお金の合計で割ったもの。これが1より大きいと、「勝った分が負けた分より多い」ってことになります。取引の通信簿みたいなものですね。

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

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

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

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

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報