取引の一時停止について

2026/03/03 18:01
29

お世話になります。
建て値ストップを使用したら、取引にはt/p(勝ち)、と3通りのs/l
 s/l>0(逆指値で+で終了)・・・①
 s/l=0(逆指値で±0で終了)・・・②
 s/l<0(逆指値でーで終了)・・・③
が発生します。
そこで3連敗③のパターンが累計で3回発生したら一旦売買を停止することは可能か?
3連敗の例
 ③③③ 負ー負ー負
 ①ー①ー③ー②ー①ー③ー③ 累計で③が3つとなる 正ー正ー負ー0-正ー負ー負
ここで一体売買を停止する。

また、取引再開のサインとしてt/p(ここは取引停止中なので実売買は行っていない)が発生した場合に
取引再開する
例 ①ー①ー③ー②ー①ー③ー③ーt/pが発生したら売買を再開する
このような設定は可能でしょうか?
わかりづらくてすみません。

コメント

GogoJungle
2026/03/07 15:18

ご質問は、「建値ストップ等で決済結果がプラス/ほぼゼロ/マイナスに分かれる中で、"マイナス(③)"が3連敗するパターンが累計3回発生したら売買停止し、停止中は"仮想的に"TP相当が起きたら再開したい」という内容ですね。

結論から言うと、EAつくーるの画面設定だけで「敗北回数(③)を数えて一時停止→仮想TPで再開」までは実現が難しいです。
(EAつくーるのオプションには「連続エントリー制限」「取引時間制限」などはありますが、"直近の取引結果(勝ち/負け)をカウントして停止/再開"というロジックを直接は持っていません。)

その代わり、EAつくーるで作成したEAのコードに最小限の追記をすると実現可能です。以下に改造案を提示します。


準備
  1. EAつくーるで通常どおりEAを作成・ダウンロードします。
  2. MetaEditorでEA(mq4)を開きます。
  3. 「OnTick()」で検索し、後述の追記を入れます。

補足(こうなっていませんか?)
建値(②)と思っていても、スプレッド・手数料(Commission)・スワップの影響で、履歴上はわずかにマイナスになり「③扱い」になりやすいです。
そのため、「±ほぼゼロ」を"ゼロ扱いする閾値(例:-0.5~+0.5通貨)」 を設けるのがおすすめです(下のコードで対応します)。


コード修正案(売買停止→仮想TPで再開) 1) グローバル変数と入力パラメータを追加

「input string comment = “”;」の近くに追記してください。

【修正前】

input string comment    = "";

【修正後】

input string comment    = "";

//--- 追加:停止ロジック用パラメータ
input int    LossStreakLen   = 3;    // ③の連敗数(例:3)
input int    LossStreakTimes = 3;    // 「③③③」が何回出たら停止するか(例:3回)
input double ZeroProfitEps   = 0.0;  // ②判定の許容(口座通貨)。手数料等があるなら例:0.5 など

//--- 追加:内部状態
bool     TradingPaused   = false;
int      ConsecutiveLoss = 0;   // 連敗中の③カウント
int      LossStreakHit   = 0;   // 「③③③」が出た回数
int      LastHistTotal   = 0;   // 履歴監視用

//--- 停止中の"仮想トレード"監視
bool   VirtualActive = false;
int    VirtualSignal = 0;       // 1=買い, -1=売り
double VirtualEntry  = 0.0;     // 仮想エントリー価格

2) 決済結果(①/②/③)を履歴から数える関数を追加

「void OnTick()」より上(どこでもOKですが、OnTickの前がおすすめ) に貼り付けます。

//--- 追加:直近の決済結果を履歴から監視し、③③③の累計回数で停止判定
void UpdatePauseStateByHistory(int magic)
{
   int ht = OrdersHistoryTotal();
   if(LastHistTotal == 0) {
      LastHistTotal = ht;
      return;
   }
   if(ht <= LastHistTotal) return;

   // 増えた分だけチェック(念のため複数件)
   for(int i = ht - 1; i >= 0 && i >= LastHistTotal; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if(OrderSymbol() != Symbol()) continue;
      if(OrderMagicNumber() != magic) continue;
      if(OrderType() != OP_BUY && OrderType() != OP_SELL) continue;

      // 損益(口座通貨)。手数料・スワップ込みにしたい場合は加算します
      double profit = OrderProfit() + OrderSwap() + OrderCommission();

      // ②(ほぼゼロ)判定
      if(MathAbs(profit) <= ZeroProfitEps) {
         ConsecutiveLoss = 0;
         continue;
      }

      // ①(プラス)
      if(profit > 0) {
         ConsecutiveLoss = 0;
         continue;
      }

      // ③(マイナス)
      ConsecutiveLoss++;

      if(ConsecutiveLoss >= LossStreakLen) {
         LossStreakHit++;
         ConsecutiveLoss = 0; // 「③③③」を1回として数えたらリセット

         if(LossStreakHit >= LossStreakTimes) {
            TradingPaused = true;
            VirtualActive = false; // 停止に入ったら仮想状態はリセット
         }
      }
   }

   LastHistTotal = ht;
}

3) 停止中に「仮想TPで再開」する処理を追加

こちらも OnTickより上に貼り付けます。

//--- 追加:停止中に"仮想エントリー"→TP到達で再開
void CheckVirtualResume(int signal, double tp_pips, double sl_pips)
{
   // すでに仮想ポジション監視中なら、TP/SL到達を判定
   if(VirtualActive)
   {
      if(VirtualSignal == 1) {
         // 買い:Ask基準
         double tp = VirtualEntry + PipsToPrice(tp_pips);
         double sl = VirtualEntry - PipsToPrice(sl_pips);

         if(Ask >= tp) {
            // 仮想TPで再開
            TradingPaused = false;
            LossStreakHit = 0;
            ConsecutiveLoss = 0;
            VirtualActive = false;
         } else if(Ask <= sl) {
            // 仮想SLなら、再開せず次の仮想チャンス待ち
            VirtualActive = false;
         }
      }
      else if(VirtualSignal == -1) {
         // 売り:Bid基準
         double tp = VirtualEntry - PipsToPrice(tp_pips);
         double sl = VirtualEntry + PipsToPrice(sl_pips);

         if(Bid <= tp) {
            TradingPaused = false;
            LossStreakHit = 0;
            ConsecutiveLoss = 0;
            VirtualActive = false;
         } else if(Bid >= sl) {
            VirtualActive = false;
         }
      }
      return;
   }

   // 仮想監視を開始していない場合、停止中に新しいエントリーシグナルが出たら仮想エントリー開始
   if(signal == 1) {
      VirtualActive = true;
      VirtualSignal = 1;
      VirtualEntry  = Ask;
   }
   else if(signal == -1) {
      VirtualActive = true;
      VirtualSignal = -1;
      VirtualEntry  = Bid;
   }
}

4) OnTick() を「停止判定→停止中は仮想監視→通常時だけエントリー」に変更

「void OnTick()」内の先頭付近を修正します。
ポイントは、signalを作る前に履歴チェックし、停止していたら発注せず仮想監視だけにすることです。

【修正前(抜粋)】

void OnTick()
{

   int signal = 0;
   double lots = Lots;
   double take_profit = TakeProfit;
   double stop_loss = StopLoss;
   Trade = true;

   if(Trade == false) return;
   ...
   if(signal != 0 && getOpenLots(Magic1) == 0) {
      if(openPosition(signal, lots, take_profit, stop_loss, Magic1)) {
         bars1 = Bars;
      }
   }
}

【修正後(抜粋)】

void OnTick()
{
   // 追加:履歴から停止状態を更新
   UpdatePauseStateByHistory(Magic1);

   int signal = 0;
   double lots = Lots;
   double take_profit = TakeProfit;
   double stop_loss = StopLoss;

   // ここでシグナル生成(EAつくーるの条件部分)
   signal = 0;
   if(iClose(Symbol(), 0, 0)+PipsToPrice(0)  ==  iClose(Symbol(), 0, 0)+PipsToPrice(0)) signal = 1;

   // 追加:停止中は発注せず、仮想TP監視のみ
   if(TradingPaused) {
      CheckVirtualResume(signal, take_profit, stop_loss);
      return;
   }

   // 通常運転(停止していないときだけ発注)
   if(signal != 0 && getOpenLots(Magic1) == 0) {
      if(openPosition(signal, lots, take_profit, stop_loss, Magic1)) {
         bars1 = Bars;
      }
   }
}

使い方の注意点(実運用でズレやすいところ)
  • ②(±0)判定
    実際は手数料等で微妙にマイナスになりやすいので、ZeroProfitEps0.51.0(口座通貨)などにすると、意図どおり「②扱い」になりやすいです。
    例:ドル口座なら 0.5、円口座なら 50 など、ブローカーの手数料感に合わせて調整します。
  • "③の定義"
    ご質問文では「建値ストップを使うとSLが3通り」とありますが、EA側からは「どの決済理由(SL/TP/手動)」かよりも、まず履歴の損益がプラスかマイナスかで判定するのが安定です。
    「SLでプラス(①)」も、履歴上は単純に利益>0なら①になります。
  • 停止中の"仮想TP"の定義
    上の実装は「停止中にエントリー条件が出た瞬間の価格を仮想エントリー価格にして、TP/SL幅に到達したら再開」という定義です。
    ご希望の「停止中なので実売買はしていないがTPが出たら再開」を、現実的に再現しやすい形に落とし込んだものになります。

もし「③③③を"連続3回負け"ではなく、"③が累計3つ溜まったら"停止」など、カウントの意味合いが別の場合でも、上の ConsecutiveLossLossStreakHit の増やし方を少し変えるだけで対応できます(例:③が出るたびに LossCountTotal++ して、3回で停止、など)。ただ、まずはご提示いただいた「③③③という3連敗パターンを何回か」であれば、上記の改造で狙いどおり動作します。

関連トピックス

検索結果がありません。

ノーコードで誰でも簡単EA開発!MQL言語学習にも使える! | GogoJungle

注目トピックス

検索結果がありません。