Author: Semko Nikolai
Price Data Components
0 Views
0 Downloads
0 Favorites
Arc
ÿþ//+------------------------------------------------------------------+

//|                                                          Arc.mq5 |

//|                                                    Semko Nikolai |

//|                         https://www.mql5.com/ru/users/nikolay7ko |

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



#property copyright "Semko Nikolai"

#property version   "1.00"



#include <Canvas\Canvas.mqh>

#property indicator_chart_window

#property indicator_buffers 2

#property indicator_plots   2

//--- plot ArcUp

#property indicator_label1  "ArcUp"

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrMediumOrchid

#property indicator_style1  STYLE_SOLID

#property indicator_width1  3

//--- plot ArcDown

#property indicator_label2  "ArcDown"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrDodgerBlue

#property indicator_style2  STYLE_SOLID

#property indicator_width2  3

//--- indicator buffers



double         ArcUpBuffer[];

double         ArcDownBuffer[];

double         A1,B1,C1,D1,A2,B2,C2,D2;

CCanvas        C;

int            click=0;

int Width;

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

//| Custom indicator initialization function                         |

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

int ButW=60;

int ButR=20;

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

//|                                                                  |

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

int OnInit()

  {

   ArraySetAsSeries(ArcUpBuffer,true);

   ArraySetAsSeries(ArcDownBuffer,true);

   SetIndexBuffer(0,ArcUpBuffer,INDICATOR_DATA);

   SetIndexBuffer(1,ArcDownBuffer,INDICATOR_DATA);

   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);

   ArrayInitialize(ArcUpBuffer,EMPTY_VALUE);

   ArrayInitialize(ArcDownBuffer,EMPTY_VALUE);

   ChartSetInteger(0,CHART_BRING_TO_TOP,false);

   Width=(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  

      if(!C.CreateBitmapLabel("ArcButton",Width-ButW-10,10,ButW,ButW,COLOR_FORMAT_ARGB_NORMALIZE))

        { Print("Error creating canvas: ",GetLastError()); return(-1); }

   DrawButton(C,ButW,ButR,clrViolet,80);

   return(INIT_SUCCEEDED);

  }

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

//|                                                                  |

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

void OnDeinit(const int reason)

  {

   ArrayInitialize(ArcUpBuffer,EMPTY_VALUE);

   ArrayInitialize(ArcDownBuffer,EMPTY_VALUE);

   C.Destroy();

  }

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

//| Custom indicator iteration function                              |

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

int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

  {

//---

   if(prev_calculated>0) if(prev_calculated<rates_total && click==4)

     {

      for(int i=(rates_total-prev_calculated-1); i>=0;i--)

        {

         D1-=2*C1;

         ArcUpBuffer[i]=ArcUpBuffer[i+1]-D1;

         D2-=2*C2;

         ArcDownBuffer[i]=ArcDownBuffer[i+1]-D2;

        }

     }

   return(rates_total);

  }

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

//| ChartEvent function                                              |

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

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

  {

   static datetime t;

   static double y=0;

   static int bar=0;

   static int window=0;

   static double Y[5];

   static int Bar[5];

   static bool editUp=false;

   static bool editDown=false;

   static uchar editN=0;

   static bool In=false;

   static int rad=ButR;

   int i;



   if(id==CHARTEVENT_CLICK)

     {

      if(In)

        {

         click=0;

         ArrayInitialize(ArcUpBuffer,EMPTY_VALUE);

         ArrayInitialize(ArcDownBuffer,EMPTY_VALUE);

        }

      else

        {

         if(click==4)

           {

            if(editUp)

              {

               editUp=false;

               PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);

               PlotIndexSetInteger(0,PLOT_LINE_WIDTH,3);

               ChartRedraw();

              }

            else if(editDown)

              {

               editDown=false;

               PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID);

               PlotIndexSetInteger(1,PLOT_LINE_WIDTH,3);

               ChartRedraw();

              }

            else

              {

               ChartXYToTimePrice(0,(int)lparam,(int)dparam,window,t,y);

               if(t!=0) bar=Bars(NULL,0,t,3200000000);

               double y_pix=5*(ChartGetDouble(0,CHART_PRICE_MAX)-ChartGetDouble(0,CHART_PRICE_MIN))/ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);

               if(fabs(y-ArcUpBuffer[bar])<y_pix)

                 {

                  editUp=true;

                  PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_DOT);

                  PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);

                  ChartRedraw();

                  if(fabs(bar-Bar[0])<6) editN=0; else if((Bar[2]+3)>bar) editN=2; else editN=1;

                 }

               if(fabs(y-ArcDownBuffer[bar])<y_pix)

                 {

                  editDown=true;

                  PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_DOT);

                  PlotIndexSetInteger(1,PLOT_LINE_WIDTH,1);

                  ChartRedraw();

                  if(fabs(bar-Bar[0])<4) editN=0; else if((Bar[2]+3)>bar) editN=2; else editN=1;

                 }

              }

           }

         if(click<4)

           {

            Y[click]=y;

            Bar[click]=bar;

            click++;

           }



        }

     }

   if(id==CHARTEVENT_MOUSE_MOVE && lparam>=0 && dparam>=0)

     {

      if(lparam>(Width-ButW-20) && dparam<(ButW+20))

        {

         In=true;

         double dist=sqrt(pow(Width-10-ButW/2-lparam,2)+pow(10+ButW/2-dparam,2));

         if(dist<ButR*1.5)

           {

            rad=(int)(ButR+0.5*ButR*(1-dist/(ButR*1.5)));

            uchar tr=(uchar)(80+(255-50)*(1-dist/(ButR*1.5)));

            if(tr<80) tr=255;

            DrawButton(C,ButW,rad,clrViolet,tr);

           }

        }

      else

        {

         In=false;

         if(rad!=ButR) { DrawButton(C,ButW,ButR,clrViolet,80); rad=ButR;}

        }

      if(click<4 || editUp || editDown) 

        {

         ChartXYToTimePrice(0,(int)lparam,(int)dparam,window,t,y);

         if(t!=0) bar=Bars(NULL,0,t,3200000000);

         if(click<3)

           {

            Y[click]=y;

            Bar[click]=bar;

           }

         if(click==1 && Bar[1]<Bar[0])

           {

            if(Bar[1]>Bar[0]) { Bar[2]=Bar[1]; Bar[1]=Bar[0]; Bar[0]=Bar[2];Y[2]=Y[1]; Y[1]=Y[0]; Y[0]=Y[2];}

            D1=0;

            if(Bar[0]!=Bar[1]) D1=(Y[0]-Y[1])/(Bar[0]-Bar[1]);

            ArrayInitialize(ArcUpBuffer,EMPTY_VALUE);

            ArcUpBuffer[Bar[1]]=Y[1];

            if(Bar[0]>Bar[1]) for( i=Bar[1]+1; i<=Bar[0]; i++) ArcUpBuffer[i]=ArcUpBuffer[i-1]+D1;

            ChartRedraw();

           }

         if((click==2 && Bar[2]<Bar[1]) || editUp)

           {

            if(editUp) {Bar[editN]=bar; Y[editN]=y;}

            double zn=(Bar[2]*Bar[2]-Bar[1]*Bar[1])*(Bar[0]-Bar[2])-(Bar[2]*Bar[2]-Bar[0]*Bar[0])*(Bar[1]-Bar[2]);

            if(zn!=0)

              {

               C1=((Y[0]-Y[2])*(Bar[1]-Bar[2])-(Y[1]-Y[2])*(Bar[0]-Bar[2]))/zn;

               B1=(Y[1]-Y[2]+C1*(Bar[2]*Bar[2]-Bar[1]*Bar[1]))/(Bar[1]-Bar[2]);

               A1=Y[2]-B1*Bar[2]-C1*Bar[2]*Bar[2];

               ArrayInitialize(ArcUpBuffer,EMPTY_VALUE);

               ArcUpBuffer[0]=A1;

               D1=B1+C1;

               for(i=1; i<=Bar[0]; i++)

                 {

                  ArcUpBuffer[i]=ArcUpBuffer[i-1]+D1;

                  D1+=2*C1;

                 }

               ChartRedraw();

               D1=B1+C1;

               A2=A1; B2=B1; C2=C1;

              }

           }

         if(click==3 || editDown)

           {

            ArrayInitialize(ArcDownBuffer,EMPTY_VALUE);

            A2=A1-ArcUpBuffer[bar]+y;

            ArcDownBuffer[0]=A2;

            D2=B2+C2;

            for(i=1; i<=Bar[0]; i++)

              {

               ArcDownBuffer[i]=ArcDownBuffer[i-1]+D2;

               D2+=2*C2;

              }

            ChartRedraw();

            D2=B2+C2;

           }

        }

     }

  }

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



void DrawButton(CCanvas &Button,int X,int R,ulong clr,uchar alfa)

  {

   ulong col=ColorToARGB((color)clr,alfa);

   Button.Erase(0);

   Button.FillCircle(X/2,X/2,R,(color)col);

   int k1=(int)round((double)R/1.5);

   int k2=(int)round((double)R/5);

   int k3=(int)round((double)R/3);

   Button.Arc(X/2,X/2,k1-1,k1-1,M_PI/2,0,ColorToARGB(clrDarkCyan,220));

   Button.FillTriangle(X/2+k1,X/2-k3,X/2+k1-k2,X/2,X/2+k1+k2,X/2,ColorToARGB(clrDarkCyan,220));

   Button.Update();

  }

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---