シェア:

ビットコイン取引のヒント!「人気の価格帯」を見つける作戦

この説明では、ビットコインの取引で、「マーケットプロファイル」という特別なグラフを使う方法を紹介します。難しい言葉は使わずに、誰でもわかるように説明するので、ビットコイン取引の新しい見方を知ることができますよ。

取引数
8
勝率
37.50%
最終リターン
+4.91%
最大DD
10.95%

導入と前提条件

この説明では、ビットコインの取引で、「マーケットプロファイル」という特別なグラフを使う方法を紹介します。難しい言葉は使わずに、誰でもわかるように説明するので、ビットコイン取引の新しい見方を知ることができますよ。

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

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

Market Profile Value の理論的背景

この作戦の基本は、「たくさんの人が取引している値段には、何か理由があるはずだ」という考え方です。「人気の価格帯」は、多くの人が「この値段ならちょうどいい」と思っている場所です。なので、値段がその範囲に入ったり出たりする時の動きに注目します。難しい計算ではなく、値動きの「クセ」を見つけるようなイメージです。

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

エントリー条件

  • 値段が「人気の価格帯」より安くなった後、またその範囲に戻ってきたら、買うチャンスかもしれません。
  • 値段が「人気の価格帯」より高くなった後、またその範囲に戻ってきたら、売るチャンスかもしれません。

エグジット条件

  • 買った後、値段が「人気の価格帯」をこえて、もっと上がっていきそうなとき。
  • 売った後、値段が「人気の価格帯」をわって、もっと下がっていきそうなとき。

リスク管理

もし予想と反対に値段が動いてしまったら、大きな損をしないように、すぐに取引を終えるルールを決めておきます。例えば、買ったのに値段が下がり続けたり、売ったのに上がり続けたりする場合です。これで、お財布を守ります。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数8回
勝率37.5%
平均利益4.69%
平均損失-1.71%
期待値0.69%
プロフィットファクター1.55
最大ドローダウン10.95%
最終リターン4.91%
シャープレシオ0.13
HODL(Buy&Hold)16.58%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Market Profile Value Area Trading Signal
マーケットプロファイル理論に基づくバリューエリア戦略
"""
import pandas as pd
import numpy as np


def calculate_market_profile_value_signals(df: pd.DataFrame,
                                          profile_period: int = 20,
                                          value_area_pct: float = 0.70,
                                          poc_weight: float = 1.5) -> pd.DataFrame:
    """
    Market Profile Value Area戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    profile_period : int
        プロファイル構築期間(デフォルト: 20)
    value_area_pct : float
        バリューエリアの割合(デフォルト: 0.70)
    poc_weight : float
        Point of Controlの重み(デフォルト: 1.5)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # TPO (Time Price Opportunity) の近似
    df['typical_price'] = (df['high'] + df['low'] + df['close']) / 3
    df['price_range'] = df['high'] - df['low']
    
    # 価格レベルごとのボリューム分布を計算
    df['vah'] = pd.Series(index=df.index, dtype=float)  # Value Area High
    df['val'] = pd.Series(index=df.index, dtype=float)  # Value Area Low
    df['poc'] = pd.Series(index=df.index, dtype=float)  # Point of Control
    df['vwap'] = pd.Series(index=df.index, dtype=float) # Volume Weighted Average Price
    
    for i in range(profile_period - 1, len(df)):
        # 期間内のデータ
        period_df = df.iloc[i - profile_period + 1:i + 1]
        
        # VWAP計算
        vwap = (period_df['typical_price'] * period_df['volume']).sum() / period_df['volume'].sum()
        df.loc[df.index[i], 'vwap'] = vwap
        
        # 価格帯を30分割してヒストグラム作成
        price_min = period_df['low'].min()
        price_max = period_df['high'].max()
        price_bins = np.linspace(price_min, price_max, 30)
        
        # 各価格帯のボリューム計算
        volume_profile = np.zeros(len(price_bins) - 1)
        for j in range(len(period_df)):
            row = period_df.iloc[j]
            # 各ローソクが通過する価格帯にボリュームを配分
            for k in range(len(price_bins) - 1):
                if row['low'] <= price_bins[k+1] and row['high'] >= price_bins[k]:
                    # 価格帯を通過する割合でボリュームを配分
                    overlap_low = max(row['low'], price_bins[k])
                    overlap_high = min(row['high'], price_bins[k+1])
                    overlap_ratio = (overlap_high - overlap_low) / (row['high'] - row['low'] + 0.0001)
                    volume_profile[k] += row['volume'] * overlap_ratio
        
        # Point of Control (最大ボリューム価格)
        poc_idx = np.argmax(volume_profile)
        poc_price = (price_bins[poc_idx] + price_bins[poc_idx + 1]) / 2
        df.loc[df.index[i], 'poc'] = poc_price
        
        # Value Area計算
        total_volume = volume_profile.sum()
        target_volume = total_volume * value_area_pct
        
        # POCから上下に拡張してValue Areaを決定
        accumulated_volume = volume_profile[poc_idx]
        va_low_idx = poc_idx
        va_high_idx = poc_idx
        
        while accumulated_volume < target_volume:
            # 上下のボリュームを比較して大きい方を追加
            up_vol = volume_profile[va_high_idx + 1] if va_high_idx < len(volume_profile) - 1 else 0
            down_vol = volume_profile[va_low_idx - 1] if va_low_idx > 0 else 0
            
            if up_vol > down_vol and va_high_idx < len(volume_profile) - 1:
                va_high_idx += 1
                accumulated_volume += up_vol
            elif va_low_idx > 0:
                va_low_idx -= 1
                accumulated_volume += down_vol
            else:
                break
        
        df.loc[df.index[i], 'val'] = (price_bins[va_low_idx] + price_bins[va_low_idx + 1]) / 2
        df.loc[df.index[i], 'vah'] = (price_bins[va_high_idx] + price_bins[va_high_idx + 1]) / 2
    
    # Initial Balance (最初の1時間の高値・安値)
    df['ib_high'] = df['high'].rolling(window=4).max()  # 15分足なら4本で1時間
    df['ib_low'] = df['low'].rolling(window=4).min()
    
        # シグナル初期化
    df['signal'] = 0
    df['is_buy'] = False
    df['is_sell'] = False
    
    # 現在のポジション状態を追跡
    position = 0
    
    for i in range(profile_period, len(df)):
        # 買いシグナル(Value Area Lowからの反発)
        if position <= 0 and df['close'].iloc[i] <= df['val'].iloc[i] and df['close'].iloc[i] > df['val'].iloc[i-1]:
            df.loc[df.index[i], 'is_buy'] = True
            df.loc[df.index[i], 'signal'] = 1
            position = 1
            
        # 売りシグナル(Value Area Highからの反落)  
        elif position >= 0 and df['close'].iloc[i] >= df['vah'].iloc[i] and df['close'].iloc[i] < df['vah'].iloc[i-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
    
    # Value Area外でのエグジット
    df.loc[(df['signal'] == 1) & (df['close'] > df['vah']), 'exit_signal'] = -1
    df.loc[(df['signal'] == -1) & (df['close'] < df['val']), 'exit_signal'] = 1
    
    return df


def get_strategy_name() -> str:
    """戦略名を返す"""
    return "Market Profile Value"


def get_strategy_description() -> str:
    """戦略の説明を返す"""
    return "マーケットプロファイルのバリューエリアとPOCを使用した戦略"

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

  1. 1「人気の価格帯」はたくさんの人が注目しているので、値段がそのあたりで跳ね返りやすいと考えられます。
  2. 2「一番人気の値段」を中心に考えることで、市場の真ん中で勝負しやすくなります。
  3. 3取引の回数が8回と少ないのは、むやみに手を出さず、「ここだ!」というチャンスをじっくり待つ作戦だからです。

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

  1. 1値段の動きだけでなく、「みんながどう考えているか」を読むことの大切さがわかります。
  2. 2「人気の価格帯」や「一番人気の値段」のように、市場の「クセ」を見つけるヒントが得られます。
  3. 3勝つ回数が少なくても(勝率37.5%)、1回で勝つときの利益が負けるときの損より大きければ、全体ではプラスになることがある、ということが学べます。

リスク管理の具体的手法

取引量の決め方

1回の取引で使うお金は、持っているお金全部の1%から2%くらいに決めておきます。そうすれば、もし負けてもダメージは少なく、次のチャンスを狙えます。

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

もしお財布のお金が、今回のテストで一番減った時(10.95%)くらいまで減ってしまったら、一度全部の取引をお休みして、作戦を見直す時間を作りましょう。

資金管理の方法

もうかったお金をどう使うか計画を立てます。もうかった分を次の取引に使ったり、一部は貯金したりして、長い目で見てお財布を育てていくことが大切です。

改良案の具体的提案

  • 「人気の価格帯」を調べる期間を変えてみて、もっとうまくいく設定を探してみましょう。
  • 「移動平均線」のような、他の分析ツールと組み合わせると、もっと精度が上がるかもしれません。
  • 取引が始まったばかりの時間の値動きもヒントにすると、もっと良いタイミングが見つかるかもしれません。

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

  • この作戦は、ビットコインのように値段がよく動くコインで試すのがおすすめです。
  • 取引のチャンスはそんなに多くないので、あせらずにじっくり待つ気持ちが大切です。
  • 実際に自分のお金で試す前に、昔のデータを使ってこの作戦がうまくいったか、練習(バックテスト)してみることがとても大事です。

検証の透明性と信頼性

  • データの出所: この作戦の成績は、2025年4月28日から8月26日までの、ビットコインの1時間ごとの値動きのデータを使って計算しました。
  • 検証のやり方: 昔のデータを使って、この作戦通りに取引していたらどうなっていたかをコンピューターでシミュレーション(バックテスト)しました。
  • コード: このシミュレーションに使ったプログラムは公開されています。
  • 注意事項: この作戦は、昔のデータにもとづいた結果です。未来も同じようにうまくいくとは限りません。お金を使うときは、自分でよく考えて決めてくださいね。

よくある質問

Q.「マーケットプロファイル」って、結局なに?

A.「どの値段で、どれくらいの時間取引されていたか」がわかるグラフのことです。みんながどの値段に注目しているかが、ひと目でわかります。

Q.「人気の価格帯(バリューエリア)」ってどうやってわかるの?

A.ある期間の取引のうち、特に活発だった中心の70%くらいの範囲のことです。「このあたりなら売ったり買ったりしてもいいな」と多くの人が思っている値段の範囲、と考えてください。

Q.「一番人気の値段(POC)」って?

A.その期間で、たった一つ、もっとも取引が集中した値段のことです。市場の中心、みたいなものです。

Q.勝率37.5%って、負ける方が多いってこと?大丈夫?

A.その通りです。でも、例えば100円の損を6回しても、300円の利益を4回出せれば、トータルでは勝ちになりますよね。この作戦は、勝つ回数よりも「トータルでプラスにする」ことを目指す考え方なんです。

Q.この作戦は、いつやるのがいいの?

A.ビットコインのように、値段が活発に動くもので試すのがおすすめです。また、ある程度の期間のデータが集まっていると分析しやすくなります。

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

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

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

A.最終リターンは4.91%、最大DDは10.95%です。

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報