エラー、バグ、質問 - ページ 269

 
AndrNuda:
お前ら遅いな :)フォールスはファルスではなく、すべてが機能する。探す場所を間違えていますよ )))正しい機能があります。
スマート?
 
BoraBo:

ArrayIsSeries(High)が常にfalseになる原因を探っています。

この関数のヘルプには、次のように書かれています(https://www.mql5.com/ru/docs/array/arrayisseries)

戻り値

チェック対象の配列が時系列配列の場合は true、そうでない場合は false を返します。OnCalculate() のパラメータとして渡された配列は、ArrayGetAsSeries() で配列の要素にアクセスする順序をチェックする必要があります。

宣言した配列は時系列ではなく、どのような状況でも時系列になることはありません。時系列は、OnCalculate() 関数などでランタイムシステムによってあらかじめ定義される配列である。

int OnCalculate (const int rates_total,      // размер входных таймсерий
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const datetime& time[],     // Time
                 const double& open[],       // Open
                 const double& high[],       // High
                 const double& low[],        // Low
                 const double& close[],      // Close
                 const long& tick_volume[],  // Tick Volume
                 const long& volume[],       // Real Volume
                 const int& spread[]         // Spread
   )
Документация по MQL5: Операции с массивами / ArrayIsSeries
Документация по MQL5: Операции с массивами / ArrayIsSeries
  • www.mql5.com
Операции с массивами / ArrayIsSeries - Документация по MQL5
 
Rosh:

この関数のヘルプには、次のように書かれています(https://www.mql5.com/ru/docs/array/arrayisseries)

宣言した配列は時系列ではなく、どのような状況でも時系列になることはありません。時系列は、OnCalculate() 関数など、ランタイムであらかじめ定義された配列である。

ArrayGetAsSeriesが意図したとおりに動作しない。
 
AlexSTAL:
ArrayGetAsSeriesが意図したとおりに動作しない。
ArrayGetAsSeries 関数はインデックスの方向を変更するだけで、配列を時系列に変換することはありません。この機能で何を得ようとしているのでしょうか?
 
Rosh:
時系列は、OnCalculate() などで実行時に定義される配列です。
int OnCalculate (const int rates_total,      // размер входных таймсерий
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const datetime& time[],     // Time
                 const double& open[],       // Open
                 const double& high[],       // High
                 const double& low[],        // Low
                 const double& close[],      // Close
                 const long& tick_volume[],  // Tick Volume
                 const long& volume[],       // Real Volume
                 const int& spread[]         // Spread
   )


これについては、ヘルプに書いてある通りです。

Примечание

Для проверки массива на принадлежность к таймсерии следует применять функцию ArrayIsSeries(). Массивы ценовых данных, переданных в качестве входных параметров в функцию OnCalculate(), не обязательно имеют направление индексации как у таймсерий. Нужное направление индексации можно установить функцией ArraySetAsSeries().

 
joo:

これについては、ヘルプに書いてある通りです。


そのようなインジケータを走らせれば、自分の目で確認することができます。

//+------------------------------------------------------------------+
//|                                           CheckArrayIsSeries.mq5 |
//|                      Copyright © 2009, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void checkArray(const double & array[])
  {
   if(ArrayGetAsSeries(array))
     {
      Print("array can use as timeseria");
     }
     else
     {
      Print("array can not use as timeseria!!!");
     }
     
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if(ArrayIsSeries(open))
     {
      Print("open[] is timeseria");
      checkArray(open);
     }
   else
     {
        {
         Print("open[] is timeseria!!!");
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Rosh:
ArrayGetAsSeries 関数はインデックスの方向を変更するだけで、配列を時系列に変換することはありません。この機能で何を得ようとしているのでしょうか?

この機能は、変化ではなく、方向をチェック します。

1) 初期化なし

double Buf[];
void OnStart()
  {
   ArrayResize(Buf, 3);

   Print("ArrayGetAsSeries(Buf): ", ArrayGetAsSeries(Buf));             // ArrayGetAsSeries(Buf): false
   
   // Меняем направление на обратный порядок
   Print("Установка в true прошла: ", ArraySetAsSeries(Buf, true));     // Установка в true прошла: true
   Print("ArrayGetAsSeries(Buf): ", ArrayGetAsSeries(Buf));             // ArrayGetAsSeries(Buf): false
   
   // Меняем направление на прямой порядок
   Print("Установка в false прошла: ", ArraySetAsSeries(Buf, false));   // Установка в false прошла: true
   Print("ArrayGetAsSeries(Buf): ", ArrayGetAsSeries(Buf));             // ArrayGetAsSeries(Buf): false
  }

2)初期化あり

double Buf[];
void OnStart()
  {
   ArrayResize(Buf, 3);
   Buf[0] = 0; Buf[1] = 1; Buf[2] = 2;

   Print("ArrayGetAsSeries(Buf): ", ArrayGetAsSeries(Buf));             // ArrayGetAsSeries(Buf): false
   
   // Меняем направление на обратный порядок
   Print("Установка в true прошла: ", ArraySetAsSeries(Buf, true));     // Установка в true прошла: true
   Print("ArrayGetAsSeries(Buf): ", ArrayGetAsSeries(Buf), " [", Buf[0], ",", Buf[1], ",", Buf[2], "]"); // ArrayGetAsSeries(Buf): true [2,1,0]
   
   // Меняем направление на прямой порядок
   Print("Установка в false прошла: ", ArraySetAsSeries(Buf, false));   // Установка в false прошла: true
   Print("ArrayGetAsSeries(Buf): ", ArrayGetAsSeries(Buf), " [", Buf[0], ",", Buf[1], ",", Buf[2], "]"); // ArrayGetAsSeries(Buf): false [0,1,2]
  }

3) 上記コードのうち、ArrayGetAsSeries 関数で配列のインデックス方向を取得しているもののみ

double High[];
#include <Indicators\TimeSeries.mqh>
void OnStart()
  {
   Print("ArrayGetAsSeries(High) ",ArrayGetAsSeries(High));                   // ArrayGetAsSeries(High) false

   CiHigh z;

   int count=3;
   if(z.Create(_Symbol,_Period)==true)
     {
      if(z.GetData(0,count,High)==count)
        {
         for(int i=0; i<count; i++) Print(i,"=",High[i]);
         Print("ArraySetAsSeries(High,true) ",ArraySetAsSeries(High,true));   // ArraySetAsSeries(High,true) true
         Print("ArrayGetAsSeries(High) true = ",ArrayGetAsSeries(High));      // ArrayGetAsSeries(High) true = false
         for(int i=0; i<count; i++) Print(i,"=",High[i]);
         Print("ArraySetAsSeries(High,false) ",ArraySetAsSeries(High,false)); // ArraySetAsSeries(High,false) true
         Print("ArrayGetAsSeries(High) false = ",ArrayGetAsSeries(High));     // ArrayGetAsSeries(High) false = false
         for(int i=0; i<count; i++) Print(i,"=",High[i]);
        }
      else
         Print("Не удалось получить ",count," данных таймсерии.");
     }
   else Print("Ошибка создания таймсерии.");
   Print("ArrayGetAsSeries(High) ",ArrayGetAsSeries(High));                   // ArrayGetAsSeries(High) false
   Print("GetLastError() ",GetLastError());
  }
サービスデスクでは、関数名を間違えてしまいました。


 
Rosh:

そのようなインジケータを走らせれば、自分の目で確認することができます。

それは理解できる。また、私の質問はエラーについてではなく、すべてがヘルプに書かれているとおりに動作することでした。

Примечание

Для проверки массива на принадлежность к таймсерии следует применять функцию ArrayIsSeries(). Массивы ценовых данных, переданных в качестве входных параметров в функцию OnCalculate(), не обязательно имеют направление индексации как у таймсерий. Нужное направление индексации можно установить функцией ArraySetAsSeries().


ヘルプで強調されている色や太字と、おっしゃることが食い違うため、疑問が生じました。

ロッシュ
時系列は、OnCalculate() などの実行時に定義された配列です。

だからOnCalculate()でやっているんです。

    //--------------------------------------
    if (ArrayGetAsSeries(time)!=true)
      ArraySetAsSeries(time,true);
    if (ArrayGetAsSeries(open)!=true)
      ArraySetAsSeries(open,true);
    if (ArrayGetAsSeries(high)!=true)
      ArraySetAsSeries(high,true);
    if (ArrayGetAsSeries(low)!=true)
      ArraySetAsSeries(low,true);
    if (ArrayGetAsSeries(close)!=true)
      ArraySetAsSeries(close,true);
    //--------------------------------------
 
Rosh:

この関数のヘルプには、次のように書かれています(https://www.mql5.com/ru/docs/array/arrayisseries)

宣言した配列は時系列ではなく、どのような状況でも時系列になることはありません。時系列は、OnCalculate() 関数などであらかじめ定義された配列です。

インジケーターでもチェックが効きません。

//+------------------------------------------------------------------+
//|                                                    ind_proba.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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 count=3;
   int i=0;
   int limit;
//   bool printCom;

   if(prev_calculated>0)
     {
      limit=1;
     }
   else
     {
      Print("rates_total  ",rates_total,"  prev_calculated  ",prev_calculated);
      for(i=0; i<count; i++) Print(i,"=",open[i]);
      Print("ArraySetAsSeries(open,true) ",ArraySetAsSeries(open,true));
      Print("ArrayIsSeries(open) true = ",ArrayIsSeries(open));
      Print("ArrayGetAsSeries(open) true = ",ArrayGetAsSeries(open));
      for(i=0; i<count; i++) Print(i,"=",open[i]);
      Print("ArraySetAsSeries(open,false) ",ArraySetAsSeries(open,false));
      Print("ArrayIsSeries(open) false = ",ArrayIsSeries(open));
      Print("ArrayGetAsSeries(open) false = ",ArrayGetAsSeries(open));
      for(i=0; i<count; i++) Print(i,"=",open[i]);
     }
   Print("GetLastError() ",GetLastError());
//--- return value of prev_calculated for next call

   return(rates_total);
  }
//+------------------------------------------------------------------+

また、prev_calculatedは もう機能せず、常に0になって います。

 

そうですね、これらの機能については、すでに自分たちで整理していると思います。


しかし、私は忘れないように、願いとして - エディタで、3つまたは何文字を入力した後にプロンプトが表示されたとき、あなたがリストの最初の行に立ってクリックすると、リストから削除されません。ただ、スタジオと同じようにすでに慣れているので、スタジオと同じようにやらないと「うっとうしい」と思う人も多いのではないでしょうか。IMHO