Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 1900

 
Vitaly Muzichenko #:


Ecco il modo migliore per farlo.
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 un buffer circolare, ricordando la posizione attuale del primo elemento?

Che idea geniale! Chi l'ha inventato e qual è la sua applicazione pratica? Dubito che sia usato esclusivamente per i grafici a finestra scorrevole...

 
Mihail Matkovskij #:

Che idea geniale! Chi l'ha inventato e qual è la sua applicazione pratica? Dubito che sia usato esclusivamente per i grafici a finestra scorrevole...

È vero, non è irragionevole sapere quanti dati si possono rollbackare. Perché questo buffer circolare si sta "pestando i piedi", a causa della sua lunghezza limitata...

 
Mihail Matkovskij #:
Ecco il modo migliore per farlo.

L'ho controllato, sì, è una buona soluzione - lo tengo.

Ma vorrei comunque controllare seArrayCopy funziona

---

Ho deciso di farlo in questo modo, perché non è bello strappare il grafico:

#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 un ring buffer che ricorda la posizione corrente del primo elemento?

Nell'esempio di Vitali, si può usare questa idea. Ma non c'è modo di evitare il ciclo (che è fondamentale per esso). In ogni caso, dobbiamo trasferire i dati dal ring buffer al buffer indicatore usando il ciclo o la funzione ArrayCopy. E cosa cambierà?

 
Mihail Matkovskij #:

Che idea geniale! Chi l'ha inventato e qual è la sua applicazione pratica? Dubito che sia usato esclusivamente per i grafici a finestra scorrevole...

Chi l'ha inventato - non c'è fine in vista, penso che sia stato reinventato molte volte, l'idea è abbastanza ovvia.

Io, per esempio, lo uso per calcolare la media mobile di dati che non sono memorizzati nella storia, ma hanno solo un valore istantaneo.

Questo è stato utilizzato nella trasmissione dei dati da tempo immemorabile.

 
Mihail Matkovskij #:

Nell'esempio di Vitali, si può usare questa idea. Ma non c'è modo di evitare il ciclo (che è fondamentale per esso). In ogni caso, dobbiamo trasferire i dati dal ring buffer al buffer indicatore usando il ciclo o la funzione ArrayCopy. E cosa sarebbe diverso?

Che un nuovo valore può essere inserito e immediatamente copiato dal posto desiderato. Il ciclo di copia rimane, ma non c'è il ciclo di spostamento.

 
Vitaly Muzichenko #:

L'ho controllato, sì, è una buona soluzione - lo tengo.

Ma vorrei comunque controllare come funzionaArrayCopy.

Con ArrayCopy, potete solo trasferire dati da un altro array. Ma non potete spostarli. Puoi usare un ring buffer e spostare i dati da esso... Ma come si può fare conArrayCopy se ha un movimento circolare... Non capisco. E, in linea di principio, non ha bisogno di essere compreso. Lo spostamento abituale utilizzando un ciclo non è così critico in termini di velocità. Almeno, non ne conosco di più veloci. Cosa può essere più veloce, solo l'assemblatore? Comunque, lasciatelo così com'è. Funzionerà.

 
JRandomTrader #:

Che un nuovo valore può essere inserito e copiato immediatamente dal posto giusto. Il ciclo di copia rimane, ma non c'è il ciclo di spostamento.

Facciamo un esempio, sarebbe nel

Il codice per l'aggiornamento è

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

Con ArrayCopy, potete solo trasferire dati da un altro array. Ma non è possibile spostarli. Si può usare un buffer circolare e trasferire dati da esso... Ma come farlo conArrayCopy se ha un movimento circolare... Non capisco. E, in linea di principio, non ha bisogno di essere compreso. Lo spostamento abituale utilizzando un ciclo non è così critico in termini di velocità. Almeno, non ne conosco di più veloci. Cosa potrebbe essere più veloce, l'assemblatore? Comunque, lasciatelo così com'è. Funzionerà.

Al momento il codice funziona, ma la velocità è discutibile a causa del loop.

Che cosa sarà?

Voglio testare alcune cucine per la capacità di arbitraggio, l'indicatore disegnerà la differenza di valori, funziona su un timer una volta ogni 100ms. I ritardi nell'esecuzione del codice sono critici per questa situazione.