Possibilities of Canvas. - page 2

 
Marco vd Heijden:


Hey thats prety good :D

Will MetaQuotes take over the Gaming Community ?

I hope so ,hahahaha .

 
Lorentzos Roussos:

Exceptional work .
I assume you were looking for a faster gradient display which lead to this :).

Cool! Thank you. Very creative!

But about the speed of the gradient, you probably joked? :))

This version works 40-50 times faster

   union RGB {uint clr; uchar c[4];};
   RGB C;   
   C.c[3]=255;
   C.c[0]=(uchar)start_blue;
   for(int y=0;y<screen_y;y++)
     {
      C.c[2]=(uchar)start_red; C.c[1]=(uchar)start_green; 
      SkyMatrix.LineHorizontal(0,screen_x-1,y,C.clr);
      s_red-=s_step;
      s_green-=s_step;
      start_red=s_red;
      start_green=s_green;
     }

 than yours:

   for(int y=0;y<screen_y;y++)
     {
      or_color=start_red+","+start_green+","+start_blue;
      g_color=StringToColor(or_color);
      sky_color=ColorToARGB(g_color,255);
      //loop to x pixels 
      for(int x=0;x<screen_x;x++)
        {
         SkyMatrix.PixelSet(x,y,sky_color);
        }
      s_red=s_red-s_step;
      s_green=s_green-s_step;
      start_red=s_red;
      start_green=s_green;
     }
2018.09.10 16:34:09.041 SuperMario2 EURUSD,M5: Time Filling fast = 315 microseconds
2018.09.10 16:34:09.039 SuperMario2 EURUSD,M5: Time Filling slow = 14848 microseconds
Files:
SuperMario2.mq4  11 kb
 
Nikolai Semko:

Cool! Thank you. Very creative!

But about the speed of the gradient, you probably joked? :))

This version works 40-50 times faster

 than yours:

I meant yours is faster , reffering to the first post :) 

 
Lorentzos Roussos:

I meant yours is faster , reffering to the first post :) 

Oops! Then it's clear.  :))

 

Flame from DOOM...

The algorithm was taken as a basis from this site with minor modifications.


Files:
Flame2.mq5  8 kb
 

Forum on trading, automated trading systems and testing trading strategies

Canvas is cool!

Nikolai Semko , 2019.02.14 08:49

Ultra-fast indicator of hundreds of moving averages, implemented on the Canvas.

100 MA lines (period step 10) - calculation and display time - 4-7 milliseconds


1000 MA lines (period step 1) - calculation and display time - 20-30 milliseconds


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

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input int MA= 1000 ;   // максимальный период скользящих средних
input int stepMa= 10 ; // шаг скользящих средних

double    Close [];
uint Col[ 6 ]={ 0xFFFF0000 , 0xFFFF00FF , 0xFF0000FF , 0xFF00FFFF , 0xFF00FF00 , 0xFFFFFF00 };
long Total;
int Ma;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit ()
  {
   ChartSetInteger ( 0 , CHART_EVENT_MOUSE_MOVE , true );
   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 );
   if (Total<(MA+W.BarsInWind)) Ma=( int )Total- 1 -W.BarsInWind; else Ma=MA;
   if (Ma<= 0 ) Ma= 1 ;
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total, const int prev_calculated, const int begin, const double &price[])
  {
   CopyClose ( _Symbol , _Period ,( int )W.Right_bar,W.BarsInWind+Ma- 1 , Close );
   Print ( "Время формирования кадра = " +( string )(nMA()/ 1000 )+ " миллискунд" );
   return (rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent ( const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   if (id== CHARTEVENT_CHART_CHANGE )
     {
       ChartSetInteger ( 0 , CHART_SCALE , 0 , 0 );
       CopyClose ( _Symbol , _Period ,( int )W.Right_bar,W.BarsInWind+Ma- 1 , Close );
       Print ( "Время формирования кадра = " +( string )(nMA()/ 1000 )+ " миллискунд" );
     }

  }
//+------------------------------------------------------------------+

ulong nMA()
  {
   ulong t= GetMicrosecondCount ();
   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();
   return GetMicrosecondCount ()-t;
  }
//+------------------------------------------------------------------+
uint Grad( double p)
  {
   p=p* 5 ;
   int n=( int )p;
   if (n== 5 ) return Col[ 5 ];
   double k= 1 -p+( int )p;
   argb c1,c2;
   c1.clr=Col[n]; 
   c2.clr=Col[n+ 1 ];
   return ARGB( 255 ,c2.c[ 0 ]+ uchar (k*(( int )c1.c[ 0 ]-( int )c2.c[ 0 ])+ 0.5 ),
                     c2.c[ 1 ]+ uchar (k*(( int )c1.c[ 1 ]-( int )c2.c[ 1 ])+ 0.5 ),
                     c2.c[ 2 ]+ uchar (k*(( int )c1.c[ 2 ]-( int )c2.c[ 2 ])+ 0.5 )); 
  }
//+------------------------------------------------------------------+

 
Nikolai Semko:

Thanks.
It is really great!



Files:
MultiMA.mq5  9 kb
 
Excellent work . Well done 
 
Lorentzos Roussos:
Excellent work . Well done 
Thanks. Another bonus is the fact that when using the canvas, the programs for mql5 and mql4 are almost the same.
 

Forum on trading, automated trading systems and testing trading strategies

Canvas is cool!

Nikolai Semko , 2019.02.15 22:39

For clarity, speed ...

Change two parameters through the mouse pointer

X - changes the maximum period of MA

Y - step change period 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 ]={ 0xFFFF0000 , 0xFFFF00FF , 0xFF0000FF , 0xFF00FFFF , 0xFF00FF00 , 0xFFFFFF00 };
   p=p* 5 ;
   int n=( int )p;
   if (n== 5 ) return Col[ 5 ];
   double k= 1 -p+( int )p;
   argb c1,c2;
   c1.clr=Col[n];
   c2.clr=Col[n+ 1 ];
   return ARGB( 255 ,c2.c[ 0 ]+ uchar (k*(( int )c1.c[ 0 ]-( int )c2.c[ 0 ])+ 0.5 ),
               c2.c[ 1 ]+ uchar (k*(( int )c1.c[ 1 ]-( int )c2.c[ 1 ])+ 0.5 ),
               c2.c[ 2 ]+ uchar (k*(( int )c1.c[ 2 ]-( int )c2.c[ 2 ])+ 0.5 ));
  }
//+------------------------------------------------------------------+

Files:
MultiMA.mq5  8 kb