Características da linguagem mql5, subtilezas e técnicas - página 81

 
Provavelmente não há muita gente a fazer isto, por isso aqui.
// Заполнение массива строками из файла - классика
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);
}
Eu próprio uso a segunda opção quando preciso de raspar alguma coisa. Provavelmente também funciona mais rápido, ainda não o testámos.
 
// "Сортировка" символов Обзора рынка

// Обмен значений
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();
}
 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Discussão do artigo "Criar e testar símbolos personalizados no 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:
Provavelmente, não são muitas pessoas que o fazem, por isso uso a segunda variante quando preciso de desesperar algo. Provavelmente também funciona mais rápido, ainda não o verifiquei.

A segunda opção não só é melhor, como também mais correcta. A primeira variante não é confiável. Há um erro fatal é um erro fatal dentro dele.

 
Ihor Herasko:

A segunda opção não só é melhor, como também mais correta. A primeira variante não é confiável. Há um erro fatal nele e é ele que conduz o erro fatal.

Eu não vi nenhum problema especial na primeira variante. Quanto à segunda, parece que uma ou duas pessoas a usam.

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

Eu não vi nenhum problema em particular com a primeira opção. Quanto à segunda, uma ou duas pessoas parecem estar a usá-la.

Que tal isso? E este aqui?

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

se não um erro fatal?

 
Ihor Herasko:

Como assim? E quanto a isto?

se não um erro fatal?

Você pode usar a Reserva para acelerar as coisas. Mas o ponto de Reserva é questionável neste caso, porque o conjunto de objetos complexos é uma cadeia.

No que diz respeito a erros fatais, lidar com um valor ArrayResize negativo está ao seu gosto.

 
fxsaber:

Você pode usar a Reserva para acelerar as coisas. Quanto ao erro fatal, o manuseio de um valor ArrayResize negativo é opcional.

Não, não é uma questão de aceleração. Devíamos pensar primeiro na fiabilidade. E é por isso que o processamento do valor de retorno do ArrayResize não pode ser chamado de "à vontade". De qualquer forma, este tópico não é para iniciantes, onde o básico é explicado e exemplos simplificados são dados.

P. S. A propósito, você pode retornar o ArrayResize com um valor positivo, mas você ainda receberá o erro de overrun do array.
 
Ihor Herasko:

O processamento do ArrayResize value return não pode ser chamado de "à vontade". Afinal, este tópico não é para iniciantes, onde o básico é explicado e exemplos simplificados são dados.

Neste caso, não vejo nenhuma razão para matar a clareza por uma questão de confiabilidade. A tarefa era mostrar o segundo método. A técnica foi demonstrada aqui, não uma solução pronta universal.

Não deve colar os meus códigos. Eles são sempre apenas para fins de treinamento. Ou seja, espera-se que uma pessoa olhe através do código e compreenda a ideia principal e escreva a sua própria variante com base nela.

P. S. A propósito, você pode retornar o ArrayResize com um valor positivo, mas ainda assim obter um erro de overrun do array.
Não vai haver nenhum desarranjo nesta situação.
 
fxsaber:

Não vai haver nenhuma desordem nesta situação.

Por favor, por favor:

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

Em casos onde o arrnArray array não pode ser expandido, o ArrayResize retornará o tamanho atual do array (pelo menos 0). Portanto, a execução do corpo do laço fará com que a matriz seja expandida fora da matriz.

Razão: