シェア:

市場の『気分』を読んでみよう!BNB/USDTの売り買い作戦をわかりやすく解説します

ここでは、ネット上のお金の一種「BNB/USDT」というセットを、5分ごとの短い時間で売り買いする作戦を紹介します。市場の『気分』がおだやかなのか、それとも荒れているのかを見分けて、もうけを出すことを目指します。この作戦がうまくいったのか、過去のデータで試してみた結果をお話ししますね。

取引数
83
勝率
33.73%
最終リターン
-26.15%
最大DD
30.59%

導入と前提条件

ここでは、ネット上のお金の一種「BNB/USDT」というセットを、5分ごとの短い時間で売り買いする作戦を紹介します。市場の『気分』がおだやかなのか、それとも荒れているのかを見分けて、もうけを出すことを目指します。この作戦がうまくいったのか、過去のデータで試してみた結果をお話ししますね。

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

  • 戦略名: Market Meanness Index を使用したトレンド追従戦略
  • 対象銘柄: BNB/USDT
  • 時間足: 5m
  • 期間: 2025-02-16〜2025-08-25(189日間)
  • 初期資金: $10,000
  • 手数料・スリッページ: 0.1% / 0.1%
  • 取引所: okx

Market Meanness Index の理論的背景

物の値段って、上がったり下がったりしますよね。でも、だいたいいつもの値段に戻ろうとすることがあります。これを「元の値段に戻る力」と呼びます。逆に、一度上がり始めるとどんどん上がり続けたり、下がり始めるとどんどん下がり続けたりする勢いのことを「トレンド」と呼びます。この作戦で使うものさしは、今が「元の値段に戻る力」が強い時なのか、「トレンド」が強い時なのかを数字で教えてくれます。数字が大きい時は、「元の値段に戻る力」が強いので、値段が動きすぎてもすぐに戻ってくるだろうと考えます。数字が小さい時は、「トレンド」が強いので、今の勢いのまま動き続けるかもしれないと考えます。この市場の気分に合わせて、いつ売り買いするかを決めるのが、この作戦のポイントです。

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

エントリー条件

  • 「元の値段に戻る力」が強い時:値段がすごく下がって、「これは売られすぎだな」と思ったら買います。
  • 「トレンド」が強い時:値段が、今までの平均の値段を表す線を下から上に突き抜けたら買います。

エグジット条件

  • 「元の値段に戻る力」が強い時:値段がすごく上がって、「これは買われすぎだな」と思ったら売って、取引を終わりにします。
  • 「トレンド」が強い時:値段が、今までの平均の値段を表す線を上から下に突き抜けたら売って、取引を終わりにします。

リスク管理

もし予想と反対に値段が動いてしまったら、損が大きくならないように、すぐに売って取引をやめます。これを「損切り」と言います。また、一度の取引に大きなお金を使いすぎないように気をつけることも大切です。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数83回
勝率33.73%
平均利益2.07%
平均損失-1.56%
期待値-0.33%
プロフィットファクター0.63
最大ドローダウン30.59%
最終リターン-26.15%
シャープレシオ-0.06
HODL(Buy&Hold)31.86%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Market Meanness Index Trading Signal Generator
市場の平均回帰性を測定する指標
"""
import pandas as pd
import numpy as np


def calculate_mmi_signals(df: pd.DataFrame,
                         period: int = 200,
                         lookback: int = 20) -> pd.DataFrame:
    """
    Market Meanness Index戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    period : int
        MMI計算期間(デフォルト: 200)
    lookback : int
        中央値計算期間(デフォルト: 20)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # 中央値計算
    df['median'] = df['close'].rolling(window=lookback).median()
    
    # 価格が中央値より上か下か
    df['above_median'] = (df['close'] > df['median']).astype(int)
    df['below_median'] = (df['close'] < df['median']).astype(int)
    
    # 連続性のカウント
    df['consecutive'] = 0
    current_streak = 0
    prev_above = None
    
    for i in range(len(df)):
        if df.iloc[i]['above_median'] == 1:
            if prev_above == True:
                current_streak += 1
            else:
                current_streak = 1
            prev_above = True
        elif df.iloc[i]['below_median'] == 1:
            if prev_above == False:
                current_streak += 1
            else:
                current_streak = 1
            prev_above = False
        df.loc[df.index[i], 'consecutive'] = current_streak
    
    # MMI計算(平均回帰の度合い)
    df['moves'] = (df['close'] > df['close'].shift(1)).astype(int)
    df['nl'] = df['moves'].rolling(window=period).sum()
    df['mmi'] = 100 * (period - df['nl']) / period
    df['mmi'] = df['mmi'].fillna(50)  # 初期値を50に設定
    
    # MMIのレベル(閾値を緩和)
    df['mmi_high'] = df['mmi'] > 60  # 高い平均回帰性
    df['mmi_low'] = df['mmi'] < 40   # トレンド性が強い
    
    # 価格のボリンジャーバンド
    df['price_ma'] = df['close'].rolling(window=lookback).mean()
    df['price_std'] = df['close'].rolling(window=lookback).std()
    df['bb_upper'] = df['price_ma'] + 2 * df['price_std']
    df['bb_lower'] = df['price_ma'] - 2 * df['price_std']
    
    # シグナル生成
    df['is_buy'] = (
        (df['mmi_high'] & (df['close'] < df['bb_lower'])) |  # 平均回帰環境で売られ過ぎ
        (df['mmi_low'] & (df['close'] > df['price_ma']) & (df['close'].shift(1) <= df['price_ma'].shift(1)))  # トレンド環境でMAクロス
    ) & df['mmi'].notna()
    df['is_sell'] = (
        (df['mmi_high'] & (df['close'] > df['bb_upper'])) |  # 平均回帰環境で買われ過ぎ
        (df['mmi_low'] & (df['close'] < df['price_ma']) & (df['close'].shift(1) >= df['price_ma'].shift(1)))  # トレンド環境でMAクロス
    ) & df['mmi'].notna()
    
    # 不要カラム削除
    df.drop(['median', 'above_median', 'below_median', 'consecutive', 'moves', 'nl',
             'mmi_high', 'mmi_low', 'price_ma', 'price_std', 'bb_upper', 'bb_lower'], 
            axis=1, inplace=True, errors='ignore')
    
    return df

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

  1. 1この作戦では、「元の値段に戻る力」が強い時に「売られすぎ」のタイミングで買っていましたが、勝てる確率が低く、あまりもうかりませんでした。
  2. 2「トレンド」が強い時に、平均の線を突き抜けたのを合図にしていましたが、これもなかなかもうけにつながりませんでした。
  3. 3結局、この作戦でBNB/USDTを売り買いしてみたら、トータルでは損をしてしまうという結果になりました。

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

  1. 1市場の「気分」が「元の値段に戻りやすい」のか「トレンドが出やすい」のかを考えるのは、売り買いでとても大事だということがわかりました。
  2. 2勝つ回数が少なくても、一回に勝つ金額が大きければ、トータルでプラスになることもある、ということを学びました。
  3. 3昔のデータでうまくいかなかったように、どんな作戦も必ずもうかるとは限りません。だから、実際にお金を使う時は、とても慎重になるべきだという教訓になりました。

リスク管理の具体的手法

取引量の決め方

1回の売り買いで使うお金は、持っているお金全部の、ほんの少しだけにしましょう。例えば100分の1とかです。そうすれば、もし負けても、ダメージは小さくてすみます。

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

もし損が思ったより大きくなってきたら、それ以上ひどくならないように、すぐに取引をやめましょう。「いくら損したらやめる」と、前もって決めておくのがとても大事です。

資金管理の方法

売り買いに使うお金は、普段の生活に使うお金とは分けて、もしなくなっても大丈夫な「余裕のあるお金」だけにしましょう。そして、一度に使うお金の量をしっかり守ることが大切です。

改良案の具体的提案

  • 「トレンド」が強い時の売り買いのルールを、もっと細かく見直す必要がありそうです。
  • 「元の値段に戻る力」が強い時に、「売られすぎ」や「買われすぎ」と判断する基準を、もっと厳しくしたり、逆にゆるくしたりして、一番良い設定を探す必要があります。
  • この作戦だけでなく、他のものさしも一緒に使って、もっと確実な「売り買いの合図」を見つけられるように工夫すると良いかもしれません。

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

  • この作戦は5分ごとの値動きを見ますが、もし実際に試してみるなら、まずはとても少ない金額から始めるのがおすすめです。
  • 取引をするたびに「手数料」という費用がかかります。これも計算に入れないと、思ったよりもうけが少なくなるので注意しましょう。
  • 市場の様子はいつも変わります。だから、この作戦がいつもうまくいくとは限りません。定期的に成績をチェックして、必要ならルールを変えていくことが大切です。

検証の透明性と信頼性

  • データの出所: このテストの結果は、みんなが見られるように公開されている、過去の値段の動きの記録を使って計算しました。
  • 検証のやり方: 昔のBNB/USDTの5分ごとの値動きのデータ(2025年2月16日〜8月25日の期間)を使って、この作戦で売り買いしたら、どれくらいもうかったり損したりしたかを計算しました。
  • コード: このテストの計算に使ったコンピューターのプログラムは、誰でも見られるように公開されています。
  • 注意事項: この記事は、「こうすればもうかるよ」とおすすめするものではありません。もし実際にお金を使って取引をするなら、必ず自分でよく考えて、自分の責任で行ってください。昔のテストで良い結果が出たとしても、将来も同じようにうまくいくとは限りません。

よくある質問

Q.「MMI」って、どうやって数字を出しているの?

A.「MMI」は、値段が「いつもの値段からどれくらい離れているか」や、「値段が動く勢いがどれくらい続いているか」などを調べて計算します。それで、市場がおだやかなのか、動きが激しいのかを数字にしているんです。むずかしい計算式というよりは、これまでの値段の動き方からわかるようになっています。

Q.「勝率33.73%」って、3回に1回しか勝てないってこと?低すぎない?

A.良い質問ですね。勝つ回数が少なくても、1回勝った時のもうけがすごく大きければ、全部合わせるとプラスになることもあります。でも、今回の作戦では、勝つ回数が少ない上に、1回あたりのもうけの見込みもマイナスだったので、残念ながらトータルで損をしてしまいました。

Q.「最大DD:30.59%」ってどういう意味ですか?

A.これは「最大ドローダウン」といって、この作戦をやっている途中で、お金が一番減ってしまった時の割合のことです。この場合は、一番運が悪かった時、持っていたお金が一時的に約30.59%も減ってしまった、ということを表しています。

Q.「HODL:31.86%」ってなんですか?

A.「HODL(ホドル)」は、ネットのお金の世界で「売ったりしないで、ずっと持っておく」という意味で使われる言葉です。もしこの作戦を使わずに、同じ期間ただBNB/USDTを持っていただけだったら、31.86%もお金が増えていた、ということです。つまり、今回はがんばって売り買いするより、ただ持っているだけの方が結果が良かった、ということになります。

Q.じゃあ、この作戦は実際に使っても勝てないの?

A.過去のデータで試した限りでは、残念ながらうまくいきませんでした。市場の様子はいつも変わるので、この作戦をそのまま今使っても、うまくいく可能性は低いかもしれません。もし使うとしたら、ルールをもっと良くしたり、他の作戦と組み合わせたりする工夫が必要だと思います。

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

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

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

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

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報