ビットコインの値動きのナゾに挑戦!『DPO』で未来を予想する方法
ビットコインを5分ごとという短い時間で売り買いするときの、新しい作戦「DPO」を紹介します。この作戦は、短い時間の値段のアップダウンの勢いを見て、いつ買ったり売ったりすればいいかのヒントを見つけるのが得意なんです。難しく考えないで、一緒に見ていきましょう!
導入と前提条件
ビットコインを5分ごとという短い時間で売り買いするときの、新しい作戦「DPO」を紹介します。この作戦は、短い時間の値段のアップダウンの勢いを見て、いつ買ったり売ったりすればいいかのヒントを見つけるのが得意なんです。難しく考えないで、一緒に見ていきましょう!
【検証】戦略のバックテスト概要
- 戦略名: Detrended Price Oscillator を使用したトレンド追従戦略
- 対象銘柄: BTC/USDT
- 時間足: 5m
- 期間: 2024-08-25〜2025-08-25(364日間)
- 初期資金: $10,000
- 手数料・スリッページ: 0.1% / 0.1%
- 取引所: binance
Detrended Price Oscillator の理論的背景
この作戦は、「値段の動きには、小さな波が隠れている」という考え方が元になっています。長い時間で見ると値段は大きく上がったり下がったりしますが、その途中には、行ったり来たりの小さな波がたくさんあるんです。「DPO」は、この小さな波を見つけやすくするための道具です。今の値段から少し前の平均点を引くことで、波が今どれくらい高いか、低いかがわかります。この波の勢いが強くなったり弱くなったりする瞬間が、売り買いの合図になるかもしれない、と考えているんです。
具体的な売買ルール(今回の検証)
エントリー条件
- DPOの線が真ん中の0のラインを上にはみ出したとき(「買い」の合図かも)
- DPOの線が一番下まで落ちて、そこからグンと上がりそうなとき(これも「買い」の合図かも)
エグジット条件
- DPOの線が真ん中の0のラインを下にはみ出したとき(「やめておく」または「売り」の合図かも)
- DPOの線が一番上まで上がって、そこからストンと落ちそうなとき(これも「やめておく」または「売り」の合図かも)
リスク管理
売り買いを始める前に、大事なルールを決めます。それは「もし予想が外れて損をしちゃっても、これ以上は損しない」という金額を決めておくことです。そして、もしその金額まで損をしてしまったら、すぐに取引をやめます。これを「損切り」と言います。こうすることで、大きな失敗を防ぐことができるんです。
再現手順(HowTo)
- Python/依存(ccxt, pandas, ta)をインストール
- ccxtでBTC/USDTのOHLCVを取得して前処理
- 『Detrended Price Oscillator』に必要な指標を算出(ta 等)
- 閾値・クロス条件から売買シグナルを生成
- 手数料・スリッページを加味して検証・評価
【結果】パフォーマンス
価格の推移
資産の推移
パフォーマンス指標
指標 | 値 |
---|---|
総トレード数 | 6504回 |
勝率 | 9.49% |
平均利益 | 0.3% |
平均損失 | -0.46% |
期待値 | -0.38% |
プロフィットファクター | 0.06 |
最大ドローダウン | 100% |
最終リターン | -100% |
シャープレシオ | -3.04 |
HODL(Buy&Hold) | 75.09% |
HODL戦略との比較
実装コード(Python)
"""
Detrended Price Oscillator Trading Signal Generator
価格からトレンドを除去してサイクルを検出
"""
import pandas as pd
import numpy as np
def calculate_detrended_signals(df: pd.DataFrame,
period: int = 20,
ma_type: str = 'sma') -> pd.DataFrame:
"""
Detrended Price Oscillator戦略のシグナル生成
Parameters:
-----------
df : pd.DataFrame
OHLCVデータ
period : int
移動平均期間(デフォルト: 20)
ma_type : str
移動平均タイプ('sma' or 'ema'、デフォルト: 'sma')
Returns:
--------
pd.DataFrame
シグナルが追加されたDataFrame
"""
df = df.copy()
# シフト期間
shift_period = period // 2 + 1
# 移動平均計算
if ma_type == 'ema':
df['ma'] = df['close'].ewm(span=period, adjust=False).mean()
else:
df['ma'] = df['close'].rolling(window=period).mean()
# シフトした移動平均
df['ma_shifted'] = df['ma'].shift(-shift_period)
# DPO計算
df['dpo'] = df['close'] - df['ma_shifted'].shift(shift_period)
# DPOの移動平均(シグナルライン)
df['dpo_signal'] = df['dpo'].rolling(window=3).mean()
# DPOのピークとボトム検出(未来データを参照しない)
# 前2本と比較して判定
df['dpo_peak'] = (df['dpo'].shift(1) > df['dpo'].shift(2)) & (df['dpo'] < df['dpo'].shift(1))
df['dpo_bottom'] = (df['dpo'].shift(1) < df['dpo'].shift(2)) & (df['dpo'] > df['dpo'].shift(1))
# サイクル長推定
df['cycle_count'] = 0
peak_positions = df[df['dpo_peak']].index
if len(peak_positions) > 1:
cycle_lengths = [peak_positions[i] - peak_positions[i-1] for i in range(1, len(peak_positions))]
if cycle_lengths:
avg_cycle = np.mean(cycle_lengths)
df['cycle_length'] = avg_cycle
# ゼロラインクロス
df['dpo_prev'] = df['dpo'].shift(1)
df['zero_cross_up'] = (df['dpo'] > 0) & (df['dpo_prev'] <= 0)
df['zero_cross_down'] = (df['dpo'] < 0) & (df['dpo_prev'] >= 0)
# シグナル生成
df['is_buy'] = (
df['zero_cross_up'] |
(df['dpo_bottom'] & (df['dpo'] < -np.std(df['dpo'].dropna()) * 0.5))
) & df['dpo'].notna()
df['is_sell'] = (
df['zero_cross_down'] |
(df['dpo_peak'] & (df['dpo'] > np.std(df['dpo'].dropna()) * 0.5))
) & df['dpo'].notna()
# 不要カラム削除
df.drop(['ma', 'ma_shifted', 'dpo_signal', 'dpo_peak', 'dpo_bottom',
'cycle_count', 'dpo_prev', 'zero_cross_up', 'zero_cross_down'],
axis=1, inplace=True, errors='ignore')
if 'cycle_length' in df.columns:
df.drop(['cycle_length'], axis=1, inplace=True, errors='ignore')
return df
なぜこの結果になったのか(3つの理由)
- 1勝てた割合が9.49%と低かったのは、短い時間の値段の動きを当てるのがすごく難しくて、ほとんどの売り買いでうまくいかなかったからです。
- 21回あたりの売り買いで、平均して0.38%ずつ損をしていた、ということです。これは、勝って得たお金よりも、負けて失ったお金の方が多かったことを意味します。
- 3儲けと損のバランス(PF)が0.06とすごく低かったのは、勝ったときにもらえるお金に比べて、負けたときに失うお金がすごく大きかった、ということです。
この結果から学べる3つの教訓
- 1この「DPO」という作戦ひとつだけでは、短い時間でコロコロ変わるビットコインの値段の動きを、ずっと当て続けるのは難しいということが分かりました。
- 2たとえ勝てる回数が少なくても、一回勝ったときにたくさん儲けて、負けたときの損をできるだけ小さくすることが大事なんだ、ということを学びました。
- 3売り買いの回数が6504回ととても多かったですが、これは、たくさん挑戦したけれど、それが儲けにはつながらなかった、ということを表しているのかもしれません。
リスク管理の具体的手法
取引量の決め方
一回の売り買いで使うお金は、自分が持っているお金全体の1%から2%くらいまでにするのが基本です。そうすれば、もし負けても、失うのは持っているお金のほんの一部で済みます。使うお金の量を調整することが大切です。
損失が大きくなったときの対処法
もし損がどんどん増えて、持っているお金の10%みたいに、決めておいた金額を超えてしまったら、一度売り買いをお休みします。そして、作戦や設定が間違っていないか見直します。損が増えてきたら、売り買いに使うお金の量を減らすのも良い方法です。
資金管理の方法
売り買いで儲けたお金は、全部を次の売り買いに使わないようにしましょう。一部は別に取っておくなどして、持っているお金全体が急に減らないように管理します。長く続けていくためには、自分のお金を守ることが一番大事なんです。
改良案の具体的提案
- 「DPO」の合図が出たときに、他の道具(例えば、値段の平均線など)も一緒に見て、「本当に今がチャンスかな?」とチェックする仕組みを追加します。こうすることで、もっと確実なチャンスを見つけられるようにします。
- これまでで一番大きく損した金額を小さくするために、「損切り」のルールをもっと厳しくします。または、一回に売り買いするお金の量を少なくすることも考えます。
- 「DPO」を計算するときの期間の設定を色々と変えてみます。そして、今のビットコインの動きに一番ピッタリな設定を見つけて、成績が良くなるように工夫します。
実用性の向上(運用上の注意)
- この作戦は短い時間の値動きを見るので、パソコンやスマホで値段のグラフをずっと見ていられる時間があるときにやるのがおすすめです。
- 「DPO」で「今だ!」という合図が出ても、すぐに飛びつかないでください。他の情報も見て、落ち着いて「本当に大丈夫かな?」と考えることが大切です。
- はじめは、なくなっても困らないくらいの少ないお金で試してみましょう。この作戦がどんな風に動くのかをよく理解してから、少しずつ使うお金を増やしていくのが安全なやり方です。
検証の透明性と信頼性
- データの出所: このお話は、過去の値段のデータを使って「この作戦を使ったらどうなったか?」をシミュレーションした結果をもとにしています。
- 検証のやり方: 実際に、昔のビットコインの5分ごとの値段のデータと、決められた設定を使って、この作戦を試してみました。
- コード: この作戦をコンピューターで動かすためのプログラム(Pythonという言葉で書かれています)も、見ることができます。
- 注意事項: これはあくまで作戦の紹介で、「こうすれば絶対儲かるよ!」とおすすめするものではありません。売り買いには損をする危険もあります。最終的にどうするかは、自分でよく考えて決めてくださいね。過去にうまくいったからといって、未来もうまくいくとは限りません。