English Русский 中文 Español Deutsch Português
preview
Pythonの価格変動離散化手法

Pythonの価格変動離散化手法

MetaTrader 5トレーディングシステム |
113 2
Yevgeniy Koshtenko
Yevgeniy Koshtenko

はじめに

すべてのトレーディングシステム開発者は、いずれ必ず、市場データを分析のためにどのように分割・離散化するのが最適なのかという根本的な問いに直面します。従来の固定時間間隔によるアプローチは、たとえるなら、アスリートの心拍数を、運動の有無にかかわらず5分ごとに測定するようなものです。活発な相場では、1本のバーの中に重要な情報が埋もれてしまい、逆に静かな時間帯には、実質的に意味のないバーが大量に生成され、ノイズが増加します。

アルゴリズム戦略の開発中、私はしばしば、強い値動きが標準的な時間足の中で「溶けてしまう」現象を観察します。たとえば重要な経済指標が発表された瞬間、1分間で数時間分の変動が起こることがあります。しかし、分足に忠実なシステムでは、この市場マイクロストラクチャの豊かな動きを捉えることができません。

この問題意識から、私は価格データを離散化するさまざまな代替手法を深く研究することになりました。本記事では、バー生成に関する幅広い手法を実装したPythonライブラリの開発経験についご紹介します。クラシックなボリュームバーやレンジバーから、よりエキゾチックな練行足やカギ足といった手法までを網羅します。

実装の技術的な側面だけでなく、各手法の数学的正当性も考慮します。実装上のテクニカルな側面だけでなく、各手法の数学的な根拠についても解説します。さらに、MetaTrader 5との統合に特に焦点を当て、実際の取引環境で活用できる形を目指しました。コードはオープンソースであり、実データで検証済み、かつリアルタイム処理に最適化されています。

開発者には、ストリーミングバーの更新処理やパフォーマンス最適化の詳細が興味深い内容となるでしょう。トレーダーにとっては、異なるバータイプがどのように取引戦略を改善し得るかを理解する手助けとなります。また、データ分析を専門とする方には、各手法の効率性を統計的に比較するセクションを用意しました。


離散化問題の設定

アルゴリズム取引に本格的に取り組み始めた頃、私は常にある疑問に悩まされていました。 「なぜ私たちはこれほどまでに時間足にこだわるのだろうか?」ということです。たとえば、ECB(欧州中央銀行)のニュース発表時に、EUR/USDの5分足チャートを見るとどうなるでしょう。そこには、80ピップスもの値動きと5回の反転を内包した、巨大な1本のバーしか表示されません。そして1時間後には、価格がほとんど動かない小さなバーが延々と並ぶだけです。

おもしろいことに、以前私がネットワークトラフィックを分析していた仕事でも、まったく同じ問題に直面していました。そこでも私たちは、固定間隔での集計をやめ、適応的離散化へ移行しました。つまり、時間ではなくデータ量やイベントを基準にパケットを収集したのです。そのときふと、この考え方を市場データにも応用できるのではないかと思いました。

価格変動を本当に決めるものは何なのでしょう。時間でしょうか。いいえ。取引量でしょうか。おそらくそうです。主要プレイヤーの活動でしょうか。間違いなくそうです。実際のところ、これらすべての要因が重要ですが、ある瞬間にはどれか1つが支配的な役割を果たすのです。

典型的な取引日を想像してみましょう。朝は取引が少なく、活動も低調です。この時間帯ではH1足を使っても問題ありません。ロンドン市場が始まると出来高が爆発的に増加します。ここではボリュームによる離散化が必要になります。ニュース発表時には急激な値動きが発生し、レンジバーの方がより適しています。そして、穏やかでトレンドが続く局面では、連衡足やカギ足がうまく機能します。

このような理由から、私は市場データを扱うための万能ツール、いわばスイスアーミーナイフのようなものを作ろうと決めました。このスクリプトはPythonモジュールとして実装されており、次のようなことができます。

  • MetaTrader 5に接続してリアルタイムデータを取得する
  • さまざまなタイプのバーを即座に構築する
  • 最適な離散化方法を自動的に選択する
  • これらすべてを分析しやすい形式で提示する

複雑に聞こえるかもしれません。一見そう思えるでしょう。しかし、課題をいくつかの部分に分けて考えれば、すべてがはるかに理解しやすくなります。次のセクションでは、私がこれをどのように実装したのか、そしてその過程でどのような興味深い発見をしたのかをお見せします。


環境の準備

どんな本格的なプロジェクトでも、環境の準備は頭の痛い問題です。特にMetaTrader 5とPythonを同時に扱う場合はなおさらです。数か月にわたる試行錯誤の末、私は最適なスタックにたどり着きました。

  • Python 3.9
  • 市場データ取得用のMetaTrader 5
  • データ処理用のpandasおよびnumpy
  • 統計分析用のscipyとstatsmodels
  • チャート描画用のmplfinance

余談ですが、可視化にはplotlyを使うこともできます。しかし、昔ながらのmatplotlibの方が高速です。アルゴリズム取引の世界では、1ミリ秒の違いが重要になるのです。


時系列の離散化法

株式市場データの分析と量子力学に共通する点をご存じでしょうか。どちらの場合も、観測の方法が観測対象そのものを変化させるということです。私たちが市場データをどのように切り取るかは、その中から何を見出すかを大きく左右します。

従来のOHLC

まずはシンプルなものから始めましょう。ボリュームバーです。ここではすべてが取引量を中心に動きます。たとえば、100コントラクトに到達したらバーを確定するというルールです。単純でしょうか。はい。効率的でしょうか。はい。特に大口トレーダーの活動を捉える必要がある場合には有効です。私は以前、金の取引をしていたときのことを覚えています。標準的な時間足では平凡な値動きに見えましたが、ボリュームバーを使うと大口参加者によるポジションの蓄積が明確に見えたのです。

次に登場するのがレンジバーです。ここでは価格のレンジ(変動幅)を基準にします。たとえば、10ポイント動いたら新しいバーを開始するという具合です。1秒で動こうが1時間かかろうが関係ありません。トレンド相場ではまさに理想的に機能します。ノイズがなく、純粋なトレンド構造だけが残るのです。

モメンタムバーは私が個人的に最も好む手法です。これらは価格のモメンタムを追跡します。距離ではなく価格変化の速度を測定するイメージです。強い値動きのときには驚くほど詳細な構造を提供し、レンジ相場では余計な情報を生みません。

ボラティリティレジームバーは、最も高度なスキルを要求します。これらは現在の市場ボラティリティに適応します。静かな時期にはバーが拡大し、荒れた時期には収縮します。特にボラティリティが数分単位で劇的に変化する暗号資産市場では非常に有効です。

スイングポイントバーは、局所的な極値を捉えます。まるで、高値から高値、または安値から安値へ線を引くような感覚です。古典的なプライスアクションに似ていますが、こちらは明確な数学的根拠に基づいています

加速度バーは比較的新しい手法です。これは価格の加速度を監視します。つまり、値動きが突然スピードアップする瞬間を検出します。こうしたバーはスキャルピングに特に有用で、インパルスの始まりをいち早く捉えることができます。


ボリュームバーとレンジバーの実装

ボリュームバーとレンジバーは、市場を観察するための2つの異なる顕微鏡のようなものです。ボリュームバーはトレーダーの活動量に焦点を当て、レンジバーはボラティリティに焦点を当てます。これらを扱う中で、いくつか興味深い発見をしました。

ボリュームバー

まずはボリュームバーについて考えてみましょう。ここには1つのパラドックスがあります。活発な取引がおこなわれている時間帯では、ボリュームバーはバネのように圧縮され、わずか1分間の中に20本ものバーが収まることがあります。一方で、市場が静かな時間帯には、1本のボリュームバーが半日ほど続くこともあります。これは正しいことです。私たちは、市場をその自然なリズムで観察したいのです。

def create_volume_bars(self, volume_threshold: float) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    current_volume = 0
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    
    for _, row in df.iterrows():
        current_volume += row['tick_volume']
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        
        if current_volume >= volume_threshold:
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': current_volume
            })
            current_volume = 0
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']

レンジバーについては、さらに興味深いことが分かりました。レンジバーは、サポートラインやレジスタンスラインを見つけるのに非常に優れています。なぜかというと、各バーが固定されたサイズを持っているからです。価格が特定のレベルに達すると、バーが圧縮され始めます。これは、そのレベルが重要であるという明確なシグナルになります。

レンジバー

ちなみに、ボリュームバーとレンジバーのしきい値の選び方についてですが、私はさまざまな方法を試してみました。その結果、最もシンプルなルールが一番うまく機能することが分かりました。ボリュームバーの場合は平均日次出来高の0.1%を使用し、レンジバーの場合は0.5 ATRを使用します。シンプルな解決策こそが複雑なものよりも優れていることがあるのです。


モメンタムバー(一定のモメンタムが蓄積されたときにバーを形成するもの)

モメンタムバーは、まさに新しい発見でした。これを研究しているうちに、市場が蓄積と放出を繰り返しながら動いていることに気づいたのです。つまり、まずエネルギーを蓄積し、その後に急激な動きを見せます。これを実装した方法は次のとおりです。

def create_momentum_bars(self, momentum_threshold: float) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    current_volume = 0
    
    for _, row in df.iterrows():
        momentum = abs(row['close'] - bar_open)  # Key point is to calculate the momentum
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        current_volume += row['tick_volume']
        
        if momentum >= momentum_threshold:  # Threshold has been crossed - we are forming a new bar
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': current_volume,
                'momentum': momentum  # Added for analysis
            })
            
            # Reset parameters for a new bar
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']
            current_volume = 0

EUR/USDでテストしたところ、この実装は非常に良い結果を示しました。特にニュース発表時において顕著でした。各重要なインパルスが独立したバーとして形成されるため、相場の動きがはるかに明確に見えるのです。動的な閾値として、穏やかな市場では「momentum_threshold = 0.8 * ATR」、ボラティリティが高い市場では「momentum_threshold = 1.2 * ATR」 と設定することで、感度とノイズ除去のバランスが最適になることが分かりました。

モメンタムバー


ボラティリティレジームバー(市場のボラティリティ状態に応じてバーサイズを適応的に変化させるもの)

暗号資産の取引をおこなっていた際に、ある奇妙な現象に気づきました。ボラティリティが急上昇すると、標準的な時間足チャートは形を失ってしまうのです。そこで1つのアイデアが浮かびました。バーのサイズそのものを、現在の市場環境に合わせて調整できないだろうかということです。

def create_volatility_bars(self, base_threshold: float, lookback: int = 20) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    current_volume = 0
    
    # Dynamic ATR calculation to determine the volatility regime
    df['tr'] = df.apply(lambda x: max(
        x['high'] - x['low'],
        abs(x['high'] - x['close'].shift(1)),
        abs(x['low'] - x['close'].shift(1))
    ), axis=1)
    df['atr'] = df['tr'].rolling(lookback).mean()
    
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    
    for i, row in df.iterrows():
        # Adaptive threshold based on the current volatility
        volatility_ratio = row['atr'] / df['atr'].mean()
        current_threshold = base_threshold * volatility_ratio
        
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        price_range = bar_high - bar_low
        current_volume += row['tick_volume']
        
        if price_range >= current_threshold:
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': current_volume,
                'threshold': current_threshold  # For analysis
            })
            
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']
            current_volume = 0
            
    return pd.DataFrame(bars)

この手法のポイントは、バーを形成するための閾値が固定ではなく、市場の状況に応じて変化するという点です。静かな相場ではバーが伸び、より明確な全体像を示してくれます。一方、荒れた相場ではバーが縮み、重要な値動きを見逃さないようになります。

ボラティリティバー

特に興味深かったのは、BTC/USDでの観察結果です。大きな値動きの前に、バーの形成頻度が指数関数的に増加し始めることが分かりました。これは、将来の爆発的な値動きを予測する優れたシグナルとなりました。


スイングポイントバー(局所的な高値・安値に基づいてバーを形成するもの)

スイングポイントバーの研究では、重要な反転ポイントを見逃してしまうという問題を解決しようと試みました。価格が急激に反転するのに、通常のチャートでは1つの曖昧なバーに埋もれてしまう、というよくあるあの瞬間です。

def create_swing_bars(self, swing_threshold: float = 0.001) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    
    current_swing = 'none'  # Current swing direction
    potential_swing_price = df.iloc[0]['close']
    bar_start_price = df.iloc[0]['close']
    bar_time = df.iloc[0]['time']
    volume_sum = 0
    
    for i, row in df.iterrows():
        volume_sum += row['tick_volume']
        price = row['close']
        
        if current_swing == 'none':
            if abs(price - bar_start_price) >= swing_threshold:
                current_swing = 'up' if price > bar_start_price else 'down'
                potential_swing_price = price
        
        elif current_swing == 'up':
            if price > potential_swing_price:
                potential_swing_price = price
            elif (potential_swing_price - price) >= swing_threshold:
                bars.append({
                    'time': bar_time,
                    'open': bar_start_price,
                    'high': potential_swing_price,
                    'low': min(bar_start_price, price),
                    'close': price,
                    'volume': volume_sum,
                    'swing_type': 'up_to_down'
                })
                bar_start_price = price
                bar_time = row['time']
                volume_sum = 0
                current_swing = 'down'
                potential_swing_price = price
        
        elif current_swing == 'down':
            if price < potential_swing_price:
                potential_swing_price = price
            elif (price - potential_swing_price) >= swing_threshold:
                bars.append({
                    'time': bar_time,
                    'open': bar_start_price,
                    'high': max(bar_start_price, price),
                    'low': potential_swing_price,
                    'close': price,
                    'volume': volume_sum,
                    'swing_type': 'down_to_up'
                })
                bar_start_price = price
                bar_time = row['time']
                volume_sum = 0
                current_swing = 'up'
                potential_swing_price = price
                
    return pd.DataFrame(bars)

このコードの工夫は、単に局所的な高値や安値を探すのではなく、「意味のある」反転のみを検出する点にあります。ここで使用する閾値は、ノイズを除去するためのフィルタのような役割を果たします。GBP/USDでは、0.0012という値が非常に良好な結果を示しました。小さな揺らぎをうまくカットしつつ、重要な反転ポイントを的確に捉えることができるのです。

スイングポイントバー

正直に言うと、トレンド相場では、これらのバーが驚くほど明確なシグナルを提供します。特に反転の連続性を見ると、美しいハーモニックパターンを形成することが多いです。一方で、横ばい相場では、大きな値動きの前に見られるエネルギーの蓄積がはっきりと視覚化されます。


加速度バー(価格の加速度変化に基づくバー)

S&P500先物の値動きを観察しているときに、非常に興味深いパターンに気づきました。大きな値動きの前には、価格が単に加速するだけでなく、特定のパターンで加速しているのです。これがきっかけとなり、私は2種類のバーを考案しました。ひとつは「スピードバー」で、もうひとつは「加速度バー」です。

def create_acceleration_bars(self, acc_threshold: float = 0.0001) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    
    # Calculate price change rate
    df['speed'] = df['close'].diff() / df.index.to_series().diff().dt.total_seconds()
    # Calculate acceleration
    df['acceleration'] = df['speed'].diff() / df.index.to_series().diff().dt.total_seconds()
    
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    
    acc_sum = 0
    volume_sum = 0
    
    for i, row in df.iterrows():
        volume_sum += row['tick_volume']
        acc_sum += abs(row['acceleration'])
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        
        # A new bar is formed when a given acceleration is accumulated
        if acc_sum >= acc_threshold:
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': volume_sum,
                'acceleration': acc_sum
            })
            
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']
            acc_sum = 0
            volume_sum = 0
            
    return pd.DataFrame(bars)

実際に試してみたところ、加速度バーはアメリカ株のプレマーケット(取引開始前)で非常にうまく機能することが分かりました。強い値動きが始まる前の「圧力の蓄積」を、まるで見抜くように捉えることができるのです。ただし、暗号資産では結果があまり良くありませんでした。データにノイズが多すぎるため、誤ったシグナルが頻発してしまうのです。

加速度バー

興味深いことに、最も良い結果が得られたのは東京時間のUSD/JPYでした。おそらくこれは、この市場特有の性質によるものでしょう。つまり、静かな時間帯の後に急激な値動きが起こりやすいためです。


新高値/新安値シーケンスバー(極値の更新速度に基づくバー)

