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

 
アルチョム・トリシキン

ハイライトは 0を返すことができます。BCSが駆けつけた。

そう、悪徳ブローカーだ。マイナスの数字も入れてくるし。

ブローカーがシンボルを設定する際に、各パラメータの設定可能範囲の制限を開発者が設定できると良い。

 
アルチョム・トリシキン

具体的に何が問題なのでしょうか?ネイティブではないタイムフレームからインジケータデータを取得するために、私は何を間違えているのだろうか?という疑問でした。

例:M1でインジケータを動作させ、M5からAOのデータを取得する場合。そのため、limit>1(履歴の再計算が必要)でありながら、M5からのAOはデータエラーがなく、0を返します。履歴が計算されると同時に(limit=0)、AOからM5でデータが届き始める。

まず第一に、そのようなエントリーをする必要がないことです。

periodForWork=PeriodForWork;

最初は、変数に自分の値を代入しているのかと思いました。

次のページ

size_ao=CopyBuffer(handle_ao,0,0,count,array_ao);

初期化時にコピーする必要はありません。初期化はこのためではありません。また、OnInit()で要求した時点ではまだ計算されていない古いTFからのデータ要求では、このレコードは意味をなさない。

ArraySetAsSeries(BufferAO,true);

しかし、この記録は初期化段階で一度だけ行えば十分である。

さらに...そのということです。

に分けたいですね。

1.1本目(ヒストリー解析)。

2.その後の走り。

2.1.それぞれのティック

2.2.形成されたバー

すなわち

if( prev_calculated > 0 )             // Не первый запуск
{
 if( rates_total <= prev_calculated ) // Новый бар не сформирован
  {
  }
 else                                 // Новый бар сформирован
  {
  }
}
else                                  // Первый запуск
{
}

そして、その後に初めて、主な計算サイクル(機能)が発生する。

コピー機能で意味のないエラーが発生する。コードがイマイチ。

古いTFのデータの同期チェックはしていません。

そして、ここで最も重要なのは、その順番を理解することです。テスト用のインジケータを作成し、最初の起動時に主要なTFのデータのみを要求し、どのようにコピーされるかを理解することをお勧めします。つまり、コードの先頭からこれを削除することです。

ArraySetAsSeries(array_ao,true);

そして、配列の 最初と最後の要素をアンセットします。そして、必要な場合にのみ、インデックスの方向性を変更する。

 
とにかく、そこから始めてください。
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input   ENUM_TIMEFRAMES inpTimeframe=PERIOD_M5;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int _handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   _handle=iAO(_Symbol,inpTimeframe);
   if(_handle==INVALID_HANDLE)
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),"! Хэндл индикатора iAO ТФ "+EnumToString(inpTimeframe)+" не получен!");
      return( INIT_FAILED );
     }
//---
   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[])
  {
//--- Массив-приемник значений индикатора
   double ao[];
//---
   if(prev_calculated>0)
     {

     }
   else                                        // Если первый запуск
     {
      //--- Количество просчитанных баров старшего ТФ
      int bars;
      if(( bars=BarsCalculated(_handle))<0 || !(bool)SeriesInfoInteger(_Symbol,inpTimeframe,SERIES_SYNCHRONIZED))
         return( 0 );
      //--- 
      int num=CopyBuffer(_handle,0,0,bars,ao);
      //---
      if(num<0)
        {
         Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Запрашиваемая таймсерия еще не построена!");
         return( 0 );
        }
      else if(num!=bars)
        {
         Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Скопированы не все данные (",num," из ",bars,")");
         return( 0 );
        }
      //---
      Print(__FUNCTION__,": Успех! Скопировано ",num," из ",bars," значение индикатора АО ТФ "+EnumToString(inpTimeframe));
     }
//---
   return( rates_total );
  }
//+------------------------------------------------------------------+
 
アレクセイ・コジツィン

まず第一に、そのようなエントリーをする必要がないことです。

最初、変数に自分の値を代入しているのかと思いました。

次のページ

初期化時にコピーする必要はありません。初期化はこのためではありません。また、OnInit()で要求した時点ではまだ計算されていない古いTFからのデータ要求では、このレコードは意味をなさない。

しかし、この記録は初期化段階で一度だけ行えば十分である。

さらに...そのということです。

に分けたいですね。

1.1本目(ヒストリー解析)。

2.その後の走り。

2.1.それぞれのティック

2.2.形成されたバー

すなわち

そして、その後に初めて、主な計算サイクル(機能)が発生する。

