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);
}
私自身は、何かを削るときには、2番目の選択肢を使います。おそらく動作も速くなると思いますが、テストしていません。
 
// "Сортировка" символов Обзора рынка

// Обмен значений
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
たぶん、やっている人は少ないと思うので、私は何か並列化する必要があるときは、2番目のバリエーションを使っています。おそらく動作も速くなると思いますが、確認していません。

2番目の選択肢は、より良いだけでなく、より正しい。最初のバリエーションは信頼性に欠ける。その中にfatal errorがあります。

 
イホル・ヘラスコ

2番目の選択肢は、より良いだけでなく、より正しい。最初のバリエーションは信頼性に欠ける。その中に致命的なエラーがあり、それを駆動しています。

最初のバリエーションでは、特に問題は感じませんでした。2つ目に関しては、1人か2 人が使っているようです。

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

最初の選択肢は特に問題ないと思いました。2つ目については、1人か2 人が使っているようです。

どうですか?これはどうでしょう。

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

致命的なエラーでないなら?

 
イホール・ヘラスコ

どうですか?これはどうでしょう。

致命的なエラーでないなら?

リザーブを使って高速化することができます。しかし、この場合、複合オブジェクトの配列が文字列であるため、Reserveの意味が疑問視されます。

致命的なエラーに関しては、負のArrayResize 値の処理はお好み次第です。

 
fxsaber

リザーブを使って高速化することができます。致命的なエラーについては、負の ArrayResize 値を処理することはオプションである。

いいえ、加速度の問題ではありません。まずは信頼性を考えるべきでしょう。そして、ArrayResizeの戻り値の 処理は、「自由に」呼び出すことができないのもそのためです。とにかく、このスレッドは、基本を説明し、簡略化した例を示す初心者向けではありません。

P.S.ちなみに、ArrayResizeに正の値を入れて返しても、配列オーバーランエラーになります。
 
イホル・ヘラスコ

ArrayResize の値返しの 処理は、"任意に "呼び出すことはできない。やはり、このスレッドは、基本を説明し、簡略化した例を示す初心者向けではありませんね。

この場合、信頼性のために透明度を殺す理由はないと思います。課題は、2つ目の方法を示すことでした。ここで披露されたのは、普遍的な既成概念にとらわれない技術です。

私のコードをコピーペーストしてはいけません。これらは常にトレーニング用としてのみ使用されます。つまり、コードに目を通して主旨を理解し、それに基づいて自分なりの変種を書くことが期待されているのです。

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)を返す。そのため、ループ本体を実行すると、配列の 外側に展開されることになります。

理由: