MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 1900

 
Vitaly Muzichenko #:


ここでは、その方法をご紹介します。
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 H=100;
  double b, a;
  if(prev_calculated==0) {
    ArrayInitialize(Buffer1,EMPTY_VALUE);
    ArrayInitialize(Buffer2,EMPTY_VALUE);
  }

  b=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  a=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

  if(rates_total-prev_calculated==1) {
    Buffer1[H+1]=EMPTY_VALUE;
    Buffer2[H+1]=EMPTY_VALUE;
  }
  else if (rates_total == prev_calculated) { // сдвигаем данные только когда количество баров не поменялось (в случае появления нового бара они сдвигаются системой терминала)
    for(int j=H; j>0; j--) { 
      Buffer1[j]=Buffer1[j-1];
      Buffer2[j]=Buffer2[j-1];
    }
  }
  // записываем новые данные
  Buffer1[0]=b;
  Buffer2[0]=a;
  return(rates_total);
}
 
JRandomTrader 循環バッファとして 使用し、最初の要素の現在位置を記憶させるのはどうでしょうか。

なんて素晴らしいアイデアなんだ誰が考え出し、どのように実用化したのか。スライディングウィンドウチャート専用に使われているのか疑問ですが...。

 
Mihail Matkovskij #:

なんて素晴らしいアイデアなんだ誰が考え出し、どのように実用化したのか。スライディングウィンドウチャート専用に使うのはどうかと思いますが...。

確かに、ロールバックできるデータの量を知っておくことは無理なことではありません。この円形バッファーは、長さが限られているため、「自分の足で踏んでいる」ことになるからです...。

 
Mihail Matkovskij #:
ここでは、その方法をご紹介します。

この製品は、私が所有することになりました。

しかし、ArrayCopyが 機能するかどうかを確認したい。

---

グラフをちぎるのは気持ち悪いので、この方法にしました。

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_label1  "Bid"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_label2  "Ask"

double Buffer1[];
double Buffer2[];
int H;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
{
  SetIndexBuffer(0,Buffer1);
  ArraySetAsSeries(Buffer1,true);
  SetIndexBuffer(1,Buffer2);
  ArraySetAsSeries(Buffer2,true);
  ArrayInitialize(Buffer1,EMPTY_VALUE);
  ArrayInitialize(Buffer2,EMPTY_VALUE);
  IndicatorSetInteger(INDICATOR_DIGITS,Digits());
  IndicatorSetString(INDICATOR_SHORTNAME,"Tick:");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
{
  H=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
  if(prev_calculated==0) {
    ArrayInitialize(Buffer1,EMPTY_VALUE);
    ArrayInitialize(Buffer2,EMPTY_VALUE);
  }

  double b=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  double a=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

  if(rates_total-prev_calculated==1) {
    Buffer1[H+1]=EMPTY_VALUE;
    Buffer2[H+1]=EMPTY_VALUE;
  } else if(rates_total == prev_calculated) { // сдвигаем данные только когда количество баров не поменялось (в случае появления нового бара они сдвигаются системой терминала)
    for(int j=H; j>0; j--) {
      Buffer1[j]=Buffer1[j-1];
      Buffer2[j]=Buffer2[j-1];
    }
  }
// записываем новые данные
  Buffer1[0]=b;
  Buffer2[0]=a;
  return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // идентификатор события
                  const long& lparam,   // параметр события типа long
                  const double& dparam, // параметр события типа double
                  const string& sparam  // параметр события типа string
                 )
{
  if(id==CHARTEVENT_CHART_CHANGE) {
    H=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
    int B=Bars(Symbol(),0);
    for(int j=H; j<B; j++) {
      Buffer1[j]=EMPTY_VALUE;
      Buffer2[j]=EMPTY_VALUE;
    }
  }
}
//+------------------------------------------------------------------+
 
JRandomTrader リングバッファとして 使用する場合はどうでしょうか。

Vitaliの例では、このような考え方ができるのです。しかし、(それにとって重要な)ループを回避する方法はないのです。いずれにしても、ループやArrayCopy関数を使って、リングバッファからインジケータバッファにデータを転送する必要があります。そして、何が変わるのか?

 
Mihail Matkovskij #:

なんて素晴らしいアイデアなんだ誰が考え出し、どのように実用化したのか。スライディングウィンドウチャート専用に使うのはどうかと思いますが...。

誰が考え出したのか......キリがない、何度も再発明されていると思う、発想は至極当然である。

私などは、履歴が残らない、瞬間的な値しかないデータの移動平均を計算するのに使っています。

古くからデータ通信に利用されている。

 
Mihail Matkovskij #:

Vitaliの例では、このような考え方ができるのです。しかし、(それにとって重要な)ループを回避する方法はないのです。いずれにしても、ループやArrayCopy関数を使って、リングバッファからインジケータバッファにデータを転送する必要があります。そして、何が違うのでしょうか?

新しい値を挿入して、すぐに目的の場所からコピーできること。コピーサイクルは残りますが、シフトサイクルはありません。

 
Vitaly Muzichenko #:

この製品は、私が所有することになりました。

ただ、やはりArrayCopyの 動作は確認したいですね。

ArrayCopyでは、他のアレイからのデータ転送のみ可能です。でも、ずらすことはできません。リングバッファを使い、そこからデータをシフトする...。でも、円運動があるのに、どうやってArrayCopyで やるんだ...。理解できない。そして、原則的に理解する必要はありません。ループを使った通常の変位は、速度の面ではそれほど重要ではありません。少なくとも、私はもっと早いのを知らない。もっと速いのはアセンブラだけ?とにかく、そのままにしておいてください。きっとうまくいく。

 
JRandomTrader #:

新しい値を挿入して、正しい位置からすぐにコピーできること。コピーサイクルは残りますが、シフトサイクルはありません。

例をあげれば、それは

バージョンアップ用の コードは

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2022.02.13
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...
 
Mihail Matkovskij #:

ArrayCopyでは、他のアレイからのデータ転送のみ可能です。しかし、それをずらすことはできない。円形バッファを使い、そこからデータを転送する...。でも、ArrayCopyで円運動がある場合、どうしたらいいのか...。理解できない。そして、原則的に理解する必要はありません。ループを使った通常の変位は、速度の面ではそれほど重要ではありません。少なくとも、私はもっと早いのを知らない。もっと速いのはアセンブラか?とにかく、そのままにしておいてください。うまくいくよ。

今現在、コードは動作していますが、ループがあるためスピードに疑問があります。

どうするんですか?

アービトラージ用のキッチンをテストしたいのですが、インジケータは値の差を描画し、100msごとにタイマーで実行されます。このような状況では、コードの実行遅延は致命的です。