Author: Copyright 2019, Nikolay Semko
0 Views
0 Downloads
0 Favorites
MA-map
ÿþ//+------------------------------------------------------------------+

//|                                                       MA-map.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2019, Nikolay Semko"

#property link      "https://www.mql5.com/ru/users/nikolay7ko"

#property link      "SemkoNV@bk.ru"  

#property version   "1.02"

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

#property indicator_chart_window

#property indicator_plots   1

#property indicator_buffers 1



double  Close[];

long Total;

int Ma=0;

int stepMa=1;

int Size=0;

bool Z=false;

//+------------------------------------------------------------------+

//|                                                                  |

//+---------------------------------1---------------------------------+

int OnInit()

  {

   Comment("");

   ChartSetInteger(0,CHART_FOREGROUND,true);

   Ma=W.Height;

   Size=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[])

  {

   if(rates_total!=prev_calculated)

     {

      Size=CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);

      if(Ma>=Size) Ma=Size-1;

      if(Size>=W.BarsInWind) nMA();

     }

   return(rates_total);

  }

//+------------------------------------------------------------------+

//| ChartEvent function                                              |

//+------------------------------------------------------------------+

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

  {

   bool Z2=Z;

   if(sparam=="44") Z=~Z;

   if(Z2) if(!Z) nMA();

   if(Z && id==CHARTEVENT_MOUSE_MOVE) nMA();

   if(id==CHARTEVENT_CHART_CHANGE)

     {

      Ma=W.Height;

      Size=CopyClose(_Symbol,_Period,(int)W.Right_bar,W.BarsInWind+Ma-1,Close);

      if(Ma>=Size) Ma=Size-1;

      if(Size>=W.BarsInWind) nMA();

     }

  }

//+------------------------------------------------------------------+



void nMA()

  {

   Canvas.Erase();

//ulong t= GetMicrosecondCount();

   double S=0;

   double A[];

   double A1[];

   ArrayResize(A,W.BarsInWind);

   ArrayResize(A1,W.BarsInWind);

   for(int i=Size-1;i>=Size-Ma; i--) S+=Close[i];

   for(int Per=Ma;Per>0;)

     {

      double s=S;

      int j=0;

      for(int i=Size-1; i>=0;i--)

        {

         double Y=s/Per;

         j=Size-1-i;

         if(j<W.BarsInWind) A[j]=Y; else break;

         if(i-Per>=0) s=s+Close[i-Per]-Close[i]; else break;

        }

      DrawIndicatorLine(A,Per);

      if(Z && Per==W.MouseY) ArrayCopy(A1,A);;

      for(j=0; j<stepMa; j++) if(Per>0) {S=S-Close[Size-Per]; Per--;} else break;

     }

   if(Z) 

     {

      DrawIndicatorLine2(A1);

      Canvas.TextPosition(W.MouseX+10,W.MouseY-18);

      Canvas.Comm("Period MA = "+string(W.MouseY));

     }

//t=GetMicrosecondCount()-t;

//Print("2@5<O D>@<8@>20=8O 87>1@065=8O: "+(string)t+" <8:@>A5:C=4");

   Canvas.Update();

  }

//+------------------------------------------------------------------+



void DrawIndicatorLine(double &arr[],int per,int barStart=INT_MIN,int barEnd=INT_MAX)

  {

//static double max=INT_MIN;

//static double min=INT_MAX;

   if(barStart<W.Right_bar) barStart=Floor(W.Right_bar);

   if(barEnd>W.Left_bar) barEnd=W.Left_bar;

   if(W.Left_bar<=barStart) return;

   double B[];

   ArrayResize(B,W.BarsInWind);

   for(int i=1; i<W.BarsInWind;i++) B[i]=arr[i]-arr[i-1];

   double max=B[ArrayMaximum(B,1)]; //if (Max>max) max=Max;

   double min=B[ArrayMinimum(B,1)]; //if (Min<min) min=Min;

   max=fmax(max,-min);

   int n=barEnd-barStart;

   int x=(int)Canvas.X((double)barStart);

   int y=per-1;

   x-=W.dx_pix;

   for(int i=1; i<n; i++,x-=W.dx_pix)

     {

      uchar G=(B[i]>0)?uchar(Round(255.0*B[i]/max)):0;

      uchar R=(B[i]<0)?uchar(Round(-255.0*B[i]/max)):0;

      uchar b=0;

      if(W.Color!=0)

        {

         if(R>0) { G=255-R; b=G; R=255;}

         else if(G>0) { R=255-G; b=R; G=255;} else {R=255; b=255; G=255;}

        }

      uint clr;

      if(Z) if(per==W.MouseY) clr=ARGB(255,G,R,b); else clr=ARGB(70,G,R,b); else clr=ARGB(255,G,R,b);

      if(W.dx_pix>1) Canvas.LineHorizontal(x,x+W.dx_pix,y,clr);

      else Canvas.PixelSet(x,y,clr);

     }

  }

//+------------------------------------------------------------------+



void DrawIndicatorLine2(double &arr[],int barStart=INT_MIN,int barEnd=INT_MAX,int shift=0)

  {

   if(barStart<W.Right_bar) barStart=Floor(W.Right_bar);

   if(barEnd>W.Left_bar) barEnd=W.Left_bar;

   if(W.Left_bar<=barStart) return;

   double B[];

   ArrayResize(B,W.BarsInWind);

   for(int i=1; i<W.BarsInWind;i++) B[i]=arr[i]-arr[i-1];

   double max=B[ArrayMaximum(B,1)];

   double min=B[ArrayMinimum(B,1)];

   max=fmax(max,-min);

   int n=barEnd-barStart;

   barStart+=shift;

   barEnd+=shift;

   int x=(int)Canvas.X((double)barStart);

   int pre_y=Round(Canvas.Y(arr[0]));

//Canvas.PixelSet(x,pre_y,clr);

   x-=W.dx_pix;

   for(int i=1; i<n; i++,x-=W.dx_pix)

     {

      int y=Round(Canvas.Y(arr[i]));

      uchar G=(B[i]>0)?uchar(Round(255.0*B[i]/max)):0;

      uchar R=(B[i]<0)?uchar(Round(-255.0*B[i]/max)):0;

      uchar b=0;

      if(W.Color!=0)

        {

         if(R>0) { G=255-R; b=G; R=255;}

         else if(G>0) { R=255-G; b=R; G=255;} else {R=255; b=255; G=255;}

        }

      uint clr=ARGB(255,G,R,b);

      if(fabs(y-pre_y)>1 || W.dx_pix>1) Canvas.Line(x,y,x+W.dx_pix,pre_y,clr);

      else Canvas.PixelSet(x,y,clr);

      pre_y=y;

     }

  }

//+------------------------------------------------------------------+

Comments