Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 81

 
Probabilmente non molte persone lo fanno, quindi ecco
// Заполнение массива строками из файла - классика
int FileToStrings( const string FileName, string &Str[] )
{
  ArrayResize(Str, 0);

  const int handle = FileOpen(FileName, FILE_READ | FILE_ANSI );
  
  if (handle != INVALID_HANDLE)
  {
    while (!FileIsEnding(handle))
      Str[ArrayResize(Str, ArraySize(Str) + 1) - 1] = FileReadString(handle);
    
    FileClose(handle);
  }
  
  return(ArraySize(Str));
}

// Заполнение массива строками из файла - альтернатива
int FileToStrings2( const string FileName, string &Str[] )
{
  uchar Bytes[];
  
  return(FileLoad(FileName, Bytes) ? StringSplit(CharArrayToString(Bytes), '\n', Str) : 0);
}

void OnStart()
{
  const string FileName = "Test.txt";
  
  string Str[];  
  FileToStrings(FileName, Str);

  string Str2[];  
  FileToStrings2(FileName, Str2);
  
  ArrayPrint(Str);
  ArrayPrint(Str2);
}
Io stesso uso la seconda opzione quando ho bisogno di raspare qualcosa. Probabilmente funziona anche più velocemente, non l'ho testato.
 
// "Сортировка" символов Обзора рынка

// Обмен значений
template <typename T>
void Swap( T &Value1, T &Value2 )
{
  const T Tmp = Value1;
  
  Value1 = Value2;
  Value2 = Tmp;  
}

// Сортировка строк
bool ArraySort( string &Str[], const bool Increase = true )
{
  const int Compare = Increase ? 1 : -1;
  const int Size = ArraySize(Str);
  
  for (int i = 0; i < Size - 1; i++)
    for (int j = i + 1; j < Size; j++)
      if (StringCompare(Str[i], Str[j]) == Compare)
        Swap(Str[i], Str[j]);
  
  return(true);
}

// Выключение (что возможно) символов в Обзоре рынка
void MarketWatchOff()
{
  for (int i = SymbolsTotal(true) - 1; i >= 0; i--)
    SymbolSelect(SymbolName(i, true), false);
}

// Получение символов из Обзора рынка
int GetMarketWatch( string &Str[] )
{
  const int Size = ArrayResize(Str, SymbolsTotal(true));
  
  for (int i = 0; i < Size; i++)
    Str[i] = SymbolName(i, true);
    
  return(Size);
}

// Задание символов Обзора рынка
void SetMarketWatch( const string &Str[] )
{
  MarketWatchOff();
  
  const int Size = ArraySize(Str);
  
  for (int i = 0; i < Size; i++)
    SymbolSelect(Str[i], true);        
}

// "Сортировка" символов Обзора рынка
void SortMarketWatch()
{
  string Str[];
  
  GetMarketWatch(Str);
  ArraySort(Str);
  
  SetMarketWatch(Str);
}

void OnStart()
{
  SortMarketWatch();
}
 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Discussione dell'articolo "Creare e testare simboli personalizzati in MetaTrader 5"

fxsaber, 2018.04.12 07:59

#property script_show_inputs

#include <fxsaber\ThirdPartyTicks\CustomSymbol.mqh> // https://www.mql5.com/ru/code/20225

// Generate M1-history from ticks
void OnStart()
{  
  MqlTick Ticks[];
  CUSTOMSYMBOL Symb;

  if (Symb.IsCustom() && (CopyTicksRange(Symb.Name, Ticks, COPY_TICKS_ALL, 0, LONG_MAX) > 0))
  {
    Symb.AddTicks(Ticks);
  
    Symb.CreateHistoryRates();
    
    ChartOpen(Symb.Name, PERIOD_CURRENT);
  }
}
 
fxsaber:
Probabilmente, non molte persone lo fanno, quindi uso la seconda variante quando ho bisogno di parallelizzare qualcosa. Probabilmente funziona anche più velocemente, non ho controllato.

La seconda opzione non è solo migliore, ma anche più corretta. La prima variante non è affidabile. C'è un errore fatale al suo interno.

 
Ihor Herasko:

La seconda opzione non è solo migliore, ma anche più corretta. La prima variante non è affidabile. C'è un errore fatale in esso e guida l'errore fatale.

Non ho visto problemi particolari nella prima variante. Per quanto riguarda la seconda, sembra che una o due persone la usino.

Поиск - MQL5.community
Поиск - MQL5.community
  • www.mql5.com
Поиск выполняется с учетом морфологии и без учета регистра. Все буквы, независимо от того, как они введены, будут рассматриваться как строчные. По умолчанию наш поиск показывает страницы...
 
fxsaber:

Non ho visto alcun problema particolare con la prima opzione. Per quanto riguarda il secondo, una o due persone sembrano usarlo.

Che ne dite? Che dire di questo:

Str[ArrayResize(Str, ArraySize(Str) + 1) - 1]

se non un errore fatale?

 
Ihor Herasko:

Com'è? Che dire di questo:

se non un errore fatale?

Puoi usare Reserve per accelerare le cose. Ma il punto di riserva è discutibile in questo caso, perché l'array di oggetti complessi è una stringa.

Per quanto riguarda gli errori fatali, la gestione di un valore ArrayResize negativo dipende dai vostri gusti.

 
fxsaber:

Puoi usare Reserve per accelerare le cose. Come per l'errore fatale, la gestione di un valore ArrayResize negativo è opzionale.

No, non si tratta di accelerazione. Dovremmo pensare prima all'affidabilità. Ed è per questo che l'elaborazione del valore di ritorno di ArrayResize non può essere chiamata "a piacere". Comunque, questo thread non è per i principianti dove si spiegano le basi e si danno esempi semplificati.

P. S. A proposito, potete restituire ArrayResize con un valore positivo, ma otterrete comunque l'errore di overrun dell'array.
 
Ihor Herasko:

L'elaborazione del ritorno del valore di ArrayResize non può essere chiamata "a piacere". Dopo tutto, questo thread non è per i principianti, dove si spiegano le basi e si danno esempi semplificati.

In questo caso, non credo che sia opportuno uccidere la chiarezza in nome dell'affidabilità. Il compito era quello di mostrare il secondo metodo. La tecnica è stata dimostrata qui, non è una soluzione universale già pronta.

Non dovete copiare e incollare i miei codici. Sono sempre solo a scopo di allenamento. Cioè ci si aspetta che una persona guardi il codice, capisca l'idea principale e scriva la propria variante basata su di essa.

P. S. A proposito, potete restituire ArrayResize con un valore positivo ma ottenere comunque un errore di overrun dell'array.
Non ci sarà nessun out-of-array in questa situazione.
 
fxsaber:

Non ci sarà nessun out-of-array in questa situazione.

Per favore:

void AddElements(int &arrnArray[], int nCount)
{
   int nTotal = ArraySize(arrnArray);
   if (ArrayResize(arrnArray, nTotal + nCount) < 0)
      return;

   for (int i = nTotal + nCount - 1; i >= nTotal; --i)
      arrnArray[i] = i;
}

Nei casi in cui l'array arrnArray non può essere espanso, ArrayResize restituirà la dimensione attuale dell'array (almeno 0). Pertanto, l'esecuzione del corpo del ciclo causerà l'espansione dell'array al di fuori dell'array.

Motivazione: