PolarCoordinateSystem

Author: Copyright 2018, Nikolay Semko
0 Views
0 Downloads
0 Favorites
PolarCoordinateSystem
//+------------------------------------------------------------------+
//|                                        PolarCoordinateSystem.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                         https://www.mql5.com/en/users/nikolay7ko |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Nikolay Semko"
#property link      "https://www.mql5.com/ru/users/nikolay7ko"
#property link      "SemkoNV@bk.ru"
#property version   "1.00"
#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

double cl[];
datetime ti[];
int per;
double N=0.3;
bool day=false;
bool mouse=true;
double min, max;
int start=0;
iCanvas info(0,0,0,"iCanvas_info",200,20);

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit() {
   per=24*60;
   ChartSetInteger(0,CHART_SHOW,false);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   ChartSetInteger(0,CHART_SHOW,true);
}
//+------------------------------------------------------------------+
//| 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[]) {
   int d=rates_total-prev_calculated;
   if (d>1 || d<0) {
      ArrayCopy(cl,close);
      ArrayCopy(ti,time);
      Draw();
   } else {
      if (d==1) {
         ArrayResize(cl,rates_total);
         ArrayResize(ti,rates_total);
      }
      cl[rates_total-1]=close[rates_total-1];
      ti[rates_total-1]=time[rates_total-1];
      //Draw();
   }
   return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   static bool click =false;
   if (sparam=="1")  {  // press left button of mouse
      if (!click) {
         if (mouse) mouse = false;
         else mouse=true;
         click=true;
      }
   } else click=false;
   if (sparam=="32") {  // press D
      if (!click) {
         if (day) day = false;
         else day=true;
         click=true;
         Draw();
      }
   } else click=false;
   if (id==CHARTEVENT_MOUSE_MOVE && mouse) {
      if (!day) per = 24*60 + W.MouseY*60;
      else per=24*60*PeriodSeconds();
      N=double(_MouseX)/_Width;
      Draw();
   }
   if (id==CHARTEVENT_MOUSE_MOVE) {
      int X=_Width/2;
      int Y=_Height/2-5;
      int r=_Height/2-7;
      double dd=sqrt((_MouseX-X)*(_MouseX-X)+(_MouseY-Y)*(_MouseY-Y));
      info.Erase(0);
      if (dd<r && dd>r*0.3) {
         info.MoveCanvas(_MouseX+3,_MouseY-10);
         info.TextPosition(0,0);
         info.Comm(DoubleToString(min+(max-min)*(dd-r*0.3)/(r*0.7),(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS)));
      } else if (_MouseY>_Height-20) {
         int xx=(_MouseX<_Width-160)?_MouseX:_MouseX-160;
         info.MoveCanvas(xx,_Height-25);
         info.TextPosition(0,0);
         info.Comm(TimeToString(ti[start+int((ArraySize(ti)-start)*double(_MouseX)/_Width)]));
      }
      info.Update();
   }
}
//+------------------------------------------------------------------+
void Draw() {
   int X=_Width/2;
   int Y=_Height/2-5;
   int size=ArraySize(cl);
   Canvas.Erase();
   start=int(size*N);
   if (start>=size) start = size-1;
   max = cl[ArrayMaximum(cl,start)];
   min = cl[ArrayMinimum(cl,start)];
   if (max-min<=0) return;
   int nn=0;
   double c=0;
   for (int i=start; i<size; i++) {
      double r = (_Height/2-7)*(0.3+0.7*(cl[i]-min)/(max-min));
      double a;
      if (day) a= 2*M_PI*double(ti[i]%per)/per-M_PI_2;
      else     a= 2*M_PI*double(i%per)/per-M_PI_2;
      double cc=cos(a);
      if (c<0 && cc>=0) nn++;
      c=cc;
      int x = Round(X+c*r);
      int y = Round(Y+sin(a)*r);
      _PixelSet(x,y,Grad(double(i-start)/(size-start)));
   }
   _CommXY(50,70,_Symbol);
   _Comment("Total "+string(nn)+" Circles");
   if (day) _Comment("Circle period = " + string(per/86400)+" days");
   else _Comment("Circle period = " + string(per)+" bars");
   _Comment("Start date = "+string(ti[start]));
   for (int i=0; i<_Width; i++) Canvas.LineVertical(i,_Height-1,_Height-10,Grad(double(i)/_Width));
   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));
}
//+------------------------------------------------------------------+

Comments