Особенности языка mql5, тонкости и приёмы работы - страница 81

fxsaber
14948
fxsaber  
Наверное, не многие так делают, поэтому сюда
// Заполнение массива строками из файла - классика
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);
}
Сам пользуюсь вторым вариантом, когда нужно что-нибудь распарсить. Наверное, и работает быстрее, не проверял.
fxsaber
14948
fxsaber  
// "Сортировка" символов Обзора рынка

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

Forum on trading, automated trading systems and testing trading strategies

Discussion of article "Creating and testing custom symbols 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);
  }
}
Ihor Herasko
19755
Ihor Herasko  
fxsaber:
Наверное, не многие так делают, поэтому сюдаСам пользуюсь вторым вариантом, когда нужно что-нибудь распарсить. Наверное, и работает быстрее, не проверял.

Второй вариант не только лучше, но и корректнее. Первый вариант ненадежный. В нем fatal error на fatal error сидит и им же погоняет.

fxsaber
14948
fxsaber  
Ihor Herasko:

Второй вариант не только лучше, но и корректнее. Первый вариант ненадежный. В нем fatal error на fatal error сидит и им же погоняет.

Особых проблем в первом варианте не увидел. Что же касается второго, то, похоже, его использует один-два человека.

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

Особых проблем в первом варианте не увидел. Что же касается второго, то, похоже, его использует один-два человека.

Ну как же? А что вот это:

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

если не fatal error?

fxsaber
14948
fxsaber  
Ihor Herasko:

Ну как же? А что вот это:

если не fatal error?

Для ускорения можно использовать Reserve. Правда, смысл в Reserve сомнителен в данном случае, т.к. массив сложных объектов - string.

Что же касается fatal error, то обработка отрицательного значения ArrayResize - это уже по желанию.

Ihor Herasko
19755
Ihor Herasko  
fxsaber:

Для ускорения можно использовать Reserve. Что же касается fatal error, то обработка отрицательного значения ArrayResize - это уже по желанию.

Нет, не об ускорении речь. Сначала стоит думать о надежности. А потому обработку возврата значения ArrayResize ну никак нельзя назвать "по желанию". Все-таки здесь ветка не для новичков, где рассказываются азы и даются упрощенные примеры.

P. S. Кстати, вернуть ArrayResize может и положительное значение, но при этом все равно получим ошибку выхода за пределы массива.
fxsaber
14948
fxsaber  
Ihor Herasko:

обработку возврата значения ArrayResize ну никак нельзя назвать "по желанию". Все-таки здесь ветка не для новичков, где рассказываются азы и даются упрощенные примеры.

В данном случае не вижу уместным убивать наглядность в угоду надежности. Задача была показать второй метод. Здесь был продемонстрирован именно прием, а не универсальное готовое решение.

Копи-пастить мои коды нельзя. Они всегда только в учебных целях. Т.е. предполагается, что человек будет разбираться в коде и, поняв основную идею, напишет свой вариант на ее основе.

P. S. Кстати, вернуть ArrayResize может и положительное значение, но при этом все равно получим ошибку выхода за пределы массива.
Выхода за пределы массива в такой ситуации не будет.
Ihor Herasko
19755
Ihor Herasko  
fxsaber:

Выхода за пределы массива в такой ситуации не будет.

Пожалуйста:

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

В тех случаях, когда массив arrnArray невозможно расширить, ArrayResize вернет текущий размер массива (как минимум, 0). Поэтому выполнение тела цикла приведет к выходу за пределы массива.