Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 1548

 
SGarnov:

Para hacerlo más fácil coge mi código fuente, tiene una lógica que funciona, salvo el problema que he descrito, no lo entiendo del todo, me hierve la cabeza pero no consigo sacarle partido.

¿Pone una orden pendiente o dos en diferentes direcciones?
 
SGarnov:
Tengo la sensación de que el robot se está fortaleciendo, no me gusta que cuando coloco órdenes o no quiero operar porque ya la he colocado, no pueda abrirla porque ya la he colocado, sólo tiene que abrir la orden.

@MakarFX ya lo está haciendo. No nos interpongamos en el camino.

Lo que quería decir... Escribe todo de forma que te quede claro (personalmente/personalmente), no saques código con copy-paste.

y un esqueleto de robot muy simplificado se parece a esto:

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

la cerveza hace maravillas y vuelve a la gente más amable :-)

 
MakarFX:
¿Pone una orden pendiente o dos en diferentes direcciones?
Siempre hago un pedido pendiente
 
SGarnov:
Siempre pongo uno pendiente.

Pruébalo, pídelo

//+------------------------------------------------------------------+
//|                                                   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:

Pruébalo, pídelo

Ya está en marcha. Te lo haré saber. Gracias por tu ayuda.
 
SGarnov:
Ya os contaré qué pasa. Gracias por la ayuda.

¿Puede alguien explicar la razón de este comportamiento?

Abro un pedido

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

entonces el Asesor Experto lo modifica

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

y entonces sucede esta mierda

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

Lo interesante es que ocurre en el USDJPY y sólo se vende en otros pares

 
MakarFX:

¿Puede alguien explicar la razón de este comportamiento?

Abro un pedido

entonces el Asesor Experto lo modifica

y entonces sucede esta mierda

Lo interesante es que sólo ocurre en el USDJPY y todo está bien en los demás

Si quieres entender algo, tienes que aprender a obtener el máximo de información útil en el mínimo de ciclos...

 
Alexey Viktorov:

Para entender algo, aprende a sacar la información más útil en el menor número de ciclos...

Es bueno hablar cuando se sabe qué hacer...

ayuda con consejos sobre cómo "sacar el máximo partido a la información útil"

 
MakarFX:

¿Puede alguien explicar la razón de este comportamiento?

Abro un pedido

entonces el Asesor Experto lo modifica

y entonces sucede esta mierda

Lo interesante es que ocurre en el USDJPY y sólo se vende en otros pares

¿Es así como funciona el asesor cuyo código has escrito?
 
SGarnov:
¿Es así como funciona el EA para el que escribiste el código?
Está bien, el problema era el terminal.
Razón de la queja: