シェア:

ビットコインの未来を予測?DMI作戦で、おこづかいは増えるかな?

このお話では、ビットコインが1時間ごとにどう動くかを調べて、もうけを出すことを目指す「DMI作戦」という方法を紹介します。約4ヶ月間のデータを使って、この作戦がうまくいったのか、そして、これからどうすればもっと良くなるのかを、わかりやすく説明しますね。

取引数
92
勝率
22.83%
最終リターン
-32.34%
最大DD
35.62%

導入と前提条件

このお話では、ビットコインが1時間ごとにどう動くかを調べて、もうけを出すことを目指す「DMI作戦」という方法を紹介します。約4ヶ月間のデータを使って、この作戦がうまくいったのか、そして、これからどうすればもっと良くなるのかを、わかりやすく説明しますね。

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

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

Directional Movement System の理論的背景

この作戦は、「市場の値段には、流れやクセがある」という考え方が元になっています。ビットコインみたいなお金は、値段がぐんぐん上がったり、どーんと下がったりする「勢い」がありますよね。DMI作戦では、この勢いを測るために「上がるパワー(+DI)」と「下がるパワー(-DI)」という2つの数字を使います。もし「上がるパワー」が「下がるパワー」よりも大きくなったら、「よし、これから上がりそうだ!」と判断します。逆に、「下がるパワー」の方が大きくなったら、「おっと、下がりそうだぞ」と判断します。さらに、「元気の強さ(ADX)」という数字で、そのパワーが本物かどうかをチェックして、十分に強いとわかったときに「今だ!」という合図を出します。

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

エントリー条件

  • 買うタイミング:「上がるパワー」の数字が「下がるパワー」の数字より大きくなって、さらに「元気の強さ」の数字が25よりも大きくなったときです。
  • 売るタイミング:「下がるパワー」の数字が「上がるパワー」の数字より大きくなって、さらに「元気の強さ」の数字が25よりも大きくなったときです。

エグジット条件

  • もうけを自分のものにするタイミング:買ったあとに、「売るタイミング」の合図が出たら、取引をやめます。
  • 損をできるだけ小さくするタイミング:売ったあとに、「買うタイミング」の合図が出たら、取引をやめます。

リスク管理

一度にたくさんのお金は使いません。もしもの時のために、なくなっても平気な金額だけで挑戦します。もし、予想と反対に値段が大きく動いてしまったら、すぐに取引をやめて、それ以上損が大きくならないようにします。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数92回
勝率22.83%
平均利益1.38%
平均損失-0.95%
期待値-0.42%
プロフィットファクター0.43
最大ドローダウン35.62%
最終リターン-32.34%
シャープレシオ-0.84
HODL(Buy&Hold)16.67%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Directional Movement System Trading Signal
DMIシステムを使用したトレンドフォロー
"""
import pandas as pd
import numpy as np


def calculate_directional_movement_system_signals(df: pd.DataFrame,
                                                period: int = 14) -> pd.DataFrame:
    """
    Directional Movement System戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    period : int
        DMI計算期間(デフォルト: 14)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # True Range
    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['tr'] = df[['h_l', 'h_c', 'l_c']].max(axis=1)
    df['atr'] = df['tr'].rolling(window=period).mean()
    
    # Directional Movement
    df['up_move'] = df['high'] - df['high'].shift(1)
    df['down_move'] = df['low'].shift(1) - df['low']
    
    df['plus_dm'] = np.where((df['up_move'] > df['down_move']) & (df['up_move'] > 0), df['up_move'], 0)
    df['minus_dm'] = np.where((df['down_move'] > df['up_move']) & (df['down_move'] > 0), df['down_move'], 0)
    
    # Smoothed DM
    df['plus_dm_smooth'] = df['plus_dm'].rolling(window=period).mean()
    df['minus_dm_smooth'] = df['minus_dm'].rolling(window=period).mean()
    
    # Directional Indicator
    df['plus_di'] = (df['plus_dm_smooth'] / df['atr']) * 100
    df['minus_di'] = (df['minus_dm_smooth'] / df['atr']) * 100
    
    # ADX
    df['dx'] = 100 * np.abs(df['plus_di'] - df['minus_di']) / (df['plus_di'] + df['minus_di'] + 0.0001)
    df['adx'] = df['dx'].rolling(window=period).mean()
    
    # シグナル初期化
    df['signal'] = 0
    df['is_buy'] = False
    df['is_sell'] = False
    
    position = 0
    
    for i in range(period * 2, len(df)):
        # 買いシグナル(+DI > -DI かつ ADX上昇)
        if position <= 0 and df['plus_di'].iloc[i] > df['minus_di'].iloc[i] and df['adx'].iloc[i] > 25:
            df.loc[df.index[i], 'is_buy'] = True
            df.loc[df.index[i], 'signal'] = 1
            position = 1
            
        # 売りシグナル(-DI > +DI かつ ADX上昇)
        elif position >= 0 and df['minus_di'].iloc[i] > df['plus_di'].iloc[i] and df['adx'].iloc[i] > 25:
            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
    
    df['signal'] = df['signal'].fillna(0)
    
    return df


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


