Preguntas de los principiantes MQL4 MT4 MetaTrader 4 - página 247

 
Valeriy Yastremskiy #:

Inserte el código correctamente, alt S o por el icono, código de pista.

¿Por qué se necesita una matrizSaveTick?

Sólo estás utilizando 2 elementos de la matriz. Sustitúyelas por variables globales o estáticas si las declaras en una función.

No es sensato utilizar un array para 2 variables.

Y parece que llamas a los arrays antes de llamar a la funciónFindTick(), donde se establece el tamaño del array SaveTick. Y hay un rebasamiento de la matriz.

Gracias. Lo tengo.
Puedes decirme cuál es el error, me parece que la función no cuenta correctamente


***
 
makssub #:

Gracias. Lo tengo.
Puedes decirme cuál es el error, me parece que la función no cuenta correctamente


Inserta el código correctamente, es la casilla 13 en la parte superior de la ventana de respuesta.

Y puedes escribir en palabras lo que hace la función línea por línea.

Ciertamente no parece correcto.

No entiendo dónde y cómo se asigna la variable Tick al ticket de pedido. Y no es necesario comprobar el número mágico y el tipo de orden según la siguiente condición
_magic < 0 || OrderMagicNumber() == _magic
Si la función es llamada con un número mágico menor que cero o el número mágico es igual al número de la orden seleccionada, solicitaremos el tamaño del punto y si es igual a cero buscaremos un valor vacío en el símbolo de la orden... y así sucesivamente.

Ah, y recuerda que el order select rellena la estructura de datos del pedido y lo almacena. Y sólo después de la siguiente selección de pedido con un número de pedido o ticket diferente, los datos de esta estructura cambiarán.

Es decir, OrderSend no rellena la estructura de datos del pedido, sino que devuelve la entrada del pedido o menos 1. Y la estructura de la orden sólo se rellena con OrderSelect. Y entonces los datos de este orden se pueden obtener de esta estructura.

 
Valeriy Yastremskiy #:

Inserta el código correctamente, es la casilla número 13 en la parte superior de la ventana de respuesta.

Y puedes escribir en palabras lo que hace la función línea por línea.

Parece que está mal, por supuesto.

Y no está claro dónde y cómo se asigna la variable Tick al ticket de pedido. Y no es necesario comprobar el número mágico y el tipo de orden según la siguiente condición
_magic < 0 || OrderMagicNumber() == _magic
Si la función es llamada con un número mágico menor que cero o el número mágico es igual al número de la orden seleccionada, solicitaremos el tamaño del punto y si es igual a cero buscaremos un valor vacío en el símbolo de la orden... y así sucesivamente.

Ah, y recuerda que el order select rellena la estructura de datos del pedido y lo almacena. Y sólo después de la siguiente selección de pedido con un número de pedido o ticket diferente, los datos de esta estructura cambiarán.

Es decir, OrderSend no rellena la estructura de datos del pedido, sino que devuelve la entrada del pedido o menos 1. Y la estructura de la orden sólo se rellena con OrderSelect. Y a partir de esta estructura podemos obtener los datos de esta orden.

int FindTicket()
   {
   int oldticket;
   int tick=0;
   ticket=0;
   
   
   for(int cnt = OrdersTotal ()-1; cnt>=0; cnt--)
      {
      if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
            oldticket = OrderTicket();
            if (oldticket > ticket)
               {
               ticket = oldticket;
               tick = OrderTicket();
               }
            }
         }
      }
   return(tick); 
   }              
int TickF = FindTicket();
int CalculateProfitHistory() 
{
  double _point;
  int    i, _ototal = OrdersHistoryTotal(), _profit=0;
  for   (i = 0; i < OrdersHistoryTotal(); i++) 
  {
    if (OrderSelect(TickF, SELECT_BY_TICKET, MODE_HISTORY)) 
    {
      if (OrderSymbol() == Symbol())
      {
        if (OrderMagicNumber() == Magic) 
        {
           _point = MarketInfo(OrderSymbol(), MODE_POINT);
           if (_point == 0) 
           {
              if (StringFind(OrderSymbol(), "") < 0) 
                 _point = 0.0001; 
              else _point = 0.01;
           }   
           if (OrderType() == OP_BUY) 
           {
              _profit += int((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice())/_point);
           }
           if (OrderType()==OP_SELL) 
           {
              _profit += int((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))/_point);
           }
         }
      }
    }
  }
  return(_profit);
}

En la primera función, encontramos el ticket de la orden requerida y la segunda función debe calcular el beneficio de todas las órdenes cerradas después de ese ticket. El beneficio de las órdenes que había antes no me interesa. Pero el segundo no lo calcula correctamente. Cuando se abre una orden, se llaman estas 2 funciones y por lo tanto debería ser igual a 0, pero no lo es.
PS tomó su consejo, dejó las matrices)
12ª caja de arriba)

 
makssub #:

En la primera función, encuentro el ticket de la orden requerida, y la segunda función debe calcular el beneficio de todas las órdenes cerradas después de este ticket. No me interesa el beneficio de los anteriores.
PS tomó su consejo, me negó matrices)
la 12 ª plaza de arriba)

La primera función encuentra el billete con el número más alto, si los billetes aumentan con los números)) En la siguiente iteración del bucle, el billete del siguiente orden numerado se compara con el billete del orden anterior. La selección de la orden llena la estructura de la orden, y OrderTicket recupera el valor del ticket de esta estructura.

Escribe o lee tú mismo lo que hace cada línea de código.

En la segunda función, OrderSelect rellenará la estructura del pedido con los mismos datos del ticket)

 
Valeriy Yastremskiy #:

La primera función encuentra el billete con el número más alto, si los billetes aumentan con los números)) En la siguiente iteración del bucle, el billete del siguiente orden numerado se compara con el billete del orden anterior. La selección de la orden llena la estructura de la orden, y OrderTicket recupera el valor del ticket de esta estructura.

Escribe o lee tú mismo lo que hace cada línea de código.

En la segunda función, OrderSelect rellenará la estructura del pedido con los mismos datos del ticket)

Lo he explicado, pero parece que es malo con la lógica con respecto a esta lengua. ¿Pueden decirme cómo determinar el ticket de la última orden abierta?

¿Cómo puedo calcular el beneficio de todas las órdenes cerradas que le siguen?

 
makssub #:

Lo he explicado, pero parece que es malo con la lógica en relación con este lenguaje. ¿Pueden decirme cómo determinar el ticket de la última orden abierta?

¿Cómo puedo calcular el beneficio de todas las órdenes cerradas que le siguen?

En el momento de la apertura de un pedido. Debería ser el mayor.) Y no deberíamos usar el número de orden. O tenemos que almacenar en nuestra base los números de pedido, los tickets, el estado de los pedidos y la hora de apertura/cierre.

 if(OrderSelect(Ticket, SELECT_BY_TICKET)==true) // Если выбор рыночного ордера произошел успешно
        {
         if(OrderCloseTime()==0)              // Если наш рыночный ордер не закрыт           {
            
            //           Alert("Наш рыночный ордер жив, Модифицируем его если нужно ");
            if(Tral_Stop!=0 || Tral_Profit!=0)
          {     ModifyTral(); }
            return;
           }
         if(OrderCloseTime()!=0)              // Если наш рыночный ордер закрылся
         {
Alert("Our market order has closed. The Adviser's work is completed ",
                  " Swap = ", OrderSwap(), " Commission = ", OrderCommission(),"Profit/loss = ",OrderProfit());
         // ..... // получаем профит и считаем общий профит например
         }

Y es mejor recordar la lógica hasta el final. Entonces es más fácil. Es mejor empezar con los datos necesarios, y debe haber suficientes datos para tomar una decisión)

Tenemos tiempo abierto de pedidos (no pendientes). Tenemos sus entradas. Tenemos un precio abierto, SL y TP de cada orden de mercado. Y hay un tiempo de cierre de orden. Y después de cerrar el pedido, se rellena el campo Beneficio.

Estos son los datos que necesitamos para crear la lógica de estos campos.

La frase "órdenes cerradas después de la última orden abierta" no está definida en absoluto. Pueden ir por número, por billete y por tiempo.

 
Valeriy Yastremskiy #:

Por la hora de apertura del pedido. Debería ser el más grande)

Lo escribes correctamente, pero el código parece un poco complicado )))))

Yo lo haría de la forma en que lo planteas:

int GetTicketLastOpenOrder()
{
   int ticket = -1;
   datetime t = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() <= OP_SELL && OrderOpenTime() > t)
      {
         ticket = OrderTicket();
         t = OrderOpenTime();
      }
   }
   return(ticket);
}


ZS: OrderSelect() por número de ticket tardará mucho más en ejecutarse que una simple búsqueda por órdenes abiertas

 
Igor Makanu #:

Lo escribes correctamente, pero el código es un poco enrevesado ))))

Escríbelo como quieras:


S : OrderSelect() por número de ticket tardará mucho más en ejecutarse que una simple enumeración de órdenes abiertas

Gracias Igor, es que cuando no entienden la esencia, el código correcto de algo no transmite la esencia, por eso pido poner algoritmos no complicados en palabras))))

 
Valeriy Yastremskiy #:

Por la hora de apertura del pedido. Debería ser el más grande) Y sólo no por número de orden, y a menudo la venta de entradas tampoco es útil. O memorizar los números de pedido, los tickets, el estado del pedido y las horas de apertura y cierre en su base de datos.

Y es mejor recordar la lógica hasta el final. Entonces es más fácil. Es mejor empezar con los datos necesarios, y debe haber suficientes datos para tomar una decisión)

Tenemos tiempo abierto de pedidos (no pendientes). Tenemos sus entradas. Tenemos un precio abierto, SL y TP de cada orden de mercado. Y hay un tiempo de cierre de orden. Y después de cerrar el pedido, se rellena el campo Beneficio.

Estos son los datos que necesitamos para crear la lógica de estos campos.

La frase "órdenes cerradas después de la última orden abierta" no está definida en absoluto. Pueden ir por número, por billete y por tiempo.

Muchas gracias por sus respuestas. He puesto en práctica algunas de sus sugerencias.
He escrito una función que encuentra la garrapata correcta.
Escribió una función que cuenta el beneficio de todas las órdenes cerradas después del tick de orden deseado de la función seleccionada. Ahora sólo me queda corregirlo según tus recomendaciones y añadir un control por tiempo, etc.

tpl = NormalizeDouble(Bid - ProfitLock*Point, Digits);
            ticket = OrderSend (Symbol(), OP_SELL, lastlot, Bid, Slippage, 0, tpl, "",Magic, 0, Red);


double CalculateProfitHistory()
{
double order=0,op=0;
int cnt=0;
datetime time=0;
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
      if(OrderSelect(Tick,SELECT_BY_TICKET,MODE_HISTORY))
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
         {
            
            
            op += OrderProfit();
            order +=op;
            cnt++;
            
         }
      }
      }
   return(order);
  }

Lo único que me confunde ahora es que no lo calcula correctamente. Si el TP sale 0,02 como resultado de la prueba, calcula y escribe 0,1300 en Comment. ¿Puede decirme qué tiene de malo?

 
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2021.09.02
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...