👌

MQL4でブレイクイーブンとトレーリングストップの機能

2024/03/10に公開

int MagicNumber = 654789;
// Trailing Stop Settings
input string trailing_stop_Comment = "---- トレーリングストップの設定 ----";
input bool trailing_stop_on = false;                   // トレーリングストップのON/OFF
input int trailing_stop_trigger = 500;                  // トレーリングストップのトリガー数値設定
input int trailing_stop_offset = 300;                   // トレーリングストップのオフセット数値設定

// Trailing Stop Settings
input string BreakEven_Comment = "---- ブレイクイーブンの設定 ----";
input bool BreakEven_on = false;                   // トレーリングストップのON/OFF
input int BreakEven_trigger = 500;                  // トレーリングストップのトリガー数値設定

int position_count(int side) {

   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         if(OrderType() == side) {
            if(OrderSymbol()==Symbol()) {
               if(OrderMagicNumber()==MagicNumber) {
                  count++;
               }
            }
         }
      }
   }
   return count;
}

class StopManagement {
private:
   int               BreakEvenTrigger;     // ブレイクイーブントリガー距離(ポイント)
   int               TrailingStopTrigger;  // トレーリングストップがアクティブになる距離(ポイント)
   int               TrailingStopLevel;    // トレーリングストップを調整する距離(ポイント)
   bool              IsBreakEvenApplied;   // ブレイクイーブンが適用されたかどうか
   bool              IsTrailingStopApplied;// トレーリングストップが適用されたかどうか
   bool              TrailingStopOn;       // トレーリングストップが有効かどうか
   bool              BreakEvenOn;          // ブレイクイーブンが有効かどうか

public:
   // コンストラクタ
                     StopManagement(int breakEvenTrigger, int trailingStopTrigger, int trailingStopLevel, bool trailingStopOn, bool breakEvenOn) :
                     BreakEvenTrigger(breakEvenTrigger),
                     TrailingStopTrigger(trailingStopTrigger),
                     TrailingStopLevel(trailingStopLevel),
                     IsBreakEvenApplied(false),
                     IsTrailingStopApplied(false),
                     TrailingStopOn(trailingStopOn),
                     BreakEvenOn(breakEvenOn) {}

   // ブレイクイーブンとトレーリングストップのパラメータを設定するメソッド
   void              SetParameters(int breakEvenTrigger, int trailingStopTrigger, int trailingStopLevel) {
      BreakEvenTrigger = breakEvenTrigger;
      TrailingStopTrigger = trailingStopTrigger;
      TrailingStopLevel = trailingStopLevel;
   }

   // トレーリングストップとブレイクイーブンロジックを適用するメソッド
   void              ApplyStopLogic() {
      if (position_count(0) == 0 && position_count(1) == 0) {
         ResetStates();
         return;
      }

      for (int i = OrdersTotal() - 1; i >= 0; i--) {
         if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
               double currentPrice = (OrderType() == OP_BUY) ? MarketInfo(OrderSymbol(), MODE_ASK) : MarketInfo(OrderSymbol(), MODE_BID);
               double orderOpenPrice = OrderOpenPrice();
               double orderStopLoss = OrderStopLoss();

               // ブレイクイーブンロジック
               if (!IsTrailingStopApplied && BreakEvenOn && !IsBreakEvenApplied && ((OrderType() == OP_BUY && currentPrice > orderOpenPrice + PointsToPrice(BreakEvenTrigger)) || (OrderType() == OP_SELL && currentPrice < orderOpenPrice - PointsToPrice(BreakEvenTrigger)))) {
                  double newStopLossPrice = orderOpenPrice;
                  if (OrderModify(OrderTicket(), orderOpenPrice, newStopLossPrice, OrderTakeProfit(), 0, clrNONE)) {
                     IsBreakEvenApplied = true;
                  } else {
                     Print("OrderModify failed with error (BreakEven): ", GetLastError());
                  }
               }

               // トレーリングストップロジック
               if (TrailingStopOn) {
                  double trailingStopTriggerPrice = (OrderType() == OP_BUY) ? orderOpenPrice + PointsToPrice(TrailingStopTrigger) : orderOpenPrice - PointsToPrice(TrailingStopTrigger);
                  if (!IsTrailingStopApplied && ((OrderType() == OP_BUY && currentPrice > trailingStopTriggerPrice) || (OrderType() == OP_SELL && currentPrice < trailingStopTriggerPrice))) {
                     double newStopLossPrice = (OrderType() == OP_BUY) ? currentPrice - PointsToPrice(TrailingStopLevel) : currentPrice + PointsToPrice(TrailingStopLevel);
                     if (OrderModify(OrderTicket(), orderOpenPrice, newStopLossPrice, OrderTakeProfit(), 0, clrNONE)) {
                        IsTrailingStopApplied = true;
                     } else {
                        Print("OrderModify failed with error (TrailingStop initial): ", GetLastError());
                     }
                  } else if (IsTrailingStopApplied) {
                     
                        double newStopLossPrice = (OrderType() == OP_BUY) ? currentPrice - PointsToPrice(TrailingStopLevel) : currentPrice + PointsToPrice(TrailingStopLevel);
                        if(newStopLossPrice!=orderStopLoss) {
                        if ((OrderType() == OP_BUY && newStopLossPrice > orderStopLoss) || (OrderType() == OP_SELL && newStopLossPrice < orderStopLoss)) {
                           if (OrderModify(OrderTicket(), orderOpenPrice, newStopLossPrice, OrderTakeProfit(), 0, clrNONE)) {
                              // Already true, no need to change IsTrailingStopApplied.
                           } else {
                              Print("OrderModify failed with error (TrailingStop adjustment): ", GetLastError());
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   // ポイントを価格に変換する補助関数
   double            PointsToPrice(int points) {
      return points * MarketInfo(Symbol(), MODE_POINT);
   }

   // トレードが存在しない場合に状態をリセットする関数
   void              ResetStates() {
      IsBreakEvenApplied = false;
      IsTrailingStopApplied = false;
   }
};

// StopManagementインスタンスの初期化
StopManagement stopManager(BreakEven_trigger, trailing_stop_trigger, trailing_stop_offset, trailing_stop_on, BreakEven_on);

Discussion