def get_strategy_description() -> str:
    """戦略の説明を返す"""
    return "DMIシステムを使用したトレンドフォロー戦略"

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

  1. 1この作戦では、勝った回数の割合が22.83%と低く、92回取引した結果、最終的にお金が32.34%減ってしまいました。これは、ビットコインの値動きが予想通りにならなかったり、合図が出たあとにすぐ反対に動いてしまったりすることが多かったからだと考えられます。
  2. 2「期待値」という、1回の取引で平均してどれくらいもうかるかを示す数字がマイナス(-0.42%)でした。これは、取引をするたびに、少しずつ損をしていた計算になります。
  3. 3「一番大きく損したときの割合(最大DD)」が35.62%と、かなり大きかったです。これは、一度の失敗で持っていたお金がガクッと減ってしまう危険があったことを示しています。

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

  1. 1値動きの波に乗る作戦でも、いつもうまくいくわけではないことを学びました。特にビットコインは、突然値動きが変わることがあります。
  2. 2勝つ回数が少なくても、1回勝ったときのもうけがすごく大きければ、全体ではプラスになることもあります。でも今回は、勝つ回数も少なく、もうけも大きくなかったので、残念な結果になりました。
  3. 3損を大きくしないための工夫(リスク管理)が、すごく大事だと改めてわかりました。一度の失敗で大きく損をしないように、もっと工夫が必要だと感じました。

リスク管理の具体的手法

取引量の決め方

取引に使うお金は、自分が持っているおこづかい全体の、ほんの少し(例えば100分の1とか)だけにします。そうすれば、もし負けても、全体へのダメージを小さくできます。

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

もし、損が続いて全体のお金が一定の割合(例えば10%)減ってしまったら、一度すべての取引をお休みします。そして、作戦が今の状況に合っているか、じっくり見直す時間を作ります。

資金管理の方法

もしもうかったら、その一部は次のチャレンジのためにとっておき、少しずつお金を育てていくことを目指します。また、負けが続いても、焦って一度に使うお金を増やしたりはしません。

改良案の具体的提案

  • 売買の合図が出たときに、他の情報も見て、「本当に今がチャンスかな?」ともう一度確かめるルールを加えることを考えます。例えば、全体の流れが上向きのときだけ買う、などです。
  • 「元気の強さ」が25より大きい、というルールだけだと、ちょっとした値動きにも反応しすぎているのかもしれません。「元気の強さ」の数字が、ただ大きいだけでなく、どんどん上がっているときだけを狙うなど、ルールをもう少し賢くすることを考えます。
  • 「これ以上損したらやめる」というライン(損切り)を、もっと手前に設定するなど、ルールを厳しくして、大きな損をしないように改善します。

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

  • この作戦は、値動きの方向がはっきりしているときには力を発揮しやすいですが、ビットコインのように急に値段が動く場合は、合図が出てもすぐに反対に動くことがあるので注意が必要です。
  • 計算に使う「14」という期間の数字は、変えて試してみることで、もっと良い結果が出るようになるかもしれません。
  • 実際にこの作戦を使う前には、必ず昔のデータで「練習(バックテスト)」をして、自分に合ったやり方かどうかを確かめることがとても大切です。

検証の透明性と信頼性

  • データの出所: このお話は、コンピュータのプログラムと、ビットコインの過去の値段の動き(始値、高値、安値、終値、取引量)のデータをもとに作られています。
  • 検証のやり方: コンピュータのプログラムを使って、2025年4月28日から8月26日までのビットコインの1時間ごとのデータで、この作戦の成績を調べました(これをバックテストと言います)。
  • コード: 作戦の計算方法がわかるコンピュータのプログラム(Pythonコード)は、見ることができます。
  • 注意事項: このお話で紹介している作戦や結果は、あくまで過去のデータにもとづくものです。将来も同じようにもうかることを約束するものではありません。お金を使うときは、必ず自分でよく考えて決めてくださいね。

よくある質問

Q.「上がるパワー(+DI)」とか「下がるパワー(-DI)」って、何のこと?

A.すごく簡単に言うと、「上がるパワー」は、今日の値段が昨日よりどれだけ元気に上がったか、「下がるパワー」は、どれだけ元気に下がったかを表す数字です。この二つを比べることで、今の流れがどっちに向かっているかがわかります。

Q.「元気の強さ(ADX)」って、いつ使うの?

A.ADXは、値動きにどれだけ「勢い」があるかを示す温度計みたいなものです。この数字が大きいほど、みんなが「上がるぞー!」または「下がるぞー!」と一方向に盛り上がっている状態です。この作戦では、ADXが25より大きい、つまり十分に盛り上がっているときだけを、本当のチャンスだと考えています。

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

A.そうとは限りません。例えば、10回やって9回負けても、最後の1回ですごく大きく勝てば、全体ではプラスになります。大事なのは、勝つ回数と、勝ったときのもうけのバランスです。今回の作戦は、勝つ回数が少なく、勝ったときのもうけもあまり大きくなかったので、マイナスになってしまいました。

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

A.最大DDは、「最大ドローダウン」の略で、一番運が悪かったときに、持っていたお金がどれくらいの割合で減ってしまったか、ということです。今回の場合、一番減ったときには元のお金の35.62%がなくなってしまった、という意味です。この数字が大きいほど、ドキドキする危ない作戦だと言えます。

Q.この作戦を使えば、ビットコインで本当にもうかるの?

A.このレポートの結果だけを見ると、残念ながら、この作戦をそのまま使ってももうかるようにはなりませんでした。でも、今回わかった改善点をヒントに、ルールを変えたり、他の作戦と組み合わせたりすれば、将来うまくいく可能性はあります。ただ、どんなすごい作戦でも、投資には必ず損をするリスクがあることを忘れないでくださいね。

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

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

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

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

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報