EMA+ZIGZAGブレイク戦略

 


【戦略名】

EMA+ZIGZAGブレイク戦略(RR1.1)


■エントリー条件

  • 条件1
    EMAの並びが上昇トレンド(EMA10 > EMA25 > EMA75)

  • 条件2
    ZIGZAGで直近安値を形成していること

  • 条件3
    直近ZIGZAG高値を終値で上抜けした場合に買いエントリー


■決済条件

  • 利確条件
    リスクリワード1.1
    (TP = エントリー価格 + (エントリー価格 - 損切り価格) × 1.1)

  • 損切り条件
    直近ZIGZAG安値に設定


■パラメータ

 

EMA_Fast = 10
EMA_Middle = 25
EMA_Slow = 75

ZigZag_Depth = 5
ZigZag_Deviation = 5
ZigZag_Backstep = 3

RR_Ratio = 1.1
Slippage = 3
LotSize = 0.1

 


■フィルター

  • 時間
    ロンドン・NY時間のみ稼働(例:15:00〜24:00)

  • スプレッド
    最大スプレッド 2.0pips以下

  • トレンド
    EMA75が上向き(前バーより上昇)かつ価格がEMA75より上


✅ 補足(EA化のポイント)

  • ZIGZAGはリペイントするため「確定バーのみ使用」
  • ブレイクは「終値確定」で判定
  • 同時ポジションは1つまで推奨

 

インジ生成プロンプト

✅ ダウカウント用インジ生成プロンプト

MQL4でカスタムインジケータを作成してください。

目的:
ダウ理論の高値・安値を自動で視覚化するインジケータ。
基準は「SMAの波(傾き変化)」を用いて判定する。

■ロジック概要
1. 指定期間のSMAを計算する
2. SMAの傾き(前バーとの差分)を計算する
3. 傾きがプラス→マイナスに転換したポイントを「天井(高値候補)」とする
4. 傾きがマイナス→プラスに転換したポイントを「ボトム(安値候補)」とする
5. 転換が「明確」である条件として、SlopeConfirmBars本連続で傾き方向が一致した場合のみ有効とする

■高値・安値の確定条件
- 高値:SMAが上昇→下降へ転換し、その周辺の一定範囲内で最も高いローソク足の高値を採用
- 安値:SMAが下降→上昇へ転換し、その周辺の一定範囲内で最も安いローソク足の安値を採用

■描画条件
- 高値確定時:
  → 高値位置の少し上に水平ライン(長さLineLength本分)を描画
- 安値確定時:
  → 安値位置の少し下に水平ラインを描画
- ラインは過去データ上に固定表示(オブジェクトで描画)

■パラメータ
SMAPeriod = 20               // SMA期間
SlopeConfirmBars = 3         // 傾き確定本数
SwingLookback = 10           // 高値・安値探索範囲(前後何本)
LineLength = 10              // 線の長さ(バー数)
OffsetPips = 5               // ライン表示位置(上下オフセット)
MinSlope = 0.0               // 最小傾き(ノイズ除去)
UseCloseSlope = true         // Closeベースで傾き計算

■フィルター
- 小さい傾き(MinSlope未満)は無視
- 横ばい相場のノイズ除去

■出力
- 高値には赤ライン
- 安値には青ライン
- 必要であればバッファでも値を保持(EA連携用)

■補足
- 再描画しない(リペイント禁止)
- 確定したスイングのみ表示(未確定は表示しない)
- パフォーマンスに配慮する(過去全再計算しない)


ea プロンプトテンプレ

✅ 共通フィルター(全戦略)

■フィルター
- 時間:08:30〜04:00(日本時間)
- スプレッド:
    USDJPY = 0.8以内
    その他通貨 = MaxSpreadPointsで管理(例:8〜20ポイント)
- トレンド:必要に応じて各戦略内で指定

① MA押し目+平均足

【MA押し目+平均足】

■エントリー条件
- TF_mainのSMA(LongMAPeriod)の傾き ≥ SlopeThreshold
- 価格が一度SMA(ShortMAPeriod)を下抜け
- 平均足が陽線に転換確定後、EntryDelay本後にBUY

■決済条件
- 平均足が陰線になったら決済
- またはTP到達

■パラメータ
TF_main = H1
LongMAPeriod = 75
SlopeThreshold = 0.0001
ShortMAPeriod = 20
EntryDelay = 1
TP = 50

■フィルター
- 時間
- スプレッド
- トレンド(SMA傾き)

② RSI+ボリンジャー逆張り

【RSI+BB逆張り】

■エントリー条件
- RSI < RSI_Low
- 価格がBB下限にタッチ
- ConfirmationBars後にBUY

■決済条件
- RSI ≥ Exit_RSI
- またはミドルバンド到達

■パラメータ
RSIPeriod = 14
RSI_Low = 30
Exit_RSI = 50
BB_Period = 20
BB_Deviation = 2.0
ConfirmationBars = 1

■フィルター
- 時間
- スプレッド
- トレンド(ADX弱い時のみ推奨)

③ レンジブレイク

【レンジブレイク】

■エントリー条件
- 過去RangeBarsのレンジ幅 ≤ MaxRangePips
- 高値更新でBUY、安値更新でSELL

■決済条件
- TPまたはSL
- トレーリング

■パラメータ
RangeBars = 20
MaxRangePips = 30
BreakBuffer = 2
TP = 50
SL = 25

■フィルター
- 時間
- スプレッド
- トレンド(なし)

④ ADXトレンドフォロー

【ADXトレンドフォロー】

■エントリー条件
- ADX ≥ ADX_Threshold
- +DI > -DI → BUY
- -DI > +DI → SELL

■決済条件
- ADX低下
- DIクロス

■パラメータ
ADX_Period = 14
ADX_Threshold = 25
ExitADX = 20

■フィルター
- 時間
- スプレッド
- トレンド(ADX)

⑤ ロンドンブレイク

【ロンドンブレイク】

■エントリー条件
- 東京時間の高安を記録
- ロンドン開始後にブレイク方向へエントリー

■決済条件
- TP or 時間終了

■パラメータ
TokyoStart = 00:00
TokyoEnd = 08:00
LondonStart = 09:00
BufferPips = 3
TP = 40
SL = 20

■フィルター
- 時間
- スプレッド
- トレンド(なし)

⑥ グリッド

【グリッド】

■エントリー条件
- 一定間隔でポジション追加

■決済条件
- 平均価格+TPで全決済

■パラメータ
GridStep = 20
MaxPositions = 5
TakeProfitPips = 30
LotMultiplier = 1.2

■フィルター
- 時間
- スプレッド
- トレンド(任意)

⑦ ピンバー

【ピンバー反転】

■エントリー条件
- ヒゲ長さ ≥ BodyRatio倍
- サポレジ付近

■決済条件
- RR到達
- 反対シグナル

■パラメータ
BodyRatio = 2.0
SR_Distance = 10
RR = 1.5

■フィルター
- 時間
- スプレッド
- トレンド(逆張り)

⑧ MTF

【MTFトレンド】

■エントリー条件
- 上位足MA方向一致
- 下位足でクロス

■決済条件
- 逆クロス
- 保有時間終了

■パラメータ
TF_high = H1
TF_low = M5
MA_fast = 10
MA_slow = 30
HoldingBars = 20

■フィルター
- 時間
- スプレッド
- トレンド(上位足)

⑨ ATRブレイク

【ATRブレイク】

■エントリー条件
- ATR ≥ Threshold
- 高値更新でBUY

■決済条件
- ATR低下
- SL

■パラメータ
ATR_Period = 14
ATR_Threshold = 0.001
BreakBars = 10
SL_Multiplier = 1.5

■フィルター
- 時間
- スプレッド
- トレンド(ボラ)

⑩ MAクロス基本

【MAクロス】

■エントリー条件
- 短期MAが長期MAを上抜け → BUY
- 下抜け → SELL

■決済条件
- 逆クロス
- TP/SL

■パラメータ
MA_fast = 10
MA_slow = 50
TP = 40
SL = 20

■フィルター
- 時間
- スプレッド
- トレンド(なし)

統計フィルター化 👉 「勝っているパターンだけ残す仕組み」

#property indicator_chart_window

 

// ===== パラメータ =====
input int BB_Period = 20;
input double BB_Dev = 2.5;
input int RSI_Period = 14;

 

// ===== 状態 =====
int position = 0;
double entry_price = 0;
string current_pattern = "";

 

// ===== 統計 =====
int win_rsi30_bb = 0;
int lose_rsi30_bb = 0;

 

int win_rsi70_bb = 0;
int lose_rsi70_bb = 0;

 

// ===== インジ =====
double Upper(int i){
   return iBands(NULL,0,BB_Period,BB_Dev,0,PRICE_CLOSE,MODE_UPPER,i);
}
double Lower(int i){
   return iBands(NULL,0,BB_Period,BB_Dev,0,PRICE_CLOSE,MODE_LOWER,i);
}
double RSI(int i){
   return iRSI(NULL,0,RSI_Period,PRICE_CLOSE,i);
}

 

// ===== 勝率計算 =====
double WinRate(int w, int l)
{
   if(w + l == 0) return 0;
   return (double)w / (w + l) * 100;
}

 

// ===== フィルター =====
bool AllowTrade(string pattern)
{
   double rate = 0;

 

   if(pattern == "RSI30_BB")
   {
      rate = WinRate(win_rsi30_bb, lose_rsi30_bb);
      if(rate < 60) return false;
   }

 

   if(pattern == "RSI70_BB")
   {
      rate = WinRate(win_rsi70_bb, lose_rsi70_bb);
      if(rate < 60) return false;
   }

 

   return true;
}

 

// ===== メイン =====
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time,
                const double &open,
                const double &high,
                const double &low,
                const double &close,
                const long &tick_volume,
                const long &volume,
                const int &spread)
{
   for(int i=100; i>=0; i--)
   {
      double upper = Upper(i);
      double lower = Lower(i);
      double rsi = RSI(i);

 

      string pattern = "";

 

      // ===== パターン分類 =====
      if(low[i] <= lower && rsi < 30)
         pattern = "RSI30_BB";

 

      if(high[i] >= upper && rsi > 70)
         pattern = "RSI70_BB";

 

      // =====================
      // エントリー
      // =====================
      if(position == 0 && pattern != "")
      {
         if(!AllowTrade(pattern))
            continue;

 

         current_pattern = pattern;
         entry_price = close[i];

 

         if(pattern == "RSI30_BB")
            position = 1;

 

         if(pattern == "RSI70_BB")
            position = -1;
      }

 

      // =====================
      // 決済
      // =====================
      if(position != 0)
      {
         bool exit = false;

 

         if(position == 1 && rsi > 50) exit = true;
         if(position == -1 && rsi < 50) exit = true;

 

         if(exit)
         {
            double profit = 0;

 

            if(position == 1)
               profit = close[i] - entry_price;
            else
               profit = entry_price - close[i];

 

            // ===== 統計更新 =====
            if(current_pattern == "RSI30_BB")
            {
               if(profit > 0) win_rsi30_bb++;
               else lose_rsi30_bb++;
            }

 

            if(current_pattern == "RSI70_BB")
            {
               if(profit > 0) win_rsi70_bb++;
               else lose_rsi70_bb++;
            }

 

            position = 0;
         }
      }
   }

 

   // ===== 表示 =====
   Comment(
   "RSI30_BB 勝率:", DoubleToString(WinRate(win_rsi30_bb, lose_rsi30_bb),1), "%\n",
   "RSI70_BB 勝率:", DoubleToString(WinRate(win_rsi70_bb, lose_rsi70_bb),1), "%"
   );

 

   return(rates_total);
}

✔ 勝率・総損益表示 ✔ 稼働時間:日本時間 08:00〜04:00 ✔ 1時間足MAが強いトレンド時は逆張り禁止 ✔ 損切後「5本待ち」 ✔ RSI 30 / 70 ブレイク時のみエントリー

#property indicator_chart_window

 

// ===== パラメータ =====
input int BB_Period = 20;
input double BB_Dev = 2.5;
input int RSI_Period = 14;
input int WaitBars = 5;

 

// ===== 状態 =====
int position = 0;
double entry_price = 0;
int wait_count = 0;

 

int win = 0;
int lose = 0;
double profit_total = 0;

 

// ===== インジ =====
double Upper(int i){ return iBands(NULL,0,BB_Period,BB_Dev,0,PRICE_CLOSE,MODE_UPPER,i); }
double Lower(int i){ return iBands(NULL,0,BB_Period,BB_Dev,0,PRICE_CLOSE,MODE_LOWER,i); }
double RSI(int i){ return iRSI(NULL,0,RSI_Period,PRICE_CLOSE,i); }

 

// ===== H1トレンド判定 =====
bool StrongTrend(int i)
{
   double ma_now = iMA(NULL,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE,i);
   double ma_prev = iMA(NULL,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE,i+5);

 

   if(MathAbs(ma_now - ma_prev) > 0.002) // 傾き閾値(調整可)
      return true;

 

   return false;
}

 

// ===== 時間制限 =====
bool TradeTime(datetime t)
{
   int h = TimeHour(t);

 

   if(h >= 8 || h <= 4) return true;

 

   return false;
}

 

// ===== 描画 =====
void Arrow(string name, datetime t, double price, int code, color clr)
{
   ObjectCreate(0,name,OBJ_ARROW,0,t,price);
   ObjectSetInteger(0,name,OBJPROP_ARROWCODE,code);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
}

 

void Text(string name, datetime t, double price, string txt, color clr)
{
   ObjectCreate(0,name,OBJ_TEXT,0,t,price);
   ObjectSetText(name,txt,10,"Arial",clr);
}

 

// ===== 統計描画 =====
void DrawStats()
{
   double rate = 0;
   if(win+lose > 0)
      rate = (double)win/(win+lose)*100.0;

 

   Comment("勝ち:",win,
           " 負け:",lose,
           " 勝率:",DoubleToString(rate,1),"%\n",
           "累計:",DoubleToString(profit_total,2));
}

 

// ===== メイン =====
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time,
                const double &open,
                const double &high,
                const double &low,
                const double &close,
                const long &tick_volume,
                const long &volume,
                const int &spread)
{
   for(int i=100; i>=0; i--)
   {
      string id = IntegerToString(i);

 

      if(!TradeTime(time[i])) continue;

 

      if(wait_count > 0)
      {
         wait_count--;
         continue;
      }

 

      double upper = Upper(i);
      double lower = Lower(i);
      double rsi   = RSI(i);

 

      bool trend = StrongTrend(i);

 

      // =====================
      // エントリー
      // =====================
      if(position == 0 && !trend)
      {
         // ロング
         if(low[i] <= lower && rsi < 30)
         {
            position = 1;
            entry_price = close[i];

 

            Arrow("Buy"+id,time[i],low[i],233,clrLime);
         }

 

         // ショート
         if(high[i] >= upper && rsi > 70)
         {
            position = -1;
            entry_price = close[i];

 

            Arrow("Sell"+id,time[i],high[i],234,clrRed);
         }
      }

 

      // =====================
      // 決済(ロング)
      // =====================
      if(position == 1)
      {
         if(high[i] >= upper || rsi > 50)
         {
            double profit = close[i] - entry_price;
            profit_total += profit;

 

            Arrow("Exit"+id,time[i],close[i],159,clrYellow);

 

            if(profit > 0)
            {
               win++;
               Text("W"+id,time[i],close[i],"〇",clrAqua);
            }
            else
            {
               lose++;
               Text("L"+id,time[i],close[i],"×",clrRed);
               wait_count = WaitBars;
            }

 

            position = 0;
         }
      }

 

      // =====================
      // 決済(ショート)
      // =====================
      if(position == -1)
      {
         if(low[i] <= lower || rsi < 50)
         {
            double profit = entry_price - close[i];
            profit_total += profit;

 

            Arrow("Exit"+id,time[i],close[i],159,clrYellow);

 

            if(profit > 0)
            {
               win++;
               Text("W"+id,time[i],close[i],"〇",clrAqua);
            }
            else
            {
               lose++;
               Text("L"+id,time[i],close[i],"×",clrRed);
               wait_count = WaitBars;
            }

 

            position = 0;
         }
      }
   }

 

   DrawStats();

 

   return(rates_total);
}

エントリー→決済→勝敗表示」まで全部入った MQL4フルコード

#property indicator_chart_window

 

// ---- パラメータ ----
input int BB_Period = 20;
input double BB_Dev = 2.0;
input int MA_Period = 20;
input int ArrowGap = 5;

 

// ---- 状態管理 ----
int position = 0; // 1=buy, -1=sell, 0=none
double entry_price = 0;

 

// ---- 関数 ----
double Upper(int i){
   return iBands(NULL,0,BB_Period,BB_Dev,0,PRICE_CLOSE,MODE_UPPER,i);
}
double Lower(int i){
   return iBands(NULL,0,BB_Period,BB_Dev,0,PRICE_CLOSE,MODE_LOWER,i);
}
double MA(int i){
   return iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_CLOSE,i);
}

 

// ---- 描画 ----
void DrawArrow(string name, datetime t, double price, int code, color clr){
   ObjectCreate(0,name,OBJ_ARROW,0,t,price);
   ObjectSetInteger(0,name,OBJPROP_ARROWCODE,code);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
}

 

void DrawText(string name, datetime t, double price, string text, color clr){
   ObjectCreate(0,name,OBJ_TEXT,0,t,price);
   ObjectSetText(name,text,10,"Arial",clr);
}

 

// ---- メイン ----
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time,
                const double &open,
                const double &high,
                const double &low,
                const double &close,
                const long &tick_volume,
                const long &volume,
                const int &spread)
{
   for(int i=100; i>=0; i--)
   {
      double upper = Upper(i);
      double lower = Lower(i);
      double ma = MA(i);

 

      string id = IntegerToString(i);

 

      // =========================
      // エントリー
      // =========================
      if(position == 0)
      {
         // ロング
         if(low[i] <= lower)
         {
            position = 1;
            entry_price = close[i];

 

            DrawArrow("Buy"+id,time[i],low[i]-Point*ArrowGap,233,clrLime);
         }

 

         // ショート
         if(high[i] >= upper)
         {
            position = -1;
            entry_price = close[i];

 

            DrawArrow("Sell"+id,time[i],high[i]+Point*ArrowGap,234,clrRed);
         }
      }

 

      // =========================
      // 決済(ロング)
      // =========================
      if(position == 1)
      {
         if(high[i] >= upper || close[i] < ma)
         {
            position = 0;

 

            DrawArrow("Exit"+id,time[i],close[i],159,clrYellow);

 

            // 勝敗判定
            if(close[i] > entry_price)
               DrawText("Win"+id,time[i],close[i],"〇",clrAqua);
            else
               DrawText("Lose"+id,time[i],close[i],"×",clrRed);
         }
      }

 

      // =========================
      // 決済(ショート)
      // =========================
      if(position == -1)
      {
         if(low[i] <= lower || close[i] > ma)
         {
            position = 0;

 

            DrawArrow("Exit"+id,time[i],close[i],159,clrYellow);

 

            // 勝敗判定
            if(close[i] < entry_price)
               DrawText("Win"+id,time[i],close[i],"〇",clrAqua);
            else
               DrawText("Lose"+id,time[i],close[i],"×",clrRed);
         }
      }
   }

 

   return(rates_total);
}

ちょうどいい高値安値のZIGZAGコード公開

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red

 

double ZigZagBuffer;

 

int depth = 20;
double deviation = 3.0;

 

int OnInit()
{
    SetIndexBuffer(0, ZigZagBuffer);
    SetIndexStyle(0, DRAW_LINE);
    return(INIT_SUCCEEDED);
}

 

// ボリンジャーバンド取得
double GetUpper(int i)
{
    return iBands(NULL, 0, 20, deviation, 0, PRICE_CLOSE, MODE_UPPER, i);
}
double GetLower(int i)
{
    return iBands(NULL, 0, 20, deviation, 0, PRICE_CLOSE, MODE_LOWER, i);
}
double GetMA(int i)
{
    return iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, i);
}

 

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time,
                const double &open,
                const double &high,
                const double &low,
                const double &close,
                const long &tick_volume,
                const long &volume,
                const int &spread[])
{
    int i;
    static int trend = 0; // 1=上昇, -1=下降
    static double lastHigh = 0;
    static double lastLow = 0;

 

    for(i = rates_total - depth; i >= 0; i--)
    {
        double upper = GetUpper(i);
        double lower = GetLower(i);

 

        // --- 初期化 ---
        if(trend == 0)
        {
            lastHigh = high[i];
            lastLow = low[i];
            trend = 1;
        }

 

        // =========================
        // 上昇トレンド中
        // =========================
        if(trend == 1)
        {
            // 高値更新
            if(high[i] > lastHigh)
            {
                lastHigh = high[i];
            }

 

            // -3σタッチで転換
            if(low[i] <= lower)
            {
                ZigZagBuffer[i] = lastHigh;
                lastLow = low[i];
                trend = -1;
            }
        }

 

        // =========================
        // 下降トレンド中
        // =========================
        if(trend == -1)
        {
            // 安値更新(重要ロジック)
            if(low[i] < lastLow)
            {
                lastLow = low[i];
            }

 

            // +3σタッチで転換
            if(high[i] >= upper)
            {
                ZigZagBuffer[i] = lastLow;
                lastHigh = high[i];
                trend = 1;
            }
        }
    }

 

    return(rates_total);
}