-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChartCloseIdle.mq5
88 lines (81 loc) · 3.35 KB
/
ChartCloseIdle.mq5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//+------------------------------------------------------------------+
//| ChartCloseIdle.mq5 |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include <MQL5Book/Periods.mqh>
#include <MQL5Book/MapArray.mqh>
#define PUSH(A,V) (A[ArrayResize(A, ArraySize(A) + 1) - 1] = V)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
MapArray<string,int> chartCounts;
ulong duplicateChartIDs[];
// collect duplicated idle charts
if(ChartIdleList(chartCounts, duplicateChartIDs))
{
for(int i = 0; i < ArraySize(duplicateChartIDs); ++i)
{
const ulong id = duplicateChartIDs[i];
// request the next idle chart to bring to front
ChartSetInteger(id, CHART_BRING_TO_TOP, true);
// refresh the windows, so the chart is actually brought to front
ChartRedraw(id);
// ask user confirmation for deletion
const int button = MessageBox(
"Remove idle chart: "
+ ChartSymbol(id) + "/" + PeriodToString(ChartPeriod(id)) + "?",
__FILE__, MB_YESNOCANCEL);
if(button == IDCANCEL) break;
if(button == IDYES)
{
ChartClose(id);
}
}
}
else
{
Print("No idle charts.");
}
}
//+------------------------------------------------------------------+
//| Main worker function to collect idle charts |
//+------------------------------------------------------------------+
int ChartIdleList(MapArray<string,int> &map, ulong &duplicateChartIDs[])
{
// keep enumerating all charts until no more found
for(long id = ChartFirst(); id != -1; id = ChartNext(id))
{
// skip objects with charts
if(ChartGetInteger(id, CHART_IS_OBJECT)) continue;
// obtain main properties of the chart
const int win = (int)ChartGetInteger(id, CHART_WINDOWS_TOTAL);
const string expert = ChartGetString(id, CHART_EXPERT_NAME);
const string script = ChartGetString(id, CHART_SCRIPT_NAME);
const int objectCount = ObjectsTotal(id);
// calculate number of indicators (if any)
int indicators = 0;
for(int i = 0; i < win; ++i)
{
indicators += ChartIndicatorsTotal(id, i);
}
const string key = ChartSymbol(id) + "/" + PeriodToString(ChartPeriod(id));
if(map[key] == 0 // always count first time occurence of symbol/timeframe
// otherwise count only empty charts:
|| (indicators == 0 // no indicators
&& StringLen(expert) == 0 // no expert
&& StringLen(script) == 0 // no script
&& objectCount == 0)) // no objects
{
const int i = map.inc(key);
if(map[i] > 1) // duplicate
{
PUSH(duplicateChartIDs, id);
}
}
}
return map.getSize();
}
//+------------------------------------------------------------------+