clusterbox_ad

Download script
Author: Scriptong
clusterbox_ad

This script is designed to provide a visual representation of price action by grouping individual market "ticks" into clusters. Instead of just showing you the final price of a candle, it helps you visualize the density of trading activity at specific price levels.

Core Functionality

The logic revolves around identifying where the most "action" happened during a specific time period. It looks at every single price change (tick) and categorizes them into "bins" or clusters based on a user-defined point size. If many ticks occur at the same price level within that span, it identifies that area as a high-activity cluster.

How the Logic Works:

  • Data Collection & Storage: The script maintains a history of market movements. To ensure no data is lost when you close your trading platform, it includes a system to save and load this tick data from a temporary file on your computer.
  • Cluster Mapping: It takes the price of every tick and rounds it to the nearest "cluster" size (for example, grouping every 50 points together). This allows the script to count how many times the market touched specific price zones.
  • Dynamic Scaling: As a new candle forms or the current price moves to a new high or low, the script dynamically adjusts the visual map. It expands the "grid" of clusters to accommodate the new price range while keeping the counts accurate for the existing data.
  • Visual Feedback:
    • Color Coding: The script allows you to set different thresholds for volume. Depending on how many ticks occur in a specific cluster, the script will change the color of that data point (e.g., a low-activity area might be blue, while a high-activity "hot spot" might turn magenta).
    • Histogram View: It displays these counts as a histogram or text labels directly on your chart, making it easy to see exactly where the most aggressive trading occurred.
    • Grid System: Optionally, it can draw a horizontal grid across the chart to help you see the boundaries of these price clusters clearly.
  • User Interaction: There is a dedicated "On/Off" button on the chart that allows you to toggle the visibility of these clusters instantly without having to remove the script from your chart.

Summary for the User

In simple terms, this tool acts like a "heat map" for price. It tells you not just where the price went, but where it spent the most time. By identifying clusters with high tick counts, traders can better see areas of heavy interest, support/resistance zones, and where significant "buying or selling pressure" was concentrated during a specific session.

Miscellaneous
It issuies visual alerts to the screenUses files from the file system
11 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