Discusión sobre la documentación de MQL4 - página 18

 
Bueno... A mi modo de ver, esa es la respuesta correcta:

void SendMail( string subject, string some_text)
Envía un correo electrónico a la dirección especificada en la ventana de configuración de la pestaña Correo.
La función no funciona en modo de prueba. Esta función tampoco puede ser llamada desde los indicadores de usuario.
El envío puede estar prohibido en los ajustes, también la dirección de correo electrónico puede no estar especificada. Se debe llamar a la función GetLastError() para obtener la información del error.
[...]

En el indicador, hay que reconocer que no lo he comprobado... :)

Z.U. Me opongo al título del tema y propongo cambiarlo por algo así: "Mejora de la documentación de MQL4: eliminación de imprecisiones y deficiencias". Algo así.
 
En el ejemplo de la función OrderSelect(), me encontré con una expresión de este tipo:
if(OrderSelect(12470, SELECT_BY_TICKET)==true) ...
Luego lo vi también en otros lugares de la documentación.

Por favor, explique, ¿es sólo un estilo de programación?
Si no es así, ¿cuál es la razón de utilizar la operación de comparación para las variables lógicas?
¿Por qué no se utiliza una expresión más sencilla?
if(OrderSelect(12470, SELECT_BY_TICKET)) ...
 
Yurixx:
¿Por qué no se utiliza una expresión más sencilla?

La primera expresión es intuitivamente más comprensible y no es controvertida, especialmente para los principiantes, aunque la segunda expresión se utiliza más ampliamente probablemente.
 
¿qué es un parámetro formal y qué tiene que ver con los parámetros pasados por referencia?
 
A menudo, las funciones para el cálculo de valores requieren algunos parámetros como entrada. Por ejemplo, si miramos la función OrderSend(), tiene muchos parámetros de este tipo:
  • Símbolo
  • Tipo de pedido
  • Volumen de posición en lotes
  • El precio del descubrimiento
  • Desplazamiento en pips
y así sucesivamente. Los parámetros pasados a la función pueden ser de dos tipos: los que no cambian de ninguna manera durante la operación de la función llamada, y los que pueden ser procesados en ella.
Por ejemplo, consideremos la siguiente función:

//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   return;   
  }
Se pasan tres parámetros a SplitString(): un array ArrayRes por referencia (precedido por un ampersand &) y dos parámetros formales InputStrung (la cadena a dividir en partes) y splitter (que es el divisor para la división).
Cuando se ejecuta la función, el array ArraRes contendrá varias cadenas. La propia función en MQL4 no puede devolver tipos complejos (por ejemplo, array), pero al utilizar el paso de los parámetros por referencia, evitamos esta restricción.

El guión completo es el siguiente :

//+------------------------------------------------------------------+
//|                                                        Split.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
 
//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   return;   
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string strInfo="aae|aer3|dzse|faw323";
   string strResult[] ;
   
   SplitString(strResult,strInfo,"|");
   
   int N=ArraySize(strResult);
   if (N>0)
      {
      for (int i=0;i<N;i++) Print("strResult[",i,"]=",strResult[i]);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
Ejecútelo en su entorno y vea el resultado.
 
Aquí hay otra pieza de documentación desafortunada

double PrecioCierreOrden( )
Devuelve el precio de cierre de la orden seleccionada.
El pedido debe ser preseleccionado mediante OrderSelect().
Ejemplo:
 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true) { datetime ctm=OrderOpenTime(); if(ctm>0) Print("Hora de apertura del pedido 10 ", ctm);
     ctm=OrderCloseTime(); if(ctm>0) Print("Hora de cierre de la orden 10 ", ctm); } else Print("El código de error de OrderSelect falló es",GetLastError());

La descripción es sobre la función OrderClosePrice, mientras que el ejemplo es sobre la función OrderClosePrice.
Probablemente por eso el 99% de los Asesores Expertos que revisamos hacen un análisis absolutamente innecesario del tipo de orden
if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 0);
Cuando se puede escribir simplemente
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)
 
Sí, es un punto que recogí la semana pasada. Creo que algo así :

 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true)
    {
     datetime  ctm= OrderOpenTime();if(ctm>0)
     Print("Open time for the order 10 ", TimeToStr(ctm)); 
     double price=OrderClosePrice();
     if(price>0) Print("Close price for the order 10 ", DoubleToStr(price,MarketInfo(OrderSymbol(),MODE_DIGITS)));
    }
  else
    Print("OrderSelect failed error code is",GetLastError());
 
Cita
------
Se pasan tres parámetros a SplitString(): el array ArrayRes por referencia (con el ampersand & delante) y dos parámetros formales InputStrung (la cadena a analizar) y splitter (que es el divisor para el análisis).
Cuando se ejecuta la función, el array ArraRes contendrá varias cadenas. La propia función en MQL4 no puede devolver tipos complejos (por ejemplo, array), pero al utilizar el paso de los parámetros por referencia, evitamos esta restricción.
------

Lo entiendo. No entiendo por qué los llamó "formales". ¿Son estos parámetros los que se pasan por diversión, de manera puramente formal? No hay tal cosa en C.

¿Por qué la descripción de los tipos de parámetros se encuentra en la sección "Variables" y no en la sección "Funciones"?
 
cout:
Lo entiendo. No entiendo por qué los llamas "formales". ¿Son parámetros que se pasan sin más, de manera puramente formal? No existe tal cosa en C.


Porque las variables que se pasan a una función se pasan allí formalmente, no como variables, sino como sus valores. Las variables pueden ser manipuladas (sus valores cambiados), mientras que tales manipulaciones con los valores no tienen sentido.
He aquí otra versión de este ejemplo:

//+------------------------------------------------------------------+
//|                                                        Split.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
 
//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   InputString="Входная строка";
   splitter="разделитель";
   Print("InputString=",InputString,"    splitter=",splitter);
   return;   
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string strInfo="aae|aer3|dzse|faw323";
   string strResult[] ;
   string devider="|";
   SplitString(strResult,strInfo,devider);
   
   int N=ArraySize(strResult);
   if (N>0)
      {
      for (int i=0;i<N;i++) Print("strResult[",i,"]=",strResult[i]);
      }
   Print("strInfo=",strInfo,"    devider=",devider);   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
Por lo tanto, llámalos "Pasar parámetros por valor".
Formalmente significa que nada depende de su valor, por ejemplo, reservado para un uso futuro :). Pero los parámetros pasados por valor sí dependen de algo, si no se llamarían formales :).