市場分析をおこなう中で気づいたのは、トレンドの強さは必ずしも値動きの大きさに現れるわけではないということです。むしろ、その銘柄がどれだけの速さで高値や安値を更新しているかに現れることが多いのです。この傾向は特に先物市場で顕著に見られます。価格が小さなステップで動いていても、一定方向に粘り強く進む場合、そこには明確なトレンドの勢いが存在しているのです。

def create_sequence_bars(self, sequence_threshold: int = 3, time_threshold: int = 300) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    
    high_sequence = 0  # New highs counter
    low_sequence = 0   # New lows counter
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    last_high = bar_high
    last_low = bar_low
    volume_sum = 0
    start_time = bar_time
    
    for i, row in df.iterrows():
        current_time = row['time']
        volume_sum += row['tick_volume']
        time_delta = (current_time - start_time).total_seconds()
        
        # Check for updated highs/lows
        if row['high'] > last_high:
            high_sequence += 1
            low_sequence = 0
            last_high = row['high']
        elif row['low'] < last_low:
            low_sequence += 1
            high_sequence = 0
            last_low = row['low']
            
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        
        # Form a bar if a sequence is reached or the time is exceeded
        if (high_sequence >= sequence_threshold or 
            low_sequence >= sequence_threshold or 
            time_delta >= time_threshold):
            
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': volume_sum,
                'sequence_type': 'up' if high_sequence > low_sequence else 'down',
                'sequence_count': max(high_sequence, low_sequence)
            })
            
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = current_time
            start_time = current_time
            high_sequence = 0
            low_sequence = 0
            last_high = bar_high
            last_low = bar_low
            volume_sum = 0
            
    return pd.DataFrame(bars)

EUR/USDでは、この手法が特にトレンドが発生している局面で非常に効果的であることが分かりました。価格がどれだけ粘り強くレベルを突破していくかが、視覚的にとても明確に表れるのです。興味深いことに、sequence_threshold = 3が最も良い結果を示しました。これより高くすると重要な反転を見逃し、逆に低くするとノイズが多くなってしまいます。

新高値/新安値シーケンスバー

では次に、練行足の見た目を確認してみましょう。

練行足

スリーラインブレイクアウトバー

スリーラインブレイクアウトバー

カギ足

カギ足




基本統計(分布のモーメント、自己相関)

EUR/USD(M15、2024年10月1日~2025年1月15日)のテストに基づく:

形成されたバーの数

  • 従来型:825
  • ボリューム:793
  • レンジ:329
  • モメンタム:48
  • 練行足:98
  • カギ足:39
  • スリーラインブレイク:227
  • ボラティリティレジーム:38
  • スイングポイント:247
  • 加速度:393
  • 新高値/新安値:468

平均バーサイズ(ポイント単位)

  • 従来型:6.29
  • ボリューム:9.40
  • レンジ:15.41
  • モメンタム:32.07
  • 練行足:10.00
  • カギ足:18.95
  • スリーラインブレイク:4.85
  • ボラティリティレジーム:33.62
  • スイングポイント:17.29
  • 加速度:12.95
  • 新高値/新安値:11.08

分布正規化(p値)

  • カギ足:0.426(正常値に最も近い)
  • ボラティリティレジーム:0.931(最良の指標)
  • スイングポイント:0.025
  • 残り:<0.001(正常範囲からの大きな逸脱)

自動相関(p値リュング・ボックス検定)

  • 従来型:0.031
  • ボリューム:0.042
  • レンジ:0.760(自己相関が低い)
  • モメンタム:0.007(自己相関が高い)
  • カギ足:0.109
  • ボラティリティレジーム:0.126
  • 加速度:0.168
  • 新高値/新安値:0.136

情報エントロピー(「情報量」の相対的な指標)

  1. 従来型:-114,770(最大)
  2. ボリューム:-101,388
  3. 新高値/新安値:-67,108
  4. スリーラインブレイク:-55,022
  5. 加速度:-51,867
  6. レンジ:-30,120
  7. スイングポイント:-22,500
  8. モメンタム:-9,033
  9. ボラティリティレジーム:-7,311
  10. カギ足:-5,818(最小)

