same EA on 2 charts with the same SYmbol and Timeperiod

 
Hi people,

this is my first post and I'm starting right away with questions.

I've done some EAs with the help of YT and, documentation and chat AIs, but nowhere can I find an answer to the question of how I should create working code so that my EA can run on the same Timeframe and Symbol at the same time, without conflicting with the same EA that will run on the same Timeframe and the same Symbol. Optimization Backtests have generated some cool results for me that I'd like to test live, but I already have my stable settings that I know. 

I can't get past this, I'm sure I'm doing something wrong.

When both EAs are open, one is becoming native and not opening positions. Each EA has different Magic, each EA has different settings. Sometimes I wonder if saving the other EA under a different name will help something.

The EA gives the position magicnumber when opening the position, by the Global variable. It seems to me that filtering in the trailing stop by magicnumber via PositionTotal and loop is properly written. But I can't check this because the second EA doesn't open positions.

I'm slowly getting the hang of it already, I'm trying, but I don't think I have enough free time to study. 

I would appreciate some hints, below is the code of the EA that I want to change. It is a simple MA crossing. If I can do it in one EA later I will be able to implement it to others.

//+------------------------------------------------------------------+ 
//| MA Crossing.mq5 with TrendMA and dynamic TP/SL adjustments       | 
//+------------------------------------------------------------------+ 
#include <Trade\Trade.mqh> // Zawiera klasę CTrade 
CTrade trade; // Obiekt trade do zarządzania pozycjami 
// Parametry wskaźników (Moving Average) 
input int ma_fast_period = 9; // Okres dla szybkiej MA 
input int ma_slow_period = 21; // Okres dla wolnej MA 
input int trendMA_period = 100; // Okres dla wskaźnika trendu 
input ENUM_MA_METHOD ma_method = MODE_SMA; // Typ średniej kroczącej 
input ENUM_APPLIED_PRICE applied_price = PRICE_CLOSE; // Cena używana do obliczeń 
// Parametry zarządzania ryzykiem (w punktach) 
input double inpLotSize = 0.01; // Wielkość lota (domyślnie 0.01) 
input int stop_loss = 50; // Stop Loss w punktach (0=off) 
input int take_profit = 100; // Take Profit w punktach (0=off) 
input int trailing_stop = 30; // Trailing Stop w punktach 
input int trailing_step = 10; // Krok dla trailing stop (w punktach) 
input double adjustment_factor = 0.5; // Czynnik zmniejszenia (domyślnie o połowę) 
input int magic_number = 123456; // Magic number dla EA 
// Zmienna do przechowywania najnowszych cen 
MqlTick Latest_Price; 
double fast_ma_buffer[], slow_ma_buffer[], trend_ma_buffer[]; // Bufory MA 
// Zmienna do przechowywania czasu ostatniego crossa 
datetime lastCrossTime = 0; 
//+------------------------------------------------------------------+ 
//| Funkcja normalizacji cen | 
//+------------------------------------------------------------------+ 
bool NormalizePrice(double &price) 
{ 
    double tickSize; 
    if(!SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize)) 
    { 
        Print("Nie udało się pobrać wielkości ticka"); 
        return false; 
    } 
    price = NormalizeDouble(MathRound(price / tickSize) * tickSize, _Digits); 
    return true; 
} 
//+------------------------------------------------------------------+ 
//| Expert initialization function | 
//+------------------------------------------------------------------+ 
int OnInit() 
{ 
    Print("EA started"); 
    // Utworzenie wskaźników MA 
    int fast_ma_handle = iMA(_Symbol, Period(), ma_fast_period, 0, ma_method, applied_price); 
    int slow_ma_handle = iMA(_Symbol, Period(), ma_slow_period, 0, ma_method, applied_price); 
    int trend_ma_handle = iMA(_Symbol, Period(), trendMA_period, 0, ma_method, applied_price); // Dodanie trendMA 
    
    // Sprawdzenie ważności uchwytów MA 
    if(fast_ma_handle == INVALID_HANDLE || slow_ma_handle == INVALID_HANDLE || trend_ma_handle == INVALID_HANDLE) 
    { 
        Print("Błąd tworzenia uchwytów MA"); 
        return INIT_FAILED; 
    } 
    
    ArraySetAsSeries(fast_ma_buffer, true); // Ustawienie bufora jako seria 
    ArraySetAsSeries(slow_ma_buffer, true); 
    ArraySetAsSeries(trend_ma_buffer, true); // Bufor dla trendMA 
    
    // Ustawienie Magic Number 
    trade.SetExpertMagicNumber(magic_number); 
    
    return(INIT_SUCCEEDED); 
} 
//+------------------------------------------------------------------+
//| Funkcja sprawdzająca, czy istnieje otwarta pozycja dla crossa    |
//+------------------------------------------------------------------+
bool IsPositionOpenForCross()
{
   datetime currentTime = TimeCurrent();
   
   // Sprawdź, czy minął wystarczający czas od ostatniego crossa
   if(currentTime - lastCrossTime < PeriodSeconds())
   {
      return true;
   }
   
   return false;
}
//+------------------------------------------------------------------+
//| Funkcja zliczająca otwarte pozycje z danym magic_number |
//+------------------------------------------------------------------+
int CountOpenPositionsWithMagic(int magicNumber)
{
    int count = 0;
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            // Check if the magic number and symbol match
            if(PositionGetInteger(POSITION_MAGIC) == magicNumber && PositionGetString(POSITION_SYMBOL) == Symbol())
            {
                count++;
            }
        }
    }
    return count;
}
//+------------------------------------------------------------------+
//| Funkcja trailing stop |
//+------------------------------------------------------------------+
void ApplyTrailingStop()
{
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            // Filter by magic number and symbol
            if(PositionGetInteger(POSITION_MAGIC) == magic_number && PositionGetString(POSITION_SYMBOL) == Symbol())
            {
                long type = PositionGetInteger(POSITION_TYPE);
                double currentPrice, stopLossPrice;
                if(type == POSITION_TYPE_BUY)
                {
                    currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
                    stopLossPrice = PositionGetDouble(POSITION_SL);
                    if(currentPrice - stopLossPrice >= trailing_step * _Point)
                    {
                        double newStopLoss = currentPrice - trailing_stop * _Point;
                        if(newStopLoss > stopLossPrice)
                        {
                            trade.PositionModify(PositionGetTicket(i), newStopLoss, PositionGetDouble(POSITION_TP));
                            Print("Zaktualizowano Trailing Stop dla pozycji BUY.");
                        }
                    }
                }
                else if(type == POSITION_TYPE_SELL)
                {
                    currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
                    stopLossPrice = PositionGetDouble(POSITION_SL);
                    if(stopLossPrice - currentPrice >= trailing_step * _Point)
                    {
                        double newStopLoss = currentPrice + trailing_stop * _Point;
                        if(newStopLoss < stopLossPrice)
                        {
                            trade.PositionModify(PositionGetTicket(i), newStopLoss, PositionGetDouble(POSITION_TP));
                            Print("Zaktualizowano Trailing Stop dla pozycji SELL.");
                        }
                    }
                }
            }
        }
    }
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Uzyskanie bieżących cen (Bid, Ask)
   if(!SymbolInfoTick(Symbol(), Latest_Price))
   {
      Print("Nie udało się pobrać bieżących cen.");
      return;
   }
   ApplyTrailingStop();  // Zastosowanie trailing stop
   // Uzyskanie wartości Moving Average (2 ostatnie wartości)
   if(CopyBuffer(iMA(Symbol(), Period(), ma_fast_period, 0, ma_method, applied_price), 0, 0, 2, fast_ma_buffer) < 2 ||
      CopyBuffer(iMA(Symbol(), Period(), ma_slow_period, 0, ma_method, applied_price), 0, 0, 2, slow_ma_buffer) < 2 ||
      CopyBuffer(iMA(Symbol(), Period(), trendMA_period, 0, ma_method, applied_price), 0, 0, 2, trend_ma_buffer) < 2)  // Kopiowanie trendMA
   {
      Print("Błąd kopiowania wartości MA");
      return;
   }
   double sl_price = stop_loss * _Point;
   double tp_price = take_profit * _Point;
   // Sprawdzenie, czy nastąpił cross MA i czy nie ma otwartej pozycji dla tego crossa
   if(!IsPositionOpenForCross())
   {
      bool trend_matches = (fast_ma_buffer[0] > slow_ma_buffer[0] && fast_ma_buffer[0] > trend_ma_buffer[0]) ||
                           (fast_ma_buffer[0] < slow_ma_buffer[0] && fast_ma_buffer[0] < trend_ma_buffer[0]);
      // Zmiana parametrów TP, SL, Trailing Stop w przypadku przecięcia MA
      double final_sl = sl_price;
      double final_tp = tp_price;
      double final_trailing_stop = trailing_stop * _Point;
      double final_trailing_step = trailing_step * _Point;
      if(!trend_matches)  // Jeśli trendMA nie zgadza się z kierunkiem MA
      {
         final_sl *= adjustment_factor;
         final_tp *= adjustment_factor;
         final_trailing_stop *= adjustment_factor;
         final_trailing_step *= adjustment_factor;
      }
      // Sygnał kupna - przecięcie MA
      if(fast_ma_buffer[1] <= slow_ma_buffer[1] && fast_ma_buffer[0] > slow_ma_buffer[0])
      {
         Print("Position SELL opened by:",magic_number);
         double sl = stop_loss == 0 ? 0 : Latest_Price.bid - final_sl;
         double tp = take_profit == 0 ? 0 : Latest_Price.bid + final_tp;
         if(!NormalizePrice(sl)) { return; }
         if(!NormalizePrice(tp)) { return; }
         if(!trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, inpLotSize, Latest_Price.bid, sl, tp, "Buy on MA cross"))
         {
            Print("Failed to open position BUY by:",magic_number);
         }
         lastCrossTime = TimeCurrent();  // Aktualizacja czasu ostatniego crossa
      }
      // Sygnał sprzedaży - przecięcie MA
      if(fast_ma_buffer[1] >= slow_ma_buffer[1] && fast_ma_buffer[0] < slow_ma_buffer[0])
      {
         Print("Position SELL opened by:",magic_number);
         double sl = stop_loss == 0 ? 0 : Latest_Price.ask + final_sl;
         double tp = take_profit == 0 ? 0 : Latest_Price.ask - final_tp;
         if(!NormalizePrice(sl)) { return; }
         if(!NormalizePrice(tp)) { return; }
         if(!trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, inpLotSize, Latest_Price.ask, sl, tp, "Sell on MA cross"))
         {
            Print("Failed to open position SELL by:",magic_number);
         }
         lastCrossTime = TimeCurrent();  // Aktualizacja czasu ostatniego crossa
      }
   }
}

Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
  • www.mql5.com
To obtain the current market information there are several functions: SymbolInfoInteger() , SymbolInfoDouble() and SymbolInfoString() . The first...
Files: