Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 1900

 
Vitaly Muzichenko #:


Das ist der beste Weg, dies zu tun.
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 kreisförmigen Puffer zu verwenden, der sich die aktuelle Position des ersten Elements merkt?

Was für eine geniale Idee! Wer hat sie erfunden und wie wird sie praktisch angewendet? Ich bezweifle, dass es ausschließlich für Schiebefensterdiagramme verwendet wird...

 
Mihail Matkovskij #:

Was für eine geniale Idee! Wer hat sie erfunden und wie wird sie praktisch angewendet? Ich bezweifle, dass es ausschließlich für Schiebefensterdiagramme verwendet wird...

Es ist zwar nicht unvernünftig, zu wissen, wie viele Daten man zurücksetzen kann. Da dieser Ringspeicher aufgrund seiner begrenzten Länge "sich selbst auf die Füße tritt"...

 
Mihail Matkovskij #:
Das ist der beste Weg, dies zu tun.

Ich habe es überprüft, ja, es ist eine gute Lösung - ich behalte es.

Aber ich möchte noch überprüfen, obArrayCopy funktioniert

---

Ich habe mich für diesen Weg entschieden, weil es nicht schön ist, das Diagramm abzureißen:

#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 Ringspeicher verwenden, der die aktuelle Position des ersten Elements speichert?

Im Beispiel von Vitali können Sie diese Idee verwenden. Aber es gibt keine Möglichkeit, die Schleife zu vermeiden (was für sie entscheidend ist). In jedem Fall müssen wir die Daten mit Hilfe der Schleife oder der Funktion ArrayCopy vom Ringpuffer in den Indikatorpuffer übertragen. Und was wird sich ändern?

 
Mihail Matkovskij #:

Was für eine geniale Idee! Wer hat sie erfunden und wie wird sie praktisch angewendet? Ich bezweifle, dass es ausschließlich für Schiebefensterdiagramme verwendet wird...

Wer hat sich das ausgedacht - ein Ende ist nicht in Sicht, ich glaube, es wurde schon oft neu erfunden, die Idee ist ziemlich offensichtlich.

Ich verwende es zum Beispiel, um den gleitenden Durchschnitt von Daten zu berechnen, die nicht in der Historie gespeichert sind, sondern nur einen Momentanwert haben.

Dies wird seit jeher bei der Datenübertragung verwendet.

 
Mihail Matkovskij #:

Im Beispiel von Vitali können Sie diese Idee verwenden. Aber es gibt keine Möglichkeit, die Schleife zu vermeiden (was für sie entscheidend ist). In jedem Fall müssen wir die Daten mit Hilfe der Schleife oder der Funktion ArrayCopy vom Ringpuffer in den Indikatorpuffer übertragen. Und was wäre anders?

So kann ein neuer Wert eingefügt und sofort an die gewünschte Stelle kopiert werden. Der Kopierzyklus bleibt bestehen, aber es gibt keinen Verschiebezyklus.

 
Vitaly Muzichenko #:

Ich habe es überprüft, ja, es ist eine gute Lösung - ich behalte es.

Aber ich würde gerne noch überprüfen, wieArrayCopy funktioniert.

Mit ArrayCopy können Sie nur Daten von einem anderen Array übertragen. Aber man kann sie nicht verschieben. Sie können einen Ringpuffer verwenden und Daten daraus verschieben... Aber wie kann man das mitArrayCopy machen, wenn es eine kreisförmige Bewegung hat... Das verstehe ich nicht. Und im Prinzip muss es auch nicht verstanden werden. Die übliche Verschiebung mit einer Schleife ist nicht so entscheidend für die Geschwindigkeit. Zumindest weiß ich nicht, ob es schneller geht. Was kann schneller sein, nur Assembler? Wie auch immer, lassen Sie es so, wie es ist. Es wird funktionieren.

 
JRandomTrader #:

Dass ein neuer Wert sofort an der richtigen Stelle eingefügt und kopiert werden kann. Der Kopierzyklus bleibt bestehen, aber es gibt keinen Verschiebezyklus.

Nehmen wir ein Beispiel, es wäre in der

Der Code für die Aufrüstung lautet

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

Mit ArrayCopy können Sie nur Daten von einem anderen Array übertragen. Aber es ist nicht möglich, sie zu verschieben. Sie können einen Ringspeicher verwenden und Daten daraus übertragen... Aber wie macht man das mitArrayCopy, wenn es eine kreisförmige Bewegung hat... Das verstehe ich nicht. Und im Prinzip muss es auch nicht verstanden werden. Die übliche Verschiebung mit einer Schleife ist nicht so entscheidend für die Geschwindigkeit. Zumindest weiß ich nicht, ob es schneller geht. Was könnte schneller sein, Assembler? Wie auch immer, lassen Sie es so, wie es ist. Es wird funktionieren.

Im Moment funktioniert der Code, aber die Geschwindigkeit ist wegen der Schleife fragwürdig.

Was wird es sein?

Ich möchte einige Küchen für Arbitrage-Fähigkeit zu testen, wird der Indikator die Differenz der Werte zeichnen, läuft auf einen Timer einmal alle 100ms. Verzögerungen bei der Codeausführung sind in dieser Situation kritisch.