La tela è forte! - pagina 20

 
Anatoli Kazharski:

C'è una limitazione. Si possono fare fino a 512 buffer di indicatori >>>https://www.mql5.com/ru/docs/indicators

Grazie.
Sì, oltre alla lunghezza del codice, centinaia di buffer di indicatori sarebbero un terribile spreco di memoria. La mia variante utilizza un array con dimensione: numero di barre sullo schermo + periodo massimo.
 
Nikolai Semko:

Un indicatore ultra-veloce di centinaia di medie mobili, implementato su Canvas.

100 linee MA (periodo passo 10) - tempo di calcolo e visualizzazione sullo schermo - 4-7 millisecondi


1000 linee MA (periodo passo 1) - tempo di calcolo e visualizzazione - 20-30 millisecondi.


Non ho testato troppo il codice. Potrebbero esserci dei bug. Implementato solo per le barre spesse un pixel (è forzato a questa scala). Anche la frequenza di aggiornamento dello schermo non è ottimizzata. Tutte le linee sono calcolate e completamente emesse ad ogni tick.

Come si capisce che la media è semplice? Ora farebbe lo stesso per l'esponenziale.

 
Dmitry Fedoseev:

Come fai a sapere che la media è semplice? Ora fareste lo stesso per un esponenziale?

Questo è solo un esempio dimostrativo. Tutti i tipi di MA possono essere implementati. Tutto ciò di cui avete bisogno è il vostro desiderio e la vostra necessità. Il codice diventerà un po' più complesso con l'expotential. Vi suggerisco di fare una prova.
 

Per illustrare la velocità...

Cambiare due parametri tramite il puntatore del mouse

X - modifiche al periodo massimo dell'AM

Y - passo del cambiamento del periodo 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));
  }
//+------------------------------------------------------------------+
File:
MultiMA.mq5  8 kb
 
Nikolai Semko:

Per illustrare la velocità...

Cambiare due parametri tramite il puntatore del mouse

X - modifiche al periodo massimo dell'AM

Y - cambio di passo del periodo MA


Bello, ma il compilatore esplode

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

È bello, ma il compilatore sta combattendo

La libreria deve essere installata, ovviamente. C'è un link a questa libreria nel codice.
 
Nikolai Semko:
La libreria deve essere installata, ovviamente. C'è un link a questa libreria nel codice.

Grazie! Funziona tutto!

Come faccio a far sì che l'indicatore venga ridisegnato/spostato quando il grafico viene ridisegnato/spostato?

 
Aleksey Vyazmikin:

Grazie! Funziona tutto!

Come faccio a far ridisegnare/spostare l'indicatore quando ridisegno/spostamento del grafico?

È il modo in cui funziona.
 
Nikolai Semko:
È così che funziona il ridisegno.

Il mio funziona solo quando il mouse è in movimento.

 
Aleksey Vyazmikin:

Il mio funziona solo quando muovo il mouse.

Sì, c'era un piccolo bug. Riparato.

Grazie per questo.