Caractéristiques du langage mql5, subtilités et techniques - page 81

 
Probablement que peu de gens font ça, donc voici
// Заполнение массива строками из файла - классика
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);
}
J'utilise moi-même la deuxième option lorsque j'ai besoin de râper quelque chose. Il est probablement plus rapide aussi, mais je ne l'ai pas testé.
 
// "Сортировка" символов Обзора рынка

// Обмен значений
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 sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Discussion de l'article "Créer et tester des symboles personnalisés dans 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:
Probablement, peu de gens le font, donc j'utilise la deuxième variante quand j'ai besoin de paralléliser quelque chose. Il fonctionne probablement plus rapidement aussi, je n'ai pas vérifié.

La deuxième option est non seulement meilleure, mais aussi plus correcte. La première variante n'est pas fiable. Il y a une erreur fatale à l'intérieur.

 
Ihor Herasko:

La deuxième option est non seulement meilleure, mais aussi plus correcte. La première variante n'est pas fiable. Il y a une erreur fatale dedans et il conduit l'erreur fatale.

Je n'ai pas vu de problèmes particuliers dans la première variante. Quant à la seconde, il semble qu'une ou deux personnes l'utilisent.

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

Je n'ai pas vu de problème particulier avec la première option. Quant à la seconde, une ou deux personnes semblent l'utiliser.

Que dites-vous de ça ? Et celui-là ?

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

si ce n'est pas une erreur fatale ?

 
Ihor Herasko:

Comment ça ? Qu'en est-il de ceci :

si ce n'est pas une erreur fatale ?

Vous pouvez utiliser la réserve pour accélérer les choses. Mais l'intérêt de la réserve est discutable dans ce cas, car le tableau d'objets complexes est une chaîne de caractères.

En ce qui concerne les erreurs fatales, la gestion d'une valeur négative de ArrayResize est à votre goût.

 
fxsaber:

Vous pouvez utiliser la réserve pour accélérer les choses. Comme pour l'erreur fatale, la gestion d'une valeur négative de ArrayResize est facultative.

Non, il ne s'agit pas d'accélération. Nous devrions d'abord penser à la fiabilité. Et c'est pourquoi le traitement de la valeur de retour de ArrayResize ne peut pas être appelé "à volonté". Quoi qu'il en soit, ce fil de discussion n'est pas destiné aux débutants, où les bases sont expliquées et des exemples simplifiés sont donnés.

P. S. À propos, vous pouvez retourner ArrayResize avec une valeur positive, mais vous obtiendrez toujours l'erreur de dépassement de tableau.
 
Ihor Herasko:

Le traitement du retour de la valeur ArrayResize ne peut pas être appelé "à volonté". Après tout, ce fil de discussion n'est pas destiné aux débutants, où les bases sont expliquées et des exemples simplifiés sont donnés.

Dans ce cas, je ne pense pas qu'il soit approprié de tuer la clarté par souci de fiabilité. La tâche consistait à montrer la deuxième méthode. La technique a été démontrée ici, il ne s'agit pas d'une solution universelle toute faite.

Vous ne devez pas copier-coller mes codes. Ils sont toujours destinés à des fins de formation uniquement. C'est-à-dire que l'on attend d'une personne qu'elle examine le code, qu'elle comprenne l'idée principale et qu'elle écrive sa propre variante sur cette base.

P. S. À propos, vous pouvez renvoyer ArrayResize avec une valeur positive mais obtenir quand même une erreur de dépassement de tableau.
Dans cette situation, il n'y aura pas de hors-réseau.
 
fxsaber:

Dans cette situation, il n'y aura pas de hors-réseau.

S'il vous plaît :

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

Dans les cas où le tableau arrnArray ne peut pas être étendu, ArrayResize retournera la taille actuelle du tableau (au moins 0). Par conséquent, l'exécution du corps de la boucle entraînera l'expansion du tableau à l'extérieur du tableau.

Raison: