Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 1548

 
SGarnov:

To make it easier take my source code, it has logic that works, except for the problem I described, I don't quite understand it, my head is boiling but I'm not getting anywhere.

Do you place one pending order or two in different directions?
 
SGarnov:
i have a feeling the robot is getting stronger, i dont dont dont like it when i place orders or do not want to trade as i have already placed it, i cannot open it as i have already placed it, it only needs to open the order.

@MakarFX is doing already. Let's not get in the way.

What I wanted to say...Write everything so it's clear to you (personally/personally), don't pull code with copy-paste.

and a greatly simplified robot skeleton looks something like this:

int ticket=-1;             // тикет открытого ордера
bool inited=false;      // признак завершения инициализации

int OnInit()
{
   ticket=-1;
   inited=false;
   // ещё надо проверить параметры, но пока чёрт с ними
   // пробуем загрузить прежнее состояние
   if (LoadState()) {
      // из файла, базы или глоб.переменных загрузились
      if (!CheckState()) {
         // проверили, плохо всё..
         ClearState(); // удалить и поругаться
         Alert("Усё пропало, шеф !");
         return INIT_FAILED();
      }
   }
   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
   if (inited) {
      // инициализация была проведена, стейт мог уже менятся во время работы
      SaveState(); // сохраняем куда-то там
   }
}

void OnTick()
{
   //// ЧТОБЫ БЫ БЫЛО ХОРОШО, 
   //// НЕ БОЛЕЕ 1-го ПРИКАЗА Open/Close/Modify на тик
   //// И ЗАВЕРШИТЬ ВСЁ ПО БЫСТРОМУ
   if (!inited) {
      // связь есть, тики идут
      // довести инициализацию до нужной кондиции
      if (!DoInit()) {
         // не довелась
         Alert("вот же блин...");
         ExpertRemove();
      } else {
         // в DoInit проставлен корректный ticket
         inited=true;
      }
      return;
   }
   // всё проиничено, ticket или -1 если нет нифига или реально тикет
   //// РАЗБОРЫ С ТИКЕТАМИ
   if (ticket<0) {
      // нет открытых ордеров
      // может открыть/переоткрыть ?
   } else {
      if (!OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) {
         // что-то не так с синхронизацией, просто пропустим тик
         return;
      }
      if (OrderCloseTime()!=0) {
         // ордер закрылся ручками или по стопам/тейкам (или стопаут, приплыли)
         OnCloseOrder();   // обработать, разобраться
         ticket=-1;        // нет у нас больше тикета..
         // в этот тик больше не успеть
         return;
      } else {
         if ((OrderStopLoss()==0 && SL!=0) || (OrderTakeProfit()==0 && TP!=0)) {
            // свежачок - надо ему выстаить Тейк и/или стоп
            
         } else {
            // для реала - проверять сработку Sl/Tp на ГЕПАХ, ЭТО ВАЖНО
         }
      }
   }
   //// РАЗБОРЫ с БАРАМИ
   CheckForOnBar();
   ///  и так далее...
}
void OnTimer()
{
   // тики завершаем быстро-быстро, поэтому открытия баров дополнительно проверяем по таймеру
   CheckForOnBar();
}

beer works wonders and makes people kinder :-)

 
MakarFX:
Do you place one pending order or two in different directions?
I always place one pending order
 
SGarnov:
I always put out a single pending one.

Try it, ask for it

//+------------------------------------------------------------------+
//|                                                   SGarnov.v2.mq4 |
//|                                           Copyright 2020, DrMak. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, DrMak."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//--- input parameters
input int      T_Profit = 2;     // Коэффициент Take Profit
input int      S_Loss   = 200;   // Уровень Stop Loss
input double   O_Lots   = 0.01;  // Лоты
input int      SL_Count = 2;     // Количество убыточных ордеров
input int      Slippage = 30;    // Проскальзывание
input int      N_Magic  = 888;   // Magic

datetime T_Start;
double sl_price,tp_price,t_profit,s_loss;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   t_profit = S_Loss*T_Profit;
   tp_price = NormalizeDouble(t_profit * Point(), Digits)+GetPointLoss();
//---
   s_loss   = MathMax(S_Loss, MarketInfo(_Symbol, MODE_STOPLEVEL));
   sl_price = NormalizeDouble(s_loss * Point(), Digits);

   // Удаляем отложенный ордер после профита
   if(CountOrders(-1)==1) DeletePending();
   // Проверяем серию убыточных ордеров
   if(GetLossOrders()<=SL_Count)
     {
      // Устанавливаем отложенный ордер
      SendPending();
     }

   // Проверяем наличие ордеров BUY
   if(CountOrders(0)>0)
     {
      // Устанавливаем StopLoss/TakeProfit
      ModifyOrder();
     }

   // Проверяем наличие ордеров SELL
   if(CountOrders(1)>0)
     {
      // Устанавливаем StopLoss/TakeProfit
      ModifyOrder();
     }
  }
//+------------------------------------------------------------------+
//| Модификация ордера                                               |
//+------------------------------------------------------------------+
void ModifyOrder()
  {
   int ticket=0;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==_Symbol)
           {
            if(OrderStopLoss()==0)
              {
               if(OrderType()==OP_BUY)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-sl_price, OrderOpenPrice()+tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
               if(OrderType()==OP_SELL)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+sl_price, OrderOpenPrice()-tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Подсчет ордеров по типу                                          |
//+------------------------------------------------------------------+
//|  0 - ордера типа BUY          1 - ордера типа SELL               |
//|  2 - ордера типа BUYLIMIT     3 - ордера типа SELLLIMIT          |
//|  4 - ордера типа BUYSTOP      5 - ордера типа SELLSTOP           |
//|  6 - ордера типа Balance     -1 - Все типы ордеров               |
//+------------------------------------------------------------------+
int CountOrders(int or_ty=-1) 
  {
   int cnt=0;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==_Symbol)
           {
            if(or_ty<0 || or_ty==OrderType()) cnt++;
           }
        }
     }
   return(cnt);
  }
//+------------------------------------------------------------------+
//| Установка отложенного ордера                                     |
//+------------------------------------------------------------------+
void SendPending()
  {
   double op=0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS)==true)
        {
         if(CountOrders(-1)==1)
           {
            if(OrderType()==OP_BUY)
              {
               if(OrderStopLoss() != 0)
                 {
                  op=OrderStopLoss();
                  if(OrderSend(_Symbol,OP_SELLSTOP,O_Lots,op,Slippage,0,0,NULL,N_Magic))
                    {Print("Отложенный ордер установлен");}
                  else
                    {Print("Ошибка установки отложеного одера: ", GetLastError());}
                 }
              }
            if(OrderType()==OP_SELL)
              {
               if(OrderStopLoss() != 0)
                 {
                  op=OrderStopLoss();
                  if(OrderSend(_Symbol,OP_BUYSTOP,O_Lots,op,Slippage,0,0,NULL,N_Magic))
                    {Print("Отложенный ордер установлен");}
                  else
                    {Print("Ошибка установки отложеного одера: ", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Удаление отложенного ордера                                      |
//+------------------------------------------------------------------+
void DeletePending()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS)==true)
        {
         if(CountOrders(-1)==1)
           {
            if(OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)
              {
               if(OrderMagicNumber() == N_Magic)
                 {
                  if(OrderDelete(OrderTicket()))
                    {Print("Отложенный ордер удален");}
                  else
                    {Print("Ошибка удаления отложеного одера: ", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Возвращает время начала цикла                                    |
//+------------------------------------------------------------------+
datetime TimeStart()
  {
   datetime ts=0;
   if(OrdersTotal()!=0)
     {
      for(int pos=OrdersTotal()-1;pos>=0;pos--)
        {
         if(OrderSelect(pos,SELECT_BY_POS)==true)
           {
            if(OrderSymbol()==_Symbol)
              {
               if(OrderMagicNumber()!=N_Magic)
                 {
                  ts=OrderOpenTime();
                 }
              }
           }
        }
     }
   else
   if(OrdersTotal()==0)
     {
      for(int pos=0; pos<OrdersHistoryTotal(); pos++)
        {
         if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
           {
            if(OrderSymbol()==_Symbol)
              {
               if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                 {
                  if(OrderProfit()>0)
                    {
                     if(ts<OrderCloseTime())
                       {
                        ts=OrderCloseTime();
                       }
                    }
                 }
              }
           }
        }
     }
   return(ts);
  }
//+------------------------------------------------------------------+
//|  Возвращает пункты убытка закрытых ордеров с начала цикла        |
//+------------------------------------------------------------------+
double GetPointLoss()
  {
   double result=0,b=0,s=0;;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(OrderProfit()<0)
                 {
                  if(OrderCloseTime()>TimeStart())
                    {
                     if(OrderType()==OP_BUY&&OrderProfit()<0)
                       {
                        b+=OrderOpenPrice()-OrderClosePrice();
                       }
                     if(OrderType()==OP_SELL&&OrderProfit()<0)
                       {
                        s+=OrderClosePrice()-OrderOpenPrice();
                       }
                    }
                 }
              }
           }
        }
     }
   return(b+s);
  }
//+------------------------------------------------------------------+
//|  Возвращает кол-во серии убыточных ордеров                       |
//+------------------------------------------------------------------+
int GetLossOrders()
  {
   int cnt=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderCloseTime()>TimeStart())
              {
               if(OrderProfit()<0) cnt++;
              }
           }
        }
     }
   return(cnt);
  }
//+------------------------------------------------------------------+
 
MakarFX:

Try it, ask for it

It's up and running. I'll let you know. Thanks for your help.
 
SGarnov:
I will let you know what happens. thanks for the help.

Can someone explain the reason for this behaviour?

I open an order

2021.07.29 18:53:57.436 '60744458': order was opened : #1639674290 sell 0.01 USDJPY at 109.519 sl: 0.000 tp: 0.000

then the Expert Advisor modifies it

2021.07.29 18:53:57.647 '60744458': modify order #1639674290 sell 0.01 USDJPY at 109.519 sl: 0.000 tp: 0.000 -> sl: 109.919 tp: 108.719

and then this shit happens

2021.07.29 18:53:58.313 '60744458': order #1639674290 sell 0.01 USDJPY closing at 0.000 failed [Off quotes]
2021.07.29 18:53:57.647 '60744458': close order #1639674290 sell 0.01 USDJPY at 109.519 sl: 0.000 tp: 0.000 at price 0.000

The interesting thing is that it happens on USDJPY and only sell on other pairs

 
MakarFX:

Can someone explain the reason for this behaviour?

I open an order

then the Expert Advisor modifies it

and then this shit happens

The interesting thing is that it only happens on USDJPY and all is good on others

If you want to understand something, you have to learn how to get the maximum of useful information in minimum cycles...

 
Alexey Viktorov:

To understand something, learn how to pull out the most useful information in the least amount of cycles...

It's good to talk when you know what to do...

help with advice on how to "get the most out of useful information"

 
MakarFX:

Can someone explain the reason for this behaviour?

I open an order

then the Expert Advisor modifies it

and then this shit happens

The interesting thing is that it happens on USDJPY and only sell on other pairs

Is this how the advisor whose code you wrote works?
 
SGarnov:
Is this how the EA that you wrote the code for works?
It's fine, the problem was the terminal.