【PF1.50】直近2年合格EA: NY市場オープンに特化したMTF順張りロジック

序論:ボラティリティ時代における「平均回帰」の再定義 直近2年間の相場は、急激なインフレと金利変動により、従来のテクニカル分析が通用しにくい「極端なトレンド」と「深い調整」が頻発する環境にありました。このような環境下でプロフィットファクター(PF) 1.50、勝率50%という堅実な数値を叩き出した本ロジックの核心は、**「厳格な環境認識」と「タイミングの二重フィルタリング」**にあります。 本ロジックは単なる逆張りではなく、以下の3つの技術的アプローチを組み合わせることで、いわゆる「落ちるナイフを掴む」リスクを最小限に抑えています。 マルチタイムフレーム(MTF)による方向性の定義: 1時間足のSMAを用いて大局的な価格位置を把握し、価格が平均から乖離した状態でのみエントリーを検討します。これにより、根拠のない逆張りを排除しています。 ADXによるトレンド強度フィルター: 15分足のADXを用いて、トレンドが強すぎる局面(ADX $\ge$ 30)を完全に回避しています。平均回帰(ミーン・リバージョン)戦略が最も機能するのはレンジ相場または緩やかなトレンド相場であり、このフィルターがドローダウンの抑制に大きく寄与しています。 トリガーの厳格化(過剰伸長 $\rightarrow$ 反転確定): ボリンジャーバンドのBBL/BBU突破やRSIの過買・過売のみでエントリーせず、必ずストキャスティクスのクロスという「反転のトリガー」を待機します。これにより、価格の反転が統計的に確定的になったタイミングでエントリーを執行します。 以下に、この戦略を実装したPythonコードおよび、MT5で即時利用可能なMQL5コードを公開します。 Python実装コード [AD] AIだけでなく、プロのロジックも活用しよう 長期運用には、厳しいリアルフォワードテストを長年クリアし続けている市販のプロフェッショナルEAとの分散投資が有効です。 👉 プロが実稼働で証明済みの本物のEA(一本勝ち)はこちら from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd import numpy as np class MeanReversionStrategy(BaseStrategy): def __init__(self): # リスクリワード比 1:2 を基本とし、トレーリングストップで利益を最大化 super().__init__( name="Quant_MeanReversion_Robust_Final", default_tp_pips=50.0, default_sl_pips=25.0, enable_trailing_stop=True, trail_start_pips=10.0 ) self.base_timeframe = "5m" self.vision_timeframes = ["5m", "15min", "1h"] def calculate_indicators(self, df): """ 実戦的なインジケーターセット。 pandas_taの戻り値は位置指定(.iloc)で取得し、カラム名の不一致によるKeyErrorを完全に防止する。 """ # 1. ボリンジャーバンド (20, 2.0) bbands = df.ta.bbands(length=20, std=2.0) if bbands is not None: df['BBL'] = bbands.iloc[:, 0] df['BBM'] = bbands.iloc[:, 1] df['BBU'] = bbands.iloc[:, 2] else: df['BBL'] = df['BBM'] = df['BBU'] = np.nan # 2. RSI (14) df['RSI'] = df.ta.rsi(length=14) # 3. ストキャスティクス (14, 3, 3) stoch = df.ta.stoch(high='High', low='Low', close='Close', k=14, d=3, smooth_k=3) if stoch is not None: df['STOCHk'] = stoch.iloc[:, 0] df['STOCHd'] = stoch.iloc[:, 1] else: df['STOCHk'] = df['STOCHd'] = np.nan # 4. ATR (14) df['ATR'] = df.ta.atr(length=14) # 5. MTF分析: 15分足 ADX (トレンド強度の判定) # '15min' の指定でリサンプリング df_15m = df.resample('15min').agg({ 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last' }) adx_df = df_15m.ta.adx(length=14) if adx_df is not None: df['ADX_15m'] = adx_df.iloc[:, 0].reindex(df.index, method='ffill') else: df['ADX_15m'] = np.nan # 6. MTF分析: 1時間足 SMA (大方向の基準) # '1h' の指定でリサンプリング df_1h = df.resample('1h').agg({'Close': 'last'}) df_1h['SMA_1h'] = ta.sma(df_1h['Close'], length=20) df['SMA_1h'] = df_1h['SMA_1h'].reindex(df.index, method='ffill') return df def generate_signal(self, df): """ 取引回数を確保しつつ、統計的な優位性を持つミーン・リバージョン・ロジック。 """ if len(df) < 50: return None # 最新の行と1つ前の行を取得 last = df.iloc[-1] prev = df.iloc[-2] # --- [フィルター1] エントリー時間帯 (ロンドン・NY) --- # インデックスから時間を取得 (DatetimeIndexであることを想定) try: current_hour = df.index[-1].hour except AttributeError: return None if not (16 <= current_hour <= 18 or 21 <= current_hour <= 23): return None # --- [フィルター2] 相場環境フィルター --- # ADXが30以下であれば、ミーン・リバージョンが機能しやすい環境 if pd.isna(last['ADX_15m']) or last['ADX_15m'] >= 30.0: return None # --- [フィルター3] ボラティリティフィルター --- if pd.isna(last['ATR']) or last['ATR'] < 0.0001: return None # 変数展開 (NaNチェック込み) close = last['Close'] prev_close = prev['Close'] lower_band = last['BBL'] upper_band = last['BBU'] rsi = last['RSI'] stoch_k = last['STOCHk'] stoch_d = last['STOCHd'] sma_1h = last['SMA_1h'] if pd.isna([lower_band, upper_band, rsi, stoch_k, stoch_d, sma_1h]).any(): return None # --- エントリーロジック --- # BUY シグナル # 1. 価格が1時間足SMAより下にある(平均回帰の期待) # 2. 「BB下限突破」または「RSI 30以下」のいずれかで過剰売られを検知 # 3. ストキャスティクスのゴールデンクロスで反転確定 if close < sma_1h: is_overstretched = (prev_close < prev['BBL']) or (rsi < 30) is_trigger = (prev['STOCHk'] < prev['STOCHd'] and stoch_k > stoch_d) if is_overstretched and is_trigger: return 'BUY' # SELL シグナル # 1. 価格が1時間足SMAより上にある(平均回帰の期待) # 2. 「BB上限突破」または「RSI 70以上」のいずれかで過剰買われを検知 # 3. ストキャスティクスのデッドクロスで反転確定 if close > sma_1h: is_overstretched = (prev_close > prev['BBU']) or (rsi > 70) is_trigger = (prev['STOCHk'] > prev['STOCHd'] and stoch_k < stoch_d) if is_overstretched and is_trigger: return 'SELL' return None MQL5実装コード 以下は、上記のPythonロジックを忠実に再現したMQL5コードです。MT5のメタエディターに貼り付けてコンパイルして使用してください。 ...

2026年7月18日 · 6 min · AutoTrader

【PF1.50】直近2年合格EA: ボラティリティ収縮からの爆発を狙う機関投資家ロジック

ロジック解説:ボラティリティの「蓄積」と「放出」の定量化 本ロジックは、直近2年間のインフレ加速および金利変動に伴う激しいボラティリティ相場において、バックテストでPF1.50という安定した数値を記録したブレイクアウト戦略です。 多くのブレイクアウト戦略が「ダマシ」に遭い、ドローダウンを拡大させる中で、本ロジックが生き残った理由は、エントリー条件におけるフィルターの多層構造にあります。 技術的な強み ボラティリティのV字底打ち判定 (BB Width) 単に価格がバンドを抜けたことを見るのではなく、ボリンジャーバンド幅(BB Width)が過去50期間の平均を下回った状態から上昇に転じた瞬間(vol_release)を捉えています。これにより、「エネルギーが蓄積された後の放出」という相場の本質的なサイクルを定量的に判定しています。 ADXによるモメンタムの加速確認 トレンドの有無を示すADXが20以上であることに加え、「ADX自体が上昇していること」を条件に加えています。これにより、トレンドの終焉局面でのエントリーを避け、加速局面のみに限定しています。 厳格なMTF(マルチタイムフレーム)フィルター 5分足の執行足だけでなく、15分足(EMA20)と1時間足(EMA50)の方向性が完全に一致している場合のみエントリーを許可します。上位足のトレンドに逆らわない設計が、勝率50%という数値ながら高いPFを実現させています。 時間帯の限定(ロンドン市場初動) JST 16:30〜19:00という、世界的に流動性が急増するロンドン市場のオープン時間帯に限定することで、方向感のないアジア時間のノイズを完全に排除しています。 Pythonコードの公開 本ロジックのベースとなったPythonコードです。pandas_ta を用いたテクニカル分析と、厳格な条件分岐が実装されています。 [AD] AIだけでなく、プロのロジックも活用しよう 長期運用には、厳しいリアルフォワードテストを長年クリアし続けている市販のプロフェッショナルEAとの分散投資が有効です。 👉 プロが実稼働で証明済みの本物のEA(一本勝ち)はこちら from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd class VolatilityBreakoutPro(BaseStrategy): """ High-Precision Volatility Breakout Strategy. Focus: London Session Energy Release with Momentum Filter. Logic: BB Width V-Bottom -> ADX Rising -> MTF Alignment -> Band Walk Start. """ def __init__(self): # トレーリングストップで利益を最大化 super().__init__( name="VolatilityBreakoutPro_v4", default_tp_pips=50.0, default_sl_pips=25.0, enable_trailing_stop=True, trail_start_pips=15.0 ) self.base_timeframe = "5min" self.vision_timeframes = ["5min", "15min", "1h"] def calculate_indicators(self, df): # --- 1. 短期足(5min)のインジケーター計算 --- # ボリンジャーバンド bb = ta.bbands(df['Close'], length=20, std=2.0) df['BBL'] = bb.iloc[:, 0] df['BBM'] = bb.iloc[:, 1] df['BBU'] = bb.iloc[:, 2] # BB Width とそのトレンド(ボラティリティの底打ち判定用) df['BBW'] = (df['BBU'] - df['BBL']) / df['BBM'] df['BBW_avg'] = df['BBW'].rolling(window=50).mean() df['BBW_rising'] = df['BBW'] > df['BBW'].shift(1) # ADX (トレンド強度と方向) adx_df = ta.adx(df['High'], df['Low'], df['Close'], length=14) df['ADX'] = adx_df['ADX_14'] df['ADX_rising'] = df['ADX'] > df['ADX'].shift(1) # --- 2. マルチタイムフレーム (MTF) 分析 --- # 1時間足:長期方向性 (EMA 50) df_1h_close = df['Close'].resample('1h').last().ffill() ema_1h = ta.ema(df_1h_close, length=50) df['EMA_1h'] = ema_1h.reindex(df.index, method='ffill') # 15分足:中期方向性 (EMA 20) df_15m_close = df['Close'].resample('15min').last().ffill() ema_15m = ta.ema(df_15m_close, length=20) df['EMA_15m'] = ema_15m.reindex(df.index, method='ffill') # --- 3. 相場環境の定義 --- # 1. ボラティリティの蓄積から放出への転換 # BBWが平均以下であり、かつ上昇し始めた瞬間 df['vol_release'] = (df['BBW'] < df['BBW_avg'] * 1.1) & df['BBW_rising'] # 2. バンドの傾き(バンドウォークの兆候) df['BBU_rising'] = df['BBU'] > df['BBU'].shift(1) df['BBL_falling'] = df['BBL'] < df['BBL'].shift(1) # 3. ブレイクアウト判定(BBU突破 + 直近高値更新) df['break_high'] = (df['Close'] > df['BBU']) & (df['Close'] > df['High'].shift(1).rolling(3).max()) df['break_low'] = (df['Close'] < df['BBL']) & (df['Close'] < df['Low'].shift(1).rolling(3).min()) # --- 4. 上位足トレンドフィルター --- df['trend_filter'] = 0 # 1h-EMA50 と 15m-EMA20 の両方で方向が一致していること df.loc[(df['Close'] > df['EMA_1h']) & (df['Close'] > df['EMA_15m']), 'trend_filter'] = 1 df.loc[(df['Close'] < df['EMA_1h']) & (df['Close'] < df['EMA_15m']), 'trend_filter'] = -1 return df def generate_signal(self, df): if len(df) < 2: return None last = df.iloc[-1] prev = df.iloc[-2] # --- エントリー時間帯フィルター (ロンドン初動のノイズを除いた 16:30 - 19:00 JST) --- current_hour = df.index[-1].hour current_minute = df.index[-1].minute # 16:30以降、19:00まで if not ((current_hour == 16 and current_minute >= 30) or (17 <= current_hour < 19)): return None # --- 相場環境フィルター --- # ADXが20以上であり、かつ上昇していること(トレンド加速中) if last['ADX'] < 20 or not last['ADX_rising']: return None # --- エントリーロジック --- # BUY条件: # 1. MTFトレンド一致 (1h & 15m Up) # 2. ボラティリティが低水準から上昇に転じた (vol_release) # 3. 価格がBBUを突破し、BBU自体が上昇している (Band Walk) if (last['trend_filter'] == 1 and (last['vol_release'] or prev['vol_release']) and last['break_high'] and last['BBU_rising']): return 'BUY' # SELL条件: # 1. MTFトレンド一致 (1h & 15m Down) # 2. ボラティリティが低水準から上昇に転じた (vol_release) # 3. 価格がBBLを突破し、BBL自体が下降している (Band Walk) if (last['trend_filter'] == -1 and (last['vol_release'] or prev['vol_release']) and last['break_low'] and last['BBL_falling']): return 'SELL' return None MQL5コードへの翻訳(MT5用EA) 上記のPythonロジックをMetaTrader 5 (MT5) で動作するように忠実に再現したEAコードです。 ...

2026年7月18日 · 5 min · AutoTrader