mql5语言的特点、微妙之处以及技巧 - 页 81

 
可能没有多少人这样做,所以在这里
// Заполнение массива строками из файла - классика
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);
}
我自己在需要研磨东西的时候使用第二种方法。可能也能更快地工作,没有测试过。
 
// "Сортировка" символов Обзора рынка

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

关于交易、自动交易系统和测试交易策略的论坛

讨论文章 "在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:
也许,没有多少人这样做,所以当我需要并行化的时候,我使用第二种变体。可能工作速度也比较快,没有检查过。

第二个选项不仅更好,而且更正确。第一个变种是不可靠的。里面有致命的错误,是致命的错误。

 
伊霍尔-赫拉斯科

第二个选项不仅更好,而且更正确。第一个变种是不可靠的。其中有一个致命的错误,它驱动了致命的错误。

我在第一种变体中没有看到任何特殊问题。至于第二种,似乎有一两个人 在使用它。

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

我没有看到第一个选项有什么特别的问题。至于第二种,似乎有一两个人 在使用它。

那又如何呢?那这个呢。

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

如果不是一个致命的错误?

 
Ihor Herasko:

怎么说呢?那这个呢。

如果不是一个致命的错误?

你可以使用储备金来加快事情的进展。但在这种情况下,Reserve的意义是值得怀疑的,因为复杂对象的阵列是一个字符串。

就致命的错误而言,处理ArrayResize 的负值取决于你的口味。

 
fxsaber:

你可以使用储备金来加快事情的进展。至于致命的错误,处理ArrayResize的负值是可选的。

不,这与加速无关。我们应该首先考虑可靠性。这就是为什么对ArrayResize返回值 的处理不能 "随意 "调用。无论如何,这个主题不是为初学者准备的,在这里解释了基础知识并给出了简化的例子。

P.S.顺便说一下,你可以用一个正值返回ArrayResize,但是你仍然会得到数组超限的错误。
 
伊霍尔-赫拉斯科

对ArrayResize返回值 的处理不能 "随意 "调用。毕竟,这个主题不是为初学者准备的,在这里解释基础知识并给出简化的例子。

在这种情况下,我认为为了可靠性而扼杀清晰度是不合适的。任务是展示第二种方法。这里展示的是技术,而不是一个普遍的现成的解决方案。

你不能复制粘贴我的代码。它们始终只用于培训目的。也就是说,一个人要看完代码,理解主要思想,并在此基础上编写自己的变体。

P.S.顺便说一下,你可以用一个正值返回ArrayResize,但仍然得到一个数组超限的错误。
在这种情况下,不会出现阵营外的情况。
 
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)。因此,执行循环体将导致数组 被扩展到数组 之外。