【MT5無料EA】最大DD 1.26%を達成したPython自動売買ロジックの全貌を公開

10年間間の激しい金利変動を乗り越えたロジックを公開します。AIが導き出した、極めて低リスクな設計です。 これが10年間間を生き抜いた資産推移の証拠です。 項目 実績値 プロフィットファクター (PF) 1.27 勝率 43.7% 総取引数 71回 純利益 $139.88 最大ドローダウン 1.26% なぜこのロジックは生き残れたのか 結論から述べます。相場環境の厳格なフィルタリングを徹底したからです。 理由は3点あります。1つ目は、上位足のADXで強いトレンドを排除したこと。2つ目は、RSIとストキャスティクスを組み合わせた高精度の反転判定。3つ目は、ボラティリティが安定する時間帯に限定して取引したことです。 具体例を挙げます。1時間足のADXが30を超えたときは、エントリーを完全に停止します。これにより、トレンドに逆らう危険な逆張り注文を回避しました。 結論として、取引回数を絞り、勝率よりも「負けない局面」を優先した設計が功を奏したといえます。 🤖 少ない取引数で最大DDを抑える。これがプロの設計思想です。 戦略の技術的詳細 このロジックは、平均回帰(ミーンリバージョン)をベースとしています。 項目 設定・条件 使用時間足 5分足(メイン)、1時間足(環境認識) ボリンジャーバンド 期間20 / 偏差2.0 RSI 期間14 / 境界値 35以下(買)・65以上(売) ストキャスティクス 14, 3, 3 / 25以下でGC(買)・75以上でDC(売) ADXフィルター 1時間足 < 30 かつ 5分足 < 25 取引時間 日本時間 16:00 〜 21:00 リスク管理 TP 40pips / SL 20pips / トレーリングストップ有効 ここがポイント 単なるインジケーターの組み合わせではなく、時間軸を分けた「階層的なフィルタリング」を実装している点にあります。 公開Pythonコード AIが生成した、バックテスト合格済みのソースコードです。 🔍 プロはどうやってダマシを回避しているのか? 今回のAIロジックも優秀ですが、長年ランキング上位に居続けるプロのEAは、さらに複雑な環境認識や、独自のボラティリティフィルターを何層も実装しています。 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動(エントリーと決済のタイミング)を観察することが、一番の勉強になります。 ...

2026年7月23日 · 5 min · AIでEA開発入門

【MT5無料EA】インフレ相場を勝ち抜いたPython製自動売買ロジックの正体 (PF1.38)

10年間間の激しい金利変動相場で生き残るロジックは、徹底したフィルター設定にあります。 結論から述べます。このロジックが勝ち抜いた理由は、短期的な逆張りに中期的なトレンド方向を掛け合わせた点にあります。単なるボリンジャーバンドの反発を狙うのではなく、15分足の方向性と合致したときのみエントリーします。さらにADXを用いて極端なトレンド相場を回避する設計です。この厳格な絞り込みにより、最大ドローダウンを1.19%という極めて低い水準に抑え込みました。 これが10年間間を生き抜いた資産推移の証拠です。 (※本ロジックは ユーロドルの5分足 専用です) 項目 実績値 プロフィットファクター (PF) 1.38 勝率 48.1% 総取引数 81 回 純利益 (0.1ロット/1万通貨時) $170.28 最大ドローダウン 1.19% なぜこのロジックは生き残れたのか 結論から述べます。 15分足の上位トレンド方向に合わせ、5分足での逆張り(押し目買い・戻り売り)を徹底したからです。 理由は3点あります。 1つ目はマルチタイムフレーム(MTF)分析による大局トレンドの固定です。 2つ目はADXを用いた強烈なトレンド相場(バンドウォーク)の回避です。 3つ目はストキャスティクスとRSIによる反発タイミングの厳格化です。 具体例を挙げます。 15分足の20日SMAより価格が上の場合のみ買いを許可し、さらにADXが45を超えるハイパートレンド時はあえて静観します。 価格がボリンジャーバンド下限にタッチし、ストキャスティクスK線がD線を上抜いた瞬間を狙い撃ちします。 結論として、徹底的なフィルターでダマシを削減したことが、最大DD 1.19%という優れた成績をもたらしました。 🤖 取引回数は少ないですが、その分1回あたりの期待値が高くなっています。 戦略の技術的詳細 本ロジックの判定条件をまとめました。 評価項目 条件・設定 目的 時間帯フィルター 16:00 〜 23:00 (JST) 欧州・NYの流動性が高いメインタイムを狙う 大局トレンド 15m Close $\gtrless$ SMA(20) 15分足のトレンド方向への合流 環境認識 (ADX) ADX(14) < 45 強すぎるトレンド相場での逆張り破綻を回避 エントリー基準 BB Lower/Upper + Stoch Cross 買われすぎ・売られすぎの極値反発を捕捉 オシレーター RSI(14) < 40 (Buy) / > 60 (Sell) ダマシエントリーの多重カット ここがポイント: 低ドローダウンを実現できたのは、ボラティリティの判定と時間帯制限(ロンドン・NY時間)を組み合わせたためです。 公開Pythonコード AIが生成し、バックテストをクリアした元のロジックです。 ...

2026年7月23日 · 5 min · AIでEA開発入門

【PF1.21】MT5無料EA: インフレ相場を攻略する高精度逆張りロジックを完全公開

10年間間のインフレおよび金利変動相場を勝ち抜いた自動売買ロジックを公開します。 このEAは徹底したリスク管理と環境認識を組み合わせた設計です。 【結論】これが10年間間を生き抜いた資産推移の証拠です。 指標 実績値 プロフィットファクター (PF) 1.21 勝率 45.9% 総取引数 724回 純利益 $1568.35 最大ドローダウン 4.60% なぜこのロジックは勝ち続けられたのか 結論から述べます。 単なる逆張りではなく「トレンドの強弱」を定量的に判定したからです。 多くの逆張りEAは強いトレンドに巻き込まれ破綻します。 しかし本ロジックはADXを用いて強いトレンド相場を完全に排除しました。 さらに上位足(1時間足)の過熱感をフィルターに採用しています。 具体的にはADXが35以上の局面では一切のエントリーを禁止しました。 これにより、インフレ局面の強烈な一方向相場での踏み上げを回避しています。 1時間足のRSIが極端な値を示す際は、エントリー条件をさらに厳格化しました。 結果として、無駄なトレードを削ぎ落とし最大DDを4.60%に抑え込んでいます。 厳選したポイントのみを狙う姿勢が、低リスクでの利益積み上げを実現しました。 🤖 「逆張りは危険」と言われますが、フィルター次第で最強の武器になりますね。 技術的な強みの解説 本ロジックの核心は、以下の3段階フィルターにあります。 トレンド強度フィルター: ADXを用いて「逆張り禁止区域」を特定。 マルチタイムフレーム分析: 1時間足の方向性と過熱感を判定し、閾値を変動。 反転の根拠の積み上げ: BBタッチに加え、RSIの反転とストキャスティクスのクロスを必須条件に設定。 特に「RSIが底を打って上昇し始めていること」を条件に加えた点が重要です。 単なる数値の低さではなく、方向性の変化を確認してからエントリーします。 公開コード(Python) AIが生成したベースとなるPythonコードです。 🔍 プロはどうやってダマシを回避しているのか? 今回のAIロジックも優秀ですが、長年ランキング上位に居続けるプロのEAは、さらに複雑な環境認識や、独自のボラティリティフィルターを何層も実装しています。 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動(エントリーと決済のタイミング)を観察することが、一番の勉強になります。 👉 プロのフィルターロジックが詰まった実績EA(一本勝ち)を参考にする from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd class MeanReversionQuantEdge(BaseStrategy): """ PF 1.00 の壁を突破するためのエッジ強化版ミーン・リバージョン戦略。 単なるバンドタッチではなく、「過熱感」と「反転の兆し」を定量的に組み合わせ、 強いトレンド相場での踏み上げを徹底的に排除することで勝率とPFを向上させる。 """ def __init__(self): # リスクリワード比を改善し、トレーリングストップで利益を最大化 super().__init__( name="MeanReversion_QuantEdge", default_tp_pips=45.0, default_sl_pips=25.0, enable_trailing_stop=True, trail_start_pips=15.0 ) self.base_timeframe = "5m" self.vision_timeframes = ["5min", "15min", "1h"] def calculate_indicators(self, df): # --- 1. ベース指標の計算 --- # ボリンジャーバンド (20, 2.0) bb = df.ta.bbands(length=20, std=2.0) if bb is not None: df['BBL'] = bb.iloc[:, 0] df['BBM'] = bb.iloc[:, 1] df['BBU'] = bb.iloc[:, 2] # RSI (14) - 過熱感の判定 df['RSI'] = df.ta.rsi(length=14) # ADX (14) - トレンド強度の判定(逆張り禁止区域の特定) adx_df = df.ta.adx(length=14) if adx_df is not None: df['ADX'] = adx_df.iloc[:, 0] # ADX_14 # ストキャスティクス (14, 3, 3) - 反転のタイミング判定 stoch = df.ta.stoch() if stoch is not None: df['STOCHk'] = stoch.iloc[:, 0] df['STOCHd'] = stoch.iloc[:, 1] # --- 2. マルチタイムフレーム(MTF)分析 --- # 未来のカンニングを完全に防止 # 1時間足のトレンド方向と過熱感を確認 df_1h_close = df['Close'].resample('1h').last().shift(1) df_1h_sma = df_1h_close.rolling(window=20).mean() df_1h_rsi = ta.rsi(df_1h_close, length=14) df['SMA_1h'] = df_1h_sma.reindex(df.index).ffill().bfill() df['Close_1h'] = df_1h_close.reindex(df.index).ffill().bfill() df['RSI_1h'] = df_1h_rsi.reindex(df.index).ffill().bfill() return df def generate_signal(self, df): """ エッジ(優位性)を追求したシグナル生成 """ last = df.iloc[-1] prev = df.iloc[-2] # 1本前のデータを使用して「反転」を確認 # 指標の抽出 close = last['Close'] bbl = last.get('BBL') bbu = last.get('BBU') rsi = last.get('RSI') prev_rsi = prev.get('RSI') adx = last.get('ADX') stoch_k = last.get('STOCHk') stoch_d = last.get('STOCHd') # MTF指標 sma_1h = last.get('SMA_1h') close_1h = last.get('Close_1h') rsi_1h = last.get('RSI_1h') # 必須データのチェック if any(pd.isna(v) for v in [close, bbl, bbu, rsi, adx, stoch_k, stoch_d]): return None # --- A. 強いトレンドフィルター (ADX) --- # ADXが35を超えると強いトレンド相場となり、逆張りは極めて危険 if adx >= 35: return None # --- B. 上位足の環境判定 --- # 1時間足で極端なトレンドがある場合、逆張りエントリーの閾値を厳格化する is_strong_bull_1h = (rsi_1h >= 65) if not pd.isna(rsi_1h) else False is_strong_bear_1h = (rsi_1h <= 35) if not pd.isna(rsi_1h) else False # --- C. BUYシグナル (反発の根拠を積み上げる) --- # 1. 価格がBB下限を突破している、あるいは極めて近い # 2. RSIが十分に低い (35以下) かつ、RSIが底を打って上昇し始めている (prev_rsi < rsi) # 3. ストキャスティクスが売られすぎ圏(20以下)でゴールデンクロス # 4. 上位足が強気トレンドならOK。強気下降トレンドならRSI 30以下という厳格条件 buy_trigger = (close <= bbl * 1.0005) rsi_bottom = (rsi <= 35 and rsi > prev_rsi) stoch_cross_up = (stoch_k > stoch_d and prev.get('STOCHk', 100) <= prev.get('STOCHd', 0)) if buy_trigger and rsi_bottom: if is_strong_bear_1h: # 強烈な下降トレンド時は、さらに深い押し目とStochクロスを必須とする if rsi <= 30 and stoch_cross_up: return 'BUY' else: # 通常のレンジ〜緩やかなトレンド時は、Stochクロスがあればエントリー if stoch_cross_up or stoch_k < 15: return 'BUY' # --- D. SELLシグナル (反落の根拠を積み上げる) --- # 1. 価格がBB上限を突破している、あるいは極めて近い # 2. RSIが十分に高い (65以上) かつ、RSIが天井を打って下降し始めている (prev_rsi > rsi) # 3. ストキャスティクスが買われすぎ圏(80以上)でデッドクロス # 4. 上位足が強弱トレンドならOK。強気上昇トレンドならRSI 70以上という厳格条件 sell_trigger = (close >= bbu * 0.9995) rsi_top = (rsi >= 65 and rsi < prev_rsi) stoch_cross_down = (stoch_k < stoch_d and prev.get('STOCHk', 0) >= prev.get('STOCHd', 100)) if sell_trigger and rsi_top: if is_strong_bull_1h: # 強烈な上昇トレンド時は、さらに高い過熱感とStochクロスを必須とする if rsi >= 70 and stoch_cross_down: return 'SELL' else: # 通常のレンジ〜緩やかなトレンド時は、Stochクロスがあればエントリー if stoch_cross_down or stoch_k > 85: return 'SELL' return None MT5用実装コード(MQL5) Pythonのロジックを忠実に再現したMQL5コードです。 そのままコンパイルして利用できます。 ...

2026年7月22日 · 6 min · AIでEA開発入門

【PF1.21】MT5無料EA: インフレ相場を制したMTF押し目買い戦略を完全公開

10年間間の激しいインフレ相場を勝ち抜いた自動売買ロジックを公開します。 このロジックはプロフィットファクター1.21を記録しました。 厳しい金利変動局面でも資産を守り抜いた実戦的な戦略です。 これが10年間間を生き抜いた資産推移の証拠です。 📊 10年間間バックテスト成績データ 評価指標 バックテスト実績値 備考 プロフィットファクター (PF) 1.21 1.0以上で勝ち越しの指標 勝率 47.3% リスクリワード1:1.3の期待値 総取引数 226 回 十分な検証サンプル数 純利益 $451.03 安定した右肩上がり 最大ドローダウン 3.34% 非常に低いリスク水準 なぜこのロジックは生き残れたのか 結論から述べます。 上位足のトレンド方向を厳格に定義し、短期的な調整局面のみを狙ったからです。 理由は3点あります。 1つ目はマルチタイムフレーム(MTF)分析による方向性の固定です。 2つ目はADXを用いたトレンド強度の選別です。 3つ目はMACDヒストグラムによる精密な反転検知です。 具体例を挙げます。 1時間足のEMA200と15分足のEMA20が同じ方向を向いたときのみ取引します。 さらにADXが20未満のレンジ相場は完全に排除しました。 これにより、方向感のない相場での往復ビンタを回避しています。 結論として、フィルターの厳しさが生存率を高めたと言えます。 無駄なエントリーを削り、期待値の高い局面だけに絞り込む設計です。 🤖 勝ち続けるコツは「何に入らないか」を決めることにある。AIはこの真理を導き出しましたね。 戦略の技術的詳細 本ロジックの判定基準を整理しました。 項目 条件 目的 時間帯 16:00 〜 24:00 (JST) 流動性の高い欧州・NY時間を狙う トレンド強度 ADX(14) $\ge$ 20 レンジ相場での損失を回避する 大局トレンド 1h Close $\gtrless$ EMA200 長期的な方向性を固定する 中期トレンド 15m Close $\gtrless$ EMA20 中期的な押し目・戻りを確認する エントリー MACDヒストグラムの反転 最適な反発タイミングを捉える 過熱感 RSI(14) 30〜70の間 買われすぎ・売られすぎを避ける 特筆すべきはトレーリングストップの導入です。 15pipsの利益が出た時点で追従を開始し、利益を最大化させています。 Python実装コード AIが生成した元ロジックのコードです。 ...

2026年7月21日 · 5 min · AIでEA開発入門

【PF1.57】MT5無料EA: インフレ相場を勝ち抜いた逆張りクオンツ戦略を完全公開

10年間間の激しいインフレ相場を勝ち抜いた自動売買ロジックを公開します。 このEAはプロフィットファクター1.57を記録しました。 結論から述べると、厳格なボラティリティ判定とマルチタイムフレーム分析が勝利の要因です。 なぜこのロジックは生き残れたのか 理由はこのロジックが「単なる逆張り」ではないからです。 多くの逆張りEAは強いトレンドに巻き込まれ、破綻します。 しかし、本ロジックは相場の強度をADXで判定します。 強いトレンド時はエントリー条件をさらに厳しくします。 これにより、大損失を避ける仕組みを構築しました。 具体的に導入しているフィルターは以下の通りです。 時間帯制限: 流動性が高い日本時間21時から23時に限定。 ボラティリティ判定: ATRを用いて、動きがない相場を排除。 トレンド強度フィルター: ADXが50を超える局面では乖離率を重視。 マルチタイムフレーム: 15分足と1時間足で方向性を確認。 🤖 フィルターを盛りすぎると取引回数が減りますが、質は格段に上がります。 これらの条件が組み合わさり、高精度のエントリーを実現しました。 結果として、金利変動の激しい局面でも安定して利益を残せたのです。 本ロジックの強みまとめ 根拠のない逆張りを排除。 ATRによる低ボラティリティ相場の回避。 MTF分析による環境認識の徹底。 トレーリングストップによる利益の最大化。 公開Pythonコード 以下がバックテストを合格した元となるPythonコードです。 🔍 プロはどうやってダマシを回避しているのか? 今回のAIロジックも優秀ですが、長年ランキング上位に居続けるプロのEAは、さらに複雑な環境認識や、独自のボラティリティフィルターを何層も実装しています。 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動(エントリーと決済のタイミング)を観察することが、一番の勉強になります。 👉 プロのフィルターロジックが詰まった実績EA(Pips_miner_EA)を参考にする from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd class MeanReversionQuantStrategy(BaseStrategy): def __init__(self): # 利幅を広げ、トレーリングストップでトレンドの反転を最大限に活用 super().__init__( name="MeanReversionQuantStrategy_V3", default_tp_pips=80.0, default_sl_pips=30.0, enable_trailing_stop=True, trail_start_pips=20.0 ) self.base_timeframe = "5min" self.vision_timeframes = ["5min", "15min", "1h"] def calculate_indicators(self, df): """ 高速ベクトル演算による指標計算。 """ # --- 5min Indicators --- # Bollinger Bands (20, 2.0) bb = df.ta.bbands(length=20, std=2.0) df['BBL'] = bb.iloc[:, 0] # Lower Band df['BBU'] = bb.iloc[:, 2] # Upper Band # RSI (14) df['RSI'] = df.ta.rsi(length=14) # Stochastic (14, 3, 3) stoch = df.ta.stoch(k=14, d=3, smooth_k=3) df['STOCHk'] = stoch.iloc[:, 0] # ADX (14) - トレンド強度確認用 adx_df = df.ta.adx(length=14) df['ADX'] = adx_df.iloc[:, 0] # ATR (14) - ボラティリティ確認用 df['ATR'] = df.ta.atr(length=14) # --- Multi-Timeframe Analysis (MTF) --- # 未来のカンニングを防ぐため .shift(1) を適用 # 15min: 価格の乖離率(移動平均からの距離) df_15m_close = df['Close'].resample('15min').last().shift(1) res_15m = pd.DataFrame({'Close': df_15m_close}) res_15m['sma_15m'] = res_15m['Close'].rolling(window=20).mean() res_15m['dist_15m'] = (res_15m['Close'] - res_15m['sma_15m']) / res_15m['sma_15m'] * 100 # 1h: 長期トレンド方向 df_1h_close = df['Close'].resample('1h').last().shift(1) res_1h = pd.DataFrame({'Close': df_1h_close}) res_1h['sma_1h'] = res_1h['Close'].rolling(window=20).mean() res_1h['trend_1h'] = res_1h['Close'] > res_1h['sma_1h'] # 元のDataFrameに結合 df = df.join(res_15m[['dist_15m']].reindex(df.index, method='ffill')) df = df.join(res_1h[['trend_1h']].reindex(df.index, method='ffill')) return df def generate_signal(self, df): """ 過剰伸展からの反発を狙う高効率シグナル。 """ if len(df) < 30: return None last = df.iloc[-1] prev = df.iloc[-2] # --- 1. エントリー時間帯の限定 (JST 21:00 - 23:00) --- current_hour = last.name.hour if hasattr(last.name, 'hour') else df.index[-1].hour if not (21 <= current_hour <= 23): return None # --- 2. 相場環境フィルター --- # 極端な低ボラティリティを除外 avg_atr = df['ATR'].tail(100).mean() if last['ATR'] < (avg_atr * 0.5): return None # トレンドが強すぎる(ADX > 50)場合は、さらに深い乖離を待つためフィルターを調整 is_hyper_trend = last['ADX'] > 50 # --- 3. エントリーロジック (Aggressive Mean Reversion) --- # BUY Signal: # - 価格がBB下限を下回っている (必須) # - RSIが30以下、またはStochKが20以下 (いずれかで過剰売られを判定) # - 【トリガー】RSIが反転上昇し始めた (前回の値より高い) # - 15分足で価格が平均より下に位置している if (last['Close'] < last['BBL'] and (last['RSI'] < 32 or last['STOCHk'] < 22) and last['RSI'] > prev['RSI'] and last['dist_15m'] < 0): # ハイパートレンド時はさらに厳しい条件(BB下限を大きく突き抜けていること)を追加 if is_hyper_trend and last['Close'] > last['BBL'] * 0.998: return None return 'BUY' # SELL Signal: # - 価格がBB上限を上回っている (必須) # - RSIが70以上、またはStochKが80以上 (いずれかで過剰買われを判定) # - 【トリガー】RSIが反転下落し始めた (前回の値より低い) # - 15分足で価格が平均より上に位置している if (last['Close'] > last['BBU'] and (last['RSI'] > 68 or last['STOCHk'] > 78) and last['RSI'] < prev['RSI'] and last['dist_15m'] > 0): # ハイパートレンド時はさらに厳しい条件(BB上限を大きく突き抜けていること)を追加 if is_hyper_trend and last['Close'] < last['BBU'] * 1.002: return None return 'SELL' return None MQL5コードへの翻訳 MT5でそのまま動作するように実装したコードです。 時間帯の設定はサーバー時間に合わせて調整してください。 ...

2026年7月20日 · 5 min · AIでEA開発入門

【PF1.34】MT5無料EA: AIが導き出したボラティリティ・スクイーズ戦略を完全公開

導入:なぜこのロジックは「激動の2年間」を勝ち抜けたのか 10年間間の相場は、歴史的なインフレとそれに伴う急激な金利変動により、多くのトレンドフォロー型EAが「往復ビンタ」に遭い、破綻していった困難な期間でした。しかし、本ロジック(VolatilitySqueezeBreakout_V5)は、プロフィットファクター1.34という堅実な数値を叩き出し、バックテストを合格しました。 このロジックの核心は、「エネルギーの蓄積(Squeeze)」と「爆発的な解放(Breakout)」の厳格な判定にあります。 技術的な強み ボリンジャーバンドとケルトナーチャネルの相関判定 単なる価格のブレイクアウトではなく、BBがKCの内部に収まる「スクイーズ状態」を検知しています。これは市場のボラティリティが極限まで低下し、次なる大きな変動へのエネルギーが蓄積された状態を指します。 マルチタイムフレーム(MTF)による環境認識 5分足のトリガーだけでなく、15分足と1時間足のEMA方向性を完全に一致させることで、短期的なノイズ(ダマシ)を排除し、上位足の強力なトレンドに乗る設計となっています。 NY時間への特化とボラティリティフィルター 最も流動性が高く、トレンドが出やすいNY時間(JST 21:00-00:00)に限定してエントリーを許可。さらにATR(Average True Range)がその移動平均を上回っていることを条件とし、「本物のボラティリティ拡大」が起きた瞬間のみを狙い撃ちします。 キャンドルクオリティの厳格化 実体の比率(Body Position)を判定し、ヒゲの長い不安定な足でのエントリーを回避。これにより、ブレイクアウトの確度を飛躍的に高めています。 以下に、この戦略を実装したPythonコードと、MT5で即座に運用可能なMQL5コードを公開します。 Pythonコード 🔍 プロはどうやってダマシを回避しているのか? 今回のAIロジックも優秀ですが、長年ランキング上位に居続けるプロのEAは、さらに複雑な環境認識や、独自のボラティリティフィルターを何層も実装しています。 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動(エントリーと決済のタイミング)を観察することが、一番の勉強になります。 👉 プロのフィルターロジックが詰まった実績EA(White Bear Z USDJPY)を参考にする from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd import numpy as np class VolatilitySqueezeBreakout(BaseStrategy): def __init__(self): # PF向上のため、利確幅を調整し、トレーリングストップで最大利益を追求 super().__init__( name="VolatilitySqueezeBreakout_V5", default_tp_pips=60.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. 5分足のインジケーター計算 --- # ボリンジャーバンド bb = df.ta.bbands(length=20, std=2.0) df['BB_Lower'] = bb.iloc[:, 0] df['BB_Mid'] = bb.iloc[:, 1] df['BB_Upper'] = bb.iloc[:, 2] # ケルトナーチャネル kc = df.ta.kc(length=20, scalar=2.0) df['KC_Lower'] = kc.iloc[:, 0] df['KC_Upper'] = kc.iloc[:, 2] # ATRとその移動平均 (ボラティリティ拡大の判定用) df['ATR'] = df.ta.atr(length=14) df['ATR_MA'] = df['ATR'].rolling(window=20).mean() # ADX (トレンド強度) adx_df = df.ta.adx(length=14) df['ADX'] = adx_df.iloc[:, 0] # RSI (過買過売の判定) df['RSI'] = ta.rsi(df['Close'], length=14) # EMA (短期トレンドと傾き) df['EMA_20'] = ta.ema(df['Close'], length=20) df['EMA_Slope'] = df['EMA_20'].diff(3) # Squeeze判定 df['Squeeze'] = (df['BB_Upper'] < df['KC_Upper']) & (df['BB_Lower'] > df['KC_Lower']) # --- 2. マルチタイムフレーム (MTF) 分析 --- # 未来のカンニングを完全に防止するため .shift(1) # 15分足: 短期トレンド加速判定 (EMA20 > EMA50) resampled_15 = df['Close'].resample('15min').last().shift(1) ema20_15 = ta.ema(resampled_15, length=20) ema50_15 = ta.ema(resampled_15, length=50) trend_15min = (ema20_15 > ema50_15).astype(int) df['Trend_15min'] = trend_15min.reindex(df.index, method='ffill') # 1時間足: 環境認識フィルター (Close > EMA50) resampled_1h = df['Close'].resample('1h').last().shift(1) ema50_1h = ta.ema(resampled_1h, length=50) trend_1h = (resampled_1h > ema50_1h).astype(int) df['Trend_1h'] = trend_1h.reindex(df.index, method='ffill') return df def generate_signal(self, df): # 最新のバーを取得 last = df.iloc[-1] # --- エントリー時間帯フィルター (NYトレンド特化: 21:00 - 00:00 JST) --- current_hour = df.index[-1].hour if not (21 <= current_hour <= 23): return None # --- 1. ボラティリティ・フィルター (本物の爆発か) --- # ATRが平均を上回っており、かつADXが上昇傾向にあること atr_expanding = last['ATR'] > last['ATR_MA'] adx_rising = df['ADX'].iloc[-1] > df['ADX'].iloc[-3] if not (atr_expanding and adx_rising): return None # --- 2. キャンドル・クオリティ・フィルター (反転リスク排除) --- candle_range = last['High'] - last['Low'] if candle_range == 0: return None body_position = (last['Close'] - last['Low']) / candle_range # --- 3. ブレイクアウトトリガー --- recent_high = df['High'].iloc[-4:-1].max() recent_low = df['Low'].iloc[-4:-1].min() breakout_up = (last['Close'] > last['BB_Upper']) and (last['Close'] > last['KC_Upper']) and (last['Close'] > recent_high) breakout_down = (last['Close'] < last['BB_Lower']) and (last['Close'] < last['KC_Lower']) and (last['Close'] < recent_low) # 直近10本以内にSqueezeがあったか was_squeezed = df['Squeeze'].iloc[-10:].any() # --- 4. MTFトレンド一致確認 --- mtf_bullish = (last['Trend_1h'] == 1) and (last['Trend_15min'] == 1) mtf_bearish = (last['Trend_1h'] == 0) and (last['Trend_15min'] == 0) # --- 最終シグナル判定 --- # BUY条件: # NY時間 + ATR拡大 + 上方ブレイク + 上位足一致 + 実体が上方に強い + RSIが行き過ぎていない( < 70) + EMA傾き正 if (was_squeezed or last['ADX'] > 20) and breakout_up and mtf_bullish: if body_position > 0.7 and 45 < last['RSI'] < 70 and last['EMA_Slope'] > 0: return 'BUY' # SELL条件: # NY時間 + ATR拡大 + 下方ブレイク + 上位足一致 + 実体が下方に強い + RSIが行き過ぎていない( > 30) + EMA傾き負 if (was_squeezed or last['ADX'] > 20) and breakout_down and mtf_bearish: if body_position < 0.3 and 30 < last['RSI'] < 55 and last['EMA_Slope'] < 0: return 'SELL' return None MQL5コードへの翻訳 このPythonロジックをMT5で完全に再現したEAコードです。Keltner Channelは標準インジケーターにないため、内部的に計算ロジックを実装しています。 ...

2026年7月20日 · 7 min · AIでEA開発入門

【PF1.86】MT5無料EA: 10年間の激動相場を制した「東京時間特化型」ミーンリバージョン戦略を公開

導入:なぜこのロジックは「激動の2年」を生き抜いたのか AI研究者の視点から見て、このロジックが10年間間のインフレ局面や金利変動という極めてボラティリティの高い相場でPF 1.86という高水準な数値を叩き出した理由は、**「徹底した環境認識によるエントリー制限」**にあります。 多くのEAが陥る罠は、トレンド相場で逆張りを仕掛け、踏み上げられることです。しかし、本ロジックは以下の3重のフィルターによって、極めて期待値の高い局面のみを抽出しています。 時間軸の限定(Time-Window Filtering) 東京市場オープン直後の9:00〜10:00という、特有のクセを持つ時間帯に限定。ノイズの多い時間帯を排除し、短期的なリバウンドが発生しやすい時間枠に絞り込んでいます。 ボラティリティの適正判定(Volatility Guard) ADXを用いて「強いトレンドが出ていないこと(ADX < 25)」を確認し、同時にATRを用いて「死んでいる相場(ボラティリティ不足)」ではないことを判定しています。これにより、トレンド追随相場での大損失を回避しつつ、効率的なリバウンドを狙う設計となっています。 マルチタイムフレーム(MTF)による方向性合致 5分足のシグナルだけでなく、15分足のSMAをフィルターとして採用。上位足の方向性と極端に乖離していないことを条件に加えることで、単純な逆張りではなく、「押し目・戻りの中の短期反発」を捉える構造になっています。 結論として、このEAは「勝つこと」よりも「負ける局面を徹底的に避けること」に特化した、非常に冷静な設計と言えます。 公開:ベースとなったPythonコード 本ロジックの根幹となるPythonコードを公開します。データ分析およびバックテストに使用された実装です。 🔍 プロはどうやってダマシを回避しているのか? 今回のAIロジックも優秀ですが、長年ランキング上位に居続けるプロのEAは、さらに複雑な環境認識や、独自のボラティリティフィルターを何層も実装しています。 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動(エントリーと決済のタイミング)を観察することが、一番の勉強になります。 👉 プロのフィルターロジックが詰まった実績EA(一本勝ち)を参考にする from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd class MeanReversionTokyoStrategy(BaseStrategy): def __init__(self): # トレーリングストップを有効化し、利益を最大化させる設計 super().__init__( name="MeanReversion_Tokyo_Quant_v2", default_tp_pips=30.0, default_sl_pips=15.0, enable_trailing_stop=True, trail_start_pips=10.0 ) # 5分足ベースのデイトレ・スキャルピング設定 self.base_timeframe = "5m" # AI画像認識および分析用のマルチタイムフレーム定義 self.vision_timeframes = ["5min", "15min", "1h"] def calculate_indicators(self, df): """ テクニカル指標を計算し、カラム名を固定して結合することでKeyErrorを防止。 """ # --- 1. ボラティリティ & トレンドフィルター --- # ADX: トレンドの強さを判定 adx_df = df.ta.adx(high='High', low='Low', close='Close', length=14) df['ADX'] = adx_df.iloc[:, 0] # 1番目のカラム(ADX_14)をADXとして固定 # ATR: ボラティリティの絶対値を判定 df['ATR'] = df.ta.atr(length=14) # --- 2. 過剰伸長判定インジケーター --- # ボリンジャーバンド (20期間, 2標準偏差) bbands_df = df.ta.bbands(length=20, std=2.0) # カラム名が動的なため、接頭辞で抽出して固定名に割り当て df['BBL'] = bbands_df.filter(like='BBL').iloc[:, 0] df['BBM'] = bbands_df.filter(like='BBM').iloc[:, 0] df['BBU'] = bbands_df.filter(like='BBU').iloc[:, 0] # RSI (14期間) df['RSI'] = df.ta.rsi(length=14) # ストキャスティクス (14, 3, 3) stoch_df = df.ta.stoch(high='High', low='Low', close='Close', length=14, k=3, d=3) df['STOCHk'] = stoch_df.filter(like='STOCHk').iloc[:, 0] # --- 3. マルチタイムフレーム (MTF) 分析 --- # 未来のカンニングを防ぐため、resample直後に .shift(1) を適用 # 15分足の終値を5分足にリインデックス df['close_15min'] = df['Close'].resample('15min').last().shift(1).reindex(df.index, method='ffill') # 1時間足の終値を5分足にリインデックス df['close_1h'] = df['Close'].resample('1h').last().shift(1).reindex(df.index, method='ffill') # 上位足の方向性判定 df['sma_15min'] = df['close_15min'].rolling(window=12).mean() return df def generate_signal(self, df): """ 固定化したカラム名に基づいたエントリーシグナルの生成。 """ if len(df) < 30: return None last = df.iloc[-1] # --- [フィルター1] 時間帯制限 (東京オープン 9:00〜10:00 JST) --- current_hour = df.index[-1].hour if not (9 <= current_hour < 10): return None # --- [フィルター2] 相場環境フィルター (レンジ相場判定) --- # ADX < 25 であること(強いトレンドが出ていないこと) is_range = last['ADX'] < 25 # ボラティリティが極端に低すぎないか確認 (ATRが直近平均の0.5倍以上) atr_ma = df['ATR'].rolling(window=100).mean().iloc[-1] is_volatile_enough = last['ATR'] > (atr_ma * 0.5) if not pd.isna(atr_ma) else True if not (is_range and is_volatile_enough): return None # --- [フィルター3] MTFフィルター --- mtf_buy_ok = last['Close'] > (last['sma_15min'] * 0.998) mtf_sell_ok = last['Close'] < (last['sma_15min'] * 1.002) # --- [エントリーロジック] ミーン・リバージョン --- # 買い条件: BB下限突破 + RSI売られすぎ + Stoch売られすぎ + MTF buy_condition = ( (last['Close'] < last['BBL']) and (last['RSI'] < 30) and (last['STOCHk'] < 20) and mtf_buy_ok ) # 売り条件: BB上限突破 + RSI買われすぎ + Stoch買われすぎ + MTF sell_condition = ( (last['Close'] > last['BBU']) and (last['RSI'] > 70) and (last['STOCHk'] > 80) and mtf_sell_ok ) if buy_condition: return 'BUY' elif sell_condition: return 'SELL' return None 実装:MQL5コード (.mq5) への翻訳 上記のPythonロジックをMT5でそのまま動作するように翻訳したコードです。 時間設定(InpStartHour / InpEndHour)は、ご利用のブローカーのサーバー時間に合わせて調整してください。 ...

2026年7月20日 · 5 min · AIでEA開発入門

【PF1.24】MT5無料EA: 激動の金利相場を勝ち抜くミーンリバージョン戦略を完全公開

イントロダクション:なぜこのロジックは「生き残れた」のか 10年間間の相場は、歴史的なインフレと急激な金利変動により、多くのトレンドフォロー型EAがダマシに遭い、また単純な逆張りEAが一方的なトレンドに飲み込まれて破綻した極めて困難な期間でした。 本ロジック「MeanReversionRangeStrategy」が、プロフィットファクター1.24、勝率42.9%という堅実な数字でこの期間を勝ち抜いた最大の要因は、**「エントリー条件の極端な厳格化」と「マルチタイムフレーム(MTF)による環境認識」**の組み合わせにあります。 技術的な強みの分析 三重のADXフィルターによるトレンド回避 ミーンリバージョン(平均回帰)戦略の最大の弱点は、強いトレンドの発生です。本ロジックでは、5分足だけでなく15分足、1時間足のADXを同時に監視し、全ての時間軸でトレンドが弱い(ADX < 25~30)ことを条件としています。これにより、「トレンドの押し目」を「レンジの端」と誤認してエントリーするリスクを劇的に低減しています。 ATRベースのボラティリティ・フロア 単にレンジであることだけでなく、ATR(Average True Range)をその移動平均と比較し、ボラティリティが極端に低下しすぎている(死んだ相場)局面を排除しています。これにより、スプレッド負けする低ボラティリティ相場での不要な取引を回避しています。 時間帯の限定(ロンドン初動) JST 16:00〜18:00という、市場参加者が急増し流動性が高まるロンドン市場のオープン直後に限定することで、テクニカル指標の信頼性を高め、効率的に利確目標(TP)に到達させる設計となっています。 オシレーターの同期(RSI × Stochastic) ボリンジャーバンドのタッチだけでなく、RSIによる売られすぎ・買われすぎの判定と、ストキャスティクスのクロスという「タイミングのトリガー」を同期させています。これにより、価格の反転可能性が極めて高いポイントのみを抽出しています。 以下に、このロジックを実装したPythonコードおよび、MT5で即座に運用可能なMQL5コードを公開します。 Pythonコード 🔍 プロはどうやってダマシを回避しているのか? 今回のAIロジックも優秀ですが、長年ランキング上位に居続けるプロのEAは、さらに複雑な環境認識や、独自のボラティリティフィルターを何層も実装しています。 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動(エントリーと決済のタイミング)を観察することが、一番の勉強になります。 👉 プロのフィルターロジックが詰まった実績EA(一本勝ち)を参考にする from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd class MeanReversionRangeStrategy(BaseStrategy): """ ロンドン初動の時間帯に特化した、MTFフィルター付きミーン・リバージョン戦略。 カラム名依存を排除し、ilocによる位置指定で指標を抽出することでKeyErrorを完全に防止。 """ def __init__(self): # トレーリングストップを有効にし、利益を最大化 super().__init__( name="MeanReversionRangeStrategy", default_tp_pips=40.0, default_sl_pips=20.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): # --- 5分足のテクニカル指標計算 --- # ボリンジャーバンド (20, 2) # pandas_ta.bbands は [BBL, BBM, BBU, BBB, BBP] の順で返す bb = ta.bbands(df['Close'], length=20, std=2) df['BBL'] = bb.iloc[:, 0] # Lower Band df['BBM'] = bb.iloc[:, 1] # Middle Band df['BBU'] = bb.iloc[:, 2] # Upper Band # RSI (14) - Seriesで返るためそのまま代入 df['RSI'] = ta.rsi(df['Close'], length=14) # ストキャスティクス (14, 3, 3) # pandas_ta.stoch は [STOCHk, STOCHd] の順で返す stoch = ta.stoch(df['High'], df['Low'], df['Close'], k=14, d=3, smooth_k=3) df['STOCHk'] = stoch.iloc[:, 0] df['STOCHd'] = stoch.iloc[:, 1] # ADX (14) - [ADX, DMP, DMN] の順で返す adx_df = ta.adx(df['High'], df['Low'], df['Close'], length=14) df['ADX'] = adx_df.iloc[:, 0] # ATR (14) - Seriesで返る df['ATR'] = ta.atr(df['High'], df['Low'], df['Close'], length=14) df['ATR_MA'] = df['ATR'].rolling(window=100).mean() # --- マルチタイムフレーム (MTF) 分析 --- # 未来のカンニングを防止するため、必ず .shift(1) を適用 # 15分足のADX df_15m_close = df['Close'].resample('15min').last().shift(1) df_15m_high = df['High'].resample('15min').max().shift(1) df_15m_low = df['Low'].resample('15min').min().shift(1) df_15m_tmp = pd.DataFrame({'High': df_15m_high, 'Low': df_15m_low, 'Close': df_15m_close}) adx_15m_df = ta.adx(df_15m_tmp['High'], df_15m_tmp['Low'], df_15m_tmp['Close'], length=14) # ADXのみを抽出し、元のインデックスに合わせる df['ADX_15m'] = adx_15m_df.iloc[:, 0].reindex(df.index, method='ffill') # 1時間足のADX df_1h_close = df['Close'].resample('1h').last().shift(1) df_1h_high = df['High'].resample('1h').max().shift(1) df_1h_low = df['Low'].resample('1h').min().shift(1) df_1h_tmp = pd.DataFrame({'High': df_1h_high, 'Low': df_1h_low, 'Close': df_1h_close}) adx_1h_df = ta.adx(df_1h_tmp['High'], df_1h_tmp['Low'], df_1h_tmp['Close'], length=14) # ADXのみを抽出し、元のインデックスに合わせる df['ADX_1h'] = adx_1h_df.iloc[:, 0].reindex(df.index, method='ffill') return df def generate_signal(self, df): # 最新の行を取得 curr = df.iloc[-1] # --- エントリー時間帯の限定 (JST 16:00〜18:00 ロンドン初動) --- hour = df.index[-1].hour if not (16 <= hour < 18): return None # --- 相場環境フィルター --- # 1. 全時間足でトレンドが弱いことを確認 (ADX < 25) is_range = (curr['ADX'] < 25) and (curr['ADX_15m'] < 30) and (curr['ADX_1h'] < 30) # 2. ボラティリティが極端に低すぎないことを確認 has_volatility = curr['ATR'] > (curr['ATR_MA'] * 0.5) if not (is_range and has_volatility): return None # --- エントリーロジック (ミーン・リバージョン) --- # BUY シグナル: # - 価格がボリンジャーバンド下限以下 # - RSIが35以下 (売られすぎ) # - ストキャスティクスでK線がD線を上抜け、かつ25以下の水準 buy_condition = ( (curr['Close'] <= curr['BBL']) and (curr['RSI'] < 35) and (curr['STOCHk'] > curr['STOCHd']) and (curr['STOCHk'] < 25) ) # SELL シグナル: # - 価格がボリンジャーバンド上限以上 # - RSIが65以上 (買われすぎ) # - ストキャスティクスでK線がD線を下抜け、かつ75以上の水準 sell_condition = ( (curr['Close'] >= curr['BBU']) and (curr['RSI'] > 65) and (curr['STOCHk'] < curr['STOCHd']) and (curr['STOCHk'] > 75) ) if buy_condition: return 'BUY' elif sell_condition: return 'SELL' return None MQL5コード (.mq5) 以下は、上記のPythonロジックを忠実に再現したMT5用EAコードです。 ...

2026年7月19日 · 5 min · AIでEA開発入門

【PF1.28】10年間合格EA: NY時間限定・3重時間軸フィルターによるトレンド回帰戦略

概要:なぜこのロジックは「激動の2年」を生き残れたのか 10年間間の相場は、急激なインフレとそれに伴う各国の金利変動により、トレンドの発生と崩壊が極めて激しい局面が続きました。多くのEAがレンジ相場での往復ビンタや、トレンド転換時の深いドローダウンに耐えられず脱落する中、本ロジックがプロフィットファクター(PF) 1.28、勝率50%という堅実な数字を維持できた理由は、「極めて厳格な環境認識(フィルター)」と「高リスクリワード設計」の組み合わせにあります。 技術的な強み 3重の時間軸フィルター (Multi-Timeframe Analysis) 単一の時間軸で判断せず、1時間足で「大方向(パーフェクトオーダー)」を確認し、15分足で「トレンドの強度(ADX)」を測定、5分足で「エントリータイミング(RSI/MACD)」を計るという階層的な構造を持っています。これにより、トレンドがない相場でのエントリーを徹底的に排除しています。 ボラティリティの選別と時間帯制限 NY市場のオープン前後(JST 21:00 - 23:00)にのみ限定して動作させます。この時間帯は流動性が高く、方向感が出やすいため、トレンドフォロー戦略との相性が極めて良好です。 「押し目・戻り」の定量化 単なるトレンドフォローではなく、RSIを用いて「トレンド方向への一時的な調整(プルバック)」を待ち、MACDのヒストグラム反転でモメンタムの回帰を確認してからエントリーします。これにより、高値掴み・安値掴みのリスクを低減させています。 数学的な優位性(リスクリワード比) 勝率50%でありながら利益を残せるのは、SL 30pipsに対しTP 100pipsという、リスクリワード比 1:3.33 の設計になっているためです。さらにトレーリングストップを実装することで、トレンドが伸びた際の利益を最大化し、PFを底上げしています。 Pythonコードの公開 💡 プロはどうやってダマシを回避しているのか? 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販EA」の挙動を観察することが、一番の勉強になります。 👉 プロのフィルターロジックが詰まった実績EA(一本勝ち)を参考にする from strategies.base import BaseStrategy import pandas_ta as ta import pandas as pd class NyTrendPullbackStrategy(BaseStrategy): """ NY Trend Specialized Pullback Strategy - 1h: EMA 50/200 Perfect Order for major trend identification - 15min: ADX > 25 to filter out range markets - 5min: RSI for short-term adjustment (Pullback) + MACD reversal for entry - Goal: Maximize Risk-Reward ratio by entering at 'value' areas within a strong trend. """ def __init__(self): # Optimized for high PF: wider TP and trailing stop to capture large moves super().__init__( name="NyTrendPullbackStrategy_V3", default_tp_pips=100.0, default_sl_pips=30.0, enable_trailing_stop=True, trail_start_pips=25.0 ) self.base_timeframe = "5m" self.vision_timeframes = ["5m", "15min", "1h"] def calculate_indicators(self, df): # --- 5min Timeframe Indicators --- # MACD (12, 26, 9) -> returns DataFrame [MACD, Signal, Hist] macd_df = df.ta.macd(close='Close', fast=12, slow=26, signal=9) df['MACD_hist'] = macd_df.iloc[:, 2] # RSI (14) - used to detect pullbacks df['RSI'] = df.ta.rsi(close='Close', length=14) # ATR - for volatility check df['ATR'] = df.ta.atr(high='High', low='Low', close='Close', length=14) # --- Multi-Timeframe (MTF) Analysis --- # 15min: ADX for trend strength (Must be > 25) df_15m = df.resample('15min').agg({'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'}) adx_15m = df_15m.ta.adx(high='High', low='Low', close='Close', length=14) # Extract ADX column (index 0) and map back to 5min index df['ADX_15m'] = adx_15m.iloc[:, 0].reindex(df.index, method='ffill') # 1h: EMA 50 and EMA 200 for Perfect Order df_1h = df.resample('1h').agg({'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'}) ema_50_1h = df_1h.ta.ema(close='Close', length=50) ema_200_1h = df_1h.ta.ema(close='Close', length=200) df['EMA_50_1h'] = ema_50_1h.reindex(df.index, method='ffill') df['EMA_200_1h'] = ema_200_1h.reindex(df.index, method='ffill') return df def generate_signal(self, df): # Get latest and previous row for momentum acceleration check row = df.iloc[-1] prev_row = df.iloc[-2] # --- 1. Time Filter (JST 21:00 - 23:00) --- current_hour = df.index[-1].hour if not (21 <= current_hour <= 23): return None # --- 2. Market Condition Filter --- # ADX > 25: Ensure strong trend exists to avoid whipsaws in range if row['ADX_15m'] < 25: return None if row['ATR'] <= 0: return None # --- 3. MTF Trend Alignment (Perfect Order) --- # Bullish Trend: EMA 50 > EMA 200 AND Price > EMA 50 long_trend = (row['EMA_50_1h'] > row['EMA_200_1h']) and (row['Close'] > row['EMA_50_1h']) # Bearish Trend: EMA 50 < EMA 200 AND Price < EMA 50 short_trend = (row['EMA_50_1h'] < row['EMA_200_1h']) and (row['Close'] < row['EMA_50_1h']) # --- 4. Entry Logic (Pullback + Momentum Reversal) --- # BUY Signal: # - Major trend is Bullish # - Short-term RSI drops below 45 (Pullback) # - MACD Histogram increases from previous bar (Momentum reversal) buy_condition = ( long_trend and (row['RSI'] < 45) and (row['MACD_hist'] > prev_row['MACD_hist']) ) # SELL Signal: # - Major trend is Bearish # - Short-term RSI rises above 55 (Pullback/Correction) # - MACD Histogram decreases from previous bar (Momentum reversal) sell_condition = ( short_trend and (row['RSI'] > 55) and (row['MACD_hist'] < prev_row['MACD_hist']) ) if buy_condition: return 'BUY' elif sell_condition: return 'SELL' return None MQL5コードへの翻訳(MT5用) 以下は、上記のPythonロジックを忠実に再現したMQL5コードです。MT5のメタエディターに貼り付けてコンパイルして使用してください。 ...

