mql5言語の特徴、微妙なニュアンスとテクニック - ページ 238

 

機械が生成したコードをソースコードに使うなんて想像もしていなかった。特にパフォーマンスのためにアーカイブ化するような場所で。


以下が生成されたコードだ。

switch (this.Flag)
{
case 0:
  return(false);
case 1:
  return(Tick.bid >= this.bid.Max);
case 2:
  return(Tick.ask <= this.ask.Min);
case 3:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min));
case 4:
  return(Tick.bid <= this.bid.Min);
case 5:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min));
case 6:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 7:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 8:
  return(Tick.ask >= this.ask.Max);
case 9:
  return((Tick.bid >= this.bid.Max) || (Tick.ask >= this.ask.Max));
case 10:
  return((Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 11:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 12:
  return((Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 13:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 14:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 15:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
}

生成にはもっと簡潔なスクリプトが書かれている。素早く仮説を検証し、人為的なミスを避けるには好都合だろう。

 
fxsaber #:

機械が生成したコードをソースコードに使うとは想像もしていなかった。特に、パフォーマンスにとってアーカイブ的に重要な場所で。


以下が生成されたコードである。

生成のために、より簡潔なスクリプトが書かれた。これは仮説を素早く検証し、人為的ミスを避けるのに役立つだろう。

同じChatGPTでも構文やロジックに間違いが多いので、ダブルチェックが必要です。

ChatGPTはコードでアイデアを表現するのに役立ちます。

 
fxsaber #:

以下は生成されたコードである。

生成のために、より簡潔なスクリプトが書かれた。これは仮説を素早く検証し、人為的ミスを避けるのに役立つだろう。

新しいコードは古いコードより速くなったのか、そうでないのか?

もしそうでないなら、なぜ理解しやすい古いコードを理解しにくい新しいコードに変えたのか?

もしそうなら、なぜMQLコンパイラーは一度にパフォーマンス的に最適なコードを生成できなかったのだろうか?

 
Aleksey Vyazmikin #:

同じChatGPTでも構文やロジックに間違いが多いので、ダブルチェックが必要です。

しかし、それは本当に良いピッチマンです、それはコードでアイデアを表現するのに役立ちます。

スクリプトの生成

// Генерация switch-кода.
string GetString( const int Num )
{
  static const string Condition[] = {"(Tick.bid >= this.bid.Max)", "(Tick.ask <= this.ask.Min)",
                                     "(Tick.bid <= this.bid.Min)", "(Tick.ask >= this.ask.Max)"};
  string Str = NULL;

  for (int i = 0; i < ArraySize(Condition); i++)
    if ((bool)(Num & (1 << i)))
      Str += ((Str == NULL) ? NULL : " || ") + Condition[i];

  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 16; i++)
    Print("case " + (string)i + ":\n  return(" + GetString(i) + ");");
}
 
A100 #:

新しいコードが古いコードより速くなったのか、そうでないのか?

新しいコードは速くなった。

もしそうなら、MQLコンパイラーはチャットよりもはるかに多くの可能性を持っているにもかかわらず、なぜパフォーマンス面で最適なコードを一度に生成できなかったのだろうか?

これはアルゴリズムの最適化であり、コンパイラの最適化ではない。

 
fxsaber #:

新しい方が速い。

これはアルゴリズムの最適化であり、コンパイラの最適化ではない。

どのくらい速くなったのか?1.5%か1.5倍か?まるで速くなったかのように?それとも正しい測定に基づいて?

コードを与えたのではなく、アルゴリズムを与えたのですか?

 
A100 #:

どのくらい速くなったのか?1.5パーセントか1.5倍か?また、感覚によってか、それとも具体的な測定によってか?

コードではなくアルゴリズムで?

バーチャルのソースコードはそれを使っている。各ティックで4つのチェックをしなければならない。

return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));


しかし、状況によっては(スイッチ0-15)、0-4という少ないチェックで済むこともある。それはTSによります。


たとえば、TS が成行注文のみでポジションをオープン/クローズし、SL/TP を使用しない場合は、1 回のチェックも必要ありません。

しかし、すべての種類の注文を同時に使用する場合は、4つのチェックをすべて行う必要があります。


そのため、特定のTSを取り上げ、そのTSの測定結果を見る必要がある。TSが異なれば、加速の結果も異なる。


ケース(の数)をより多くのバリエーションに分類することも可能だった。率直に言って、私にはできなかった。

 

MQL5にはStringReserve関数が あり、これを使えば理論的には文字列のメモリ再割り当ての回数を減らすことができる:十分な大きさのバッファを一度に確保し、その中で作業を行うのだ。

しかし、実際にやってみるとわかるが、この文字列に値を代入すると、バッファのサイズが変わってしまう(つまり、メモリの再割り当てが発生する)。

その結果

string str;
str.Reserve(8192);
str="test";

の代わりに

string str;
str.Reserve(8192);
StringSetLength(str,0);  // или str.SetLen(0); - в документации есть, но у меня в 4073 не поддерживается
str+="test";
 
JRandomTrader #:

を使うのは理にかなっている。

その通りだ。この仕組みは文字列の補完に大いに役立つ。例えば、大きなHTMLレポートを作成する場合などだ。

 

あるシンボルにデータがあるかどうかを調べるにはどうすればいいでしょうか。データがない場合、[Market Watch]ウィンドウにそのシンボルを残したままにしないですみますか?

私はそのようなチェックをループの中で使っています:

ulong first_server_date = (ulong)SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE);

if(first_server_date == NULL) {
  SymbolSelect(symbol, false);
  continue;
}

しかし、Expert Advisorがチャート上にある間は、[Market Watch] ウィンドウからシンボルを手動で1つずつ削除することも、一度に 削除することもできません:


理由: