シェア:

ビットコインの未来の動きを予測?「線形回帰チャネル」で取引にチャレンジしてみよう!

「線形回帰チャネル」って聞いたことありますか?なんだか難しそうですよね。でも実は、ビットコインみたいに値段が大きく変わるものの、これからの動きを予想するのに役立つ、面白い方法なんです。今回は、この方法を分かりやすく説明しますね!

取引数
10
勝率
50.00%
最終リターン
-1.61%
最大DD
10.70%

導入と前提条件

「線形回帰チャネル」って聞いたことありますか?なんだか難しそうですよね。でも実は、ビットコインみたいに値段が大きく変わるものの、これからの動きを予想するのに役立つ、面白い方法なんです。今回は、この方法を分かりやすく説明しますね!

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

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

Linear Regression Channel の理論的背景

この作戦は、「値段って、だいたい決まった範囲の中で動くことが多いよね」という考え方が元になっています。これまでの値段の動きを参考にして、未来の値段が通りそうな「真ん中の線」と、その周りの「川幅みたいな線(チャネル)」を引きます。値段が川幅の上の線に近づいたら「ちょっと上がりすぎかな?」、下の線に近づいたら「ちょっと下がりすぎかな?」と考えて、値段の動きすぎをキャッチしようとする方法です。

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

エントリー条件

  • 値段が下の線を突き抜けて、そこから値段が上がる向きに変わったら「買い」で取引を始めます。
  • 値段が上の線を突き抜けて、そこから値段が下がる向きに変わったら「売り」で取引を始めます。

エグジット条件

  • 「買い」で始めていた場合、値段が真ん中の線まで戻ってきたら取引を終えます。もし予想と反対に、もっと下がってしまった時も、大きな損になる前に取引を終えます。
  • 「売り」で始めていた場合、値段が真ん中の線まで戻ってきたら取引を終えます。もし予想と反対に、もっと上がってしまった時も、大きな損になる前に取引を終えます。

リスク管理

一度に大きなお金を使わず、少しずつチャレンジすることが大切です。もし予想が外れても、大きな失敗にならないように、あらかじめ「ここまで損したらやめる」というルールを決めておきます。ゲームでライフがゼロになる前に、いったん引いてやり直すのに似ていますね。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数10回
勝率50%
平均利益1.92%
平均損失-2.22%
期待値-0.15%
プロフィットファクター0.84
最大ドローダウン10.7%
最終リターン-1.61%
シャープレシオ-0.01
HODL(Buy&Hold)16.58%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Linear Regression Channel Trading Signal
線形回帰チャネルを使用した統計的戦略
"""
import pandas as pd
import numpy as np


def calculate_linear_regression_channel_signals(df: pd.DataFrame,
                                               period: int = 100,
                                               deviation: float = 2.0) -> pd.DataFrame:
    """
    Linear Regression Channel戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    period : int
        回帰期間(デフォルト: 100)
    deviation : float
        標準偏差の倍数(デフォルト: 2.0)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # 線形回帰の計算
    df['lr_line'] = pd.Series(index=df.index, dtype=float)
    df['lr_slope'] = pd.Series(index=df.index, dtype=float)
    df['lr_upper'] = pd.Series(index=df.index, dtype=float)
    df['lr_lower'] = pd.Series(index=df.index, dtype=float)
    df['r_squared'] = pd.Series(index=df.index, dtype=float)
    
    for i in range(period - 1, len(df)):
        # 期間内のデータ
        y = df['close'].iloc[i - period + 1:i + 1].values
        x = np.arange(period)
        
        # 線形回帰(numpy使用)
        A = np.vstack([x, np.ones(len(x))]).T
        m, c = np.linalg.lstsq(A, y, rcond=None)[0]
        slope, intercept = m, c
        
        # 相関係数
        correlation = np.corrcoef(x, y)[0, 1]
        r_value = correlation
        
        # 回帰線の値
        regression_line = slope * x + intercept
        current_value = slope * (period - 1) + intercept
        
        # 残差の標準偏差
        residuals = y - regression_line
        std_dev = np.std(residuals)
        
        # 値を保存
        df.loc[df.index[i], 'lr_line'] = current_value
        df.loc[df.index[i], 'lr_slope'] = slope
        df.loc[df.index[i], 'lr_upper'] = current_value + deviation * std_dev
        df.loc[df.index[i], 'lr_lower'] = current_value - deviation * std_dev
        df.loc[df.index[i], 'r_squared'] = r_value ** 2
    
    # 短期の線形回帰(エントリータイミング用)
    short_period = int(period / 4)
    df['lr_short'] = pd.Series(index=df.index, dtype=float)
    df['lr_short_slope'] = pd.Series(index=df.index, dtype=float)
    
    for i in range(short_period - 1, len(df)):
        y = df['close'].iloc[i - short_period + 1:i + 1].values
        x = np.arange(short_period)
        A = np.vstack([x, np.ones(len(x))]).T
        m, c = np.linalg.lstsq(A, y, rcond=None)[0]
        slope, intercept = m, c
        current_value = slope * (short_period - 1) + intercept
        df.loc[df.index[i], 'lr_short'] = current_value
        df.loc[df.index[i], 'lr_short_slope'] = slope
    
        # シグナル初期化
    df['signal'] = 0
    df['is_buy'] = False
    df['is_sell'] = False
    
    # 現在のポジション状態を追跡
    position = 0
    
    for i in range(period, len(df)):
        # 買いシグナル(下部チャネルからの反発)
        if position <= 0 and df['close'].iloc[i] <= df['lr_lower'].iloc[i] and df['lr_slope'].iloc[i] > 0:
            df.loc[df.index[i], 'is_buy'] = True
            df.loc[df.index[i], 'signal'] = 1
            position = 1
            
        # 売りシグナル(上部チャネルからの反落)  
        elif position >= 0 and df['close'].iloc[i] >= df['lr_upper'].iloc[i] and df['lr_slope'].iloc[i] < 0:
            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
    
    # 回帰線タッチでエグジット
    for i in range(period, len(df)):
        # ロングポジションのエグジット
        if df['signal'].iloc[i] == 1:
            if df['close'].iloc[i] >= df['lr_line'].iloc[i] or df['close'].iloc[i] <= df['lr_lower'].iloc[i] - df['lr_lower'].iloc[i] * 0.02:
                df.loc[df.index[i], 'exit_signal'] = -1
        
        # ショートポジションのエグジット
        if df['signal'].iloc[i] == -1:
            if df['close'].iloc[i] <= df['lr_line'].iloc[i] or df['close'].iloc[i] >= df['lr_upper'].iloc[i] + df['lr_upper'].iloc[i] * 0.02:
                df.loc[df.index[i], 'exit_signal'] = 1
    
    return df


def get_strategy_name() -> str:
    """戦略名を返す"""
    return "Linear Regression Channel"


def get_strategy_description() -> str:
    """戦略の説明を返す"""
    return "線形回帰チャネルの上下限でのリバーサルを狙う統計的戦略"

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

  1. 1結果的に少し損をしてしまったのは、この作戦が、試した期間のビットコインの動き方と、あまり相性が良くなかったからかもしれません。
  2. 2勝ったり負けたりは半々くらいだったのですが、負けたときのダメージが、勝ったときの嬉しさよりも大きかったのが、全体でマイナスになった大きな原因です。
  3. 3ただビットコインを持っているだけの方が、結果が良かったんです。これは、この作戦が、ビットコインがぐんぐん値上がりしていく大きな波にうまく乗れなかったことを表しています。

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

  1. 1どんな時でもうまくいく「完璧な作戦」はないんだ、ということが分かりました。その時々の状況に合わせて、作戦を使い分けることが大事なんですね。
  2. 2勝つ回数が多いだけではダメで、勝った時に大きく勝ち、負けた時に少しのダメージで済ませることが大切だと学びました。
  3. 3昔のデータでうまくいくかテストしても、未来も同じ結果になるとは限らないんですね。いつも状況をチェックして、作戦を見直していく必要があります。

