MT4 iMAOnArrayとiBandsOnArrayの要素数が計算に与える影響について - ページ 3

 
Alexey Viktorov:

いいえ、ウラジミールです。ちょっと間違っていますね。

この場合、iMAOnArray()を考慮した300要素の配列に対して、ArraySetAsSeries(array, false);を適用する必要があります。しかし、配列の充填ループの代わりにCopyOpen() を使用した方が良いですね。

私の理解では、このバリエーションでは、次のようにするのがよいでしょう。

課題の設定からして、そうやって実証したのです。とても良い仕上がりになりました。そしてさらに自分でできること :)
 
Alexey Viktorov:

いいえ、ウラジミールです。ちょっと間違っていますね。

この場合、iMAOnArray()を考慮した300要素の配列に対して、ArraySetAsSeries(array, false);を適用する必要があります。しかし、配列の充填ループの代わりにCopyOpen() を使用した方が良いですね。

私の理解では、このバリエーションでは、次のようにするのがよいでしょう。

そこで、コードの「作業」バリエーションを示してください。オリジナルのソースコードはここにありますが、要求された300の要素の代わりに12要素に削減しようとしているわけで、最終的には指定されたデータで3つのインジケータバッファになるはずで、少なくとも300要素が地下に表示されることになります。そして、新しいバーが来ると、それぞれ、301以降の値が描画されますが、この場合、0を計算限界とすると、新しいバーだけが再計算されることと、2番目のバッファの平均(スムージング)の種類は、必ずしもSMAではなく、4種類用意されているうちのどれでもいいことを忘れないでください。
 
Sergey Efimenko:

これが問題なのです。配列全体を計算する必要がなく、最後のN個の要素だけを計算する場合。

リミッターをかけるときに、これらの関数を計算するロジックがよくわからない。時系列配列(インジケータバッファの1つ)があるのですが、要素数を0にしておくと問答無用で全てカウントされて計算されますが、計算に関わる要素数を同じシフト数だけ減らすと、主要なものだけが表示されます。簡単に言うと、5000個の要素(チャート上のバー)があり、時間を節約するために最後の300個だけを計算する必要があるのですが、第2パラメータに値300を指定すると、一次5000-4700個の要素が得られ、オフセット300-0で、呼び出し時のそれ以上の値は変わりません。 このパラメータを使う意味は何でしょうか?

地獄は知っている。ただ、忘れてください。計算を高速 化する必要がある場合は、ループ内で計算される項目の数を減らしてください。

if(prev_calculated==0)limit=300; else ...; 

不可能か、時系列ではなく、計算方向の秘密の組み合わせが必要かのどちらかです。

 
Dmitry Fedoseev:

知るか忘れてください。計算を高速化したい場合は、サイクルで計算する要素の数を減らしてください。

不可能か、時系列ではなく、計算方向の秘密の組み合わせが必要かのどちらかです。

そう、先ほども少し書きましたが、可能性はただ一つ、上記の関数の独自のアナログを使い、少なくとも一つの要素を計算することです。

このような状況の逆説は、任意のインジケータ(価格ライン)に平均またはボリンジャーバーを 重ね、同様のテンプレートを作成した場合、すべての履歴バーの最初の計算が遅くなるようなことはありません、コード内のこれらの関数を使用するとき、端末を再起動するか、TFを切り替えるので、これらの関数の計算に時間がかかるもの、不明である。

 
Dmitry Fedoseev:

知るか忘れてください。計算を高速化したい場合は、サイクルで計算する要素の数を減らしてください。

不可能か、時系列ではなく、計算方向の秘密の組み合わせが必要かのどちらかです。

また、こんな構造も使ってみました。

if (limit > 300)limit=300;

ちなみに、「MovingAverages.mqh」はiMAOnArray」よりも旧バージョンでも2倍速い んだそうです。

https://www.mql5.com/ru/forum/79988

Использование MovingAverages.mqh в MQL4
Использование MovingAverages.mqh в MQL4
  • www.mql5.com
При вызове в советнике индикатор работает корректно, но если его поместить в тело условного оператора "if", то советник не открывает сделок, хотя логика советника остается та же.
 
Sergey Efimenko:

そう、先ほども書いたように、少なくとも1つの要素を計算することが可能な、前述の関数の独自のアナログを使うという選択肢しかないのです。

逆説的ですが、MAやボリンジャーバンドを任意のインジケータ(価格線)に貼り付けて同様のテンプレートを作ると、これらの機能をコードで使用した場合のように、端末の再起動やTFの切り替え時に、全ての履歴バーの初期計算が遅くなることはなく、これらの機能で何がそんなに時間がかかるのか不明な状況になっています。

iMAOnArrayを使用して も遅くなるのでしょうか?そうであってはならないのです。ご指摘の通り、StdOnArray(あるいはBandsOnArrayか忘れましたが)からラグが発生しており、開発者は長い間バグの存在を認めませんでした。そしたら突然直って、早く使えるようになったんです。もしかしたら、バグが再発したのかもしれませんね。iMAOnArray()も顕著なスローダウンを起こすようであれば、それはバグです。数ヶ月前にもその話があったような...。でも、まだあるらしい。

 
Dmitry Fedoseev:

iMAOnArrayを使っても スローダウン?そんなことはないはずです。一時期、StdOnArrayによるスローダウンがあったように、開発者は長い間そのバグを認めなかったのです。その後、急に直ったので、早く使えるようになりました。もしかしたら、バグが再発したのかもしれませんね。iMAOnArray()も顕著なスローダウンを起こすようであれば、それはバグです。数ヶ月前にもその話があったような...。でも、まだあるらしい。

チャートの長さ(バーの数)に依存するため、「かなり遅くなる」のか「許容範囲内」なのか判断が難しいところですが、最適化のためには少し計算すればいいというのがキャッチで、実際には計算長を制限するのは不可能です。
 
Sergey Efimenko:
遅いかどうかは、チャートの長さ(バーの数)によるので、判断が難しいのですが、問題は、最適化のためには、ちょっとだけ計算すればいいのであって、実際の計算で長さを制限することはできないのです。
MovingAverages.mqhで 計算すると、とても速い です。
 
forexman77:
MovingAverages.mqhで 計算を行うと、非常に早く計算 できます。
また、このライブラリは、すべての配列の計算ではなく、最後の部分(現在の値)のみの計算を設定した場合、正しく計算されるのでしょうか?それに、問題の半分に過ぎませんが、iBandsOnArrayはどうでしょう。
 
Sergey Efimenko:
だから私にコードの "作業 "バリアントを示して、元のコードはここにある、あなたは私が要求した300の代わりに12表示要素にカットしようとしている、少なくとも300要素が地下に表示されたように、指定されたデータで3指標バッファを終了する必要があります。そして、新しいバーが来ると、それぞれ、301とその値が描画されますが、この場合、0を計算のリミットとすると、新しいバーだけが再計算されることと、2番目のバッファの平均(スムージング)の種類は、必ずしもSMAとは限らず、4種類用意されているうちのどれでもいいことを忘れないでください。

お待たせしました。

//+------------------------------------------------------------------+
//|                                         Test300AsSeriesFalse.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   int i, limit;
   limit = rates_total-prev_calculated-1;
   double buffer[];

   for(i = limit; i >= 0; i--)
     {
      Buffer[i]=open[i];
       ArrayCopy(buffer, Buffer, 0, i, 12);
      BufferMA[i] = iMAOnArray(buffer, 300, 12, 0, MODE_SMA, 0);
      BufferBMA[i] = iBandsOnArray(buffer, 300, 12, 2.0, 0, MODE_UPPER, 0);
      int x=0;
     }
   return(rates_total);
}
//+------------------------------------------------------------------+