La toile est cool ! - page 20

 
Anatoli Kazharski:

Il y a une limite. Il est possible de créer jusqu'à 512 tampons indicateurs >>>https://www.mql5.com/ru/docs/indicators

Merci.
Oui, en plus de la longueur du code, des centaines de tampons d'indicateurs seraient un terrible gaspillage de mémoire. Ma variante utilise un tableau avec la dimension suivante : nombre de barres à l'écran + période maximale.
 
Nikolai Semko:

Un indicateur ultra-rapide de centaines de moyennes mobiles, implémenté sur Canvas.

100 lignes MA (pas de période 10) - temps de calcul et d'affichage à l'écran - 4-7 millisecondes


1000 lignes MA (période étape 1) - temps de calcul et d'affichage - 20-30 millisecondes.


Je n'ai pas trop testé le code. Il peut y avoir des bugs. Implémenté seulement pour une barre d'un pixel d'épaisseur (elle est forcée à cette échelle). Le taux de rafraîchissement de l'écran n'est pas non plus optimisé. Toutes les lignes sont calculées et entièrement sorties à chaque tick.

Comme on l'a compris, la moyenne est simple ? Je ferais maintenant la même chose pour l'exponentiel.

 
Dmitry Fedoseev:

Comment savez-vous que la moyenne est simple ? Maintenant, feriez-vous la même chose pour une exponentielle ?

Il ne s'agit que d'un exemple de démonstration. Tous les types de MA peuvent être mis en œuvre. Tout ce dont vous avez besoin est votre désir et votre nécessité. Le code deviendra un peu plus complexe avec l'expotentiel. Je vous suggère de l'essayer.
 

Pour illustrer la vitesse...

Modification de deux paramètres à l'aide du pointeur de la souris

X - modifications de la période maximale de l'AMM

Y - étape du changement de période MA


#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
#property indicator_chart_window

double  Close[];
long Total;
int Ma=0;
int stepMa=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   ChartSetInteger(0,CHART_SCALE,0,0);
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
   Total=SeriesInfoInteger(_Symbol,_Period,SERIES_BARS_COUNT);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
  {
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   static int MaOld=-1,stepMaOld=-1;
   Ma=W.MouseX+100;
   stepMa=W.MouseY;
   if(stepMa<=0) stepMa=1;
   stepMa=1+stepMa/10;
   if(stepMa>Ma) stepMa=Ma-1;
   if(id==CHARTEVENT_CHART_CHANGE || MaOld!=Ma || stepMaOld!=stepMa)
     {
      ChartSetInteger(0,CHART_SCALE,0,0);
      CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);
      nMA();
      MaOld=Ma; stepMaOld=stepMa;
     }
  }
//+------------------------------------------------------------------+

void nMA()
  {
   int preY=0;
   Canvas.Erase();
   double S=0;
   for(int i=0;i<Ma; i++) S+=Close[i];

   for(int Per=Ma;Per>0;)
     {
      double s=S;
      uint Clr=Grad((double)Per/Ma);
      for(int x=0; x<W.BarsInWind;x++)
        {
         int Y=(int)(Canvas.Y(s/Per)-0.5);
         if(x>0) if(fabs(Y-preY)>1) Canvas.Line(x-1,preY,x,Y,Clr);
         else Canvas.PixelSet(x,Y,Clr);
         if((Ma+x)<ArraySize(Close)) s=s-Close[x+Ma-Per]+Close[Ma+x]; else break;
         preY=Y;
        }
      for(int j=0; j<stepMa; j++) if(Per>0) {S=S-Close[Ma-Per]; Per--;} else break;
     }
   Canvas.Update();
  }
//+------------------------------------------------------------------+
uint Grad(double p)
  {
   static uint Col[6]={0xFF0000FF,0xFFFF00FF,0xFFFF0000,0xFFFFFF00,0xFF00FF00,0xFF00FFFF};
   if(p>0.9999) return Col[5];
   if(p<0.0001) return Col[0];
   p=p*5;
   int n=(int)p;
   double k=p-n;
   argb c1,c2;
   c1.clr=Col[n];
   c2.clr=Col[n+1];
   return ARGB(255,c1.c[2]+uchar(k*(c2.c[2]-c1.c[2])+0.5),
                   c1.c[1]+uchar(k*(c2.c[1]-c1.c[1])+0.5),
                   c1.c[0]+uchar(k*(c2.c[0]-c1.c[0])+0.5));
  }
//+------------------------------------------------------------------+
Dossiers :
MultiMA.mq5  8 kb
 
Nikolai Semko:

Pour illustrer la vitesse...

Modification de deux paramètres à l'aide du pointeur de la souris

X - modifications de la période maximale de l'AMM

Y - changement d'échelon de la période MA


Sympa, mais le compilateur explose

can't open "..\MQL5\Include\Canvas\iCanvas.mqh" include file    MultiMA.mq5     9       11
 
Aleksey Vyazmikin:

C'est beau, mais le compilateur est en train de combattre

La bibliothèque doit être installée, bien sûr. Il y a un lien vers cette bibliothèque dans le code.
 
Nikolai Semko:
La bibliothèque doit être installée, bien sûr. Il y a un lien vers cette bibliothèque dans le code.

Merci ! Tout fonctionne !

Comment faire pour que l'indicateur se redessine/déplace lorsque je redessine/déplace le graphique ?

 
Aleksey Vyazmikin:

Merci ! Tout fonctionne !

Comment faire pour que l'indicateur se redessine/se déplace lorsque le graphique est redessiné/déplacé ?

C'est comme ça que ça marche.
 
Nikolai Semko:
C'est ainsi que le redécoupage fonctionne.

Le mien ne fonctionne que lorsque la souris est en mouvement.

 
Aleksey Vyazmikin:

Le mien ne fonctionne que lorsque je bouge la souris.

Oui, il y avait un petit bug. Je l'ai corrigé.

Merci pour cela.

Raison: