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

 
fxsaber:
単一フィールドを持つユニオンは不思議なものです。

これは構造体と同じで、エラーがより明白になるだけです。それについては、ドキュメントにも「そうでなければ ユニオンは 構造体として動作する」と書かれているほどです。

Unioncharもおかしいし、わかりやすくするためでもありますが、書き直せばいいんです。

union X3 { //(3) Error: 'X2' - struct is too large
        char x31[INT_MAX/2+1];
        int  x32[INT_MAX/8+1];
};
だから、誰にとっても不思議なことではないと思うんです。
 
Andrey Dik:

をもう一度考えてみてください。

考えるんだ、アンドレイ。ゴキブリがいるのは、あなたのコードの中なんです。

まあ、今日はそんな気分なので...良い方向へ推し進めようと思います。

新しいバーが 開かれ、iBars()が1つ増えました...... しかし、カウントされたバーの数は変わっていません。そして、この新しいバーを再計算するまで変わらない...。

次はどうする?

 
Igor Makanu:

というのは、インジケータでは正しく動作しないはずです。

もし私が間違っていなければ、ヘルプにすべてのTFのデータをページングするスクリプトの内訳があり、インジケータが非同期に動作するため、この方法でインジケータから履歴データを要求することができないという警告があるはずです。

で、ハンドルをバインドした後に BarsCalculated() を一度使うことが推奨されています。


UPD: ヒストリーページング用スクリプトと、インディケータで動作しない理由の説明: https://www.mql5.com/ru/docs/series/timeseries_access

コードの意味を理解していますか?

 
Alexey Viktorov:

考えるんだ、アンドレイ。ゴキブリがいるのは、あなたのコードの中です。

まあ、今日はそんな気分なので...良い方向へ推し進めようと思います。

新しいバーが 開かれ、iBars()が1つ増えた......が、カウントされたバーの数は変わっていない。そして、この新しいバーを再計算するまで変わらない...。

次はどうする?

my good man, please don't write to me, you are not in the loop.

あるいはコードで証明する。

 
Andrey Dik:

コードの意味を理解していますか?

高い確率で - 確実に、理解できる

他のインジケータを呼び出す前に、「上位のTF」を同期させたい場合

私のインジケーターは動くんでしょう?- あなたはそれにBarsCalculated()を追加することができます - しかし、配信から指標の例のように、例えば、MACD.mql5


HH: QBにはたくさんのマルチタイムフレームインジケーターがありますが、何をどうすればいいのか覚えたいときは、いつもMladen Rakicのインディケーターを検索して、彼のものに目を通します。

https://www.mql5.com/ru/users/mladen

 
Andrey Dik:

Dear.さんは、輪に入れないので、書き込まないでください。

またはコードで証明する。

それなら、ふつーに...。

開発者は、そのような無意味なことに反応しないでください、イゴールはすぐに退屈します... そして、滞在し、自分自身に話してください...

ただ、適切なスレッドを乱雑にしないために、あなたの暴言を別のスレッドに移動するようにドラマーに頼んでください......。

 

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

バグ、バグ、質問

アンドレイ・ディク 2021.05.28 05:16

要求されたタイムフレーム(M5)のデータ同期と その上のインジケータの準備をチェックしようとしています、もし準備ができていなければ終了します。

その結果、このインジケータはM1バーのオープン時に一度だけ動作し、毎ティックで動作するわけではありません。


//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

//проверка на наличие нового бара
if (rates_total == prev_calculated) return rates_total;

開発者の方々には、私の訴えを聞いてほしい。

あなたのコードがよくわからないのですが。次のOnCalculateの呼び出しで、"return 0; "の後はどうすればよいのでしょうか?
 
Alexey Viktorov:

イゴールもすぐに飽きるだろうし...。

ただ、理解したいという欲求がある

MT5では同期に多くの落とし穴があり、今回はその点についても質問させていただきました。

インジケータが各バーでコンストラクション(矢印ではなく線)を使用する場合、イミホ

このサイクルは、経済的な計算には十分です。

for(int i = prev_calculated; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }

最初の呼び出しがあった場合、prev_calculated は = 0 となり、それ以降の呼び出しでは新しいバーが再計算されます。


そして、両方のインジケータが正しく書かれていれば、追加で何かを同期させる必要はなく、すべてが機能します。唯一残っているのは、CopyBuffer()と呼び出されたインジケータの必要な値の数を比較することです。

 
Igor Makanu:

ただ、それを理解したいだけなんです。

MT5では同期に多くの落とし穴があり、今回はその点についても質問させていただきました。

インジケータが各バーで構築(矢印でなく線)を使用する場合、イミホ

このサイクルは、経済的な計算には十分です。

最初の呼び出しがあった場合、prev_calculated は = 0 となり、それ以降の呼び出しでは新しいバーが再計算されます。


そして、両方のインジケータが正しく書かれていれば、追加で何かを同期させる必要は なく、すべてが機能します。唯一残っているのは、CopyBuffer()と呼び出されたインジケータの必要な値の数を比較することです。

そういうことなんです。初回実行前にシンクロを試みてもいいのですが、こうしてみると......ですね。

 
Igor Makanu:

ただ、それを理解したいだけなんです。

MT5では同期に多くの落とし穴があり、今回はその点についても質問させていただきました。

インジケータが各バーにコンストラクション(矢印ではなく線)を使用する場合、IMOは

このサイクルは、経済的な計算には十分です。

最初の呼び出しがあった場合、prev_calculated は = 0 となり、それ以降の呼び出しでは新しいバーが再計算されます。


そして、両方のインジケータが正しく書かれていれば、追加で何かを同期させる必要はなく、すべてが動作します。唯一残っているのは、CopyBuffer()と呼び出されたインジケータの必要な値の数を比較することです。

もし、反対しないで理解したいのであれば、以下のコードのようなものを書くべきです。

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double         IBuffer[];

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   return(INIT_SUCCEEDED);
}

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 (rates_total == prev_calculated) return rates_total;
   
   ulong t = GetMicrosecondCount ();
   
   ArraySetAsSeries (high,        true);

   int limit = rates_total - prev_calculated - 1;

   for (int i = limit; i >= 0; i--)
   {
      IBuffer [i] = high [i];
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, рассчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

//--- plot I
#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input ENUM_TIMEFRAMES  OldTF = PERIOD_M5;

double IBuffer[];
int    Handle = 0;

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   Handle = iCustom (Symbol (), OldTF, "OldTF.ex5");
   if (Handle == INVALID_HANDLE)
   {
      Print ("Не удалось получить хендл индикатора OldTF.ex5");
      return INIT_FAILED;
   }

   return INIT_SUCCEEDED;
}

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 (rates_total == prev_calculated) return rates_total;

   if (SeriesInfoInteger (Symbol (), OldTF, SERIES_SYNCHRONIZED))
   {
      if (iBars (Symbol (), OldTF) != BarsCalculated (Handle))
      {
        Print ("Индикатор на периоде ", OldTF, " ещё не рассчитан");
        return 0;
      }
   }
   else 
   {
     Print ("Период ", OldTF, " не синхронизирован.");
     return 0;
   }

   ulong t = GetMicrosecondCount ();

   ArraySetAsSeries (high, true);
   ArraySetAsSeries (time, true);

   int limit = rates_total - prev_calculated - 1;

   double buff [];
   int ind = 0;
   for (int i = limit; i >= 0; i--)
   {
      ind = iBarShift (Symbol (), OldTF, time [i], false);
      if (CopyBuffer (Handle, 0, ind, 1, buff) != -1)
      {
        IBuffer [i] = buff [0];
      }
      else
      {
        Print ("Ошибка копирования буфера ", GetLastError ());
        return 0;
      }
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, расcчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}

両方のコードをコンパイルして、2番目のコードを実行します。シニアインジケータのM1とM3で実行すると、ログに次のようなものが表示されます。

2021.05.28 19:05:01.408 OldTF (EURUSD,M3) 0.000234 sec, 50000 bars calculated, 50000 bars total

2021.05.28 19:05:03.860 LitTF (EURUSD,M1) 0.007452 sec, 50023 bars calculated, 50023 bars total

2021.05.28 19:06:00.670 OldTF (EURUSD,M3) 0.000001 sec, calculated 1 bar, total bars 50001

2021.05.28 19:06:02.211 LitTF (EURUSD,M1) 0.008180 sec, 50024 bars calculated, 50024 bars total

2021.05.28 19:07:00.780 LitTF (EURUSD,M1) 0.000004 sec, calculated 1 bar, total bars 50025

2021.05.28 19:08:01.246 LitTF (EURUSD,M1) 0.000014 sec, settled 1 bar, total bars 50026

2021.05.28 19:09:00.959 OldTF (EURUSD,M3) 0.00000014 sec, calculated 1 bars, total bars 50002

2021.05.28 19:09:01.775 LitTF (EURUSD,M1) 0.006898 sec, 50027 bars calculated, total 50027 bars

2021.05.28 19:10:00.830 LitTF (EURUSD,M1) 0.000004 sec, calculated 1 bar, total bars 50028

肉眼で見ても、第一に高速なインジケータを構築する最速の方法、第二に事前計算がゼロになっていることがわかります。

この例では、新しいバーM3ごとにインジケータが完全に再計算されることを強制しています。

Alexey Viktorov:

まあ、やらなくてもいいんですけどね。

開発者はそんなくだらないことに反応してはいけない、イゴールもすぐに飽きてしまう...そしてここにいて独り言を言うんだ...。

ただ、drubashkaさんにお願いして、あなたの吐露を別スレッドに移動してもらい、右のスレッドを乱雑にしないようにする必要があります...。

上のコードを見て、パスポートを食べ、頭に灰を振りかけ、その傲慢さを誰にも見えないところに押し込めてください。