Discussione sulla documentazione MQL4 - pagina 18

 
Bene... Per come la vedo io, questa è la risposta giusta:

void SendMail( stringa soggetto, stringa some_text)
Invia un'e-mail all'indirizzo specificato nella finestra delle impostazioni nella scheda Mail.
La funzione non funziona in modalità test. Anche questa funzione non può essere chiamata dagli indicatori utente.
L'invio può essere proibito nelle impostazioni, anche l'indirizzo e-mail può non essere specificato. La funzione GetLastError() deve essere chiamata per ottenere le informazioni sull'errore.
[...]

Nell'indicatore, certo, non ho controllato... :)

Z.U. Mi oppongo al titolo del topic e propongo di rinominarlo in qualcosa del genere: "Miglioramento della documentazione MQL4: rimozione di imprecisioni e carenze". Qualcosa del genere.
 
Nell'esempio della funzione OrderSelect(), mi sono imbattuto in una tale espressione:
if(OrderSelect(12470, SELECT_BY_TICKET)==true) ...
Poi l'ho visto anche in altri punti della documentazione.

Per favore, spiega, è solo uno stile di programmazione?
Se non lo è, qual è la ragione per usare l'operazione di confronto per le variabili logiche?
Perché non si usa un'espressione più semplice?
if(OrderSelect(12470, SELECT_BY_TICKET)) ...
 
Yurixx:
Perché non si usa un'espressione più semplice:

La prima espressione è intuitivamente più comprensibile e non controversa soprattutto per i principianti, anche se la seconda espressione è usata più ampiamente probabilmente.
 
cos'è un parametro formale e cosa ha a che fare con i parametri passati per riferimento?
 
Spesso le funzioni per il calcolo dei valori richiedono alcuni parametri come input. Per esempio, se guardiamo la funzione OrderSend(), ha molti di questi parametri:
  • Simbolo
  • Tipo di ordine
  • Volume della posizione in lotti
  • Il prezzo della scoperta
  • Slippage in pip
e così via. I parametri passati alla funzione possono essere di due tipi: quelli che non cambiano in alcun modo durante il funzionamento della funzione chiamata, e quelli che possono essere elaborati in essa.
Per esempio, consideriamo la seguente funzione:

//+------------------------------------------------------------------+
//|  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;   
  }
Tre parametri vengono passati in SplitString(): un array ArrayRes per riferimento (preceduto da una efemmina &) e due parametri formali InputStrung (la stringa da dividere in parti) e splitter (che è lo splitter per la divisione).
Quando la funzione viene eseguita, l'array ArraRes conterrà diverse stringhe. La funzione stessa in MQL4 non può restituire tipi complessi (ad esempio array), ma utilizzando il passaggio dei parametri per riferimento, si evita questa restrizione.

Lo script completo è il seguente:

//+------------------------------------------------------------------+
//|                                                        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);
  }
//+------------------------------------------------------------------+
Eseguitelo nel vostro ambiente e vedete il risultato.
 
Ecco un altro pezzo sfortunato di documentazione

doppio OrderClosePrice( )
Restituisce il prezzo di chiusura dell'ordine selezionato.
L'ordine deve essere preselezionato usando OrderSelect().
Esempio:
 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true) { datetime ctm=OrderOpenTime(); if(ctm>0) Print("Open time for the order 10 ", ctm);
     ctm=OrderCloseTime(); if(ctm>0) Print("Tempo di chiusura dell'ordine 10 ", ctm); } else Print("OrderSelect failed error code is",GetLastError());

La descrizione è sulla funzione OrderClosePrice, mentre l'esempio è sulla funzione OrderClosePrice.
Questo è probabilmente il motivo per cui il 99% degli Expert Advisors che recensiamo fanno un'analisi assolutamente non necessaria del tipo di ordine
if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 0);
Quando si poteva semplicemente scrivere
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)
 
Sì, questo è un punto che ho ripreso la settimana scorsa. Penso che qualcosa del genere:

 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());
 
Quote
------
Tre parametri sono passati a SplitString(): array ArrayRes per riferimento (con ampersand & davanti) e due parametri formali InputStrung (la stringa da analizzare) e splitter (che è lo splitter per l'analisi).
Quando la funzione viene eseguita, l'array ArraRes conterrà diverse stringhe. La funzione stessa in MQL4 non può restituire tipi complessi (ad esempio array), ma utilizzando il passaggio dei parametri per riferimento, si evita questa restrizione.
------

Lo capisco. Non capisco perché li hai chiamati "formali". Sono parametri che vengono passati solo per divertimento, in modo puramente formale? Non esiste una cosa del genere in C.

Perché la descrizione dei tipi di parametri è descritta nella sezione "Variabili" e non nella sezione "Funzioni"?
 
cout:
Lo capisco. Non capisco perché li chiami "formali": sono parametri che si passano, puramente formali? Non esiste una cosa del genere in C.


Perché le variabili passate in una funzione sono passate lì formalmente, non come variabili, ma come loro valori. Le variabili possono essere manipolate (i loro valori cambiati), mentre tali manipolazioni con i valori non hanno senso.
Ecco un'altra versione di questo esempio:

//+------------------------------------------------------------------+
//|                                                        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);
  }
//+------------------------------------------------------------------+
 
Quindi, chiamateli "Passaggio di parametri per valore".
Formalmente significa che nulla dipende dal suo valore, ad esempio riservato per un uso futuro :). Ma i parametri passati per valore dipendono da qualcosa, altrimenti sarebbero chiamati formali :).
Motivazione: