Советник торгует неправильно

 
Добрый день. У кого есть возможность посмотреть пожалуйста код советника, т. к. сам не знаю языка mql4, писал советник через нейро qwen max. Вроде как то открывает советник сделки, но неправильно, сколько не переправлял через тот же qwen, он нп видит корень проблемы Когда я спрашиваю весь функционал и параметры кода советника, то qwen пишет что советник работает нормально и все в общем работает как надо, а на деле, я сам не понимаю по какому принципу он открывает сделки.

Там правила вроде простые, вот все что нужно от советника в целом:
Таймфрейм и валютные пары любые
1.Советник определяет на графике локальные уровни поддержки и сопротивления - точки на вершинах (этот параметр настраиваем);
2. В советнике встроен МА1 и МА2 (также настраивается период, способ метод итп.)
3. Условия для входа в сделку: советник дожидается момента когда линия МА1 пересекает уровень поддержки (ближайший уровень к текущему движущемуся графику), тут как бы пересечение МА1 уровня не основной момент, а как первый признак того, что возможно скоро откроется сделка. Теперь, если открывается новый бар, где линия МА1 находится под уровнем поддержки, то открывается ордер на продажу, но если следующий бар у которого МА1 находится над уровнем сопротивления (хоть сам бар будет под уровнем, частично или полностью), то не нужно открывать ордер. Основной момент сделки - это первый открывшийся бар где МА1 находится под уровнем поддержки, после пересечения уровня. Проще говоря, бар с МА1 пробивает уровень, бар закрывается а его МА1 находится под уровнем поддержки, открывается новый бар, где 
МА1 также находится под уровнем то это сигнал на открытие сделки, при этом, неважно где находится бар, за уровнем или под ним, важна само положение МА1. Сделки в покупку с МА2 по вышеуказанным условиям - зеркально.
4.Дополнительные условия. Советник не должен открывать новую сделку, пока после открытия текущей не сработает стоп, тейк-профит, или сам человек не закроет ордер, при этом, если сработает какое-то из этих событий, то все равно, не нужно открывать сделку, до тех пор, пока не появится новый сигнал. Один сигнал - одна сделка, в любом раскладе.
Если появился сигнал и открывается сделка, и далее возник новый сигнал, то можно открывать новую сделку (параметр по максимальному количеству открытых ордеров по советнику можно настраивать) предыдущая сделка закроется по соответствующему событию.
И последнее, при добавлении советника на график, он ждет только нового сигнала на сделку, даже если после добавления советника секунду назад возник сигнал, советник его игнорирует, в общем, как запустили советник то тот ждет только последующий сигнал.

Вот полный код советника:

//+------------------------------------------------------------------+
//| SupportResistance_MA_Advisor.mq4 |
//| Советник для торговли на основе MA1, MA2, уровней поддержки и сопротивления |
//| Developed by Assistant |
//+------------------------------------------------------------------+
#property copyright "Developed by Assistant"
#property link "https://example.com"
#property version "1.00"
#property strict

// Входные параметры советника
input double LotSize = 0.1; // Размер лота для сделок
input int StopLoss = 50; // Стоп-лосс в пунктах
input int TakeProfit = 100; // Тейк-профит в пунктах

// Параметры для первой Moving Average
input int MAPeriod1 = 1; // Период первой MA
input int MAShift1 = 0; // Сдвиг первой MA
input int MAMethod1 = MODE_SMA; // Метод первой MA (MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA)
input int MAPrice1 = PRICE_CLOSE; // Цена для расчета первой MA (PRICE_CLOSE, PRICE_OPEN, и т.д.)

// Параметры для второй Moving Average
input int MAPeriod2 = 20; // Период второй MA
input int MAShift2 = 0; // Сдвиг второй MA
input int MAMethod2 = MODE_EMA; // Метод второй MA (MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA)
input int MAPrice2 = PRICE_CLOSE; // Цена для расчета второй MA (PRICE_CLOSE, PRICE_OPEN, и т.д.)

// Параметры для расчета уровней поддержки и сопротивления
input int Lookback = 5; // Количество свечей для анализа локальных максимумов/минимумов
input double Tolerance = 0.0001; // Допуск для проверки пересечений

// Глобальные переменные
datetime LastBuySignalBar = 0; // Время бара, на котором был сигнал на покупку
datetime LastSellSignalBar = 0; // Время бара, на котором был сигнал на продажу
bool BuySignalPending = false; // Флаг для ожидающего сигнала на покупку
bool SellSignalPending = false; // Флаг для ожидающего сигнала на продажу

//+------------------------------------------------------------------+
//| Инициализация советника |
//+------------------------------------------------------------------+
int OnInit()
{
   Print("Советник инициализирован.");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Деинициализация советника |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Print("Советник деинициализирован.");
}

//+------------------------------------------------------------------+
//| Основной цикл советника |
//+------------------------------------------------------------------+
void OnTick()
{
   // Расчет скользящих средних
   double MA1_Current = iMA(NULL, 0, MAPeriod1, MAShift1, MAMethod1, MAPrice1, 0);
   double MA1_Previous = iMA(NULL, 0, MAPeriod1, MAShift1, MAMethod1, MAPrice1, 1);

   double MA2_Current = iMA(NULL, 0, MAPeriod2, MAShift2, MAMethod2, MAPrice2, 0);
   double MA2_Previous = iMA(NULL, 0, MAPeriod2, MAShift2, MAMethod2, MAPrice2, 1);

   // Нахождение ближайших уровней поддержки и сопротивления
   double Support = FindNearestSupport();
   double Resistance = FindNearestResistance();

   // Отладочные сообщения
   Print("=== НАЧАЛО ОТЛАДКИ ===");
   Print("MA1_Current: ", MA1_Current, " MA1_Previous: ", MA1_Previous);
   Print("MA2_Current: ", MA2_Current, " MA2_Previous: ", MA2_Previous);
   Print("Support: ", Support, " Resistance: ", Resistance);
   Print("IsOrderOpen(OP_BUY): ", IsOrderOpen(OP_BUY), " IsOrderOpen(OP_SELL): ", IsOrderOpen(OP_SELL));
   Print("Time[0]: ", Time[0], " LastBuySignalBar: ", LastBuySignalBar, " LastSellSignalBar: ", LastSellSignalBar);
   Print("BuySignalPending: ", BuySignalPending, " SellSignalPending: ", SellSignalPending);
   Print("=== КОНЕЦ ОТЛАДКИ ===");

   // Проверка условий для покупки
   if (!BuySignalPending && !SellSignalPending && Resistance != EMPTY_VALUE &&
       ((MA2_Previous + Tolerance < Resistance && MA2_Current - Tolerance > Resistance) || 
        (MathAbs(MA2_Current - Resistance) <= Tolerance)))
   {
      Print("Первый признак сигнала на покупку: MA2 пересек уровень сопротивления.");
      BuySignalPending = true; // Ждем подтверждения следующим баром
   }

   if (BuySignalPending && Open[0] > Resistance && Time[0] > LastBuySignalBar && !IsOrderOpen(OP_BUY))
   {
      Print("Подтвержден сигнал на покупку: следующий бар открылся выше уровня сопротивления.");
      BuySignalPending = false;
      LastBuySignalBar = Time[0];
      OpenBuyOrder();
   }
   else if (BuySignalPending && Open[0] <= Resistance)
   {
      Print("Сигнал на покупку отменен: следующий бар открылся ниже или равен уровню сопротивления.");
      BuySignalPending = false;
   }

   // Проверка условий для продажи
   if (!SellSignalPending && !BuySignalPending && Support != EMPTY_VALUE &&
       ((MA1_Previous - Tolerance > Support && MA1_Current + Tolerance < Support) || 
        (MathAbs(MA1_Current - Support) <= Tolerance)))
   {
      Print("Первый признак сигнала на продажу: MA1 пересек уровень поддержки.");
      SellSignalPending = true; // Ждем подтверждения следующим баром
   }

   if (SellSignalPending && Open[0] < Support && Time[0] > LastSellSignalBar && !IsOrderOpen(OP_SELL))
   {
      Print("Подтвержден сигнал на продажу: следующий бар открылся ниже уровня поддержки.");
      SellSignalPending = false;
      LastSellSignalBar = Time[0];
      OpenSellOrder();
   }
   else if (SellSignalPending && Open[0] >= Support)
   {
      Print("Сигнал на продажу отменен: следующий бар открылся выше или равен уровню поддержки.");
      SellSignalPending = false;
   }
}

//+------------------------------------------------------------------+
//| Функция для открытия ордера на покупку |
//+------------------------------------------------------------------+
void OpenBuyOrder()
{
   double sl = Ask - StopLoss * Point; // Расчет стоп-лосса
   double tp = Ask + TakeProfit * Point; // Расчет тейк-профита

   int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp, "Buy Order", 0, 0, Blue);
   if (ticket < 0)
   {
      Print("Ошибка открытия ордера на покупку: ", GetLastError());
   }
   else
   {
      Print("Открыт ордер на покупку. Тикет: ", ticket);
   }
}

//+------------------------------------------------------------------+
//| Функция для открытия ордера на продажу |
//+------------------------------------------------------------------+
void OpenSellOrder()
{
   double sl = Bid + StopLoss * Point; // Расчет стоп-лосса
   double tp = Bid - TakeProfit * Point; // Расчет тейк-профита

   int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp, "Sell Order", 0, 0, Red);
   if (ticket < 0)
   {
      Print("Ошибка открытия ордера на продажу: ", GetLastError());
   }
   else
   {
      Print("Открыт ордер на продажу. Тикет: ", ticket);
   }
}

//+------------------------------------------------------------------+
//| Функция для поиска ближайшего уровня поддержки |
//+------------------------------------------------------------------+
double FindNearestSupport()
{
   double support = EMPTY_VALUE;
   for (int i = 1; i < Bars; i++)
   {
      if (IsLocalLow(i, Low, Lookback) && Low[i] < Close[0]) // Берем только уровни поддержки ниже текущей цены
      {
         if (support == EMPTY_VALUE || Low[i] > support) // Берем ближайший уровень поддержки
         {
            support = Low[i];
         }
      }
   }
   return support;
}

//+------------------------------------------------------------------+
//| Функция для поиска ближайшего уровня сопротивления |
//+------------------------------------------------------------------+
double FindNearestResistance()
{
   double resistance = EMPTY_VALUE;
   for (int i = 1; i < Bars; i++)
   {
      if (IsLocalHigh(i, High, Lookback) && High[i] > Close[0]) // Берем только уровни сопротивления выше текущей цены
      {
         if (resistance == EMPTY_VALUE || High[i] < resistance) // Берем ближайший уровень сопротивления
         {
            resistance = High[i];
         }
      }
   }
   return resistance;
}

//+------------------------------------------------------------------+
//| Функция проверки локального максимума |
//+------------------------------------------------------------------+
bool IsLocalHigh(int index, const double &high[], int lookback)
{
   for (int i = 1; i <= lookback; i++)
   {
      if (index - i < 0 || index + i >= ArraySize(high)) continue; // Защита от выхода за границы массива
      if (high[index] < high[index - i] || high[index] < high[index + i])
      {
         return false;
      }
   }
   return true;
}

//+------------------------------------------------------------------+
//| Функция проверки локального минимума |
//+------------------------------------------------------------------+
bool IsLocalLow(int index, const double &low[], int lookback)
{
   for (int i = 1; i <= lookback; i++)
   {
      if (index - i < 0 || index + i >= ArraySize(low)) continue; // Защита от выхода за границы массива
      if (low[index] > low[index - i] || low[index] > low[index + i])
      {
         return false;
      }
   }
   return true;
}

//+------------------------------------------------------------------+
//| Функция для проверки открытых ордеров |
//+------------------------------------------------------------------+
bool IsOrderOpen(int type)
{
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderType() == type)
      {
         return true;
      }
   }
   return false;
}

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

...

Sergey Golubev, 2020.03.23 16:08

Вставляйте правильно код -

----------------‌

MQL5.community - Памятка пользователя 

Кнопка  Исходный кодпредназначена для вставки исходного кода в текст сообщения. При нажатии появляется пустое окно, в которое необходимо вставить код и далее нажать кнопку Вставить. Для отмены вставки кода необходимо нажать кнопку Отмена.