Expert Advisors • Indicators • Scripts • Libraries

MQL.RobotFX.org is the biggest collection of MetaTrader expert advisors (MT5 & MT4), indicators, scripts and libraries that can be used to improve trading results, minimize risks or simply automate trading tasks

MetaTrader 4 Libraries | Easy Canvas (iCanvas)

The library and iCanvas class simplify writing programs using Canvas.

Here is an example of a simple indicator using this library.

In this example, the indicator body features no function for processing OnChartEvent events. But it may also be present.

MetaTrader Experts, Indicators, Scripts and Libraries

MetaTrader Experts, Indicators, Scripts and Libraries

#property indicator_chart_window #property strict #include <Canvas\iCanvas.mqh> //+------------------------------------------------------------------+ int OnInit()   {    EventSetMillisecondTimer(30);    ChartSetInteger(0,CHART_CROSSHAIR_TOOL,false);  // turn off the crosshair    return(INIT_SUCCEEDED);   }  void OnDeinit(const int reason) {if(reason<2) {ChartSetInteger(0,CHART_CROSSHAIR_TOOL,true); ChartRedraw();}} //+------------------------------------------------------------------+ void  OnTimer()   {    static int X=0;    static int Y=0;    if(X!=W.MouseX || Y!=W.MouseY)      {       Canvas.Erase(0);       // Draw a blurry spot       for(int ix=-20;ix<=20;ix++) for(int iy=-20;iy<=20;iy++)         {          double p=sqrt(ix*ix+iy*iy)/20.0;          if(p>1) p=1;          uchar P=(uchar)Round((1.0-p)*255.0);          Canvas.PixelSet(W.MouseX+ix,W.MouseY+iy,ARGB(P,100,0,200));         }       //  Display the information block       int Y1=(int)Canvas.Y(Canvas.Close(W.MouseX));  // Y coordinate - Close price at the location of the mouse pointer.       Canvas.FillRectangle(W.MouseX,Y1,W.MouseX+140,Y1+67,0xA0808080);       Canvas.TextPosition(W.MouseX+5,Y1+2);       Canvas.CurentFont("Arial",14,16,clrWhite);       Canvas.Comm("Close = "+DoubleToString(Canvas.Close(W.MouseX),_Digits));       Canvas.Comm("Bar = "+DoubleToString(W.MouseBar,2));       Canvas.Comm(TimeToString(W.MouseTime,TIME_DATE|TIME_SECONDS));       Canvas.Comm("SubWindow = "+string(W.MouseSubWin));       //  Crosshairs       Canvas.LineHorizontal(0,W.Width-1,W.MouseY,~W.Color);       Canvas.LineVertical(W.MouseX,0,W.Height-1,~W.Color);       int Ym=(W.MouseY>W.Height/2)?(W.MouseY-16):(W.MouseY+2);       int Xm=(W.MouseX< W.Width/2)?(W.MouseX+4):(W.MouseX-105);       Canvas.TextOut(W.Width-50,Ym,DoubleToString(W.MousePrice,_Digits),~W.Color);       Canvas.TextOut(Xm,W.Height-16,TimeToString(W.MouseTime,TIME_DATE|TIME_SECONDS),~W.Color);        Canvas.Update();       X=W.MouseX; Y=W.MouseY;      }   } //+------------------------------------------------------------------+ int OnCalculate(const int rates_total,                 const int prev_calculated,                 const int begin,                 const double &price[])   {    return(rates_total);   }

struct Window: 

