clusterbox_ad

Author: Scriptong
clusterbox_ad
Miscellaneous
It issuies visual alerts to the screenUses files from the file system
0 Views
0 Downloads
0 Favorites
clusterbox_ad
//+------------------------------------------------------------------+
//|                                                clusterbox_ad.mq4 |
//|                                        Copyright 2015, Scriptong |
//|                                          http://advancetools.net |
//+------------------------------------------------------------------+
#property copyright "Scriptong"
#property link      "http://advancetools.net"
#property description "English: Displays the ticks volume of candles in the form of clusters.\nRussian: Îòîáðàæåíèå òèêîâûõ îáúåìîâ ñâå÷è â âèäå êëàñòåðîâ."
#property strict

#property indicator_chart_window
#property indicator_buffers 1

#define MAX_POINTS_IN_CANDLE 30000                                                                 // Ïðèáðîñêà äëÿ ñâå÷åé ìåñÿ÷íîãî ãðàôèêà ïÿòèçíàêà
#define MAX_TICKS_IN_CANDLE 1000000                                                                // Ïðèáðîñêà äëÿ ñâå÷åé ìåñÿ÷íîãî ãðàôèêà ïÿòèçíàêà
#define MAX_VOLUMES_SHOW      5                                                                    // Êîëè÷åñòâî óðîâíåé ìàêñèìàëüíîãî îáúåìà, êîòîðûå ñëåäóåò îòîáðàæàòü
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct LevelVolumeColor                                                                            // Ñòðóêòóðà ñîîòâåòñòâèÿ óðîâíåé îáúåìà, äîñòèæåíèå êîòîðûõ íà öåíîâîì óðîâíå îòîáðàæàåòñÿ.. 
  {                                                                                                 // ..ñîîòâåòñòâóþùèì öâåòîì
   color             levelColor;
   int               levelMinVolume;
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct TickStruct                                                                                  // Ñòðóêòóðà äëÿ çàïèñè äàííûõ îá îäíîì òèêå
  {
   datetime          time;
   double            bid;
   double            ask;
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_YESNO
  {
   YES,                                                                                           // Yes / Äà
   NO                                                                                             // No / Íåò
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_CHARTSCALE
  {
   SCALE_SMALLER,                                                                                  // Smallest / Íàèìåíüøèé
   SCALE_SMALL,                                                                                    // Small / Ìàëûé
   SCALE_MEDIUM,                                                                                   // Medium / Ñðåäíèé
   SCALE_BIG,                                                                                      // Big / Áîëüøîé
   SCALE_BIGGEST,                                                                                  // Greater / Áîëüøèé
   SCALE_LARGE                                                                                     // Biggest / Íàèáîëüøèé
  };

//--- Íàñòðîå÷íûå ïàðàìåòðû èíäèêàòîðà
input int      i_pointsInBox           = 50;                                                       // Points in one cluster / Êîëè÷åñòâî ïóíêòîâ â îäíîì êëàñòåðå
input string   i_string1               = "Min volumes and colors / Ìèí. îáúåìû è öâåòà";           // ==============================================
input int      i_minVolumeLevel1       = 1;                                                        // Minimal volume. Level 1 / Ìèíèìàëüíûé îáúåì. Óðîâåíü 1
input color    i_colorLevel1           = clrSkyBlue;                                               // Color of level 1 / Öâåò óðîâíÿ 1
input int      i_minVolumeLevel2       = 250;                                                      // Minimal volume. Level 2 / Ìèíèìàëüíûé îáúåì. Óðîâåíü 2
input color    i_colorLevel2           = clrTurquoise;                                             // Color of level 2 / Öâåò óðîâíÿ 2
input int      i_minVolumeLevel3       = 500;                                                      // Minimal volume. Level 3 / Ìèíèìàëüíûé îáúåì. Óðîâåíü 3
input color    i_colorLevel3           = clrRoyalBlue;                                             // Color of level 3 / Öâåò óðîâíÿ 3
input int      i_minVolumeLevel4       = 1000;                                                     // Minimal volume. Level 4 / Ìèíèìàëüíûé îáúåì. Óðîâåíü 4
input color    i_colorLevel4           = clrBlue;                                                  // Color of level 4 / Öâåò óðîâíÿ 4
input int      i_minVolumeLevel5       = 2000;                                                     // Minimal volume. Level 5 / Ìèíèìàëüíûé îáúåì. Óðîâåíü 5
input color    i_colorLevel5           = clrMagenta;                                               // Color of level 5 / Öâåò óðîâíÿ 5
input string   i_string2               = "Ïàðàìåòðû ãðàôèêà";                                      // ==============================================
input ENUM_YESNO i_useNeededScale      = YES;                                                      // Use the specific chart scale? / Çàäàòü ìàñøòàá ãðàôèêà?
input ENUM_CHARTSCALE i_chartScale     = SCALE_LARGE;                                              // Chart scale / Ìàñøòàá
input ENUM_YESNO i_showClusterGrid     = YES;                                                      // Display the cluster grid / Ïîêàçûâàòü ñåòêó êëàñòåðîâ
input color    i_gridColor             = clrDarkGray;                                              // Color of clusters lines / Öâåò ëèíèé êëàñòåðîâ

input int      i_indBarsCount=10000;                                                    // Number of bars to display / Êîë-âî áàðîâ îòîáðàæåíèÿ

//--- Ïðî÷èå ãëîáàëüíûå ïåðåìåííûå èíäèêàòîðà
bool g_activate,                                                                              // Ïðèçíàê óñïåøíîé èíèöèàëèçàöèè èíäèêàòîðà
g_isShowInfo,                                                                                 // Ïðèçíàê íåîáõîäèìîñòè îòîáðàæåíèÿ äàííûõ èíäèêàòîðà
g_chartForeground,                                                                            // Ïðèçíàê íàõîæäåíèÿ ñâå÷åé íà ïåðåäíåì ïëàíå
g_init;                                                                                       // Ïåðåìåííàÿ äëÿ èíèöèàëèçàöèè ñòàòè÷åñêèõ ïåðåìåííûõ âíóòðè ôóíêöèé â ìîìåíò ïðîâåäåíèÿ..
                                                                                              // ..ïîâòîðíîé èíèöèàëèçàöèè
int g_currentScale,// Ìàñøòàá ãðàôèêà äåéñòâóþùèé íà ìîìåíò ïðèñîåäèíåíèÿ èíäèêàòîðà
g_volumePriceArray[MAX_POINTS_IN_CANDLE];                                                      // Ðàáî÷èé ìàññèâ óðîâíåé, â êîòîðûé çàïèñûâàåòñÿ êîëè÷åñòâî òèêîâ, êîòîðûå ïîïàëè íà..
                                                                                               // ..ñîîòâåòñòâóþùóþ öåíó ñâå÷è. Êîëè÷åñòâî çàïîëíåííûõ ýëåìåíòîâ ìàññèâà - âûñîòà ñâå÷è
double g_ticksPrice[MAX_TICKS_IN_CANDLE];                                                      // Ìàññèâ äëÿ âðåìåííîãî õðàíåíèÿ íàáîðà òèêîâ, ïðèõîäÿùèõñÿ íà îäíó ñâå÷ó

double g_point,
g_tickSize;

TickStruct        g_ticks[];                                                                       // Ìàññèâ äëÿ õðàíåíèÿ òèêîâ, ïîñòóïèâøèõ ïîñëå íà÷àëà ðàáîòû èíäèêàòîðà                    
LevelVolumeColor g_volumeLevelsColor[MAX_VOLUMES_SHOW];                                            // Ìàññèâ îáúåìîâ è, ñîîòâåòñòâóþùèì èì, öâåòîâ óðîâíåé

#define PREFIX                                  "CLSTRBX_"                                         // Ïðåôèêñ ãðàôè÷åñêèõ îáúåêòîâ, îòîáðàæàåìûõ èíäèêàòîðîì 

#define SIGN_BUTTON                             "INFO_BUTTON_"                                     // Êîðåíü èìåíè ãðàôè÷åñêîãî îáúåêòà "êíîïêà"
#define BUTTON_FONT_NAME                        "MS Sans Serif"                                    // Èìÿ øðèôòà äëÿ îòîáðàæåíèÿ òåêñòà êíîïêè
#define BUTTON_TOOLTIP                          "Âêë/âûêë îòîáðàæåíèå êëàñòåðîâ è ñåòêè"           // Ïîäñêàçêà ê íàçíà÷åíèþ êíîïêè
#define BUTTON_XCOORD                           2                                                  // Õ-êîîðäèíàòà ëåâîãî âåðõíåãî óãëà êíîïêè
#define BUTTON_YCOORD                           14                                                 // Y-êîîðäèíàòà ëåâîãî âåðõíåãî óãëà êíîïêè
#define BUTTON_WIDTH                            110                                                // Øèðèíà êíîïêè
#define BUTTON_HEIGHT                           20                                                 // Âûñîòà êíîïêè
#define BUTTON_FONT_SIZE                        7                                                  // Ðàçìåð øðèôòà äëÿ òåêñòà êíîïêè
#define BUTTON_TEXT_COLOR                       clrBlack                                           // Öâåò øðèôòà òåêñòà â êíîïêå
#define BUTTON_BORDER_COLOR                     clrNONE                                            // Öâåò ãðàíèöû êíîïêè
#define BUTTON_BACKGROUND_COLOR                 clrLightGray                                       // Öâåò çàëèâêè êíîïêè

#define FONT_NAME                               "MS Sans Serif"
#define FONT_SIZE                               7
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
  {
   g_activate=false;                                                                             // Èíäèêàòîð íå èíèöèàëèçèðîâàí
   g_init=true;

   if(!IsTuningParametersCorrect()) // Íåâåðíî óêàçàííûå çíà÷åíèÿ íàñòðîå÷íûõ ïàðàìåòðîâ - ïðè÷èíà íåóäà÷íîé èíèöèàëèçàöèè
      return INIT_FAILED;

   if(!IsLoadTempTicks()) // Çàãðóçêà äàííûõ î òèêàõ, ñîõðàíåííûõ çà ïðåäûäóùèé ïåðèîä ðàáîòû èíäèêàòîðà   
      return INIT_FAILED;

   CreateVolumeColorsArray();                                                                    // Êîïèðîâàíèå äàííûõ î öâåòå è âåëè÷èíå óðîâíåé â ìàññèâ
   SetChartView();                                                                               // Óñòàíîâêà ñïåöèôè÷åñêîãî âèäà ãðàôèêà

   g_activate=true;                                                                              // Èíäèêàòîð óñïåøíî èíèöèàëèçèðîâàí

   return INIT_SUCCEEDED;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà êîððåêòíîñòè íàñòðîå÷íûõ ïàðàìåòðîâ                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTuningParametersCorrect()
  {
   string name=WindowExpertName();

   int period= Period();
   if(period == 0)
     {
      Alert(name,": ôàòàëüíàÿ îøèáêà òåðìèíàëà - ïåðèîä 0 ìèíóò. Èíäèêàòîð îòêëþ÷åí.");
      return (false);
     }

   g_point=Point;
   if(g_point==0)
     {
      Alert(name,": ôàòàëüíàÿ îøèáêà òåðìèíàëà - âåëè÷èíà ïóíêòà ðàâíà íóëþ. Èíäèêàòîð îòêëþ÷åí.");
      return (false);
     }

   g_tickSize=MarketInfo(Symbol(),MODE_TICKSIZE);
   if(g_tickSize==0)
     {
      Alert(name,": ôàòàëüíàÿ îøèáêà òåðìèíàëà - âåëè÷èíà øàãà îäíîãî òèêà ðàâíà íóëþ. Èíäèêàòîð îòêëþ÷åí.");
      return (false);
     }

   if(i_pointsInBox<1)
     {
      Alert(name,": êîëè÷åñòâî ïóíêòîâ â êëàñòåðå äîëæíî áûòü ïîëîæèòåëüíûì. Èíäèêàòîð îòêëþ÷åí.");
      return (false);
     }

   return (true);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| ×òåíèå äàííûõ î òèêàõ, íàêîïëåííûõ â òå÷åíèå ïðåäûäóùåé ðàáî÷åé ñåññèè ïðîãðàììû                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsLoadTempTicks()
  {
//--- Îòêðûòèå ôàéëà òèêîâîé èñòîðèè
   int hTicksFile=FileOpen(Symbol()+"temp.tks",FILE_BIN|FILE_READ|FILE_SHARE_READ|FILE_SHARE_WRITE);
   if(hTicksFile<1)
      return true;

//--- Ðàñïðåäåëåíèå ïàìÿòè äëÿ ìàññèâà g_ticks
   int recSize=(int)(FileSize(hTicksFile)/sizeof(TickStruct));
   if(ArrayResize(g_ticks,recSize,1000)<0)
     {
      Alert(WindowExpertName(),": íå óäàëîñü ðàñïðåäåëèòü ïàìÿòü äëÿ ïîäêà÷êè äàííûõ èç âðåìåííîãî ôàéëà òèêîâ. Èíäèêàòîð îòêëþ÷åí.");
      FileClose(hTicksFile);
      return false;
     }

//--- ×òåíèå ôàéëà
   int i=0;
   while(i<recSize)
     {
      if(FileReadStruct(hTicksFile,g_ticks[i])==0)
        {
         Alert(WindowExpertName(),": îøèáêà ÷òåíèÿ äàííûõ èç âðåìåííîãî ôàéëà. Èíäèêàòîð îòêëþ÷åí.");
         return false;
        }
      i++;
     }

   FileClose(hTicksFile);
   return true;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ôîðìèðîâàíèå ìàññèâà çíà÷åíèé îáúåìîâ è ñîîòâåòñòâóþùèõ èì öâåòàì óðîâíåé                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CreateVolumeColorsArray()
  {
   g_volumeLevelsColor[0].levelMinVolume = i_minVolumeLevel1;
   g_volumeLevelsColor[1].levelMinVolume = i_minVolumeLevel2;
   g_volumeLevelsColor[2].levelMinVolume = i_minVolumeLevel3;
   g_volumeLevelsColor[3].levelMinVolume = i_minVolumeLevel4;
   g_volumeLevelsColor[4].levelMinVolume = i_minVolumeLevel5;

   g_volumeLevelsColor[0].levelColor = i_colorLevel1;
   g_volumeLevelsColor[1].levelColor = i_colorLevel2;
   g_volumeLevelsColor[2].levelColor = i_colorLevel3;
   g_volumeLevelsColor[3].levelColor = i_colorLevel4;
   g_volumeLevelsColor[4].levelColor = i_colorLevel5;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Óñòàíîâêà íóæíîãî ìàñøòàáà ãðàôèêà äëÿ ðàáîòû èíäèêàòîðà                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SetChartView()
  {
//--- Ïîëîæåíèå ñâå÷íîãî ãðàôèêà îòíîñèòåëüíî ïðî÷åé ãðàôèêè
   g_chartForeground=(bool)ChartGetInteger(0,CHART_FOREGROUND);
   ChartSetInteger(0,CHART_FOREGROUND,false);

   if(i_useNeededScale==NO)
      return;

//--- Ìàñøòàá ãðàôèêà
   g_currentScale=(int)ChartGetInteger(0,CHART_SCALE);
   ChartSetInteger(0,CHART_SCALE,(long)i_chartScale);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(!IsSavedFile())    // Åñëè íè îäèí èç ïîäêëþ÷åííûõ èíäèêàòîðîâ íå ñîõðàíèë äàííûå, òî èõ ñîõðàíèò òåêóùèé èíäèêàòîð
      SaveTempTicks();   // Ñîõðàíåíèå äàííûõ î òèêàõ, íàêîïëåííûõ çà òåêóùèé ïåðèîä ðàáîòû èíäèêàòîðà   
   DeleteAllObjects();
   RestoreChartView();
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà íàëè÷èÿ çàïèñàííûõ äàííûõ äðóãèì èíäèêàòîðîì                                                                                                                                             |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsSavedFile()
  {
//--- Ïîëó÷åíèå âðåìåíè ïîñòóïëåíèÿ ïîñëåäíåãî çàïèñàííîãî òèêà
   int lastTickIndex=ArraySize(g_ticks)-1;
   if(lastTickIndex<0) // Íè îäèí òèê íå áûë ïîëó÷åí. Çàïèñü äàííûõ íå òðåáóåòñÿ
      return true;

//--- Îòêðûòèå ôàéëà òèêîâîé èñòîðèè
   int hTicksFile=FileOpen(Symbol()+"temp.tks",FILE_BIN|FILE_READ|FILE_SHARE_READ|FILE_SHARE_WRITE);
   if(hTicksFile<1)
      return false;

//--- Ïåðåìåùåíèå ê ïîñëåäíåé çàïèñè â ôàéëå
   if(!FileSeek(hTicksFile,-sizeof(TickStruct),SEEK_END))
     {
      FileClose(hTicksFile);
      return false;
     }

//--- ×òåíèå ïîñëåäíåé çàïèñè è çàêðûòèå ôàéëà
   TickStruct tick;
   uint readBytes=FileReadStruct(hTicksFile,tick);
   FileClose(hTicksFile);
   if(readBytes==0)
      return false;

//--- Ñðàâíåíèå äàòû òèêà, çàïèñàííîãî â ôàéëå, è äàòû ïîñëåäíåãî ïîñòóïèâøåãî òèêà
   return tick.time >= g_ticks[lastTickIndex].time;                                                // Äàòà/âðåìÿ ïîñëåäíåãî çàïèñàííîãî â ôàéëå òèêà áîëüøå èëè ðàâíà äàòå/âðåìåíè..
                                                                                                   // ..çàðåãèñòðèðîâàííîãî òèêà. Çíà÷èò, ôàéë óæå çàïèñàí, è ïîâòîðíàÿ çàïèñü íå òðåáóåòñÿ
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ñîõðàíåíèå äàííûõ î òèêàõ, íàêîïëåííûõ çà òåêóùóþ ðàáî÷óþ ñåññèþ ïðîãðàììû                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SaveTempTicks()
  {
//--- Ñîçäàíèå ôàéëà òèêîâîé èñòîðèè
   int hTicksFile=FileOpen(Symbol()+"temp.tks",FILE_BIN|FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE);
   if(hTicksFile<1)
      return;

//--- Çàïèñü ôàéëà
   int total=ArraySize(g_ticks),i=0;
   while(i<total)
     {
      if(FileWriteStruct(hTicksFile,g_ticks[i])==0)
        {
         Print("Îøèáêà ñîõðàíåíèÿ äàííûõ âî âðåìåííûé ôàéë...");
         return;
        }
      i++;
     }

   FileClose(hTicksFile);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå êíîïêè âêë./âûêë. âèçóàëèçàöèè ïîêàçàíèé èíäèêàòîðà                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowInfoViewButton()
  {
   if(!g_init)
      return;

   g_isShowInfo=true;
   ShowButton(BUTTON_XCOORD,BUTTON_YCOORD,"Êëàñòåðû âûêë.");
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå ãðàôè÷åñêîãî îáúåêòà "Êíîïêà"                                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowButton(int x,int y,string text)
  {
   string name=PREFIX+SIGN_BUTTON+IntegerToString(x)+IntegerToString(y);

   if(ObjectFind(0,name)<0)
     {
      ObjectCreate(0,name,OBJ_BUTTON,0,0,0);

      ObjectSetInteger(0,name,OBJPROP_CORNER,0);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);

      ObjectSetInteger(0,name,OBJPROP_XSIZE,BUTTON_WIDTH);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,BUTTON_HEIGHT);

      ObjectSetString(0,name,OBJPROP_TEXT,text);
      ObjectSetString(0,name,OBJPROP_FONT,BUTTON_FONT_NAME);
      ObjectSetString(0,name,OBJPROP_TOOLTIP,BUTTON_TOOLTIP);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,BUTTON_FONT_SIZE);

      ObjectSetInteger(0,name,OBJPROP_COLOR,BUTTON_TEXT_COLOR);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,BUTTON_BORDER_COLOR);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,BUTTON_BACKGROUND_COLOR);

      ObjectSetInteger(0,name,OBJPROP_BACK,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      return;
     }

   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetString(0,name,OBJPROP_TEXT,text);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Óäàëåíèå âñåõ îáúåêòîâ, ñîçäàííûõ ïðîãðàììîé                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void DeleteAllObjects()
  {
   for(int i=ObjectsTotal()-1; i>=0; i--)
      if(StringSubstr(ObjectName(i),0,StringLen(PREFIX))==PREFIX)
         ObjectDelete(ObjectName(i));

   g_init=true;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Âîçâðàùåíèå äåéñòâóþùåãî ìàñøòàáà ãðàôèêà                                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void RestoreChartView()
  {
   ChartSetInteger(0,CHART_FOREGROUND,g_chartForeground);

   if(i_useNeededScale==NO)
      return;

   ChartSetInteger(0,CHART_SCALE,g_currentScale);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îïðåäåëåíèå èíäåêñà áàðà, ñ êîòîðîãî íåîáõîäèìî ïðîèçâîäèòü ïåðåðàñ÷åò                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex(int &total,const int ratesTotal,const int prevCalculated)
  {
//--- Îïðåäåëåíèå ïåðâîãî áàðà èñòîðèè, íà êîòîðîì áóäóò äîñòóïíû àäåêâàòíûå çíà÷åíèÿ èíäèêàòîðà
   total=ratesTotal-1;

//--- À ìîæåò çíà÷åíèÿ èíäèêàòîðà íå íóæíî îòîáðàæàòü íà âñåé èñòîðèè?
   if(i_indBarsCount>0 && i_indBarsCount<total)
      total=MathMin(i_indBarsCount,total);

//--- Ïåðâîå îòîáðàæåíèå èíäèêàòîðà èëè ïðîèçîøëà ïîäêà÷êà äàííûõ, ò. å. íà ïðåäûäóùåì òèêå áàðîâ áûëî íå íà îäèí áàð ìåíüøå, êàê ïðè íîðìàëüíîì ðàçâèòèè èñòîðèè, à íà äâà èëè áîëåå áàðîâ ìåíüøå
   if(prevCalculated<ratesTotal-1)
     {
      DeleteAllObjects();
      return (total);
     }

//--- Íîðìàëüíîå ðàçâèòèå èñòîðèè. Êîëè÷åñòâî áàðîâ òåêóùåãî òèêà îòëè÷àåòñÿ îò êîëè÷åñòâà áàðîâ ïðåäûäóùåãî òèêà íå áîëüøå, ÷åì íà îäèí áàð
   return (MathMin(ratesTotal - prevCalculated, total));
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Áîëüøå ëè ïåðâîå ÷èñëî, ÷åì âòîðîå?                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsFirstMoreThanSecond(double first,double second)
  {
   return (first - second > Point / 10);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ðàâíû ëè ÷èñëà?                                                                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsValuesEquals(double first,double second)
  {
   return (MathAbs(first - second) < Point / 10);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| ×òåíèå îäíîãî òèêà èç ôàéëà                                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsReadTimeAndBidAskOfTick(int hTicksFile,TickStruct &tick)
  {
   if(FileIsEnding(hTicksFile))
     {
      FileClose(hTicksFile);
      return false;
     }

   uint bytesCnt=FileReadStruct(hTicksFile,tick);
   if(bytesCnt==sizeof(TickStruct))
      return true;

   FileClose(hTicksFile);
   return false;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðèâåäåíèå ðûíî÷íîé öåíû ê öåíå êëàñòåðà ñ ó÷åòîì åãî âûñîòû                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double CastPriceToCluster(double price)
  {
   int priceInPoints=(int)MathRound(price/Point);
   int clusterPrice =(int)MathRound(priceInPoints/1.0/i_pointsInBox);
   return NormalizeDouble(clusterPrice * Point * i_pointsInBox, Digits);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ñ÷èòûâàíèå òèêîâ, ïðèíàäëåæàùèõ îäíîé ñâå÷å                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ReadTicksFromFile(int hTicksFile,datetime limitTime,TickStruct &tick,int &ticksCount,bool &fileClose)
  {
   while(!fileClose)
     {
      fileClose=!IsReadTimeAndBidAskOfTick(hTicksFile,tick);
      if(tick.time>=limitTime || fileClose || tick.time==0)
         break;

      g_ticksPrice[ticksCount]=CastPriceToCluster(tick.bid);
      ticksCount++;
      if(ticksCount>MAX_TICKS_IN_CANDLE)
         break;
     }
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ðàñïðåäåëåíèå òèêîâ ïî êëàñòåðàì                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SortTicksByCluster(int ticksCount,int &arraySize)
  {
   arraySize=1;
   ArrayInitialize(g_volumePriceArray,0);
   g_volumePriceArray[0]=1;
   for(int i=1; i<ticksCount; i++)
     {
      if(!IsValuesEquals(g_ticksPrice[i-1],g_ticksPrice[i]))
        {
         arraySize+=(int)MathRound((g_ticksPrice[i]-g_ticksPrice[i-1])/g_tickSize);
         if(arraySize>MAX_POINTS_IN_CANDLE)
            break;
        }
      g_volumePriceArray[arraySize-1]++;
     }
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| ×òåíèå òèêîâûõ äàííûõ èç áóôåðà òèêîâ                                                                                                                                                             |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void AddDataFromBuffer(datetime limitTime,TickStruct &tick,int &ticksCount)
  {
//--- Ïîèñê â áóôåðå òèêà, âðåìÿ êîòîðîãî áîëüøå ïîñëåäíåãî ñ÷èòàííîãî òèêà
   int total=ArraySize(g_ticks),i=0;
   while(i<total && tick.time>=g_ticks[i].time)
      i++;

//--- Äîñòèãëè êîíöà áóôåðà - óõîäèì
   if(i>=total)
     {
      tick.time=0;                                                                               // Óêàçàíèå öèêëó while â ôóíêöèè ProcessOldCandles íà òî, ÷òî äàííûå â áóôåðå çàêîí÷èëèñü
      return;
     }

//--- Ïåðåçàïèñü äàííûõ èç îäíîãî áóôåðà â äðóãîé
   while(i<total && g_ticks[i].time<limitTime)
     {
      g_ticksPrice[ticksCount]=CastPriceToCluster(g_ticks[i].bid);
      ticksCount++;
      i++;
     }

//--- Ñîõðàíåíèå äàííûõ î òèêå ñëåäóþùåãî áàðà
   if(i<total)
      tick=g_ticks[i];
   else
      tick.time=0;                                                                               // Óêàçàíèå öèêëó while â ôóíêöèè ProcessOldCandles íà òî, ÷òî äàííûå â áóôåðå çàêîí÷èëèñü
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïîäãîòîâêà äàííûõ äëÿ îäíîãî áàðà                                                                                                                                                                 |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void FormDataForOneBar(int hTicksFile,datetime limitTime,TickStruct &tick,double &lowPrice,int &arraySize,bool &fileClose)
  {
//--- Ñ÷èòûâàíèå òèêîâ, ïðèíàäëåæàùèõ îäíîé ñâå÷å
   int ticksCount=1;
   g_ticksPrice[0]=CastPriceToCluster(tick.bid);
   if(!fileClose)
      ReadTicksFromFile(hTicksFile,limitTime,tick,ticksCount,fileClose);

   if(fileClose) // Ýòî íå îøèáêà - else íå íóæåí, ò. ê. ïîñëå âûïîëíåíèÿ ReadTicksFromFile ìîæåò èçìåíèòüñÿ fileClose
      AddDataFromBuffer(limitTime,tick,ticksCount);

//--- Ñîðòèðîâêà ìàññèâà â ïîðÿäêå âîçðàñòàíèÿ. Ïîñëå íåå íóëåâîé ýëåìåíò ñîäåðæèò ìèíèìóì ñâå÷è, à ýëåìåíò [ticksCount - 1] - ìàêñèìóì
   ArraySort(g_ticksPrice,ticksCount);
   lowPrice=g_ticksPrice[0];

//--- Ðàñïðåäåëåíèå òèêîâ ïî êëàñòåðàì
   SortTicksByCluster(ticksCount,arraySize);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå ãîðèçîíòàëüíîé ëèíèè                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowHLine(double price,color clr)
  {
   string name=PREFIX+"HLINE_"+IntegerToString((int)(price/g_point));

   if(ObjectFind(0,name)<0)
     {
      ObjectCreate(0,name,OBJ_HLINE,0,0,price);
      ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT);
      ObjectSetInteger(0,name,OBJPROP_BACK,true);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      return;
     }

   ObjectMove(0,name,0,1,price);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå îáúåêòà "Òåêñò"                                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowText(int index,datetime time,double price,string text,string toolTip,color clr)
  {
   string name=PREFIX+IntegerToString(time)+IntegerToString(index);
   if(ObjectFind(0,name)<0)
     {
      ObjectCreate(0,name,OBJ_TEXT,0,time,price);
      ObjectSetString(0,name,OBJPROP_FONT,FONT_NAME);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,FONT_SIZE);
      ObjectSetString(0,name,OBJPROP_TEXT,text);
      ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip);
      ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,name,OBJPROP_BACK,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      return;
     }

   ObjectMove(0,name,0,time,price);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetString(0,name,OBJPROP_TEXT,text);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îïðåäåëåíèå, êàêîìó èç óêàçàííûõ îáúåìîâ ñîîòâåòñòâóåò ðàññìàòðèâàåìàÿ âåëè÷èíà îáúåìà                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetVolumeLevel(int index)
  {
   for(int i=0; i<MAX_VOLUMES_SHOW; i++)
      if(g_volumeLevelsColor[i].levelMinVolume>g_volumePriceArray[index])
         return i - 1;

   return MAX_VOLUMES_SHOW - 1;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå ãèñòîãðàìì îäíîãî áàðà                                                                                                                                                                |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowBarHistogramms(int barIndex,double lowPrice,int arraySize)
  {
   if(!g_isShowInfo)
      return;

   for(int i=0; i<arraySize; i+=i_pointsInBox)
     {
      //--- ßâëÿåòñÿ ëè îáúåì óðîâíÿ äîñòàòî÷íî áîëüøèì?
      int volumeLevel=GetVolumeLevel(i);
      if(volumeLevel<0)
         continue;

      //--- Îòîáðàæåíèå îáúåìîâ
      double price=lowPrice+i*g_tickSize;
      ShowText(i,Time[barIndex],price,IntegerToString(g_volumePriceArray[i]),DoubleToString(price,Digits),g_volumeLevelsColor[volumeLevel].levelColor);
     }
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå äàííûõ ïî èñòîðè÷åñêèì áàðàì, íà÷èíàÿ ñ óêàçàííîãî                                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessOldCandles(int limit,double &lowPrice,int &arraySize)
  {
//--- Îòêðûòèå ôàéëà òèêîâîé èñòîðèè
   bool fileClose = false;
   int hTicksFile = FileOpen(Symbol() + ".tks", FILE_BIN | FILE_READ | FILE_SHARE_READ | FILE_SHARE_WRITE);
   if(hTicksFile<1)
      fileClose=true;

//--- Ïîèñê ïåðâîãî òèêà, ïðèíàäëåæàùåãî áàðó limit èëè ëþáîìó áîëåå ïîçäíåìó áàðó
   TickStruct tick;
   tick.time= Time[limit];
   tick.bid = Open[limit];
   while(!IsStopped() && !fileClose)
     {
      if(!IsReadTimeAndBidAskOfTick(hTicksFile,tick))
         return;

      if(tick.time>=Time[limit])
         break;
     }

//--- Îòîáðàæåíèå äàííûõ
   datetime extremeTime=Time[0]+PeriodSeconds();
   while(tick.time<extremeTime && tick.time!=0)
     {
      int barIndex=iBarShift(NULL,0,tick.time);
      FormDataForOneBar(hTicksFile,Time[barIndex]+PeriodSeconds(),tick,lowPrice,arraySize,fileClose);
      ShowBarHistogramms(barIndex,lowPrice,arraySize);
     }

   if(!fileClose)
      FileClose(hTicksFile);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îáðàçîâàíèå íîâîãî áàðà                                                                                                                                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessNewBarForming(double bid,double &lowPrice,int &arraySize)
  {
   ArrayInitialize(g_volumePriceArray,0);
   arraySize= 1;
   lowPrice = bid;
   g_volumePriceArray[0]=1;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îáíîâëåíèå ìèíèìóìà òåêóùåé ñâå÷è                                                                                                                                                                 |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessCandleMinimumUpdate(int priceIndex,double bid,double &lowPrice,int &arraySize)
  {
   priceIndex = MathAbs(priceIndex);
   arraySize += priceIndex;
   if(arraySize>MAX_POINTS_IN_CANDLE)
      return;

//--- Óâåëè÷åíèå êîëè÷åñòâà çíà÷èìûõ ýëåìåíòîâ ìàññèâà íà priceIndex ýëåìåíòîâ
   for(int i=arraySize-1; i>priceIndex-1; i--)
      g_volumePriceArray[i]=g_volumePriceArray[i-priceIndex];

//--- Çàïîëíåíèå íóëÿìè ýëåìåíòîâ, ñîîòâåòñòâóþùèõ öåíàì ìåæäó ïðåäûäóùèì ìèíèìóìîì è òåêóùèì
   for(int i=priceIndex-1; i>=0; i--)
      g_volumePriceArray[i]=0;
   g_volumePriceArray[0]=1;

//--- Íîâûé ìèíèìóì
   lowPrice=bid;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïèñü äàííûõ î òèêå â ìàññèâ g_ticks                                                                                                                                                             |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsUpdateTicksArray(TickStruct &tick)
  {
   int total=ArraySize(g_ticks);
   if(ArrayResize(g_ticks,total+1,100)<0)
     {
      Alert(WindowExpertName(),": èíäèêàòîðó íå õâàòàåò ïàìÿòè äëÿ ñîõðàíåíèÿ äàííûõ îá î÷åðåäíîì òèêå.");
      return false;
     }

   g_ticks[total]=tick;
   return true;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Äîáàâëåíèå îäíîãî íîâîãî òèêà ê èìåþùåéñÿ ñâå÷å                                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessOneTick(int limit,double &lowPrice,int &arraySize)
  {
   TickStruct tick;
   tick.time= TimeCurrent();
   tick.ask = Ask;
   tick.bid = Bid;

//--- Äîáàâëåíèå îäíîãî òèêà â ìàññèâ õðàíåíèÿ òèêîâ   
   if(!IsUpdateTicksArray(tick))
     {
      g_activate=false;
      return;
     }

   double bid=CastPriceToCluster(Bid);

//--- Îáðàçîâàíèå íîâîãî áàðà èëè íà÷àëî ðàáîòû "ñ íóëÿ"
   if(limit==1 || lowPrice==0 || arraySize==0)
     {
      ProcessNewBarForming(bid,lowPrice,arraySize);
      return;
     }

//--- Åñëè ýêñòðåìóìû ñâå÷è íå îáíîâëåíû, òî ïðîñòî äîáàâëÿåòñÿ îáúåì îäíîìó èç ñóùåñòâóþùèõ óðîâíåé
   int priceIndex=(int)MathRound((bid-lowPrice)/g_tickSize);                                 // Èíäåêñ ýëåìåíòà ìàññèâà g_volumePriceArray, êîòîðîìó ñîîòâåòñòâóåò öåíà Bid
   if(priceIndex>=0 && priceIndex < arraySize)
     {
      g_volumePriceArray[priceIndex]++;
      return;
     }

//--- Îáíîâëåí ìèíèìóì òåêóùåé ñâå÷è. Íóæíî ñäâèíóòü âñå ýëåìåíòû ìàññèâà g_volumePriceArray íà priceIndex ââåðõ
   if(IsFirstMoreThanSecond(lowPrice,bid))
     {
      ProcessCandleMinimumUpdate(priceIndex,bid,lowPrice,arraySize);
      return;
     }

//--- Îáíîâëåí ìàêñèìóì òåêóùåé ñâå÷è. 
   if(priceIndex+1>MAX_POINTS_IN_CANDLE)
      return;

   arraySize=priceIndex+1;
   g_volumePriceArray[priceIndex]=1;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå ñåòêè êëàñòåðîâ                                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowGrid()
  {
   if(!g_init)
      return;

   g_init=false;

   if(i_showClusterGrid==NO)
      return;

//--- Îïðåäåëåíèå èñòîðè÷åñêèõ ýêñòðåìóìîâ
   double highPrice= CastPriceToCluster(High[iHighest(NULL,0,MODE_HIGH)]);
   double lowPrice = CastPriceToCluster(Low[iLowest(NULL,0,MODE_LOW)]);

//--- Îòîáðàæåíèå ëèíèé êëàñòåðîâ
   for(double price=lowPrice; price<=highPrice; price=NormalizeDouble(price+i_pointsInBox*g_point,Digits))
      ShowHLine(price,i_gridColor);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå äàííûõ èíäèêàòîðà                                                                                                                                                                     |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowIndicatorData(int limit,int total)
  {
   static double lowPrice = 0;                                                                     // Öåíà, ñîîòâåòñòâóþùàÿ ìèíèìóìó ñâå÷è è íóëåâîìó ýëåìåíòó ìàññèâà g_volumePriceArray. Ïåðâîìó..
                                                                                                   // ..ýëåìåíòó áóäåò ñîîòâåòñòâîâàòü öåíà lowPrice + Point è ò.ä.;
   static int arraySize = 0;                                                                       // Êîëè÷åñòâî ýëåìåíòîâ, çàïèñàííûõ â ìàññèâ g_volumePriceArray.  èäåàëå ýòî çíà÷åíèå äîëæíî áûòü..
                                                                                                   // ..ðàâíî êîëè÷åñòâó ïóíêòîâ, èç êîòîðûõ ñîñòîèò ñâå÷à. Íî èç-çà ðàçäåëüíîé çàïèñè òèêîâ è..
                                                                                                   // ..ðåàëüíîãî ôîðìèðîâàíèÿ ñâå÷åé âîçìîæíû ñäâèãè
   if(limit>1)   // Âûçîâ ïðîèñõîäèò òîëüêî â ìîìåíò îòîáðàæåíèÿ âñåé èñòîðèè - íà÷àëüíàÿ çàãðóçêà èëè îáíîâëåíèå..
     {           // ..áàðîâ ñ èíäåêñîì áîëåå 1
      ProcessOldCandles(limit,lowPrice,arraySize);
      return;
     }

//--- Íîðìàëüíîå îáíîâëåíèå - ïðèõîä íîâîãî òèêà èëè îáðàçîâàíèå íîâîãî áàðà
   ProcessOneTick(limit,lowPrice,arraySize);
   ShowBarHistogramms(0,lowPrice,arraySize);
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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(!g_activate) // Åñëè èíäèêàòîð íå ïðîøåë èíèöèàëèçàöèþ, òî ðàáîòàòü îí íå äîëæåí
      return rates_total;

   ProcessGlobalTick(rates_total,prev_calculated);

   return rates_total;
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Âûïîëíåíèå îäíîé èòåðàöèè îòîáðàæåíèÿ äàííûõ                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessGlobalTick(const int rates_total,const int prev_calculated)
  {
   int total;
   int limit=GetRecalcIndex(total,rates_total,prev_calculated);                                // Ñ êàêîãî áàðà íà÷èíàòü îáíîâëåíèå?

   ShowInfoViewButton();                                                                           // Îòîáðàæåíèå êíîïêè âêë./âûêë. âèçóàëèçàöèè ïîêàçàíèé èíäèêàòîðà
   ShowGrid();                                                                                     // Îòîáðàæåíèå ëèíèé êëàñòåðîâ
   ShowIndicatorData(limit, total);                                                                // Îòîáðàæåíèå äàííûõ èíäèêàòîðà
  }
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îáðàáîò÷èê ñîáûòèé ÷àðòà                                                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   if(id!=CHARTEVENT_OBJECT_CLICK)
      return;

   if(sparam!=PREFIX+SIGN_BUTTON+IntegerToString(BUTTON_XCOORD)+IntegerToString(BUTTON_YCOORD))
      return;

//--- Âûêëþ÷åíèå êëàñòåðîâ   
   if(g_isShowInfo)
     {
      DeleteAllObjects();
      ShowButton(BUTTON_XCOORD,BUTTON_YCOORD,"Êëàñòåðû âêë.");
      g_isShowInfo=false;
      g_init=false;
      return;
     }

//--- Âêëþ÷åíèå êëàñòåðîâ
   g_init=true;
   ProcessGlobalTick(Bars,0);
  }
//+------------------------------------------------------------------+

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 ---