tickscollector_ad

Author: Scriptong
Miscellaneous
It issuies visual alerts to the screenImplements a curve of type %1Uses files from the file system
0 Views
0 Downloads
0 Favorites
tickscollector_ad
#property copyright "Scriptong"
#property link      "http://advancetools.net"
#property description "English: Record a tick stream to a file and the formation of non-standard timeframes.\nDescription available online AdvanceTools.net in the \"Tick volume - Collector ticks.\"\n\nRussian: Çàïèñü òèêîâîãî ïîòîêà â ôàéë è ôîðìèðîâàíèå íåñòàíäàðòíûõ òàéìôðåéìîâ.\nÎïèñàíèå äîñòóïíî íà ñàéòå AdvanceTools.net â ðàçäåëå \"Òèêîâûå îáúåìû - Ñáîðùèê òèêîâ.\""
#property version "1.02"


#property strict

#property indicator_separate_window
#property indicator_buffers 2 
#property indicator_color1 clrTurquoise
#property indicator_color2 clrRed

#include <TicksCollector_Classes_AD.mqh>

#define MAX_VIRTUAL_TICKS 1000000                                                                  // Ìàêñèìàëüíî äîïóñòèìîå êîëè÷åñòâî òèêîâ, õðàíèìîå â ïàìÿòè êîìïüþòåðà

struct NonStandartWindow                                                                           // Äàííûå ãðàôèêà íåñòàíäàðòíîãî òàéìôðåéìà
{
   int hWindow;                                                                                    // Äåñêðèïòîð îêíà
   int hFile;                                                                                      // Îïèñàòåëü èñòîðè÷åñêîãî ôàéëà
   datetime lastBar;                                                                               // Âðåìÿ îòêðûòèÿ ïîñëåäíåãî îáðàáîòàííîãî áàðà ãðàôèêà
};

enum ENUM_YESNO
{
    YES,                                                                                           // Yes / Äà
    NO                                                                                             // No / Íåò
};


// Íàñòðîå÷íûå ïàðàìåòðû èíäèêàòîðà

input string     i_string1                      = "The ticks collecting params / Ïàðàìåòðû ñáîðà òèêîâ";// =========================
input ENUM_YESNO i_collectTicks                 = YES;                                             // Use ticks collecting? / Ïðîèçâîäèòü ñáîð òèêîâ?
input ENUM_YESNO i_setUserFileName              = NO;                                              // Set the custom file name? / Óñòàíîâèòü ñâîå èìÿ òèêîâîãî ôàéëà?
input string     i_userFileName                 = "user.tks";                                      // Name of ticks file / Èìÿ òèêîâîãî ôàéëà
input ENUM_YESNO i_useForcedUpdate              = YES;                                             // Use file flush? / Ïðèíóäèòåëüíî ñáðàñûâàòü äàííûå â ôàéë?
input int        i_everyNTicks                  = 10;                                              // File flush every N ticks / Ñáðîñ äàííûõ êàæäûå N òèêîâ
input int        i_maxShowTicksCount            = 1000;                                            // Maximal showing ticks / Êîëè÷åñòâî îòîáðàæàåìûõ òèêîâ

input string     i_string2                      = "Equal time chart / Ðàâíîâðåìåííîé ãðàôèê";      // =========================
input ENUM_YESNO i_convertToTime                = NO;                                              // Create the chart? / Ñîçäàâàòü ãðàôèê?
input int        i_secondsPerBar                = 30;                                              // Period in seconds / Ïåðèîä â ñåêóíäàõ
input int        i_resultTimeTFInMinutes        = 312;                                             // Name of TF in minutes / Íàèìåíîâàíèå ÒÔ â ìèíóòàõ
input ENUM_BID_ASK_TYPE i_timeBidAskType        = BID_ASK_TYPE_ONLY_BID;                           // Price type / Öåíîâîé òèï 

input string     i_string3                      = "Chart of Range-bar / Ãðàôèê Range-áàðîâ";       // =========================
input ENUM_YESNO i_convertToPoints              = NO;                                              // Create the chart? / Ñîçäàâàòü ãðàôèê?
input int        i_pointsPerBar                 = 10;                                              // Points per one bar / Ïóíêòîâ íà îäèí áàð
input int        i_resultPointsTFInMinutes      = 313;                                             // Name of TF in minutes / Íàèìåíîâàíèå ÒÔ â ìèíóòàõ
input ENUM_BID_ASK_TYPE i_pointBidAskType       = BID_ASK_TYPE_ONLY_BID;                           // Öåíîâîé òèï ïîñòðîåíèÿ ãðàôèêà

input string     i_string4                      = "Equal volume chart / Ãðàôèê ýêâèîáúåìíûõ áàðîâ";// =========================
input ENUM_YESNO i_convertToTicksVolume         = NO;                                              // Create the chart? / Ñîçäàâàòü ãðàôèê?
input int        i_ticksPerBar                  = 10;                                              // Ticks per one bar / Òèêîâ íà îäèí áàð
input int        i_resultTicksTFInMinutes       = 314;                                             // Name of TF in minutes / Íàèìåíîâàíèå ÒÔ â ìèíóòàõ
input ENUM_BID_ASK_TYPE i_volumeBidAskType      = BID_ASK_TYPE_ONLY_BID;                           // Price type / Öåíîâîé òèï 


bool g_activate;

int g_mt4Message,                                                                                  // Äåñêðèïòîð ñîîáùåíèé ÌÒ4
    g_newTicksCnt,                                                                                 // Òåêóùåå êîëè÷åñòâî òèêîâ, êîòîðûå íå áûëè çàïèñàíû â ôàéë
    g_everyNTicks,                                                                                 // ×àñòîòà ñîõðàíåíèÿ äàííûõ â ôàéë, èçìåðÿåìàÿ â òèêàõ
    g_ticksCnt;                                                                                    // Êîëè÷åñòâî òåêóùèõ íàáðàííûõ òèêîâ
    
TickStruct g_nonWritedTicks[];                                                                     // Áóôåð òèêîâ, êîòîðûå íå áûëè çàïèñàíû â ôàéë
    

NonStandartTFChart g_chartTime(i_convertToTime == YES, i_resultTimeTFInMinutes, i_secondsPerBar, CONVERT_TYPE_TF, i_timeBidAskType, _Digits, _Point, _Symbol),
                   g_chartPoint(i_convertToPoints == YES, i_resultPointsTFInMinutes, i_pointsPerBar, CONVERT_TYPE_POINT, i_pointBidAskType, _Digits, _Point, _Symbol),                                                                   
                   g_chartTick(i_convertToTicksVolume == YES, i_resultTicksTFInMinutes, i_ticksPerBar, CONVERT_TYPE_VOLUME, i_volumeBidAskType, _Digits, _Point, _Symbol);                                                                    

// Ìàññèâû áóôåðîâ íäèêàòîðà
double g_bid[];
double g_ask[];

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   g_activate = false;
   
   if (!TuningParameters())                                                                        // Ïðîâåðêà êîððåêòíîñòè çíà÷åíèé íàñòðîå÷íûõ ïàðàìåòðîâ
      return INIT_FAILED; 
      
   if (!IsTicksBufferReady())                                                                      // Èíèöèàëèçàöèÿ áóôåðà òèêîâ
      return INIT_FAILED;                                

   if (!BuffersBind())                                                                             // Âûäåëåíèå ïàìÿòè äëÿ èíäèêàòîðíûõ áóôåðîâ
      return INIT_FAILED;       
      
   if (!IsFilesReady())
      return INIT_FAILED;                        
                                                   
   g_activate = true;
   return INIT_SUCCEEDED;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà êîððåêòíîñòè íàñòðîå÷íûõ ïàðàìåòðîâ                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool TuningParameters()
{
   string name = WindowExpertName();
   bool isRussian = TerminalInfoString(TERMINAL_LANGUAGE) == "Russian";
   

   if (i_maxShowTicksCount < 2)
   {
      if (isRussian)
         Alert(name, ": ìàêñèìàëüíîå êîëè÷åñòâî îòîáðàæàåìûõ òèêîâ íå ìîæåò áûòü ìåíüøå 2. Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(name, ": the maximal amount of showing ticks could not be less than 2. Indicator is off.");
      return false;
   } 
   
   if (i_maxShowTicksCount > Bars)
   {
      if (isRussian)
         Alert(name, ": ìàêñèìàëüíîå êîëè÷åñòâî îòîáðàæàåìûõ òèêîâ íå ìîæåò áûòü áîëüøå ", Bars,". Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(name, ": the maximal amount of showing ticks could not be more than ", Bars, ". Indicator is off.");
      return false;
   } 

   g_everyNTicks = i_everyNTicks;
   if (i_useForcedUpdate == NO)
      g_everyNTicks = MAX_VIRTUAL_TICKS;
   
   if (i_useForcedUpdate == YES && i_everyNTicks < 1)
   {
      if (isRussian)
         Alert(name, ": êîëè÷åñòâî òèêîâ, ÷åðåç êîòîðûå äîëæåí îñóùåñâëÿòüñÿ ñáðîñ òèêîâ â ôàéë, äîëæíî áûòü áîëüøå íóëÿ. Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(name, ": the value of parameter \"File flush every N ticks\" could not be less than 1. Indicator is off.");
      
      return false;
   } 

   ENUM_YESNO convertToTime = i_convertToTime;
   ENUM_YESNO convertToPoints = i_convertToPoints;
   ENUM_YESNO convertToTicksVolume = i_convertToTicksVolume;
   if (!IsDllsAllowed() && (i_convertToTime == YES || i_convertToPoints == YES || i_convertToTicksVolume == YES))
   {
      if (isRussian)
         Alert(name, ": äëÿ ïîääåðæêè íåñòàíäàðòíûõ òàéìôðåéìîâ íåîáõîäèìî ðàçðåøèòü èìïîðò DLL ôóíêöèé. Ïîääåðæêà ïðèíóäèòåëüíî âûêëþ÷åíà.");
      else
         Alert(name, ": the DLL import should be allowed if updating of non-standard timeframes needed.");
      
      convertToTime = NO;
      convertToPoints = NO;
      convertToTicksVolume = NO;
   }

   if (!IsThreeParametersCorrect(convertToTime, i_secondsPerBar,  i_resultTimeTFInMinutes, "Period in seconds / Ïåðèîä â ñåêóíäàõ", "Name of TF in minutes / Íàèìåíîâàíèå ÒÔ â ìèíóòàõ")) 
      return false;
      
   if (!IsThreeParametersCorrect(convertToPoints, i_pointsPerBar, i_resultPointsTFInMinutes, "Points per one bar / Ïóíêòîâ íà îäèí áàð", "Name of TF in minutes / Íàèìåíîâàíèå ÒÔ â ìèíóòàõ")) 
      return false;

   if (!IsThreeParametersCorrect(convertToTicksVolume, i_ticksPerBar, i_resultTicksTFInMinutes, "Ticks per one bar / Òèêîâ íà îäèí áàð", "Name of TF in minutes / Íàèìåíîâàíèå ÒÔ â ìèíóòàõ")) 
      return false;

   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà êîððåêòíîñòè çíà÷åíèé òðåõ íàñòðîå÷íûõ ïàðàìåòðîâ, îòíîñÿùèõñÿ ê îïðåäåëåííîìó òèïó íåñòàíäàðòíîãî ãðàôèêà                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsThreeParametersCorrect(bool isConvert, int param, int tf, string paramName, string tfName)
{
   if (!isConvert)
      return (true);
      
   string name = WindowExpertName();
      
   if (param < 1)
   {
      if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
         Alert(name, ": çíà÷åíèå ïàðàìåòðà ", paramName, " äîëæíî áûòü íàòóðàëüíûì ÷èñëîì. Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(name, ": the value of parameter ", paramName," could be the natural number. Indicator is off.");
      return false;
   }

   if (IsTFCorrect(tf))
   {
      if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
         Alert(name, ": çíà÷åíèå ïàðàìåòðà ", tfName, " íå äîëæíî óêàçûâàòü íà ñòàíäàðòíûé òàéìôðåéì. Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(name, ": the value of parameter ", tfName," could not be specified the standard timeframe. Indicator is off.");
      return false;
   }
   
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà êîððåêòíîñòè ïåðèîäà ãðàôèêà                                                                                                                                                             |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTFCorrect(int tf)
{
   return (tf == PERIOD_M1  || tf == PERIOD_M5 || tf == PERIOD_M15 || 
           tf == PERIOD_M30 || tf == PERIOD_H1 || tf == PERIOD_H4  ||
           tf == PERIOD_D1  || tf == PERIOD_W1 || tf == PERIOD_MN1);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Èíèöèàëèçàöèÿ áóôåðà âðåìåííîãî õðàíåíèÿ òèêîâ                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTicksBufferReady()
{
   g_ticksCnt = 0;
   g_newTicksCnt = 0;
        
   if (ArrayResize(g_nonWritedTicks, g_everyNTicks) != g_everyNTicks)
   {
      if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
         Alert(WindowExpertName(), ": íå óäàëîñü âûäåëèòü ïàìÿòü äëÿ áóôåðà òèêîâ. Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(WindowExpertName(), ": unable to allocate memory for ticks buffer. Indicator is off.");
      return false;
   }
   
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   IsFileFlush(true);

   g_chartPoint.CloseFile();
   g_chartTime.CloseFile();
   g_chartTick.CloseFile();
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ñâÿçûâàíèå áóôåðîâ èíäèêàòîðà ñ ìàññèâàìè                                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool BuffersBind()
{
   string name = WindowExpertName();
   
   // Ñâÿçûâàíèå áóôåðîâ èíäèêàòîðà ñ ìàññèâàìè
   if (!SetIndexBuffer(0, g_bid) ||
       !SetIndexBuffer(1, g_ask))
   {
      int error = GetLastError();
      if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
         Alert(name, ": îøèáêà ñâÿçûâàíèÿ ìàññèâîâ ñ áóôåðàìè èíäèêàòîðà. Îøèáêà ¹", error);
      else
         Alert(name, ": unable to bind the arrays to the indicator buffers. Indicator is off. Error N", error);
      
      return false;
   }

   // Çàäàíèå ãðàôè÷åñêîãî òèïà áóôåðîâ
   for (int i = 0; i < 2; i++)
      SetIndexStyle(i, DRAW_LINE);
   
   SetIndexLabel(0, "Bid");
   SetIndexLabel(1, "Ask");
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòêðûòèå ôàéëà òèêîâîé èñòîðèè                                                                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTicksFileOpen(int &hTicksFile)
{
   string fileName = GetTicksFileName();
   hTicksFile = FileOpen(fileName, FILE_BIN | FILE_READ | FILE_WRITE | FILE_SHARE_READ | FILE_SHARE_WRITE);
   if (hTicksFile >= 0)
      return true;

   if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
      Alert(WindowExpertName(), ": íå óäàëîñü îòêðûòü ôàéë ", fileName, ". Èíäèêàòîð îòêëþ÷åí.");
   else
      Alert(WindowExpertName(), ": unable to open the file ", fileName, ". Indicator is off.");
   return false;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòêðûòèå ôàéëîâ äëÿ çàïèñè òèêîâîãî ïîòîêà è ñèíòåòè÷åñêèõ ñâå÷åé                                                                                                                                 |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsFilesReady()
{
   // Îòêðûòèå ôàéëîâ èñòîðèè
   return g_chartPoint.CreateHistoryFile() && 
          g_chartTime.CreateHistoryFile() && 
          g_chartTick.CreateHistoryFile();
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ãåíåðàöèÿ èìåíè ôàéëà, èñïîëüçóåìîãî äëÿ çàïèñè òèêîâîãî ïîòîêà                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetTicksFileName()
{
   if (i_setUserFileName == YES)
      return (i_userFileName);
      
   return (Symbol() + ".tks");
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| ×òåíèå äàííûõ èç ôàéëà â áóôåðà èíäèêàòîðà                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ReadFile(bool fillOnlyBuffers)
{
   // Îòêðûòèå ôàéëà
   int hTicksFile = -1;
   if (!IsTicksFileOpen(hTicksFile))
      return;

   // Îïðåäåëåíèå íà÷àëüíûõ çíà÷åíèé ïåðåìåííûõ
   int recSize = sizeof(TickStruct);                                                               // Ðàçìåð ñòðóêòóðû, êîòîðàÿ áóäåò ïðî÷èòàíà çà îäèí ðàç
   ulong sizeInRec = FileSize(hTicksFile) / recSize;                                               // Ðàçìåð ôàéëà â ðàçìåðàõ ñòðóêòóðû (ðàçìåð ôàéëà äîëæåí áûòü êðàòåí ðàçìåðó ñòðóêòóðû)
   g_ticksCnt = (int)MathMin(i_maxShowTicksCount, sizeInRec);                                      // Êîëè÷åñòâî òèêîâ, êîòîðîå áóäåò çàïèñàíî â áóôåðà èíäèêàòîðà
   
   int cnt = g_ticksCnt - 1;                                                                       // Èíäåêñ áóôåðà èíäèêàòîðà, â êîòîðûé áóäåò ïðîèçâåäåíà çàïèñü
   ulong startRecNumber = sizeInRec - g_ticksCnt;                                                  // Íîìåð çàïèñè (â ðàçìåðàõ ñòðóêòóðû), ñ êîòîðîãî íà÷íåòñÿ êîïèðîâàíèå äàííûõ â áóôåðà èíäèêàòîðà
   ulong currentRec = 0;                                                                           // Òåêóùèé íîìåð çàïèñè
   TickStruct tick;                                                                                // Áóôåð äëÿ âðåìåííîãî õðàíåíèÿ äàííûõ î ïðî÷èòàííîé çàïèñè
   
   while (currentRec < sizeInRec)
   {
      // ×òåíèå îäíîé çàïèñè
      uint bytesCnt = FileReadStruct(hTicksFile, tick);
      if (bytesCnt != recSize)
      {
         int error = GetLastError();
         if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
            Alert(WindowExpertName(), ": îøèáêà ÷òåíèÿ èñõîäíîãî ôàéëà ¹", error);
         else
            Alert(WindowExpertName(), ": unable to read the source file. Error N", error);
         
         return;
      }

      // Çàïîëíåíèå áóôåðîâ èíäèêàòîðà
      if (currentRec >= startRecNumber)
         FillIndicatorBuffers(tick, cnt);
      currentRec++;   
         
      // Íå âûïîëíÿåì îáíîâëåíèå ãðàôèêîâ, åñëè ïðîèçîøëà ïîäêà÷êà èñòîðèè
      if (fillOnlyBuffers)   
         continue;
         
      // Êîíâåðòàöèÿ òèêîâ âî âðåìåííÛå, ðàâíîâûñîêèå è ýêâèîáúåìíûå ñâå÷è
      bool isWrite = g_chartTime.ConvertData(tick, false) &&
                     g_chartPoint.ConvertData(tick, false) &&
                     g_chartTick.ConvertData(tick, false);
      if (!isWrite)
      {
         g_activate = false;
         return;
      }
   }

   // Ïåðåõîä ê äîçàïèñè äàííûõ â ôàéëû
   FileClose(hTicksFile);
   g_chartTime.SetPointerToEndOfFile();
   g_chartPoint.SetPointerToEndOfFile();
   g_chartTick.SetPointerToEndOfFile();
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïîëíåíèå áóôåðîâ èíäèêàòîðà                                                                                                                                                                     |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void FillIndicatorBuffers(TickStruct &tick, int& cnt)
{
   g_bid[cnt] = tick.bid;
   g_ask[cnt] = tick.ask; 
   cnt--;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïåðåìåùåíèå äàííûõ èíäèêàòîðà íà îäèí ýëåìåíò âëåâî                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void MoveDataToTheLeft()
{
   for (int i = g_ticksCnt - 1; i > 0; i--)
   {
      g_bid[i] = g_bid[i - 1];
      g_ask[i] = g_ask[i - 1];
   }
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ñáðîñ äàííûõ êàæäûå g_everyNTicks òèêîâ â ôàéë òèêîâîé èñòîðèè                                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsFileFlush(bool isDeinit)
{
   if (i_collectTicks == NO)
      return true;

   // Çàïèñü äàííûõ â áóôåð
   g_nonWritedTicks[g_newTicksCnt].time = TimeCurrent();
   g_nonWritedTicks[g_newTicksCnt].bid = Bid;
   g_nonWritedTicks[g_newTicksCnt].ask = Ask;
   g_newTicksCnt++;
   if (g_newTicksCnt < g_everyNTicks && !isDeinit)
      return true;
   
   // Çàïèñü äàííûõ â ôàéë
   int hTicksFile = -1;
   if (!IsTicksFileOpen(hTicksFile))
      return false;
     
   FileSeek(hTicksFile, 0, SEEK_END);
   for (int i = 0; i < g_newTicksCnt; i++)
   {
      if (FileWriteStruct(hTicksFile, g_nonWritedTicks[i]) == sizeof(TickStruct))
         continue;
         
      int error = GetLastError();
      if (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian")
         Alert(WindowExpertName(), ": îøèáêà çàïèñè äàííûõ â ôàéë ", error, ". Èíäèêàòîð îòêþ÷åí.");
      else
         Alert(WindowExpertName(), ": uunable to save the data to file. Error N", error, ". Indicator is off.");
      
      return false;
   }
   
   // Çàêðûòèå ôàéëà è ïåðåõîä ê íîâîìó ñáîðó òèêîâ
   FileClose(hTicksFile);
   g_newTicksCnt = 0;

   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïèñü î÷åðåäíîãî òèêà â áóôåðà èíäèêàòîðà, â ôàéëû èñòîðèè è òèêîâ                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool SaveRegularTick()
{
   TickStruct tick(TimeCurrent(), Bid, Ask);

   // Îáíîâëåíèå íåñòàíäàðòíûõ ãðàôèêîâ
   bool isWrite = g_chartTime.ConvertData(tick, true) &&
                  g_chartPoint.ConvertData(tick, true) &&
                  g_chartTick.ConvertData(tick, true);
   if (!isWrite)
      return false;

   g_chartTime.UpdateChart();
   g_chartPoint.UpdateChart();
   g_chartTick.UpdateChart();
   
   // Çàïèñü äàííûõ â áóôåðà èíäèêàòîðà
   g_bid[0] = Bid;
   g_ask[0] = Ask;
   
   return IsFileFlush(false);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ðàñ÷åò çíà÷åíèé èíäèêàòîðà                                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool CalcIndicatorData()
{
   static datetime lastBarTime = 0;
   
   if (g_ticksCnt < i_maxShowTicksCount)
      g_ticksCnt++;

   if (lastBarTime == Time[0])
      MoveDataToTheLeft();
   else
      lastBarTime = Time[0];
   
   return SaveRegularTick();
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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;

   // Çàãðóçêà èìåþùèõñÿ òèêîâ
   if (g_ticksCnt == 0)
   {
      ReadFile(false);
      if (g_ticksCnt > 0)
         return rates_total;
   }
 
   // Îáíîâëåíèå äàííûõ ñ êàæäûì íîâûì òèêîì   
   if (!CalcIndicatorData())
      g_activate = false;

   return rates_total;
}

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