This script is designed for MetaTrader 4 (MT4) to perform a comprehensive audit of historical trading data. Its primary purpose is to identify and quantify "gaps" in market history—periods where price data is missing due to server outages, connectivity issues, or low liquidity—and categorize them based on their severity.
Here is a breakdown of how the logic functions:
Data Input Methods
The script offers two ways to source information for analysis:
- Direct Chart Analysis: It can scan the history currently visible on your active trading chart (e.g., an H1 or M15 chart).
- External File Analysis: You can point the script toward a specific historical data file (
.hst). The script is capable of opening these files, reading the specific symbol names, timeframes, and date ranges contained within them to perform the audit.
The Core Filtering Logic
The script does not just report every tiny flicker in price; it uses user-defined filters to focus on meaningful data inconsistencies:
- Hole Detection: It looks for missing bars (time gaps). You can set a minimum threshold so that only significant gaps are recorded.
- Breakup Identification: It distinguishes between minor "holes" and major "breakups" based on a specific bar count.
- Gap Analysis: It calculates the price difference (in pips) between two consecutive data points. If the price "jumps" significantly without continuous data, it records this as a gap.
How the Analysis Works
The script moves through the history chronologically and performs the following steps:
- Time Gap Calculation: It compares the timestamp of one bar to the next. If the difference exceeds the expected duration of that timeframe (e.g., more than 60 minutes for an H1 chart), it identifies a gap.
- Holiday/Weekend Adjustment: The logic is smart enough to account for weekends and holidays. It attempts to subtract standard non-trading periods so that it doesn't falsely report a "gap" simply because the market was closed.
- Classification:
- If a gap exceeds your minimum threshold, it is logged as a Hole.
- If a gap is exceptionally large (exceeding your "Breakup" threshold), it is categorized as a Breakup.
- Statistics Gathering: As it scans, it keeps a running tally of the total number of holes, the average size of those holes, and the maximum price jump (pips) recorded.
Output and Reporting
Once the analysis is complete, the script generates a professional report in two ways:
- CSV Report: It creates a detailed
.csvfile (which can be opened in Excel). This table lists every single gap found, including the start time, end time, duration in minutes, number of bars missing, and the price jump in pips. - Summary Report: If enabled, the script adds a summary at the beginning or end of the file. This provides "at-a-glance" statistics, such as the total count of gaps, average sizes, maximum jumps, and a clear distinction between minor holes and major breakups.
Essentially, this tool acts as a data quality inspector, helping traders identify unreliable periods in their historical charts to ensure they aren't making decisions based on "broken" or incomplete price history.
//+------------------------------------------------------------------+
//| history_data_analysis_v3.mq4 |
//| Copyright © 2007, Kiriyenko Dmitriy |
//| http://kiriyenko.moikrug.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Kiriyenko Dmitriy"
#property link "http://kiriyenko.moikrug.ru"
//----
#property show_inputs
#define FILE_NAME "history_data_analysis_v3.ex4"
#define WRONG_TF "Òàéìôðåéì äîëæåí íàõîäèòüñÿ â ïðåäåëàõ M1-H4.\n\nÂûáåðèòå äðóãîé òàéìôðåéì."
#define WRONG_TF_HDR "Íåâåðíî âûáðàí òàéìôðåéì âõîäíûõ äàííûõ!"
#define WRONG_BREAKUP "Çíà÷åíèå break_up äîëæíî áûòü íå ìåíüøå êðèòåðèÿ ôèëüòðà äëÿ äûðû.\n"
#define BREAKUP_CHANGE "Çíà÷åíèå breakup_min áóäåò èçìåíåíî íà "
#define WRONG_BREAKUP_HDR "Íåâåðíî çàäàí êðèòåðèé ðàçðûâà!"
#define WRONG_FILE_EXT "Íåâåðíûé òèï ôàéëà: ìîæíî çàäàâàòü òîëüêî *.hst ôàéëû"
#define WRONG_FILE_EXT_HDR "Îøèáêà âõîäíûõ äàííûõ"
//----
extern string header0 = "<---------- Âõîäíûå äàííûå ---------->";
extern bool input_from_file = false;
extern string input_file_name = ".hst";
extern bool input_file_in_history = true;
//----
extern string header1 = "<---------- Ïàðàìåòðû ôèëüòðàöèè ---------->";
extern bool bars_ignore = true; // àêòèâàòîð
extern int hole_min = 3; // êîëè÷åñòâî îòñóòñòâóþùèõ áàðîâ, êîòîðûå êîä ñ÷èòàåò äûðîé
//----
extern int breakup_min = 20; // êîë-âî îòñóòñòâóþùèõ áàðîâ, êîòîðûå êîä ñ÷èòàåò ðàçðûâîì
extern bool gap_ignore = true; // àêòèâàòîð
extern int gap_min = 5; // êîë-âî îòñóòñòâóþùèõ ïèïñîâ, êîòîðûå êîä áóäåò èãíîðèðîâàòü
//----
extern string header2 = "<---------- Ïàðàìåòðû îò÷¸òà ---------->";
extern bool report_summary = false; // âûâîäèòü ñâîäêó
extern bool report_table = true; // âûâîäèòü òàáëèöó
//----
string begin_week_sessions = "00:00"; // âðåìÿ íà÷àëà íåäåëüíîé ñåññèè (÷÷:ìì)
string end_week_sessions = "21:59"; // âðåìÿ îêîí÷àíèÿ íåäåëüíîé ñåññèè (÷÷:ìì)
bool new_file = true; // ôëàã, ÷òîáû øàïêó òàáëèöû çàïèñàòü îäèí ðàç
int in_handle, out_handle; // ôàéëîâûå îáðàáîò÷èêè îòêðûòûõ ôàéëîâ
int err; // ïåðåìåííàÿ äëÿ õðàíåíèÿ êîäà îøèáêè
//----
#include <WinUser32.mqh>
#include <stdlib.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int period; // òàéìôðåéì â ìèíóòàõ
string symbol; // îáðàáàòûâàåìûé ñèìâîë
int bars; // ÷èñëî áàðîâ íà ãðàôèêå
double point; // ðàçìåð ïóíêòà â âàëþòå êîòèðîâêè
datetime time_start, time_end; // íà÷àëüíûé è êîíå÷íûé áàð
// íà÷àëüíàÿ îáðàáîòêà âõîäíîãî ôàéëà è óñòàíîâêà ãëîáàëüíûõ äàííûõ
if(input_from_file)
{
// îïðåäåëåíèå òèïà
if(file_ext(input_file_name) != "hst")
{
MessageBox(WRONG_FILE_EXT, WRONG_FILE_EXT_HDR, MB_OK | MB_ICONSTOP);
return(-3);
}
// îòêðûòèå ôàéëà
if(input_file_in_history)
in_handle = FileOpenHistory(input_file_name, FILE_BIN | FILE_READ);
else
in_handle = FileOpen(input_file_name, FILE_BIN | FILE_READ);
err = GetLastError();
if(in_handle < 0 || err > 0)
return(error_out(err, "Îòêðûòèå âõîäíîãî ôàéëà"));
// îïðåäåëåíèå ÷èñëà áàðîâ
bars = (FileSize(in_handle) - 148) / 44;
err = GetLastError();
if(err > 0)
return(error_out(err, "Îïðåäåëåíèå ðàçìåðà âõîäíîãî ôàéëà"));
// ÷òåíèå çàãîëîâêà âõîäíîãî ôàéëà
FileSeek(in_handle, 68, SEEK_SET);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõîäíîì ôàéëå ê ñèìâîëó"));
// ÷òåíèå ñèìâîëà/ïåðèîäà
symbol = FileReadString(in_handle, 12);
period = FileReadInteger(in_handle, LONG_VALUE);
int digits = FileReadInteger(in_handle, LONG_VALUE);
point = MathPow(10, -digits);
err = GetLastError();
if(err > 0)
return(error_out(err, "×òåíèå ñèìâîëà è ïåðèîäà èç âõîäíîãî ôàéëà"));
// îïðåäåëåíèå âðåìåííûõ ãðàíèö èñòîðè÷åñêèõ äàíûõ
FileSeek(in_handle, 60, SEEK_CUR);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõîäíîì ôàéëå ê ïåðâîé äàòå"));
time_start = FileReadInteger(in_handle, LONG_VALUE);
err = GetLastError();
if(err > 0)
return(error_out(err, "×òåíèå ïåðâîé äàòû èç âõîäíîãî ôàéëà"));
FileSeek(in_handle, -44, SEEK_END);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõîäíîì ôàéëå ê ïîñëåäíåé äàòå"));
time_end = FileReadInteger(in_handle, LONG_VALUE);
err = GetLastError();
if(err > 0)
return (error_out(err, "×òåíèå ïîñëåäíåé äàòû èç âõîäíîãî ôàéëà"));
// ïåðåâîä êóðñîðà â íà÷àëî êîòèðîâîê â *.hst ôàéëå
FileSeek(in_handle, 148, SEEK_SET);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõîäíîì ôàéëå ê íà÷àëó êîòèðîâîê"));
}
else // èëè ïîäñòàíîâêà ãëîáàëüíûõ äàííûõ ñ ãðàôèêà
{
bars = Bars;
symbol = Symbol();
period = Period();
point = Point;
time_start = Time[Bars-1];
time_end = Time[0];
}
// âûáîð ïàðàìåòðîâ ïîä òàéìôðåéì
string time_frame; // òàéìôðåéì
int duration_bar = period*60; // äëèòåëüíîñòü áàðà â ñåê.
switch(period)
{
case 1: time_frame = "M1"; break;
case 5: time_frame = "M5"; break;
case 15: time_frame = "M15"; break;
case 30: time_frame = "M30"; break;
case 60: time_frame = "H1"; break;
case 240: time_frame = "H4"; break;
default:
MessageBox(WRONG_TF, WRONG_TF_HDR, MB_OK | MB_ICONWARNING | MB_DEFBUTTON1);
return(-2);
}
// ïðîâåðêà êîððåêòíîñòè çàäàíèÿ ôèëüòðà ïî áàðàì
if(hole_min < 1)
hole_min = 1;
if(bars_ignore == false)
hole_min = 1;
// ïðîâåðêà êîððåêòíîñòè çàäàíèÿ ôèëüòðà ïî ãýïàì
if(gap_min < 0)
gap_min = 0;
if(gap_ignore == false)
gap_min = 0;
if(breakup_min < hole_min)
{
string message = StringConcatenate(WRONG_BREAKUP, BREAKUP_CHANGE, hole_min);
int warning_1 = MessageBox(message, WRONG_BREAKUP_HDR,
MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON1);
if(warning_1 == 1)
breakup_min = hole_min;
else
return(-1);
err = GetLastError();
if(err > 0)
return(error_out(err, "Âûâîä ñîîáùåíèÿ î êîððåêöèè êðèòåðèÿ ðàçðûâà"));
}
// ñîçäàíèå èìåíè ôàéëà
string date_start = TimeToStr(time_start, TIME_DATE);
string date_end = TimeToStr(time_end, TIME_DATE);
string file_name = StringConcatenate(symbol, "_", time_frame, "_holes_",
date_start, "-", date_end, ".csv");
// îòêðûòèå âûõîäíîãî ôàéëà
out_handle = FileOpen(file_name, FILE_CSV |FILE_WRITE, ";");
err = GetLastError();
if(out_handle < 0 || err > 0)
return(error_out(err, "Îòêðûòèå âûõîäíîãî ôàéëà"));
// àíàëèç äàííûõ èñòîðèè
int week_seconds = 604800; // êîëè÷åñòâî ñåêóíä â íåäåëå
double weeks; // îòíîøåíèå äèàïàçîíà äûðû ê êîëè÷åñòâó ñåêóíä â íåäåëå
// âûõîäíûå äíè â ñåê.
datetime holiday = StrToTime(begin_week_sessions) - StrToTime(end_week_sessions)
+ (24*3600*3) - duration_bar;
int hole_range; // äèàïàçîí äûðû
int bars_hole; // áàðîâ â äûðå
int holes_total_amount; // îáùåå êîëè÷åñòâî äûð
int breakup_total_amount; // îáùåå êîëè÷åñòâî ðàçðûâîâ
int bars_hole_amount; // îáùåå êîëè÷åñòâî áàðîâ â äûðàõ
int bars_breakup_amount; // îáùåå êîëè÷åñòâî áàðîâ â ðàçðûâàõ
int gap_total_amount; // îáùåå êîëè÷åñòâî ãýïîâ
int gap_holes; // îáùèé ãýï â äûðàõ
int gap_breakups; // îáùèé ãýï â ðàçðûâàõ
int hole_max; // çíà÷åíèå ìàêñèìàëüíîé äûðû
int breakup_max; // çíà÷åíèå ìàêñèìàëüíîãî ðàçðûâà
int gap_max; // çíà÷åíèå ìàêñèìàëüíîãî ãýïà
bool note_ = false;
double months, days, hours, minutes, seconds;
int n = 1;
for(int h = 0; h < bars; h++)
{
// âðåìÿ òåêóùåãî è ïðåäûäóùåãî áàðîâ â èñòîðèè
datetime bar_time_current, bar_time_previous;
// öåíà îòêðûòèÿ òåêóùåãî è öåíà çàêðûòèÿ ïðåäûäóùåãî áàðîâ â èñòîðèè
double open_price_current, close_price_previous;
if(!input_from_file)
{
bar_time_current = iTime(NULL, 0, Bars - h - 2);
bar_time_previous = iTime(NULL, 0, Bars - h - 1);
open_price_current = NormalizeDouble(Open[Bars - h - 2],4);
close_price_previous = NormalizeDouble(Close[Bars - h - 1],4);
}
else
{
bar_time_previous = FileReadInteger(in_handle, LONG_VALUE);
err = GetLastError();
// åñëè ôàéë çàêîí÷èëñÿ, çàâåðøàåì öèêë
if(err == 4099)
break;
if(err > 0)
return(error_out(err, "×òåíèå èç âõîäíîãî ôàéëà âðåìåíè ïðåä.áàðà"));
FileSeek(in_handle, 24, SEEK_CUR);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõ. ôàéëå ê ö.çàêð. ïðåä. áàðà"));
close_price_previous = FileReadDouble(in_handle, DOUBLE_VALUE);
if(err == 4099)
break; // åñëè ôàéë çàêîí÷èëñÿ, çàâåðøàåì öèêë
err = GetLastError();
if(err > 0)
return(error_out(err, "×òåíèå èç âõîäíîãî ôàéëà öåíû çàêðûòèÿ"));
FileSeek(in_handle, 8, SEEK_CUR);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõîäíîì ôàéëå ê ñëåä.áàðó"));
bar_time_current = FileReadInteger(in_handle, LONG_VALUE);
open_price_current = FileReadDouble(in_handle, DOUBLE_VALUE);
err = GetLastError();
if(err == 4099)
break; // åñëè ôàéë çàêîí÷èëñÿ, çàâåðøàåì öèêë
if(err > 0)
return(error_out(err, "×òåíèå èç âõ. ôàéëà ñëåä.áàðà"));
FileSeek(in_handle, -12, SEEK_CUR);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå âî âõîäíîì ôàéëå ê íà÷àëó áàðà"));
}
// ãýï â ïóíêòàõ
double abs_gap = MathAbs(open_price_current - close_price_previous);
double pips_gap = NormalizeDouble(abs_gap/point, 0);
// ôàêòè÷åñêèé äèàïàçîí òàéìôðåéìà ñ ó÷åòîì íåòî÷íîñòè
int time_frame_range = bar_time_current - bar_time_previous;
if(time_frame_range > duration_bar) // êîë-âî ñåêóíä â áàðå ïðåâûøàåò òàéìôðåéì
{
// êîë-âî ñåêóíä â áàðå ïðåâûøàåò êîëè÷åñòâî ñåêóíä â íåäåëå
if(time_frame_range > week_seconds)
{
// çíà÷åíèå äûðû â íåäåëüíîì âûðàæåíèè
weeks = MathFloor(time_frame_range / week_seconds);
if(TimeDayOfWeek(bar_time_previous) > TimeDayOfWeek(bar_time_current))
hole_range = time_frame_range - holiday * (1 + weeks) - duration_bar;
else
hole_range = time_frame_range - (holiday * weeks) - duration_bar;
}
else
{
weeks = 0;
if(TimeDayOfWeek(bar_time_previous) > TimeDayOfWeek(bar_time_current))
hole_range = time_frame_range - holiday - duration_bar;
else
hole_range = time_frame_range - duration_bar;
}
bars_hole = hole_range / duration_bar;
if(bars_hole >= hole_min && pips_gap >= gap_min)
{
holes_total_amount++; // îáùåå êîëè÷åñòâî äûð (óâåëè÷èâàåì)
// îáùåå êîëè÷åñòâî áàðîâ â äûðàõ (óâåëè÷èâàåì)
bars_hole_amount += bars_hole;
int gap;
if(pips_gap >= gap_min)
{
gap_holes += pips_gap; // îáùèé ãýï â äûðàõ
gap = pips_gap;
if(pips_gap == 0)
n = 0;
}
else
gap = 0;
seconds = bars_hole * duration_bar;
string duration_hole = interval_to_str(seconds);
if(bars_hole >= breakup_min)
{
// îáùåå êîëè÷åñòâî ðàçðûâîâ
breakup_total_amount++;
// îáùåå êîëè÷åñòâî áàðîâ â ðàçðûâàõ
bars_breakup_amount += bars_hole;
// îáùèé ãýï â ðàçðûâàõ
gap_breakups += pips_gap;
}
if(hole_max < bars_hole && bars_hole < breakup_min)
{
// ìàêñèìàëüíàÿ äûðà
hole_max = bars_hole;
// ï/ï íîìåð
int number_hole = holes_total_amount;
}
if(breakup_max <= bars_hole && bars_hole >= breakup_min)
{
// ìàêñèìàëüíûé ðàçðûâ
breakup_max = bars_hole;
// ï/ï íîìåð
int number_breakup = holes_total_amount;
}
if(gap_max <= pips_gap)
{
// ìàêñèìàëüíûé ãýï
gap_max = pips_gap;
// ï/ï íîìåð
int number_gap = holes_total_amount;
}
// ñîçäàíèå òàáëèöû *.csv ôàéëà
if(new_file && report_table)
{
if(report_summary)
{
FileSeek (out_handle, 2400, SEEK_END);
err = GetLastError();
if(err > 0)
return(error_out(err, "Ñìåùåíèå â ôàéëå äëÿ ñâîäêè"));
}
FileWrite(out_handle, "¹ ï/ï","Âðåìÿ íà÷àëà", "Âðåìÿ îêîí÷àíèÿ",
"Ðàçìåð (áàðîâ)", "Äëèòåëüíîñòü (ìèí)",
"Äëèòåëüíîñòü", "Ãýï (ïò)");
err = GetLastError();
if(err > 0)
return(error_out(err, "Çàïèñü øàïêè òàáëèöû"));
new_file = false;
}
FileWrite(out_handle, holes_total_amount,
TimeToStr(bar_time_previous + duration_bar),
TimeToStr(bar_time_current),
bars_hole, bars_hole*Period(),
duration_hole, gap);
err = GetLastError();
if(err > 0)
return(error_out(err, "Çàïèñü ñòðîêè òàáëèöû"));
// ìàêñèìàëüíàÿ äûðà è ðàçðûâ
int hole_range_max = number_hole;
int breakup_range_max = number_breakup;
int gap_range_max = number_gap;
}
}
}
// ëîâëÿ îøèáêè "èíäåêñ çà ïðåäåëàìè ìàññèâà"
err = GetLastError();
if(err > 0 && err != 4002)
return(error_out(err, "Ïîñëå îêîí÷àíèÿ ïåðåáîðà áàðîâ"));
// ñîçäàíèå îò÷åòà *.csv ôàéëà
double bars_hole_amount_ = bars_hole_amount;
double bars_breakup_amount_ = bars_breakup_amount;
double holes_total_amount_ = holes_total_amount;
double breakup_total_amount_ = breakup_total_amount;
double gap_holes_ = gap_holes;
double gap_total_amount_ = gap_total_amount;
double bars_ = bars;
double hole_average_size_;
if(holes_total_amount != breakup_total_amount)
{
seconds = (bars_hole_amount - bars_breakup_amount) * duration_bar;
string duration_holes = interval_to_str(seconds);
hole_average_size_ = NormalizeDouble((bars_hole_amount_ -
bars_breakup_amount_) /
(holes_total_amount_ -
breakup_total_amount_), 2);
int only_holes_total_amount_ = (holes_total_amount - breakup_total_amount);
int bars_only_hole_amount_ = (bars_hole_amount - bars_breakup_amount);
}
seconds = time_end - time_start;
string duration_period = interval_to_str(seconds);
if (holes_total_amount > 0)
{
seconds = bars_hole_amount * duration_bar;
string duration_holes_ = interval_to_str(seconds);
double hole_average_size = NormalizeDouble(bars_hole_amount_/holes_total_amount_,2);
string gap_average_size = NormalizeDouble(gap_holes_/holes_total_amount_, 2);
FileSeek(out_handle, 0, SEEK_SET);
err = GetLastError();
if (err > 0) return (error_out(err,"Ñìåùåíèå â íà÷àëî ôàéëà äëÿ çàïèñè îò÷¸òà"));
string hole_comment;
if (hole_min == breakup_min) hole_comment = "ñìîòðåòü <Ðàçðûâû>, ñîãëàñíî çàäàííûì"+
" ïîëüçîâàòåëåì óñëîâèÿì)";
else hole_comment = StringConcatenate(hole_min," - ",breakup_min," áàðîâ )");
hole_comment = StringConcatenate("ÄÛÐÛ ( ",hole_comment);
string breakup_comment = StringConcatenate("ÐÀÇÐÛÂÛ ( ",breakup_min," áàðîâ è âûøå)");
if (breakup_total_amount != 0)
{
seconds = bars_breakup_amount * duration_bar;
string duration_breakups = interval_to_str(seconds);
double breakup_average_size = NormalizeDouble(bars_breakup_amount_
/breakup_total_amount_, 2);
}
if (report_summary)
{
FileWrite(out_handle, "\nÎò÷åò ïî îòñóòñòâóþùèì áàðàì â äàííûõ èñòîðèè");
FileWrite(out_handle, "Èíñòðóìåíò - ",Symbol(),"Òàéìôðåéì",time_frame);
FileWrite(out_handle, "Ïåðèîä",date_start,date_end);
FileWrite(out_handle, "Áàðîâ â èñòîðèè",bars,"áàðîâ");
FileWrite(out_handle, "Äëèòåëüíîñòü (ìèí)",(time_end-time_start)/60,
duration_period);
FileWrite(out_handle, "\nÎÁÙÈÉ ÀÍÀËÈÇ äûð è ðàçðûâîâ");
FileWrite(out_handle, "Êîëè÷åñòâî",holes_total_amount);
FileWrite(out_handle, "Îáùèé ðàçìåð",bars_hole_amount,"áàðîâ");
FileWrite(out_handle, "Äëèòåëüíîñòü (ìèí)",
(bars_hole_amount*duration_bar)/60,duration_holes_);
FileWrite(out_handle, "Ñðåäíèé ðàçìåð",hole_average_size,"áàðîâ");
FileWrite(out_handle, "Îáùèé ãýï",gap_holes,"ïò");
FileWrite(out_handle,"Ìàêñèìàëüíûé ãýï",gap_max,"ïò","¹",gap_range_max);
FileWrite(out_handle, "Ñðåäíèé ãýï",gap_average_size,"ïò");
FileWrite(out_handle, "\n" + hole_comment);
FileWrite(out_handle, "Êîëè÷åñòâî",only_holes_total_amount_);
FileWrite(out_handle, "Ðàçìåð",bars_only_hole_amount_,"áàðîâ");
FileWrite(out_handle, "Äëèòåëüíîñòü (ìèí)",
(bars_hole_amount-bars_breakup_amount)*duration_bar/60,
duration_holes);
FileWrite(out_handle, "Ìàêñèìàëüíûé ðàçìåð",hole_max,"¹",hole_range_max);
FileWrite(out_handle, "Ñðåäíèé ðàçìåð",hole_average_size_);
FileWrite(out_handle, "\n" + breakup_comment);
FileWrite(out_handle, "Êîëè÷åñòâî",breakup_total_amount);
FileWrite(out_handle, "Ðàçìåð",bars_breakup_amount,"áàðîâ");
FileWrite(out_handle, "Äëèòåëüíîñòü (ìèí)",bars_breakup_amount*duration_bar/60,
duration_breakups);
FileWrite(out_handle, "Ìàêñèìàëüíûé ðàçìåð",breakup_max,"áàðîâ","¹",
breakup_range_max);
FileWrite(out_handle, "Ñðåäíèé ðàçìåð",breakup_average_size,"áàðîâ\n");
err = GetLastError();
if (err > 0) return (error_out(err,"Çàïèñü îò÷¸òà"));
}
}
else
{
FileWrite(out_handle, "Íà äàííîì ãðàôèêå äûð è ðàçðûâîâ ÍÅ ÎÁÍÀÐÓÆÅÍÎ");
err = GetLastError();
if (err > 0) return (error_out(err,"Çàïèñü \"Äûð íå îáíàðóæåíî\""));
}
FileClose(out_handle);
err = GetLastError();
if(err > 0)
return(error_out(err, "Çàêðûòèå ôàéëà"));
MessageBox(" ïàïêå òåðìèíàëà MT4: \Experts\files\ ñîçäàí ôàéë îò÷åòà:\n\n" + file_name,
"Àíàëèç äàííûõ èñòîðèè óñïåøíî çàâåðøåí", MB_OK | MB_DEFBUTTON1);
err = GetLastError();
if(err > 0)
return(error_out(err, "Âûâîä ñîîáùåíèÿ î çàâåðøåíèè ðàáîòû"));
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string interval_to_str(int seconds)
{
int hours = seconds / 3600;
int minutes = seconds % 3600 / 60;
string str_interval;
string zero_h = "", zero_m = "";
if(hours < 10)
zero_h = "0";
if(minutes < 10)
zero_m = "0";
str_interval = StringConcatenate(zero_h, DoubleToStr(hours, 0), ":",
zero_m, DoubleToStr(minutes, 0));
if(hours > 24)
{
int days = hours / 24; hours = hours % 24;
if(hours < 10)
zero_h = "0";
str_interval = StringConcatenate(DoubleToStr(days, 0), " äí. ",
zero_h, DoubleToStr(hours, 0), ":",
zero_m, DoubleToStr(minutes, 0));
if(days > 30)
{
int months = days/30; days = days%30;
str_interval = StringConcatenate(DoubleToStr(months,0)," ìåñ. ",
DoubleToStr(days,0)," äí. ",
zero_h,DoubleToStr(hours,0),":",
zero_m,DoubleToStr(minutes,0));
if(months > 12)
{
int years = months / 2; months = months % 12;
str_interval = StringConcatenate(DoubleToStr(years, 0), " ëåò ",
DoubleToStr(months, 0), " ìåñ. ",
DoubleToStr(days, 0), " äíåé ",
zero_h, DoubleToStr(hours, 0),":",
zero_m, DoubleToStr(minutes, 0));
}
}
}
return (str_interval);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int error_out(int err, string where)
{
if (err == 0) return;
string message = StringConcatenate("Îøèáêà ¹", err, ":\"", ErrorDescription(err), "\"\n",
"âîçíèêëà ïðè âûïîëíåíèè îïåðàöèè \"", where, "\"");
string caption = StringConcatenate("Âîçíèêëà îøèáêà â ìîäóëå: \"", FILE_NAME, "\"!");
MessageBox(message, caption, MB_OK | MB_ICONSTOP);
return (err);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string file_ext(string file_name)
{
string result = StringSubstr(file_name, StringLen(file_name) - 3, 3);
int err = GetLastError();
if(err > 0)
return(error_out(err, "Îáðàáîòêà çàäàííîé ñòðîêè-èìåíè ôàéëà"));
return (result);
}
//+------------------------------------------------------------------+
Comments