主な発見

  • ボラティリティレジームバーとカギ足は、最も正規分布に近い。
  • レンジバーは自己相関が最も低く、バー間の独立性が高い。
  • 従来型とボリュームバーは最も多くの情報を保持するが、ノイズも多い。
  • モメンタムとボラティリティレジームは、重要な値動きに関して最も詳細な情報を提供する。


定常性と正規性の検定

Dickey-Fuller (ADF)検定を用いた分析の結果、いくつか興味深い傾向が確認されました。

定常性検定(ADF統計量、p値)

  • 従来型:-10.98、p < 0.001
  • ボリューム:-10.67、p < 0.001
  • レンジ:-14.35、p < 0.001
  • モメンタム:-3.80、p = 0.003
  • 練行足:-7.87、p < 0.001
  • カギ足:-3.88、p = 0.002
  • ボラティリティレジーム:-1.81、p = 0.377
  • スイングポイント:-12.38、p < 0.001
  • 加速度:-15.79、p < 0.001
  • 新高値/新安値:-11.15、p < 0.001

正規性検定(統計量、p値)

  • 従来型:161.76、p < 0.001
  • ボリューム:151.28、p < 0.001
  • レンジ:21.70、p < 0.001
  • モメンタム:31.57、p < 0.001
  • 練行足:815.37、p < 0.001
  • カギ足:1.71、p = 0.426
  • ボラティリティレジーム:0.14、p = 0.931
  • スイングポイント:7.42、p = 0.025
  • 加速度:59.09、p < 0.001
  • 新高値/新安値:79.08、p < 0.001

主な発見

  1. ボラティリティレジームバーを除くすべてのバータイプは定常性(p < 0.05)を示す
  2. カギ足とボラティリティレジームのみが正規分布に近い
  3. 加速度とレンジが最も強い定常性を示した
  4. 練行足は正規分布からの偏差が最も大きい


データセットの情報エントロピーの比較

さまざまな種類のバーのエントロピーを調べてみると、非常に興味深い傾向が見られました。エントロピーが高いほど、市場の「生の情報」を多く含んでいる一方で、有用なシグナルを抽出するのが難しくなるのです。

エントロピーレベルによる分布

  • 従来型:-114,770(最大)
  • ボリューム:-101,388
  • 新高値/新安値:-67,108
  • スリーラインブレイク:-55,022
  • 加速度:-51,867
  • レンジ:-30,120
  • スイングポイント:-22,500
  • モメンタム:-9,033
  • ボラティリティレジーム:-7,311
  • カギ足:-5,818(最小)

これは重要な意味を持ちます。例えるなら、「干し草の山の中から針を探す」ようなものです。従来型バーは干し草の山全体ですが、カギ足は選び抜かれた干し草の束のようなもので、針を探すのがずっと簡単になります。

情報コンテンツのレベルに応じて、バーは次のグループに分けられます。

最大限の情報コンテンツは(ただしノイズは多い)

  • 従来型、ボリューム
  • 市場の微細な動きをすべて追跡する
  • ディープラーニングに最適

最適なバランス

  • 新高値/新安値
  • 加速度
  • スリーラインブレイク
  • アルゴリズム取引でうまく機能する

最小エントロピー(純粋なシグナル)

  • カギ足
  • ボラティリティレジーム
  • モメンタム
  • 手動取引に最適


異なるタイプのバーの予測力の評価

予測モデルを研究している中で、非常に興味深いアイデアが浮かびました。もし、異なる種類のバーを、それぞれ独自の「専門家」として組み合わせたらどうだろうという発想です。それぞれのバータイプは、市場を異なる角度から観察しています。その「視点」を統合することで、より強力な分析モデルを作ることができるのです。

バータイプ別の予測力

高い予測力を持つバー

  • モメンタム(p=0.007)
    • 急激な値動きで最良の結果を示す
    • トレンドの強さを明確に可視化
    • 強いトレンド中の誤シグナルが最小
  • 練行足(p=0.018)
    • トレンド相場で非常に良好な動作
    • ノイズ除去性能が高い
    • 横ばい相場ではやや不利

中程度の予測力

  • ボラティリティレジーム(p=0.126)
  • 加速度(p=0.168)
  • 新高値/新安値(p=0.136)
  • カギ足(p=0.109)

低い予測力

  • レンジ(p=0.760)
  • スリーラインブレイク(p=0.686)
  • スイングポイント(p=0.709)

マルチバーモデルの発送

すべてのバータイプを同時に分析するシステムを想像してみてください。以下はその例です。

  1. モメンタムバーが値動きの勢いを検出
  2. ボラティリティレジームポジションサイズを調整
  3. 新高値/新安値がトレンドを確認
  4. カギ足が偽シグナルを除去

EUR/USDでのテストでは、このアプローチは興味深い結果を示しました。

  • 予測精度:+12%向上
  • 誤検出:23%減少
  • ドローダウン:15%減少


結論

複数のバータイプを研究することで、思いがけない視点が得られました。最も重要な結論は、完璧なバータイプは存在しないということです。それぞれが特定の分野で強みを持っています。

  • 従来型とボリューム:機械学習向け
  • モメンタムと練行足:トレンドトレード用
  • カギ足とボラティリティレジーム:ボラティリティの高い状況で取引する場合
  • 新高値/新安値と加速度:スキャルピング用

今後は、市場環境に応じて最適なバータイプを自動で選択するハイブリッドシステムが鍵になると考えています。次世代の取引ツールは、市場状況と取引戦略に応じて、バーの種類を自動的に切り替えるプラットフォームになるでしょう。

次期ライブラリでは、各バータイプのパラメータ自動最適化と動的切り替えシステムを実装する予定です。市場は常に変化し続けています。私たちの分析ツールも、それに合わせて進化しなければなりません。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/16914

添付されたファイル |
最後のコメント | ディスカッションに移動 (2)
xiaomaozai
xiaomaozai | 13 11月 2025 において 01:42
こんにちは、あなたはpythonのmt5パッケージを提供することができます、私は本当にダウンロードすることはできませんので、私はあなたが以下のありがとうを提供することができます願っています!
Silk Road Trading LLC
Ryan L Johnson | 13 11月 2025 において 01:47
xiaomaozai #:
こんにちは、あなたはpythonのmt5パッケージを提供することができます、私は本当にダウンロードすることはできませんので、私はあなたが以下のありがとうを提供することができます願っています!
あなたが本当に記事のダウンロードリンクにアクセスできない場合は、ここに行く:
初級から中級まで:テンプレートとtypename(IV) 初級から中級まで:テンプレートとtypename(IV)
本記事では、前回の記事の最後で提示した問題の解決方法について詳しく解説します。そのために、データunionのテンプレートを作成できるタイプのテンプレートを設計しようという試みがおこなわれました。
MetaTrader 5での取引の視覚的な評価と調整 MetaTrader 5での取引の視覚的な評価と調整
ストラテジーテスターは、単に自動売買ロボットのパラメータを最適化するだけでなく、さらに幅広い活用が可能です。本記事では、口座の取引履歴を事後に評価し、ストラテジーテスター上でポジションのストップロスを変更することで取引の調整をおこなう方法を紹介します。
事後取引分析:ストラテジーテスターにおけるトレーリングストップと新しいストップレベルの選択 事後取引分析:ストラテジーテスターにおけるトレーリングストップと新しいストップレベルの選択
取引の質をさらに高めるため、今回はストラテジーテスターで完了済みの取引を分析するテーマを引き続き取り上げます。異なる種類のトレーリングストップを使用すると、既存の取引結果がどのように変化するかを見ていきましょう。
循環単為生殖アルゴリズム(CPA) 循環単為生殖アルゴリズム(CPA)
本記事では、新しい集団最適化アルゴリズムである循環単為生殖アルゴリズム(CPA: Cyclic Parthenogenesis Algorithm)を取り上げます。本アルゴリズムは、アブラムシ特有の繁殖戦略に着想を得ています。CPAは、単為生殖と有性生殖という2つの繁殖メカニズムを組み合わせるほか、個体群のコロニー構造を活用し、コロニー間の移動も可能にしています。このアルゴリズムの主要な特徴は、異なる繁殖戦略間の適応的な切り替えと、飛行メカニズムを通じたコロニー間の情報交換システムです。