Leinwand ist cool! - Seite 20

 
Anatoli Kazharski:

Es gibt eine Einschränkung. Es können bis zu 512 Anzeigepuffer erstellt werden >>>https://www.mql5.com/ru/docs/indicators

Ich danke Ihnen.
Ja, abgesehen von der Länge des Codes wären Hunderte von Indikatorpuffern eine schreckliche Verschwendung von Speicherplatz. Meine Variante verwendet ein Array mit der Dimension: Anzahl der Balken auf dem Bildschirm + maximale Periode.
 
Nikolai Semko:

Ein ultraschneller Indikator mit Hunderten von gleitenden Durchschnitten, implementiert auf Canvas.

100 MA-Zeilen (Periodenschritt 10) - Zeit der Berechnung und Anzeige auf dem Bildschirm - 4-7 Millisekunden


1000 MA-Zeilen (Periodenschritt 1) - Zeit für Berechnung und Anzeige - 20-30 Millisekunden.


Ich habe den Code nicht allzu sehr getestet. Es kann Fehler geben. Nur für einen Pixel dicken Balken implementiert (er wird zu diesem Maßstab gezwungen). Auch die Bildwiederholfrequenz ist nicht optimiert. Alle Zeilen werden berechnet und bei jedem Tick vollständig ausgegeben.

Wie verstanden ist der Durchschnitt einfach? Jetzt würde das gleiche für exponentielle tun.

 
Dmitry Fedoseev:

Woher wissen Sie, dass der Durchschnitt einfach ist? Würden Sie das auch für einen Exponentialwert tun?

Dies ist nur ein Demo-Beispiel. Alle Arten von MA können implementiert werden. Alles, was Sie brauchen, ist Ihr Wunsch und Ihr Bedürfnis. Der Code wird mit Expotential etwas komplexer werden. Ich schlage vor, Sie versuchen es einmal.
 

Zur Veranschaulichung der Geschwindigkeit...

Ändern von zwei Parametern über den Mauszeiger

X - Änderungen des maximalen MA-Zeitraums

Y - Schritt des MA-Periodenwechsels


#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));
  }
//+------------------------------------------------------------------+
Dateien:
MultiMA.mq5  8 kb
 
Nikolai Semko:

Zur Veranschaulichung der Geschwindigkeit...

Ändern von zwei Parametern über den Mauszeiger

X - Änderungen des maximalen MA-Zeitraums

Y - Schrittweite der MA-Periode


Nett, aber der Compiler stürzt ab

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

Es ist schön, aber der Compiler kämpft

Die Bibliothek muss natürlich installiert werden. Es gibt einen Link zu dieser Bibliothek im Code.
 
Nikolai Semko:
Die Bibliothek muss natürlich installiert werden. Es gibt einen Link zu dieser Bibliothek im Code.

Ich danke Ihnen! Es klappt alles!

Wie kann ich den Indikator neu zeichnen/verschieben, wenn das Diagramm neu gezeichnet/verschoben wird?

 
Aleksey Vyazmikin:

Ich danke Ihnen! Es klappt alles!

Wie bringe ich den Indikator dazu, sich neu zu zeichnen/zu verschieben, wenn das Diagramm neu gezeichnet/verschoben wird?

Das ist die Art und Weise, wie es funktioniert.
 
Nikolai Semko:
So funktioniert das Umzeichnen.

Meiner funktioniert nur, wenn sich die Maus bewegt.

 
Aleksey Vyazmikin:

Meine funktioniert nur, wenn ich die Maus bewege.

Ja, da war ein kleiner Fehler. Es wurde korrigiert.

Vielen Dank dafür.