DCA Bot for Both Directions Works Well – Trailing Stop Logic Not Working

Tarea técnica

Hi everyone,

I have developed a DCA (Dollar Cost Averaging) trading bot for MetaTrader 5, which manages both long and short series separately, each with its own Magic Number.
The core DCA logic is working well:

  • The bot opens an initial market order and then places pending DCA limit orders according to my custom lot and profit arrays.

  • It manages both directions (long & short) independently and everything works as expected.

The Problem:
The only issue I’m struggling with is implementing the trailing stop logic after a certain profit or number of positions is reached.
Every time I try to apply the trailing stop to open trades, it either doesn’t update the SL at all, or it updates incorrectly (sometimes even closes positions unexpectedly).

Questions:

  • Is there a recommended way to add a trailing stop for an entire DCA basket (all open trades for a given Magic Number) after a profit target or X trades are reached?

  • Is there any example or known best practice for this scenario in MT5 (MQL5, CTrade)?

  • Any code sample or link to a reliable EA/code with robust trailing stop logic would be greatly appreciated!

My Approach (Summary):



  • I loop over all positions with a specific Magic Number.

  • When profit target is hit (or basket reaches 10+ trades), I delete all pending orders and try to activate trailing stop on the open positions.

  • But the SL either doesn't update, or updates in a weird way.

If anyone can review my trailing stop code, or suggest a robust implementation, that would help me a lot!

Thank you in advance!



📜 DCA + Trailing Stop Management Rules for MT5 Bot

General Strategy Structure

1️⃣ There must always be open trades – either in longs, shorts, or both.
2️⃣ If there are no open positions at all (no longs and no shorts), open a new DCA long group and a new DCA short group.
3️⃣ When a group reaches its profit target:

  • If there are fewer than 10 trades without SL in the group → close all trades in the group and open a new group in the same direction.

  • If there are 10 or more trades without SL in the group → activate trailing stop on all open trades, delete all pending orders, and open a new group in the same direction.
    4️⃣ After trailing stop is activated and all pending orders are deleted, immediately open a new DCA group in the same direction. From now on, profit tracking and trade count refer only to the trades without SL from the new group.
    5️⃣ If there are no trades without SL and no pending orders in a direction, open a new DCA group in that direction.


🔵 Step-by-Step Rules

1️⃣ Opening DCA Groups (Long/Short)

When do you open a new DCA group?
✅ If there are no open trades at all (neither long nor short), open a new DCA long + a new DCA short group.
✅ If a group was closed (by reaching profit target or trailing), open a new group in the same direction.
✅ If there are no trades without SL and no pending orders in a direction, open a new group in that direction.

2️⃣ Profit Management & Group Closure

What to do when a group reaches its profit target?

  • Check how many trades are still open without SL (from the current group):

    • If there are fewer than 10 trades without SL: close all trades and delete all pending orders → open a new group in the same direction.

    • If there are 10 or more trades without SL: activate trailing stop on all open trades and delete all pending orders → open a new group in the same direction.

3️⃣ Trailing Stop Management

How does the trailing stop work?

  • After a group reaches its profit target and there are at least 10 trades without SL, all open trades in the group receive a dynamic SL.

  • The SL distance from the current price is set by TrailingStopPips .

  • Whenever price moves in your favor by at least TrailingStepPips , the SL is moved accordingly.

What happens after trailing is activated?
✅ All pending orders for that direction are deleted.
✅ A new DCA group is immediately opened in that direction.
✅ From this point, both profit calculations and trade counts only refer to trades without SL from the new group.

4️⃣ What if all trades are closed?

  • If there are no open trades at all → open a new DCA long + a new DCA short group.

  • If there are no trades without SL and no pending orders in a direction → open a new DCA group in that direction.


//+------------------------------------------------------------------+
//|      Combined DCA EA (MQL5) – ניהול מלא לונג ושורט עם פתיחה במחיר השוק   |
//|                                                                |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Your Name"
#property link      "https://www.yourwebsite.com"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>        // כולל גישה ל-CTrade
#include <Trade\PositionInfo.mqh> // עבור CPositionInfo
#include <Trade\OrderInfo.mqh>    // עבור COrderInfo

// אובייקטים לגישה לפונקציות מסחר ומידע
CTrade      m_trade;
CPositionInfo m_position; // אובייקט לגישה למידע על פוזיציות
COrderInfo  m_order;     // אובייקט לגישה למידע על פקודות

// דגלים לניהול מצב הרובוט - לונג ושורט
bool LongInProgress = false;      // True אם סדרת לונג פעילה (עסקאות פתוחות או פקודות פנדינג)
bool ShortInProgress = false;    // True אם סדרת שורט פעילה (עסקאות פתוחות או פקודות פנדינג)
bool LongTrailingActive = false;  // דגל המציין אם טריילינג ללונג פעיל כרגע
bool ShortTrailingActive = false; // דגל המציין אם טריילינג לשורט פעיל כרגע

//+------------------------------------------------------------------+
//|                                 INPUTS                           |
//+------------------------------------------------------------------+
input int   MaxDeviation   = 10;      // סטיית מחיר מקסימלית בפיפס לביצוע פקודות
input double WaitSeconds   = 1.0;      // זמן המתנה בשניות בין פעולות קריטיות (עבור Sleep)
input long  MagicLong      = 123456;    // מספר זיהוי ייחודי לעסקאות לונג
input long  MagicShort     = 654321;    // מספר זיהוי ייחודי לעסקאות שורט

input int   TotalOrders    = 50;        // המספר המקסימלי של עסקאות בסדרה (כולל הראשונה)

// ✅ פרמטרים לטריילינג סטופ
input int   TrailingStopPips = 50;  // מרחק הסטופ לוס (SL) מהמחיר הנוכחי בפיפס בעת הפעלת טריילינג
input int   TrailingStepPips = 10;  // הצעד המינימלי (בפיפס) שבו ה-SL יזוז

// 🔹 מרחק בין עסקאות DCA (בפיפס) - נפרד ללונג ושורט
input double PipDistanceLong  = 125;
input double PipDistanceShort = 125;

// 🔹 סף הגנה כולל על החשבון - סגירת כל העסקאות והפקודות אם ההפסד הצף הכולל מגיע לסכום זה
// הערה: יש להזין ערך שלילי! לדוגמה: -700000.0
input double MaxDrawdown    = -700000.0;

// 🔹 גודל לוט עבור כל עסקה בסדרה (עד 50 עסקאות) - עבור לונג
const double LotSizesLong[50] = { 
  0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02, 0.02,
  0.02, 0.02, 0.06, 0.03, 0.03, 0.05, 0.06, 0.06, 0.20, 0.07,
  0.08, 0.10, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15,
  0.15, 0.15, 0.30, 0.30, 0.80, 0.70, 0.40, 0.40, 0.40, 0.40,
  0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40
};
// 🔹 רווח יעד עבור כל עסקה בסדרה (עד 50 עסקאות) - עבור לונג
const double ProfitTargetsLong[50] = {
  1, 3, 4, 10, 15, 20, 27, 27, 27, 27,
  70, 70, 65, 70, 70, 70, 70, 70, 70, 100,
  100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
  500, 500, 500, 500, 500, 500, 500, 500, 500, 500
};

// 🔹 גודל לוט עבור כל עסקה בסדרה (עד 50 עסקאות) - עבור שורט
const double LotSizesShort[50] = {  
  0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02, 0.02,
  0.02, 0.02, 0.06, 0.03, 0.03, 0.05, 0.06, 0.06, 0.20, 0.07,
  0.08, 0.10, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15,
  0.15, 0.15, 0.30, 0.30, 0.80, 0.70, 0.40, 0.40, 0.40, 0.40,
  0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40, 0.40
};
// 🔹 רווח יעד עבור כל עסקה בסדרה (עד 50 עסקאות) - עבור שורט
const double ProfitTargetsShort[50] = {
   1, 3, 4, 10, 15, 20, 27, 27, 27, 27,
  70, 70, 70, 70, 70, 70, 70, 70, 70, 100,
  100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
  500, 500, 500, 500, 500, 500, 500, 500, 500, 500
};


//+------------------------------------------------------------------+
//| Convert Pips to Price (תיקון לחישוב נכון ב-XAUUSD וכו')          |
//+------------------------------------------------------------------+
// מחשב את שווי הפיפס במונחי מחיר עבור הסימבול הנוכחי.
// לדוגמה, עבור XAUUSD עם SYMBOL_POINT=0.01, פיפס אחד הוא 0.01$
double PipsToPrice(double pips){
   return pips * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}

//+------------------------------------------------------------------+
//| Close all positions and pending orders by magic (סגירה מוחלטת)    |
//+------------------------------------------------------------------+
// סוגר את כל העסקאות הפתוחות ומוחק את כל הפקודות הממתינות עבור Magic Number נתון.
void CloseAll(long magic) {
    PrintFormat("🔴 מתחיל תהליך סגירה כוללת עבור Magic: %llu", magic);
    int closedPositions = 0;
    int deletedOrders = 0;

    // 🔴 סגירת כל העסקאות הפתוחות עבור ה-Magic Number
    // לולאה הפוכה למניעת בעיות עם אינדקסים
    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        if (m_position.SelectByIndex(i)) {
            if (m_position.Magic() == magic) {
                if (m_trade.PositionClose(m_position.Ticket())) {
                    PrintFormat("🔴 עסקה נסגרה | Magic: %llu | כרטיס: %llu | רווח: %.2f", 
                                    magic, m_position.Ticket(), m_position.Profit());
                    closedPositions++;
                } else {
                    PrintFormat("❌ שגיאה בסגירת עסקה | Magic: %llu | כרטיס: %llu | שגיאה: %d", 
                                    magic, m_position.Ticket(), GetLastError());
                }
                Sleep(100); // המתנה קצרה למניעת עומס על השרת
            }
        }
    }

    // 🔴 מחיקת כל הפקודות הממתינות עבור ה-Magic Number
    // לולאה הפוכה למניעת בעיות עם אינדקסים
    for (int i = OrdersTotal() - 1; i >= 0; i--) {
        if (m_order.SelectByIndex(i)) {
            // בדיקה אם סוג הפקודה הוא Pending Order (LIMIT, STOP, BUY LIMIT, SELL LIMIT וכו')
            if (m_order.Magic() == magic && (m_order.OrderType() >= ORDER_TYPE_BUY_LIMIT && m_order.OrderType() <= ORDER_TYPE_SELL_STOP_LIMIT)) {
                if (m_trade.OrderDelete(m_order.Ticket())) {
                    PrintFormat("🔴 פקודת פנדינג נמחקה | Magic: %llu | כרטיס: %llu", magic, m_order.Ticket());
                } else {
                    PrintFormat("❌ שגיאה במחיקת פקודת פנדינג | Magic: %llu | כרטיס: %llu | שגיאה: %d", 
                                    magic, m_order.Ticket(), GetLastError());
                }
                Sleep(100);
            }
        }
    }

    PrintFormat("✅ Magic: %llu - סגירה כוללת הסתיימה. נסגרו %d עסקאות, נמחקו %d פקודות ממתינות.", magic, closedPositions, deletedOrders);
}

//+------------------------------------------------------------------+
//| Open Market Order (פתיחת עסקה בודדת במחיר השוק)                   |
//+------------------------------------------------------------------+
// פותח עסקת שוק (BUY/SELL) עם לוט סייז ומג'יק נתונים.
// פונקציית עזר לפתיחת העסקה הראשונה בסדרה.
bool OpenMarketOrder(long magic, ENUM_ORDER_TYPE orderType, double lotSize, double &openPrice){
    double price = (orderType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);

    m_trade.SetDeviationInPoints(MaxDeviation);
    m_trade.SetTypeFilling(ORDER_FILLING_IOC);

    bool res;
    if (orderType == ORDER_TYPE_BUY) {
        res = m_trade.Buy(lotSize, _Symbol, price, 0, 0, "DCA-MT5");
    } else {
        res = m_trade.Sell(lotSize, _Symbol, price, 0, 0, "DCA-MT5");
    }

    if (!res){
        PrintFormat("❌ שגיאה בפתיחת עסקת %s: %d", (orderType == ORDER_TYPE_BUY) ? "BUY" : "SELL", GetLastError());
        return false;
    } else {
        Sleep(500);
        for(int i = PositionsTotal() - 1; i >= 0; i--){
            if(m_position.SelectByIndex(i) && m_position.Magic() == magic && m_position.Symbol() == _Symbol){
                openPrice = m_position.PriceOpen();
                PrintFormat("✅ עסקת %s נפתחה בהצלחה | כרטיס: %llu | במחיר: %.5f", (orderType == ORDER_TYPE_BUY) ? "BUY" : "SELL", m_position.Ticket(), openPrice);
                return true;
            }
        }
        PrintFormat("❌ עסקת %s בוצעה, אך לא הצלחתי לאתר אותה כדי לקבל מחיר פתיחה! שגיאה: %d", (orderType == ORDER_TYPE_BUY) ? "BUY" : "SELL", GetLastError());
        return false;
    }
}

//+------------------------------------------------------------------+
//| Open DCA Series (פתיחת סדרת DCA ראשונית - עסקת שוק + פקודות פנדינג) |
//+------------------------------------------------------------------+
// פותח סדרה חדשה של עסקאות DCA: עסקת שוק ראשונית ו-49 פקודות פנדינג.
// פונקציה זו נמנעת מפתיחה אם כבר קיימות עסקאות פתוחות או פקודות ממתינות עבור אותו Magic Number,
// מה שמבטיח שרק סדרה אחת רצה בכל זמן.
void OpenDCA(int magic, ENUM_ORDER_TYPE orderType){
    // ... (בדיקות כמו בקוד שלך)

    double firstPrice = 0.0;
    double lotSize = (magic == MagicLong) ? LotSizesLong[0] : LotSizesShort[0];

   double openPrice = 0.0;
if (!OpenMarketOrder(magic, (magic == MagicLong) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL, lotSize, openPrice)) {
    Print("❌ שגיאה בפתיחת עסקת השוק הראשונית!");
    return;
}

    Sleep(200);

    // שליפת מחיר העסקה שבוצעה באמת
    for(int i = PositionsTotal() - 1; i >= 0; i--){
        if(m_position.SelectByIndex(i) && m_position.Magic() == magic){
            firstPrice = m_position.PriceOpen();
            break;
        }
    }

    if (firstPrice == 0.0) {
        Print("❌ לא הצלחנו לאתר את מחיר הפתיחה – לא נמשיך לפתוח פקודות!");
        return;
    }

    PrintFormat("✅ מחיר פתיחה ראשון נשמר: %.5f", firstPrice);

    double pipDistance = (magic == MagicLong) ? PipDistanceLong : PipDistanceShort;
    for (int i = 1; i < TotalOrders; i++){
        double offset = PipsToPrice(pipDistance * i);
        double pendingPrice = (magic == MagicLong) ? firstPrice - offset : firstPrice + offset;

        MqlTradeRequest request;
        MqlTradeResult result;
        ZeroMemory(request);
        ZeroMemory(result);

        request.action = TRADE_ACTION_PENDING;
        request.symbol = _Symbol;
        request.volume = (magic == MagicLong) ? LotSizesLong[i] : LotSizesShort[i];
        request.type = (magic == MagicLong) ? ORDER_TYPE_BUY_LIMIT : ORDER_TYPE_SELL_LIMIT;
        request.price = NormalizeDouble(pendingPrice, _Digits);
        request.tp = 0;
        request.sl = 0;
        request.magic = magic;
        request.deviation = MaxDeviation;
        request.type_filling = ORDER_FILLING_IOC;

        if (!OrderSend(request, result)){
            PrintFormat("❌ שגיאה בפתיחת פקודת DCA #%d: %d", i, GetLastError());
        } else {
            PrintFormat("✅ פקודת DCA #%d נפתחה במחיר %.5f", i, pendingPrice);
        }
        Sleep(200);
    }
}


//+------------------------------------------------------------------+
//| Activate Trailing Stop and Open New DCA Series (כשמגיעים ל-10+ עסקאות ורווח יעד) |
//+------------------------------------------------------------------+
// מפעיל טריילינג סטופ על עסקאות פתוחות, מוחק פקודות פנדינג, ופותח סדרה חדשה.
// מופעל רק כאשר הקבוצה הגיעה ל-10 עסקאות פתוחות ומעלה והשיגה את יעד הרווח.
void ActivateTrailingStop(long magic, ENUM_POSITION_TYPE positionType) {
    PrintFormat("🟢 מפעיל טריילינג סטופ עבור Magic: %llu", magic);

    // 1. מחיקת כל הפקודות הממתינות עבור ה-Magic הזה
    for (int i = OrdersTotal() - 1; i >= 0; i--) {
        if (m_order.SelectByIndex(i)) {
            // בדיקה אם סוג הפקודה הוא Pending Order (LIMIT, STOP, BUY LIMIT, SELL LIMIT וכו')
            if (m_order.Magic() == magic && (m_order.OrderType() >= ORDER_TYPE_BUY_LIMIT && m_order.OrderType() <= ORDER_TYPE_SELL_STOP_LIMIT)) {
                if (m_trade.OrderDelete(m_order.Ticket())) {
                    PrintFormat("🔴 פקודת פנדינג נמחקה (הפעלת טריילינג) | Magic: %llu | כרטיס: %llu", magic, m_order.Ticket());
                } else {
                    PrintFormat("❌ שגיאה במחיקת פקודת פנדינג (הפעלת טריילינג) | Magic: %llu | כרטיס: %llu | שגיאה: %d",
                                magic, m_order.Ticket(), GetLastError());
                }
                Sleep(100);
            }
        }
    }

    // 2. הפעלת טריילינג סטופ על העסקאות הפתוחות
    double currentPrice;
    double newSL;
    double trailingStopPrice = PipsToPrice(TrailingStopPips);
    double trailingStepPrice = PipsToPrice(TrailingStepPips);

    m_trade.SetDeviationInPoints(MaxDeviation);

    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        if (m_position.SelectByIndex(i)) {
            if (m_position.Magic() == magic) {
                if (m_position.PositionType() == POSITION_TYPE_BUY) {
                    currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
                    newSL = currentPrice - trailingStopPrice;
                    if (m_position.StopLoss() == 0 || newSL > m_position.StopLoss() + trailingStepPrice) {
                        if (m_trade.PositionModify(m_position.Ticket(), NormalizeDouble(newSL, _Digits), m_position.TakeProfit())) {
                            PrintFormat("✅ SL מעודכן (לונג) | כרטיס: %llu | SL חדש: %.5f", m_position.Ticket(), newSL);
                        } else {
                            PrintFormat("❌ שגיאה בעדכון SL (לונג) | כרטיס: %llu | שגיאה: %d", m_position.Ticket(), GetLastError());
                        }
                    }
                } else { // עסקת שורט
                    currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
                    newSL = currentPrice + trailingStopPrice;
                    if (m_position.StopLoss() == 0 || newSL < m_position.StopLoss() - trailingStepPrice) {
                        if (m_trade.PositionModify(m_position.Ticket(), NormalizeDouble(newSL, _Digits), m_position.TakeProfit())) {
                            PrintFormat("✅ SL מעודכן (שורט) | כרטיס: %llu | SL חדש: %.5f", m_position.Ticket(), newSL);
                        } else {
                            PrintFormat("❌ שגיאה בעדכון SL (שורט) | כרטיס: %llu | שגיאה: %d", m_position.Ticket(), GetLastError());
                        }
                    }
                }
                Sleep(100);
            }
        }
    }

    // 3. פתיחת סדרה חדשה
    PrintFormat("🔄 פותח סדרה חדשה עבור Magic: %llu לאחר הפעלת טריילינג.", magic);
    if (positionType == POSITION_TYPE_BUY) {
        OpenDCA(magic, ORDER_TYPE_BUY);
    } else {
        OpenDCA(magic, ORDER_TYPE_SELL);
    }

    // הגדרת דגל הטריילינג כפעיל - הפונקציה תופעל שוב ושוב עד שכל העסקאות עם הטריילינג ייסגרו
    if (magic == MagicLong) LongTrailingActive = true;
    else ShortTrailingActive = true;
}

//+------------------------------------------------------------------+
//| Manage DCA (פונקציית הניהול הראשית עבור כל Magic Number)          |
//+------------------------------------------------------------------+
// סורקת את העסקאות הפתוחות והפקודות הממתינות עבור Magic Number נתון,
// ומנהלת את תהליך ה-DCA (פתיחה, סגירה ברווח, הפעלת טריילינג)
void ManageDCA(long magic, bool &inProgress, bool &trailingActiveFlag){
    int noSLPositionsCount = 0;
    double totalProfit = 0.0;
    int pendingOrdersCount = 0;
    ENUM_POSITION_TYPE currentPositionType = WRONG_VALUE;

    // ספירת עסקאות פתוחות וחישוב רווח צף
    for (int i = PositionsTotal() - 1; i >= 0; i--){
        if (m_position.SelectByIndex(i) && m_position.Magic() == magic){
            totalProfit += m_position.Profit();
            noSLPositionsCount++;

            currentPositionType = (ENUM_POSITION_TYPE)m_position.PositionType();
        }
    }

    // ספירת פקודות ממתינות
    for (int i = OrdersTotal() - 1; i >= 0; i--){
        if (m_order.SelectByIndex(i)) {
            // בדיקה אם סוג הפקודה הוא Pending Order (LIMIT, STOP, BUY LIMIT, SELL LIMIT וכו')
            if (m_order.Magic() == magic && (m_order.OrderType() >= ORDER_TYPE_BUY_LIMIT && m_order.OrderType() <= ORDER_TYPE_SELL_STOP_LIMIT)) {
                pendingOrdersCount++;
            }
        }
    }

    // 1. לוגיקה לפתיחת סדרה חדשה אם אין עסקאות ואין פקודות ממתינות עבור ה-Magic Number
    if (noSLPositionsCount == 0 && pendingOrdersCount == 0 && !inProgress && !trailingActiveFlag){
        PrintFormat("✅ Magic: %llu - אין עסקאות פתוחות או פקודות ממתינות. פותח סדרה חדשה.", magic);
        inProgress = true;
        if (MathRand() % 2 == 0) {
            OpenDCA(magic, ORDER_TYPE_BUY);
        } else {
            OpenDCA(magic, ORDER_TYPE_SELL);
        }
        inProgress = false;
        return;
    }

    // 2. איפוס דגל טריילינג אם אין עסקאות פתוחות עבור ה-Magic Number (כלומר, הטריילינג סיים את עבודתו)
    if (noSLPositionsCount == 0 && trailingActiveFlag) {
        PrintFormat("✅ Magic: %llu - טריילינג סיים את עבודתו (אין עסקאות פתוחות). מאפס דגל.", magic);
        trailingActiveFlag = false;
        return;
    }

    // אם הרובוט נמצא במצב של טריילינג פעיל, הפעל את לוגיקת הטריילינג (רק עדכון SL, לא פתיחה חדשה)
    if (trailingActiveFlag && noSLPositionsCount > 0) {
        ActivateTrailingStop(magic, currentPositionType);
        return;
    }


    // 3. לוגיקת טיפול בהגעה ליעד רווח / הפעלת טריילינג סטופ
    double target = 0;
    if (noSLPositionsCount > 0) {
        int index = MathMin(noSLPositionsCount - 1, ArraySize(ProfitTargetsLong) - 1);
        if (magic == MagicLong) {
            target = ProfitTargetsLong[index];
        } else {
            target = ProfitTargetsShort[index];
        }
    }

    if (totalProfit >= target && noSLPositionsCount > 0){
        PrintFormat("✅ Magic: %llu - הגיע ליעד רווח של %.2f$ עם %d עסקאות פתוחות.", magic, totalProfit, noSLPositionsCount);

        if (noSLPositionsCount < 10) {
            PrintFormat("🟢 Magic: %llu - פחות מ-10 עסקאות פתוחות (יש %d). סוגר הכל ופותח סדרה חדשה.", magic, noSLPositionsCount);
            CloseAll(magic);
            if (MathRand() % 2 == 0) {
                OpenDCA(magic, ORDER_TYPE_BUY);
            } else {
                OpenDCA(magic, ORDER_TYPE_SELL);
            }
        } else {
            PrintFormat("🟢 Magic: %llu - יש %d עסקאות פתוחות. מפעיל טריילינג סטופ ופותח סדרה חדשה.", magic, noSLPositionsCount);
            ActivateTrailingStop(magic, currentPositionType);
        }
        return;
    }
}


//+------------------------------------------------------------------+
//| OnTick function                                                 |
//+------------------------------------------------------------------+
void OnTick(){
    static datetime lastTradeTime = 0;
    if (TimeCurrent() == lastTradeTime) return;
    lastTradeTime = TimeCurrent();

    // 🛡️ בדיקת MaxDrawdown כללי על כל החשבון
    double totalFloatingProfit = 0.0;
    for(int i = PositionsTotal() - 1; i >= 0; i--){
        if(m_position.SelectByIndex(i)){
            totalFloatingProfit += m_position.Profit();
        }
    }

    if (totalFloatingProfit <= MaxDrawdown) {
        PrintFormat("🚨🚨🚨 הגענו ל-MaxDrawdown של %.2f$ (נוכחי: %.2f$). סוגר את כל העסקאות והפקודות בחשבון ומפסיק פעולה! 🚨🚨🚨", MaxDrawdown, totalFloatingProfit);
       
        for (int i = PositionsTotal() - 1; i >= 0; i--) {
            if (m_position.SelectByIndex(i)) {
                m_trade.PositionClose(m_position.Ticket());
                Sleep(100);
            }
        }
        for (int i = OrdersTotal() - 1; i >= 0; i--) {
            if (m_order.SelectByIndex(i)) {
                // בדיקה אם סוג הפקודה הוא Pending Order (LIMIT, STOP, BUY LIMIT, SELL LIMIT וכו')
                if (m_order.OrderType() >= ORDER_TYPE_BUY_LIMIT && m_order.OrderType() <= ORDER_TYPE_SELL_STOP_LIMIT) {
                    m_trade.OrderDelete(m_order.Ticket());
                    Sleep(100);
                }
            }
        }
        ExpertRemove();
        return;
    }

    // ניהול סדרת לונג
    ManageDCA(MagicLong, LongInProgress, LongTrailingActive);
    Sleep((int)(WaitSeconds * 1000));

    // ניהול סדרת שורט
    ManageDCA(MagicShort, ShortInProgress, ShortTrailingActive);
    Sleep((int)(WaitSeconds * 1000));
}

//+------------------------------------------------------------------+
//| OnInit function                                                 |
//+------------------------------------------------------------------+
int OnInit(){
    // הגדרת הסמבול עבור אובייקטי CTrade - אין צורך ב-SetSymbol עבור CPositionInfo ו-COrderInfo כאן,
    // הם נבחרים לפי אינדקס או Ticket ומביאים איתם את הסמבול.


    if (MagicLong == MagicShort) {
        Print("❌ שגיאה: MagicLong ו-MagicShort חייבים להיות שונים זה מזה!");
        ExpertRemove();
        return INIT_PARAMETERS_INCORRECT;
    }

    if (TotalOrders <= 0 || TotalOrders > 50) {
        Print("❌ שגיאה: TotalOrders חייב להיות בין 1 ל-50.");
        ExpertRemove();
        return INIT_PARAMETERS_INCORRECT;
    }
    if (TrailingStopPips <= 0 || TrailingStepPips <= 0) {
        Print("❌ שגיאה: TrailingStopPips ו-TrailingStepPips חייבים להיות גדולים מ-0.");
        ExpertRemove();
        return INIT_PARAMETERS_INCORRECT;
    }
    if (PipDistanceLong <= 0 || PipDistanceShort <= 0) {
        Print("❌ שגיאה: PipDistanceLong ו-PipDistanceShort חייבים להיות גדולים מ-0.");
        ExpertRemove();
        return INIT_PARAMETERS_INCORRECT;
    }
    if (MaxDrawdown >= 0) {
        Print("❌ אזהרה חמורה: MaxDrawdown הוגדר כערך חיובי או אפס. מנגנון ההגנה על חשבונך לא יפעל כמצופה. יש להזין ערך שלילי (לדוגמה: -700000.0).");
    }

    int longPositions = 0;
    int shortPositions = 0;
    int longPending = 0;
    int shortPending = 0;

    for(int i = PositionsTotal() - 1; i >= 0; i--){
        if(m_position.SelectByIndex(i)){
            if(m_position.Magic() == MagicLong) longPositions++;
            if(m_position.Magic() == MagicShort) shortPositions++;
        }
    }
    for(int i = OrdersTotal() - 1; i >= 0; i--) {
        if(m_order.SelectByIndex(i)) {
            // שימוש ב-OrderType() כדי לבדוק אם זו פקודת פנדינג
            if(m_order.Magic() == MagicLong && (m_order.OrderType() >= ORDER_TYPE_BUY_LIMIT && m_order.OrderType() <= ORDER_TYPE_SELL_STOP_LIMIT)) longPending++;
            if(m_order.Magic() == MagicShort && (m_order.OrderType() >= ORDER_TYPE_BUY_LIMIT && m_order.OrderType() <= ORDER_TYPE_SELL_STOP_LIMIT)) shortPending++;
        }
    }

    // הגדרת דגלי inProgress לפי המצב הקיים
    if (longPositions > 0 || longPending > 0) {
        LongInProgress = true;
        PrintFormat("✅ MagicLong (%llu): נמצאו %d עסקאות פתוחות ו-%d פקודות ממתינות. דגל LongInProgress הוגדר ל-true.", MagicLong, longPositions, longPending);
    } else {
        PrintFormat("✅ MagicLong (%llu): לא נמצאו עסקאות או פקודות ממתינות. דגל LongInProgress הוגדר ל-false. הרובוט ינסה לפתוח סדרת לונג חדשה.", MagicLong);
    }

    if (shortPositions > 0 || shortPending > 0) {
        ShortInProgress = true;
        PrintFormat("✅ MagicShort (%llu): נמצאו %d עסקאות פתוחות ו-%d פקודות ממתינות. דגל ShortInProgress הוגדר ל-true.", MagicShort, shortPositions, shortPending);
    } else {
        PrintFormat("✅ MagicShort (%llu): לא נמצאו עסקאות או פקודות ממתינות. דגל ShortInProgress הוגדר ל-false. הרובוט ינסה לפתוח סדרת שורט חדשה.", MagicShort);
    }

    Print("Initialization complete.");
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| OnDeinit function                                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
    PrintFormat("EA deinitialized. Reason: %d", reason);
}

Han respondido

1
Desarrollador 1
Evaluación
(263)
Proyectos
329
29%
Arbitraje
35
26% / 63%
Caducado
10
3%
Trabaja
2
Desarrollador 2
Evaluación
(634)
Proyectos
1003
47%
Arbitraje
33
36% / 36%
Caducado
98
10%
Trabajando
Ha publicado: 6 ejemplos
3
Desarrollador 3
Evaluación
(17)
Proyectos
21
14%
Arbitraje
8
38% / 38%
Caducado
3
14%
Trabajando
4
Desarrollador 4
Evaluación
(13)
Proyectos
20
40%
Arbitraje
3
0% / 67%
Caducado
3
15%
Libre
5
Desarrollador 5
Evaluación
(87)
Proyectos
121
68%
Arbitraje
5
80% / 0%
Caducado
12
10%
Trabaja
6
Desarrollador 6
Evaluación
(271)
Proyectos
553
50%
Arbitraje
57
40% / 37%
Caducado
227
41%
Trabaja
7
Desarrollador 7
Evaluación
(44)
Proyectos
53
38%
Arbitraje
8
13% / 38%
Caducado
8
15%
Libre
8
Desarrollador 8
Evaluación
(574)
Proyectos
945
47%
Arbitraje
309
58% / 27%
Caducado
125
13%
Libre
Solicitudes similares
We are seeking talented Graphic Designers capable of transforming concepts into visually striking representations. Whether your expertise lies in branding, marketing materials, or digital graphics, we welcome your application. Our criteria include: - Creativity and originality - Effective communication skills - Prompt delivery of work - A comprehensive and professional portfolio We invite you to submit your portfolio
I already have the source code of an MT5 Expert Advisor. The EA is about 70% complete. I need someone to modify and complete it. Requirements: • Manage EURUSD only. • Manage manual trades only (Magic Number = 0). • Support unlimited manual positions simultaneously. • Automatically add a 10-pip Stop Loss if a position has no Stop Loss. • Automatically add a 10-pip Take Profit if a position has no Take Profit. • Do not
I am looking for an expert MQL5 developer to build a robust, professional Expert Advisor for Gold (XAUUSD). The EA must be Event-Driven (OnTick) with no 'Sleep' functions, ensuring instant execution. ​ Core Logic: ​ Grid Strategy: Start with 0.02 Buy/Sell. Lot size sequence: 0.02, 0.03, 0.05, 0.09, 0.14, 0.26, 0.44, 0.75, 1.28, 2.18 (Max 10 steps). ​ Dynamic TP: Total basket TP must update instantly upon new order
I am currently using the attached Arbitrage MACD indicator. However, there are no signal alerts associated with this indicator. I would like to receive notifications on my android device the bar after a blue long arrow appears and the bar after a red short arrow appears. This is the current code: //+------------+-----------------------------------------------------+ //| v.22.04.07 | ArrZZx2.mq4 |
SETJEO'S GOLD EA 30 - 200 USD
double GetTodayProfit() { double profit = 0; datetime today = StringToTime(TimeToString(TimeCurrent(), TIME_DATE)); HistorySelect(today, TimeCurrent()); for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { ulong ticket = HistoryDealGetTicket(i); if(HistoryDealGetString(ticket, DEAL_SYMBOL) == _Symbol) { profit += HistoryDealGetDouble(ticket, DEAL_PROFIT); } } return profit; }
مطلوب موشر مع ربطه علي بوت تداول قوي جدا مختبر ومجرب مع التاكيد علي نسبه النجاح يتم انشاءه علي جميع الموشرات في الفوركس الذهب والبتكوين والus100 مع شرح للستراتيجية ونتايج اختيار اذا كان مجرب
I have an expert advisor's investor login. I want you to study it and make me the exact same EA. There should be absolutely no differences or mistakes. You should have great observation skills for this aswell
I am looking for an experienced MQL5 developer to code a simple grid trading strategy into an Expert Advisor. The strategy logic is already defined, and I am looking for someone with strong MQL5 development experience to implement it accurately and efficiently. If you are interested and have relevant experience, please get in touch so we can discuss the project details
I am looking for an experienced MQL5 or MQL4 developer with a strong background in low-latency algorithmic trading, market data integration, arbitrage and execution optimization. The project involves developing a high-performance HFT Expert Advisor (EA) for XAUUSD or US30 on IC Markets that is designed for robust execution in both demo and live environments. The EA may use market data feeds (such as lmax,one zero or
I am looking for an experienced MQL5 or MQL4 developer with a strong understanding of high-frequency trading (HFT) concepts who can explain how certain HFT-style strategies have historically been able to pass proprietary firm evaluations while also being profitable on demo accounts and capable of transitioning successfully to live trading. I am interested in understanding the legitimate trading logic, execution

Información sobre el proyecto

Presupuesto
30+ USD