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

Spezifikation

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);
}

Bewerbungen

1
Entwickler 1
Bewertung
(250)
Projekte
313
28%
Schlichtung
34
26% / 65%
Frist nicht eingehalten
10
3%
Arbeitet
2
Entwickler 2
Bewertung
(626)
Projekte
985
46%
Schlichtung
33
36% / 36%
Frist nicht eingehalten
98
10%
Arbeitet
Veröffentlicht: 6 Beispiele
3
Entwickler 3
Bewertung
(16)
Projekte
20
10%
Schlichtung
8
38% / 38%
Frist nicht eingehalten
3
15%
Arbeitet
4
Entwickler 4
Bewertung
(12)
Projekte
19
42%
Schlichtung
3
0% / 67%
Frist nicht eingehalten
3
16%
Arbeitet
5
Entwickler 5
Bewertung
(87)
Projekte
121
68%
Schlichtung
5
80% / 0%
Frist nicht eingehalten
12
10%
Arbeitet
6
Entwickler 6
Bewertung
(270)
Projekte
552
49%
Schlichtung
57
40% / 37%
Frist nicht eingehalten
227
41%
Arbeitet
7
Entwickler 7
Bewertung
(44)
Projekte
53
38%
Schlichtung
8
13% / 38%
Frist nicht eingehalten
8
15%
Arbeitet
8
Entwickler 8
Bewertung
(574)
Projekte
945
47%
Schlichtung
309
58% / 27%
Frist nicht eingehalten
125
13%
Frei
Ähnliche Aufträge
Zone detection is coded , you will be working from that point . Trailing Stop Optimization for live chart . Apply Specific Currency Support . Clean Code . Zone Upper Limit and Lower Limit
حلل لي اصل مالي ) اكتب هنا مثلا XAU EUR USD USD اريد تحليلا تعليما و ليس توصية مالية ۱- نوع التحليل المطلوب : ( فني / اساسي / سلوك سعري ) ٢ - المدي الزمني : ( قصير / متوسط / طويل ) M15 / H1 / H4 / ) اذكر الفريمات المطلوبه + (D1 ما اريد استخراجه من التحليل : الاتجاه العام اقوي مستويات دعم و مقاومة رقمية سيناريو صعود و سيناريو هبوط مع شروط كل سيناريو ( IF / THEN ) اين يصبح السيناريو لاغيا مناطق دخول و خروج تعليمية (
I need modifications to an existing MT5 Expert Advisor. Modification 1 EA must be able to run on indices as well as forex , specifically: SP500 US100 US30 No other changes to the current logic Modification 2 Other alterations/notes: Opening breakout range option for 15min or 30 min from session start. 5 min fair value gap (FVG) break outside of the range (instead of 1 min). At least one of the candles must be within
AutoTrade_v4_Arbon-v4 35 - 250 USD
============================================================ GOLD AI INSTITUTIONAL TERMINAL v4.0 - AutoTrade + EA Indikator EDISI GABUNGAN Sinkronisasi MT4 Realtime + Dasbor PWA + AI Multi-TF Menggabungkan MT4 + Server AI Node.js ============================================================ CARA MENJALANKAN (MUDAH): -------------------------- 1. Ekstrak ZIP ke folder manapun (misal: C:\GoldAI\) 2. Buka folder hasil
I am looking for an experienced quantitative developer to analyze and optimize an MT5 Expert Advisor that I have already developed. The EA is relatively complex and includes: Multiple strategies (Trend Pullback, Breakout, Mean Reversion, EMA Reclaim) Scoring system combining technical score and probabilistic filter Regime detection (ADX based) Volatility filters (ATR regime) Correlation and cluster exposure control
Until zone detection is coded , you will be from that point . Trailing Stop Optimization for live chart . Apply with Specific Currency Support . Clean Code . Zone Upper Limit and Lower Limit . Apply with careful understanding of the project requirement
Subject: Professional MT5 Trading Bot Inquiry - Pre-Purchase Requirements Dear [Bot Name/Company Name] Developers, Greetings, I am a professional trader seeking a highly professional and extremely powerful MT5 trading bot , and after extensive research, your product has caught my attention. However, before I click the payment button, I have specific requirements as I am not looking for an ordinary bot, but rather a
hello, please take a moment to review my project. It is for Quanttower. it is very detailed in the instructions. Thank you, Just let me know if you can do it and the whats the cost and timeframe
GoldAI_v2_FINAL 30 - 70 USD
========================================================== Terminal Institusional GOLD AI v2.10 Sinkronisasi Realtime MT4 + Dasbor PWA + AI Multi-TF ========================================================== CARA MENJALANKAN (MUDAH): -------------------------- 1. Ekstrak ZIP ke folder manapun (misal: C:\GoldAI\) 2. Buka folder hasil ekstrak 3. Klik dua kali: INSTALL.bat → installotomatis 4. Klik dua kali
Exe source code 70+ USD
Need a developer to help with a exe file and provide the source code, if you can do this please kidnly apply and tell me what you need to get this started

Projektdetails

Budget
30+ USD