コピー機能で意味のないエラーが発生する。コードがイマイチ。

古いTFのデータの同期チェックはしていません。

そして、ここで最も重要なのは、その順番を理解することです。テスト用のインジケータを作成し、最初の起動時に主要なTFのデータのみを要求し、どのようにコピーされるかを理解することをお勧めします。つまり、コードの先頭からこれを削除することです。

そして、配列の 最初と最後の要素をアンセットします。そして、必要な場合にのみ、インデックスの方向を変更する。

一目でわかるような変数を作っています。理解できないなら、理解できる方法で作ればいい ;)

私はいつも、グローバルでない変数は小さな文字で書き始めます。理由は簡単で、大文字と小文字を区別するからです...。

非テストコードでも十分大きいので、これはテストコードです。MT4では、トラフを切り替えても飛ぶし、データ不足のエラーもなく、すべてが常に存在します。しかし、MT5は、私は半分のためにだけmtfを切り替えると、履歴をロードし、その後、彼のTFではないデータで動作しません - 彼らの不在について述べています。

そのため、何が間違っているのかを議論したのです。その結果、initで使用する全てのクライアントのデータを要求する必要があることが判明しました。中古携帯の推定台数が事前に分からない場合は、全て依頼する必要があると思います。半分ずつしかカウントされません。全部で21個あるのですが...。

また何かあったんですか?

 
初心者の 方にはとても便利な機能です。

MT5では、etfを切り替えると履歴のダウンロードに半分しかかからない


それについて書いている

я правильно понимаю тогда, что подготовив кэш,терминал при последующих обращениях (начиная со 2 обращения) затрачивает на порядки меньше времени?

можно ли как-то уменьшить время первого обращения после перезагрузки терминала,чтобы было как в МТ4?
Теперь выводы:

    Разница только в скорости начальной инициализации кеша чарта 0.6 мс МТ4 против 113 мс у МТ5

詳しくはこちら

https://www.mql5.com/ru/forum/1111/page1871#comment_4866969

https://www.mql5.com/ru/forum/1111/page1871#comment_4867939

TFやシンボルを要求するほど、起動が遅くなります。

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • www.mql5.com
Форум алго-трейдеров MQL5
 
kaus_bonus さん


それについて書いている

詳しくはこちら

https://www.mql5.com/ru/forum/1111/page1871#comment_4866969

https://www.mql5.com/ru/forum/1111/page1871#comment_4867939

TFやキャラクターの数が多いほど、起動が遅くなります。

インジケーターを初めて起動した時だけ発生するようにすれば良いと思います。しかし、タイムフレームを切り替えると、切り替えのたびに30分ほど履歴が読み込まれています。そんなことしちゃいけないってわかってるんだけど...。何か間違っているような...。そして、1つのインディケータでのみ、ネイティブでないタイムフレームにアクセスしようとすると、それが起こります。
 
アルチョム・トリシキン
初めてインジケータを起動する時だけなら良いと思います。時間軸を切り替えるたびに履歴の読み込みが半端ない。そんなことしちゃいけないってわかってるんだけど...。何か間違っているような...。1つのインジケータのみで、ネイティブではないタイムフレームにアクセスしようとしています。

まあ、別の時間軸のデータをコピーする速度を測って、どこがボトルネックになっているのか見てください。
 
アルチョム・トリシキン

異なるTFから複数のインディケータを計算に使用する必要がある場合 - それぞれのTFのハンドルを取得する必要があります。

もし、より速くしたいのであれば、ターミナルのヒストリーのサイズを小さくしてください。

私のテスト用インジケータを実行しましたか?データを集めているのでしょうか?

 
アレクセイ・コジツィン

異なるTFから複数のインディケータを計算に使用する必要がある場合 - それぞれのTFのハンドルを取得する必要があります。

もし、より速くしたいのであれば、ターミナルのヒストリーのサイズを小さくしてください。

私のテスト用インジケータを実行しましたか?データを集めているのでしょうか?

いいえ、していません。

ALLタイムフレームが必要な場合、AOインジケータのハンドルを21個作成する必要があることがわかりました。もったいないと思いませんか?

 
アルチョム・トリシキン

いいえ、まだ実行していません。

ALLタイムフレームが必要な場合、21個のAOインジケーターハンドルを作成する必要があることがわかりました。もったいないと思いませんか?

他に正しいシンボル/TFからデータを取得するにはどうすればよいですか?CopyBufferは ハンドルでのみ動作します。
理由: