シェア:

価格の波に乗ろう! SOLっていうコインで試す、ちょっと特別な取引方法

この説明では、「SOL」という仮想通貨(暗号資産)を5分ごとに売り買いするときの、ある作戦についてお話しします。専門的な言葉は使わずに、誰にでも分かるように説明しますね。この作戦はうまくいかなかったのですが、どうして失敗したのかを知ることで、取引のヒントが見つかるかもしれません。

取引数
6951
勝率
18.85%
最終リターン
-100.00%
最大DD
100.00%

導入と前提条件

この説明では、「SOL」という仮想通貨(暗号資産)を5分ごとに売り買いするときの、ある作戦についてお話しします。専門的な言葉は使わずに、誰にでも分かるように説明しますね。この作戦はうまくいかなかったのですが、どうして失敗したのかを知ることで、取引のヒントが見つかるかもしれません。

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

  • 戦略名: Hilbert Transform を使用したトレンド追従戦略
  • 対象銘柄: SOL/USDT
  • 時間足: 5m
  • 期間: 2024-10-22〜2025-08-25(306日間)
  • 初期資金: $10,000
  • 手数料・スリッページ: 0.1% / 0.1%
  • 取引所: bybit

Hilbert Transform の理論的背景

世の中のものの値段は、いつも同じペースで動くわけではありません。急に上がったり、ゆっくり下がったり、行ったり来たりを繰り返す波のような動きをします。「ヒルベルト変換」は、そんな複雑な波の動きをくわしく分析するための方法です。価格が上がる勢いがあるか、下がる勢いがあるかを計算で探して、売り買いのベストなタイミングを見つけるための道具になるはずなんです。難しい計算は全部コンピューターがやってくれるので、私たちはその結果を見るだけで大丈夫ですよ。

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

エントリー条件

  • グラフに「サイン線」と「リード線」という2本の線があります。サイン線がリード線を下から上に追い抜いたときが「買い」の合図です。
  • 1つ前の時点ではサイン線がリード線より下だったのに、今、上になったときも「買い」の合図です。

エグジット条件

  • サイン線がリード線を上から下に追い抜いたときが「売って手じまい」する合図です。
  • 1つ前の時点ではサイン線がリード線より上だったのに、今、下になったときも「売って手じまい」する合図です。

リスク管理

大きな損をしないように、1回の取引で失ってもいい金額をあらかじめ決めておきます。例えば、「持っているお金の2%まで」という感じです。もし予想と反対に価格が動いて損が出始めたら、すぐに売って取引を終えることで、それ以上損が大きくならないようにします。

再現手順(HowTo)

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

【結果】パフォーマンス

価格の推移

価格推移

資産の推移

資産推移

パフォーマンス指標

指標
総トレード数6951回
勝率18.85%
平均利益0.48%
平均損失-0.59%
期待値-0.39%
プロフィットファクター0.18
最大ドローダウン100%
最終リターン-100%
シャープレシオ-2.29
HODL(Buy&Hold)20.86%

HODL戦略との比較

HODL戦略との比較

実装コード(Python)

strategy.py
"""
Hilbert Transform Trading Signal Generator
ヒルベルト変換を使用してサイクルとトレンドを検出
"""
import pandas as pd
import numpy as np


def calculate_hilbert_signals(df: pd.DataFrame,
                             period: int = 7) -> pd.DataFrame:
    """
    Hilbert Transform戦略のシグナル生成
    
    Parameters:
    -----------
    df : pd.DataFrame
        OHLCVデータ
    period : int
        基本期間(デフォルト: 7)
    
    Returns:
    --------
    pd.DataFrame
        シグナルが追加されたDataFrame
    """
    df = df.copy()
    
    # Weighted Close Price
    df['wcp'] = (df['high'] + df['low'] + 2 * df['close']) / 4
    
    # Smooth (4期間WMA)
    df['smooth'] = (4 * df['wcp'] + 3 * df['wcp'].shift(1) + 
                    2 * df['wcp'].shift(2) + df['wcp'].shift(3)) / 10
    
    # Detrender (高周波成分の除去)
    df['detrender'] = (0.0962 * df['smooth'] + 0.5769 * df['smooth'].shift(2) -
                       0.5769 * df['smooth'].shift(4) - 0.0962 * df['smooth'].shift(6)) * 0.075
    df['detrender'] = df['detrender'].shift(3)
    
    # Compute InPhase and Quadrature components
    df['q1'] = (0.0962 * df['detrender'] + 0.5769 * df['detrender'].shift(2) -
                0.5769 * df['detrender'].shift(4) - 0.0962 * df['detrender'].shift(6)) * 0.075
    df['i1'] = df['detrender'].shift(3)
    
    # Advance Phase components
    df['ji'] = (0.0962 * df['i1'] + 0.5769 * df['i1'].shift(2) -
                0.5769 * df['i1'].shift(4) - 0.0962 * df['i1'].shift(6)) * 0.075
    df['jq'] = (0.0962 * df['q1'] + 0.5769 * df['q1'].shift(2) -
                0.5769 * df['q1'].shift(4) - 0.0962 * df['q1'].shift(6)) * 0.075
    
    # Phasor components
    df['i2'] = df['i1'] - df['jq']
    df['q2'] = df['q1'] + df['ji']
    
    # Smooth the components
    df['i2'] = 0.2 * df['i2'] + 0.8 * df['i2'].shift(1).fillna(0)
    df['q2'] = 0.2 * df['q2'] + 0.8 * df['q2'].shift(1).fillna(0)
    
    # Homodyne Discriminator
    df['re'] = df['i2'] * df['i2'].shift(1) + df['q2'] * df['q2'].shift(1)
    df['im'] = df['i2'] * df['q2'].shift(1) - df['q2'] * df['i2'].shift(1)
    
    # Smooth
    df['re'] = 0.2 * df['re'] + 0.8 * df['re'].shift(1).fillna(0)
    df['im'] = 0.2 * df['im'] + 0.8 * df['im'].shift(1).fillna(0)
    
    # Compute Period
    df['period'] = 2 * np.pi / (np.arctan2(df['im'], df['re'] + 0.0001) + 0.0001)
    df['period'] = df['period'].clip(period * 0.67, period * 1.5)
    df['period'] = 0.2 * df['period'] + 0.8 * df['period'].shift(1).fillna(period)
    
    # Compute Phase
    df['phase'] = np.arctan2(df['q1'], df['i1'] + 0.0001) * 180 / np.pi
    
    # Sine and Lead Sine
    df['sine'] = np.sin(df['phase'] * np.pi / 180)
    df['lead_sine'] = np.sin((df['phase'] + 45) * np.pi / 180)
    
    # シグナル生成
    df['sine_prev'] = df['sine'].shift(1)
    df['lead_sine_prev'] = df['lead_sine'].shift(1)
    df['is_buy'] = (
        (df['sine'] > df['lead_sine']) & 
        (df['sine_prev'] <= df['lead_sine_prev'])
    ) & df['sine'].notna()
    df['is_sell'] = (
        (df['sine'] < df['lead_sine']) & 
        (df['sine_prev'] >= df['lead_sine_prev'])
    ) & df['sine'].notna()
    
    # 不要カラム削除
    drop_cols = ['wcp', 'smooth', 'detrender', 'q1', 'i1', 'ji', 'jq', 'i2', 'q2',
                 're', 'im', 'phase', 'sine_prev', 'lead_sine_prev']
    df.drop(drop_cols, axis=1, inplace=True, errors='ignore')
    
    return df

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

  1. 1この作戦の勝率は約19%と低く、平均すると1回の取引で少しずつ損をする計算になっていました。
  2. 2「もうけ」と「損」のバランスを示す数字(PF)が0.18と、とても低かったです。これは、もうけよりも損がずっと多かったことを意味します。
  3. 3最終的に、最初のお金が全部なくなってしまいました(最終リターン-100%)。また、取引の途中で、一時的にお金がゼロになるくらいまで減ってしまう場面がありました(最大ドローダウン100%)。

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

  1. 1この作戦は、過去のデータで試したところ、残念ながら利益を出すことができませんでした。なので、このまま使うのは危ないということが分かりました。
  2. 2計算上は面白そうな方法でも、実際にやってみて利益が出ないと意味がない、という大切な教訓になりました。
  3. 3勝率が低くても、1回勝ったときの利益が、負けたときの損失よりずっと大きければトータルでプラスになります。でも、この作戦は逆のパターンになっていたようです。

リスク管理の具体的手法

取引量の決め方

1回の取引で使うお金の量は、もし負けても全体のお金が大きく減らないように、あらかじめ決めておきます。例えば、全部のお金の1%とか2%とか、少ない量にするのが基本です。

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

もしも損が続いて、全体のお金が一定の割合(例えば10%)以上減ってしまったら、一度取引をお休みします。そして、作戦を見直したり、市場の様子が変わるのを待ったりします。

資金管理の方法

持っているお金の全部を取引に使うのではなく、一部だけを使います。残りは現金などで持っておき、万が一の事態にそなえることが大切です。

改良案の具体的提案

  • 計算に使う数字の設定(パラメータ)を色々と変えてみて、もっと良い結果が出ないか試してみる必要があります。
  • 取引の回数をへらして、「これは!」という確信が持てるタイミングだけで取引するように、ルールをもっと厳しくしてみます。
  • 他の分析ツール(例えば移動平均線など)と組み合わせて、「買い」や「売り」の合図が本物かどうかを確かめる工夫をします。これで、「だまし」の合図に引っかかるのを減らせるかもしれません。

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

  • この作戦は、このまま使うとお金を失う可能性がとても高いです。もし試すなら、まずはお小遣いのような本当に少ない金額でやるか、ゲームのお金で練習(シミュレーション)をたくさんしてください。
  • 5分ごとの取引は、値動きが速くてドキドキしやすいです。感情的にならずに、決めたルールを冷静に守ることがとても大事ですよ。
  • マーケットの状況はいつも変わっていきます。だから、この作戦がずっとうまくいくとは限りません。定期的に成績をチェックして、必要なら作戦を見直しましょう。

検証の透明性と信頼性

  • データの出所: この結果は、2024年10月から2025年8月までの「SOL/USDT」の過去の価格データを使った、練習試合(バックテスト)にもとづいています。
  • 検証のやり方: 取引回数、勝率、もうけと損のバランス(PF)、最終的なもうけ、最大でどれくらいお金が減ったか(最大DD)などの成績データを見て、作戦がうまくいったかを確かめています。
  • コード: この取引ルールをコンピューターで動かすためのプログラム(Pythonコード)が公開されています。
  • 注意事項: この説明は、過去のデータにもとづいたものです。未来でも同じように利益が出ることを保証するものではありません。投資には、お金が減ってしまうリスクが必ずあります。自分のお金を使うときは、自分の判断と責任で行ってくださいね。

よくある質問

Q.ヒルベルト変換って、一体何をしているの?

A.価格の「波の形」をくわしく調べて、「これから上がる勢いがあるかな?それとも下がる勢いかな?」を見つけようとする、特別な計算方法のことだよ。

Q.勝率がこんなに低いのは普通なの?

A.約19%というのは、かなり低い方だね。勝率が低くても、1回勝ったときの利益がすごく大きければ、全体ではプラスになることもあるんだ。でも、この作戦は残念ながらそうはならなかったみたい。

Q.PFって何?

A.PFは「プロフィットファクター」の略で、「もうけの合計」を「損の合計」で割った数字だよ。これが1より大きいと、もうけの方が多いってこと。この作戦は0.18だから、損の方がずっと多かったって意味になるね。

Q.最大DD100%って、どういうこと?

A.これは、取引の途中で、持っていたお金が一時的に全部なくなってしまうくらいまで減ってしまった、ということ。これは、その作戦がすごく危険だっていうサインなんだ。

Q.この戦略は、実際に使っても大丈夫?

A.この成績のままだと、大切なお金がなくなってしまう可能性がすごく高いから、使わない方が安全だよ。もしこの方法に興味があるなら、まずはゲームなどのお金で練習して、どうすればもっと良くなるか、たくさん研究してからの方がいいね。

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

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

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

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

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

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

Q.HODLとの比較結果は?

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

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

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

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

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

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

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

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

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

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

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

Q.改良の方向性は?

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

著者情報