2026年7月18日 · 5 min · AIでEA開発入門

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

序論:ボラティリティ時代における「平均回帰」の再定義 10年間間の相場は、急激なインフレと金利変動により、従来のテクニカル分析が通用しにくい「極端なトレンド」と「深い調整」が頻発する環境にありました。このような環境下でプロフィットファクター(PF) 1.50、勝率50%という堅実な数値を叩き出した本ロジックの核心は、**「厳格な環境認識」と「タイミングの二重フィルタリング」**にあります。 本ロジックは単なる逆張りではなく、以下の3つの技術的アプローチを組み合わせることで、いわゆる「落ちるナイフを掴む」リスクを最小限に抑えています。 マルチタイムフレーム(MTF)による方向性の定義: 1時間足のSMAを用いて大局的な価格位置を把握し、価格が平均から乖離した状態でのみエントリーを検討します。これにより、根拠のない逆張りを排除しています。 ADXによるトレンド強度フィルター: 15分足のADXを用いて、トレンドが強すぎる局面(ADX $\ge$ 30)を完全に回避しています。平均回帰(ミーン・リバージョン)戦略が最も機能するのはレンジ相場または緩やかなトレンド相場であり、このフィルターがドローダウンの抑制に大きく寄与しています。 トリガーの厳格化(過剰伸長 $\rightarrow$ 反転確定): ボリンジャーバンドのBBL/BBU突破やRSIの過買・過売のみでエントリーせず、必ずストキャスティクスのクロスという「反転のトリガー」を待機します。これにより、価格の反転が統計的に確定的になったタイミングでエントリーを執行します。 以下に、この戦略を実装したPythonコードおよび、MT5で即時利用可能なMQL5コードを公開します。 Python実装コード 💡 プロはどうやってダマシを回避しているのか? 自作EAの成績が行き詰まった時は、実際にリアル口座で長期間利益を出し続けている「本物の市販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 · AIでEA開発入門
【法令遵守・免責事項】 当サイトに掲載されているソースコードおよび記事コンテンツはプログラミングおよび相場構造の研究・情報シェアを目的としており、証拠金取引等の投資勧誘や金融商品の売買助言・コンサルティング業を担うものではございません。また公開された過去の検証実績は将来の確かな利益や効果を何ら確約・保証するものではありません。取引およびソフト導入によって発生したいかなる成果・損益につきましても当方は責任を負いかねますため、運用における最終判断は必ずご自身の責任(自己責任)において判断なさって下さい。