struct Window   {    long              ChartId;     // current window identifier    uint              Color;       // window background color    int               Width;       // window width    int               Height;      // window height    int               height[];    // sub_windows height    int               Left_bar;    // number of the leftmost bar in the window    double            Right_bar;   // number of the rightmost bar in the window    double            Total_bars;  // the maximum number of bars in the window    int               BarsInWind;  // number of visible bars in the window    double            Y_min;       // The minimum value of the price in the window    double            Y_max;       // The maximum value of the price in the window    double            dy_pix;      // price change for one pixel    int               dx_pix;      // changing the number of bars per pixel    int               MouseX;      // coordinate X of the current position of the mouse pointer    int               MouseY;      // coordinate Y of the current position of the mouse pointer    double            MouseBar;    // the current bar position of the mouse pointer     double            MousePrice;  // the current price of the mouse pointer    datetime          MouseTime;   // the current time of the mouse pointer    int               MouseSubWin; // number of the subwindow in which the mouse pointer is located    int               WindowsTotal;// total subwindows, including the main window    int               SubWin;      // current subwindow    datetime          time[];      // array of opening time of all visible bars in the window   };

iCanvas class:

class iCanvas : public CCanvas   { private:    datetime          T[1];    double            Pr[1];    bool              FullWinCanvW; // using full window canvas by width    bool              FullWinCanvH; // using full window canvas by height public:                      iCanvas(long chart_id=0,int Xpos=0,int Ypos=0,string Name="iCanvas",int width=0,int height=0,ENUM_COLOR_FORMAT formatCF=COLOR_FORMAT_ARGB_NORMALIZE,int subwin=-1);                     ~iCanvas() { Destroy(); ChartRedraw();};    double            X(double bar){return((double)W.Left_bar-bar)*W.dx_pix;}; //The X coordinate by the bar number. The bar number must be of type double, otherwise, the bar will be interpreted as time.    double            X(datetime Time);                                        //The X coordinate by the time.    double            Y(double Price) {if(W.dy_pix==0) W.dy_pix=1; return((W.Y_max-Price)/W.dy_pix); }; //The Y coordinate by the price.    double            Price(int y)     {return (W.Y_max-y*(W.Y_max-W.Y_min)/W.Height);};       // Price by the Y coordinate    double            Bar(int x) {return((double)W.Left_bar+1-(double)x/(double)W.dx_pix);};   // bar number by coordinate X                                                                          datetime          TimePos(int x);                                                          // time by coordinate X     double            Close(int x)     {CopyClose(_Symbol,_Period,int(Bar(x)),1,Pr); return Pr[0];};    double            Open(int x)      {CopyOpen(_Symbol,_Period,int(Bar(x)),1,Pr); return Pr[0];};    double            High(int x)      {CopyHigh(_Symbol,_Period,int(Bar(x)),1,Pr); return Pr[0];};    double            Low(int x)       {CopyLow(_Symbol,_Period,int(Bar(x)),1,Pr); return Pr[0];};    bool              FullWinCanvWidth()  {return FullWinCanvW;};                              // using full window canvas by width      bool              FullWinCanvHeight() {return FullWinCanvH;};                              // using full window canvas by height       void              Comm(string text) {TextOut(TextPosX,TextPosY,text,TextColor); TextPosY+=StepTextLine;}; // Print comment    void              TextPosition(int x,int y) {TextPosX=x; TextPosY=y;};                                    // Setting the XY position for comment output in pixels    void              CurentFont(string FontName="Courier New",int size=18,int LineStep=20,color clr=clrDarkOrchid,double transp=1.0);  // Set font options for comment. LineStep - step between lines. transp - transparency from 0 to 1                                                                                                                                            void              TextPosition(double x,double y); // Setting the XY position for outputting comments as a percentage of the width and height of the window    void              Line(double x1,double y1,double x2,double y2,const uint clr);    int               TextPosX;      // Position X for comment text    int               TextPosY;      // Position Y for comment text    int               StepTextLine;  // line spacing for comment    uint              TextColor;     // Font color for comment    ENUM_PROGRAM_TYPE ProgType;    int               SubWin;    long              Handle;   };

If you do not need an instance of the Canvas class for the full window, you can delete it and (or) change it to a partial window.

For example:

delete Canvas; Canvas= new iCanvas(0,0,"iCanvas",300,0);          // Only the left bar of a window 300 pixels wide is created. Resizing the window is controlled // Canvas= new iCanvas(0,0,"iCanvas",0,300);       // Only the top bar of a window height of 300 pixels is created. Resizing the window is controlled // Canvas= new iCanvas(200,100,"iCanvas",300,300); // A square of 300x300 pixels is created with a starting point at (200,100). Window resizing is not controlled.

You can also create new instances of the class and initialize them at the time of creation.

For example:

iCanvas C2(300,200,"Canvas2",200,150,COLOR_FORMAT_XRGB_NOALPHA,1);

Important note: Since by default, the color format with transparency COLOR_FORMAT_ARGB_NORMALIZE is used, then when specifying the color, you must take into account the high byte of transparency.

If you use color names, for example, clrRed, then the color will be absolutely transparent because the transparency byte will be 0.

Therefore, you must use the ColorToARGB function (for example, ColorToARGB (clrRed))

or specify the color explicitly with non-zero transparency:

-for example, 0xFFAABBCC (Hexadecimal color representation),

where:

FF -byte of transparency,

AA - is red bytes,

BB - is green bytes,

CC - is blue bytes.

P.S.: This library was developed for MQL5 and ported from MQL5 code. Therefore, for MQL4 it is not optimal.

MQL5 version is much faster.

23840