リスク管理の具体的手法

取引量の決め方

取引に使うお金は、持っているお小遣いのほんの一部だけにします。もし負けても、全体のお金がガクッと減らないようにするためです。これが一番大事なルールです。

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

もし負けが続いてしまって、お金がちょっと減ってきたら、いったんお休みします。そして、どうして負けたのか冷静に考え直します。ゲームで連敗したら、一度休憩して作戦を立て直すのと同じですね。

資金管理の方法

「取引に使うお金」と「大事にとっておくお金」をしっかり分けます。負けた分を取り返そうと焦って、大きなお金をつぎ込んだりするのは絶対にダメです。計画的にお金を管理しましょう。

改良案の具体的提案

  • 作戦で使う「チャネルの線の幅」などの設定を色々変えてみて、もっとうまくいく組み合わせを探してみます。
  • 値段がどんどん上がっているような時には、この作戦がうまく働くように、ルールを少し変えたり、新しいルールを加えたりしてみます。
  • 取引を「やめるタイミング」のルールをもっと工夫して、損を小さくして、利益を大きく伸ばせるように改善します。

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

  • この作戦は、ビットコイン以外でも、色々なものの値段で試せます。でも、それぞれに合った設定を見つけるのがポイントです。
  • 本番で使う前に、まずは昔のデータでたくさん練習(テスト)をして、この作戦が本当にうまくいくか確かめることが大事です。
  • この作戦一つだけに頼るのではなく、ニュースを見たり、世の中全体の動きを気にしたり、他の調べ方と組み合わせると、もっと成功しやすくなるかもしれません。

検証の透明性と信頼性

  • データの出所: このテストで使ったのは、ビットコインなどを売ったり買ったりできる場所が公開している、昔のビットコインの値段のデータ(1時間ごと)です。
  • 検証のやり方: 昔の値段のデータを使って、この作戦で取引したらどれくらいプラスになったりマイナスになったりしたかを計算して、テストしました。
  • コード: このテストで使った計算プログラムは、みんなが見られるようになっています。なので、誰でも同じようにテストしたり、もっと良くしたりできます。
  • 注意事項: これは、あくまで勉強のための情報です。「こうすれば絶対もうかる」というものではありません。もし実際にお金を使って取引する時は、自分でよく考えて、自分の責任で行ってくださいね。昔うまくいったからといって、未来もうまくいくとは限りません。

よくある質問

Q.「線形回帰チャネル」って、どうやって作るの?

A.これまでの値段の動きの、ちょうど真ん中を通るようなまっすぐな線を引きます。次に、その真ん中の線から上下に、値段の平均的な動きの幅の2倍くらい離れたところに線を引きます。これで川みたいな帯(チャネル)が完成します。

Q.「期待値」がマイナスって、どういうこと?

A.この取引を何回も繰り返していくと、平均して少しずつ損をしてしまうかもしれない、ということです。勝ったり負けたりを全部合わせると、トータルではマイナスになっちゃう、という意味ですね。

Q.「PF(プロフィットファクター)」って何?

A.「利益の合計」を「損失の合計」で割った数字のことです。もし1より大きければ、利益の方が大きいということ。今回は0.84なので、残念ながら損失の方が利益よりも大きかった、ということになります。

Q.「最大DD」って、一番ひどいときの損失のこと?

A.はい、その通りです!一番お金が増えた時から、一番減ってしまった時までの、一番大きな下落率のことです。10.7%ということは、一番悪い時には、一時的にお金が10.7%も減ってしまった瞬間があった、ということですね。

Q.この戦略で、どうやって利益を出すの?

A.値段が、作った川幅(チャネル)の上の線や下の線にぶつかった時、「ちょっと行きすぎたから、そろそろ反対に戻るかな?」と予想して取引します。下の線にぶつかったら「買い」、上の線にぶつかったら「売り」、という感じで利益を狙います。

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

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

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

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

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報