Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 1900

 
Vitaly Muzichenko #:


Voici la meilleure façon de le faire.
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 tampon circulaire, en se souvenant de la position actuelle du premier élément ?

Quelle idée géniale ! Qui en a eu l'idée et quelle est son application pratique ? Je doute qu'il soit utilisé exclusivement pour les graphiques à fenêtre coulissante...

 
Mihail Matkovskij #:

Quelle idée géniale ! Qui l'a inventé et quelle est son application pratique ? Je doute qu'il soit utilisé exclusivement pour les graphiques à fenêtre coulissante...

Il est vrai qu'il n'est pas déraisonnable de savoir combien de données vous pouvez récupérer. Parce que ce tampon circulaire "marche sur ses propres pieds", en raison de sa longueur limitée...

 
Mihail Matkovskij #:
Voici la meilleure façon de le faire.

J'ai vérifié, oui c'est une bonne solution - je la garde.

Mais je voudrais quand même vérifier siArrayCopy fonctionne

---

J'ai décidé de le faire de cette façon, car ce n'est pas agréable de déchirer le graphique :

#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 tampon en anneau se souvenant de la position actuelle du premier élément ?

Dans l'exemple de Vitali, vous pouvez utiliser cette idée. Mais il n'y a aucun moyen d'éviter la boucle (qui est critique pour elle). Dans tous les cas, nous devons transférer les données du tampon circulaire au tampon indicateur en utilisant la boucle ou la fonction ArrayCopy. Et qu'est-ce qui va changer ?

 
Mihail Matkovskij #:

Quelle idée géniale ! Qui en a eu l'idée et quelle est son application pratique ? Je doute qu'il soit utilisé exclusivement pour les graphiques à fenêtre coulissante...

Qui l'a inventé - pas de fin en vue, je pense qu'il a été réinventé plusieurs fois, l'idée est assez évidente.

Je l'utilise, par exemple, pour calculer la moyenne mobile de données qui ne sont pas stockées dans l'historique, mais qui ont seulement une valeur instantanée.

Elle est utilisée dans la transmission de données depuis des temps immémoriaux.

 
Mihail Matkovskij #:

Dans l'exemple de Vitali, vous pouvez utiliser cette idée. Mais il n'y a aucun moyen d'éviter la boucle (qui est critique pour elle). Dans tous les cas, nous devons transférer les données du tampon circulaire au tampon indicateur en utilisant la boucle ou la fonction ArrayCopy. Et qu'est-ce qui serait différent ?

Il est possible d'insérer une nouvelle valeur et de la copier immédiatement à l'endroit souhaité. Le cycle de copie demeure, mais il n'y a pas de cycle de décalage.

 
Vitaly Muzichenko #:

J'ai vérifié, oui c'est une bonne solution - je la garde.

Mais j'aimerais quand même vérifier comment fonctionneArrayCopy.

Avec ArrayCopy, vous ne pouvez transférer des données qu'à partir d'une autre matrice. Mais vous ne pouvez pas les déplacer. Vous pouvez utiliser un tampon en anneau et déplacer les données depuis celui-ci... Mais comment le faire avecArrayCopy s'il a un mouvement circulaire... Je ne comprends pas. Et, en principe, il n'a pas besoin d'être compris. Le déplacement habituel utilisant une boucle n'est pas si critique en termes de vitesse. En tout cas, je ne connais pas de plus rapide. Qu'est-ce qui peut être plus rapide, seulement l'assembleur ? Quoi qu'il en soit, laissez-le comme il est. Ça va marcher.

 
JRandomTrader #:

Pour qu'une nouvelle valeur puisse être insérée et copiée immédiatement à l'endroit correct. Le cycle de copie demeure, mais il n'y a pas de cycle de décalage.

Donnons un exemple, il s'agirait de l'

Le code pour la mise à niveau est

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

Avec ArrayCopy, vous ne pouvez transférer des données qu'à partir d'une autre matrice. Mais il n'est pas possible de les déplacer. Vous pouvez utiliser un tampon circulaire et transférer des données à partir de celui-ci... Mais comment le faire avecArrayCopy s'il a un mouvement circulaire... Je ne comprends pas. Et, en principe, il n'a pas besoin d'être compris. Le déplacement habituel utilisant une boucle n'est pas si critique en termes de vitesse. En tout cas, je ne connais pas de plus rapide. Qu'est-ce qui pourrait être plus rapide, l'assembleur ? Quoi qu'il en soit, laissez-le comme il est. Ça va marcher.

Actuellement, le code fonctionne, mais la vitesse est discutable à cause de la boucle.

Qu'est-ce que ça va être ?

Je veux tester quelques cuisines pour la capacité d'arbitrage, l'indicateur va dessiner la différence de valeurs, fonctionne sur un timer une fois toutes les 100ms. Les délais d'exécution du code sont critiques dans cette situation.